version: "3" chore_min_version: 0.6.0 # THE DEPENDENCY MODEL THIS FILE OWNS. # # This repo depends on two different KINDS of thing, and they get two # different mechanisms. Getting that split right is the whole point: # # FAMILY REPOS -> siblings, checked out next to this one. # am-fs-core, am-fs-ext4, winfsp-fs-skeleton, fs-windows-test-harness. # These release together and are expected to agree on a version at # any given moment. A submodule pins a copy PER CONSUMER, so the # same crate ends up on disk several times at several versions with # nothing reporting the divergence -- each repo being internally # consistent with its own stale pin. A sibling has one copy, so # that drift is not merely detected, it is unrepresentable. # # It had already happened here. Before this file existed, this repo # pinned am-fs-core at v0.1.0 while the rest of the family was on # v0.2.4, and pinned am-fs-ext4 and winfsp-fs-skeleton to # `heads/main` -- floating refs, which the dependency-pinning policy # forbids outright, and which mean the build was not reproducible. # # THIRD-PARTY FORKS -> siblings as well, pinned to a COMMIT. # winfsp-rs is our fork of SnowflakePowered/winfsp-rs on the # gnullvm-support branch, carrying a patch that is not ours to # release and not on a schedule we control. It used to be a # submodule at vendor/winfsp-rs; it is now checked out at # ../winfsp-rs like everything else, so there are no submodules # left. Because a fork has no release cadence of ours, it is pinned # to a bare commit (WINFSP_RS_REF) rather than a tag, and both CI # workflows patch a header inside that checkout. vars: # The family pins. One place, read by both `chore siblings` and the # CI workflow -- CI parses them out of this file rather than # restating them, so bumping one is still a one-line edit. # URL as well as ref, because the family is NOT all in one org -- # rust-fs-ext4 and rust-fs-ntfs live under christhomas/ while the rest # are under antimatter-studios/. Anything that reconstructs a URL from # the repo name gets that wrong for exactly two of them, and the # failure is an interactive credential prompt on a private-looking # URL rather than a clean 404, so it reads as an auth problem. FS_CORE_URL: https://github.com/antimatter-studios/rust-fs-core.git FS_CORE_REF: v0.2.4 FS_EXT4_URL: https://github.com/christhomas/rust-fs-ext4.git FS_EXT4_REF: v0.5.0 # Pinned to the tag, not to `main`. A floating ref was one of the two # things wrong with the submodule setup this file replaces, and # swapping a floating submodule for a floating sibling would have # fixed nothing. Bump this when the skeleton next releases -- its # `translate` and `reader` modules are what this driver will move to. SKELETON_URL: https://github.com/antimatter-studios/winfsp-fs-skeleton.git SKELETON_REF: v0.2.1 # Pinned to a COMMIT, not a branch. This is a fork of a third-party # crate, so there is no release cadence of ours to track, and upstream # 0.13.0 does not compile for *-pc-windows-gnullvm -- it declares the # guard-strategy constant signed while bindgen emits it unsigned for # that target. WINFSP_RS_URL: https://github.com/antimatter-studios/winfsp-rs.git WINFSP_RS_REF: 59ab48bca2a67c95d4eba640343b6b80b87bb6ea HARNESS_URL: https://github.com/antimatter-studios/fs-windows-test-harness.git HARNESS_REF: v4.0.0 tasks: siblings: desc: Check out the sibling repos this crate builds against, at their pinned refs # REFUSES TO TOUCH A DIRTY SIBLING. A checkout is destructive to # uncommitted work, and a task that runs in CI must not be a task # that eats someone's afternoon when they run it locally. It # reports and fails; the human decides. cmds: - | set -eu # nameurlref printf '%s\t%s\t%s\n' \ rust-fs-core '{{.FS_CORE_URL}}' '{{.FS_CORE_REF}}' \ rust-fs-ext4 '{{.FS_EXT4_URL}}' '{{.FS_EXT4_REF}}' \ winfsp-fs-skeleton '{{.SKELETON_URL}}' '{{.SKELETON_REF}}' \ fs-windows-test-harness '{{.HARNESS_URL}}' '{{.HARNESS_REF}}' \ winfsp-rs '{{.WINFSP_RS_URL}}' '{{.WINFSP_RS_REF}}' \ | while IFS="$(printf '\t')" read -r name url ref; do dir="../$name" if [ ! -d "$dir/.git" ]; then echo "siblings: cloning $name at $ref" # init + fetch-by-ref, not clone. One of these refs is a # bare commit, and `git clone --branch` takes a ref NAME # only. A plain clone does not help either: that commit is # reachable from no published branch, so it simply is not # in the result. `git fetch origin ` asks the server # for it directly, which GitHub serves. git init --quiet "$dir" git -C "$dir" remote add origin "$url" git -C "$dir" fetch --quiet --depth 1 origin "$ref" git -C "$dir" checkout --quiet FETCH_HEAD continue fi if [ -n "$(git -C "$dir" status --porcelain)" ]; then echo "siblings: $name has uncommitted changes -- refusing to move it." >&2 echo " Commit or stash them in $dir, then re-run." >&2 exit 1 fi current=$(git -C "$dir" rev-parse HEAD) # Fetch the ref itself rather than everything: this also has # to work for a bare commit that no branch contains, which # `fetch --tags` would never bring down. git -C "$dir" fetch --quiet origin "$ref" wanted=$(git -C "$dir" rev-parse FETCH_HEAD) if [ "$current" = "$wanted" ]; then echo "siblings: $name already at $ref" continue fi echo "siblings: moving $name to $ref" git -C "$dir" checkout --quiet FETCH_HEAD done siblings:check: desc: Report whether the siblings are at their pinned refs, changing nothing cmds: - | set -eu rc=0 printf '%s\t%s\n' \ rust-fs-core '{{.FS_CORE_REF}}' \ rust-fs-ext4 '{{.FS_EXT4_REF}}' \ winfsp-fs-skeleton '{{.SKELETON_REF}}' \ fs-windows-test-harness '{{.HARNESS_REF}}' \ | while IFS="$(printf '\t')" read -r name ref; do dir="../$name" if [ ! -d "$dir/.git" ]; then echo "siblings: $name is not checked out (want $ref)" >&2 rc=1 continue fi have=$(git -C "$dir" describe --tags --always 2>/dev/null || echo unknown) printf ' %-24s %s (want %s)\n' "$name" "$have" "$ref" done exit $rc check: desc: Type-check the parts that build off Windows cmds: - cargo check --locked --no-default-features test: desc: Run the tests that do not need Windows cmds: - cargo test --locked --no-default-features