Repository navigation
v0.1.6: job-level reusable-workflow uses: refs are invisible — missed desync, false stale, and fix mode prunes a correct entry #129
Description
Summary
gh actions-lock v0.1.6 does not appear to consider job-level reusable-workflow uses:
refs (jobs.<id>.uses:) when reconciling workflows against actions.lock. GitHub's own
startup validation does enforce them, so the tool disagrees with the platform in both
directions:
- a missed desync that caused a real startup failure and was reported by nothing, and
- a false
staleon a ref that is present in the workflow.
Consequently fix mode would prune a lockfile entry that is actually required, reintroducing
the startup failure.
Environment
gh actions-lockv0.1.6 (gh extension install github/gh-actions-lock --pin v0.1.6)- lockfile
version: 'v0.0.2', 30–31 workflows - public repository, Linux runner and local Linux both reproduce
1. Missed desync (false negative) — caused a startup failure
A workflow whose only uses: is job-level:
# .github/workflows/mirror.yml
jobs:
mirror:
uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@4d104d325b96c348d685956c6678139640c15c4bactions.lock recorded the previous commit under that path:
workflows:
'.github/workflows/mirror.yml':
- 'hyperpolymath/standards@d135b05b...'Observed:
- GitHub refused to start the run — zero jobs created, no log, only
"This run likely failed because of a workflow file issue." gh actions-lock --no-fix→ not reportedgh actions-lock --verify-local→ not reported; output was
"All 30 workflows have complete lockfile coverage"- fix mode → did not repair the entry
So a desync that GitHub treats as fatal is invisible to all three modes.
2. False stale (false positive)
A different workflow with a job-level ref on line 144:
# .github/workflows/release.yml:144
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0This ref was absent from the lock entirely and was not reported as missing. After adding
the required entry by hand, --verify-local reports:
{
"workflow": ".github/workflows/release.yml",
"category": "stale",
"severity": "warning",
"confidence": "high",
"dependency": "slsa-framework/slsa-github-generator@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a",
"detail": "lockfile pins slsa-framework/slsa-github-generator@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a but no uses: in this workflow references it",
"remediation": "remove the entry or re-run `gh actions-lock`"
}The claim "no uses: in this workflow references it" is false; the ref is on line 144.
Following the remediation — removing the entry — reintroduces the startup failure from §1.
Why the two cases differ
mirror.yml parses 0 step-level refs, so the stale check appears to be skipped for it.
release.yml parses 9 step-level refs, so the unmatched job-level entry looks orphaned. That
also means fix mode would prune the correct slsa entry as stale, which is the most
damaging consequence: running the tool on a correct lockfile makes it incorrect.
Suggested fix
Treat jobs.<id>.uses: as a dependency reference, normalising
owner/repo/.github/workflows/<file>@<ref> to owner/repo@<ref> the same way action subpaths
are normalised today, for coverage, staleness and fix mode alike.
Related
severity is warning for both stale and sha-as-ref, so downstream tooling cannot use
severity to distinguish an advisory finding from a blocking one. That may be worth separating.
Reported separately: the management banner is not idempotent and fix mode de-pins bare SHAs (#130).
🤖 Generated with Claude Code
Activity
chore(ci): bump standards pins fcb566cf → e977cc67, regenerating acti…
Docs: correct the reusable workflow gap and guard the update job
Docs: mark the reusable workflow guidance as under review