fix(gate): skip the Rust build cache on a repo with no Cargo manifest - #55
Merged
Conversation
Swatinem/rust-cache shells out to `cargo metadata`, which fails outright where there is no Cargo.toml: `error: could not find Cargo.toml`. The step ran unconditionally, so it failed the whole gate for a cache it could never have populated. Not every consumer of this gate is a Rust repo. typikon passes `true` for fmt, clippy and nextest and uses check_cmd for its own non-Rust checks -- deliberately, with a comment saying so -- and has no Cargo.toml anywhere in its tree. Its gate has been failing on this step rather than on anything it actually checks. The guard is a positive test for what the cache needs, so a repo that gains Rust later picks the cache back up with no further change, and a repo that never had it stops being asked for one. Both event-shape checkers still pass: gate evaluation 10/10, and 16 pull_request-only values examined with none reaching git unguarded.
forkwright added a commit
to forkwright/typikon
that referenced
this pull request
Aug 25, 2026
## Finding This repo's gate has been failing on a defect **already fixed upstream**, and the failure looked like typikon's problem rather than a stale pin. The mechanism: `hybrid-gate.yml` ran `Swatinem/rust-cache` unconditionally, which shells out to `cargo metadata` and fails outright here — ``` error: could not find `Cargo.toml` ``` — because typikon has **no `Cargo.toml` anywhere**. That is deliberate: this repo passes `fmt_cmd: "true"`, `clippy_cmd: "true"`, `nextest_cmd: "true"` and uses `check_cmd` for its own non-Rust checks, and the caller says so in a comment. Fixed in `forkwright/.github#55`, which guards that step on a manifest existing. ## Why the fix could not reach here This repo pins the reusable **by SHA**, and `forkwright/.github` publishes **no tags** — so dependabot has no version to compare a SHA against and never touches the line. The pin does not get bumped; it freezes. ## The previous comment's concern, answered rather than deleted It said: a mutable branch ref lets the remote workflow's behaviour change under an already-merged commit. That is true, and it is the real tradeoff. But the mitigation it proposed was a **manual** refresh — `gh api repos/forkwright/.github/commits/main --jq '.sha'`, review the diff, bump. Nobody ran it. So the pin did not stay reviewed; it just went stale, far enough that the gate started failing on something fixed upstream. A first-party reusable that holds none of our secrets is not the supply-chain case a SHA pin exists for. The ci-substrate SPEC settles the convention — *"Triggers + permissions + inputs live in the caller; logic is delegated. Pin `@main`."* A floating first-party ref **cannot** go stale, which is a stronger property than any process for keeping it fresh. `akroasis` froze in exactly this way, on a revision predating a fix, while its own comment asserted dependabot was maintaining the pin. ## Note This PR runs its own gate against the **floated** ref, since `pull_request` workflows execute the workflow file from the head branch — so a green check here is evidence the fix works, not just that the syntax parses. Co-authored-by: forkwright <cody@forkwright.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Finding
Swatinem/rust-cacheshells out tocargo metadata, which fails outright on a repo with noCargo.toml:The step ran unconditionally, so it failed the entire gate for a cache it could never have populated.
Not every consumer is a Rust repo
typikoncalls this gate withfmt_cmd: "true",clippy_cmd: "true",nextest_cmd: "true"and usescheck_cmdfor its own non-Rust checks. That is deliberate — its caller carries a comment saying the repo "has no Rust code of its own". Confirmed: there is noCargo.tomlanywhere in typikon's tree.Its gate has therefore been failing on a cache step rather than on anything it actually checks. Same shape applies to any other non-Rust consumer.
This is the fleet's own standard as a defect rather than as prose —
FLEET-REPO-SETUP.mdsays adding Rust CI to a repo with no crates "produces a job that fails looking for a build, on every push, forever." That is exactly what happened here, from the reusable's side rather than the consumer's.The guard
A positive test for what the cache actually needs. A repo that gains Rust later picks the cache back up with no further change; a repo that never had it stops being asked for one.
Verification
Both event-shape checkers pass against the edited file:
YAML parses; the five jobs are unchanged.
Note for consumers
This reaches repos that float
@mainon their next push.typikoncurrently pins this workflow by SHA with a# maincomment — the shape that cannot be bumped, since this repo publishes no tags — so it will not receive the fix until that pin moves. That is being handled separately.