Summary
gh aw compile adds newly-referenced action SHAs to .github/aw/actions-lock.json but never removes entries that no workflow references anymore. After an action version bump, the old pin lingers indefinitely. There is no gh aw command to prune it, so the lock accumulates stale, unreferenced SHA pins that must be hand-edited out.
Steps to reproduce
- In a workflow (or vendored shared workflow), bump a pinned action, e.g.
microsoft/apm-action@v1.7.2 → @v1.9.1.
gh aw compile.
- Inspect
.github/aw/actions-lock.json.
Expected
The lock contains only pins referenced by the compiled workflows — the v1.7.2 entry is removed when nothing references it.
Actual
Both v1.7.2 and v1.9.1 entries are present. The compiled .lock.yml references only v1.9.1; the v1.7.2 entry is orphaned and never removed by recompiling.
This is an additive rewrite, not a no-op: the same compile added the v1.9.1 pin (it was not in the lock beforehand), so it demonstrably rewrote actions-lock.json — and in that same pass it retained v1.7.2, which the recompiled .lock.yml no longer references. Compile adds newly-referenced pins but does not remove orphaned ones.
Note: gh aw compile --purge deletes stale .lock.yml files, not orphaned entries inside actions-lock.json — there is no flag for the latter, so the orphan must be removed by hand.
Impact
Stale pins accumulate one per bump. In supply-chain / compliance review, a lock file listing SHA pins that no workflow uses is misleading — an auditor can't tell at a glance which pins are live versus dead weight, and dead pins read as unexplained surface area. Removing them is currently a manual JSON edit (easy to get wrong; no tooling guard).
Proposed change
Either of:
gh aw compile garbage-collects actions-lock.json entries not referenced by any compiled workflow in the target directory (the default — keeps the lock a faithful reflection of what's actually used).
- A
--prune flag on compile, or a gh aw lock --prune subcommand, for opt-in cleanup (safer if there are intended-but-not-yet-referenced pins).
Option 1 matches the mental model that the lock mirrors current uses: references; option 2 is the conservative alternative if silent removal is a concern.
Workaround (today)
Manually delete the orphaned entry from .github/aw/actions-lock.json after a version bump. A subsequent gh aw compile does not re-add it (nothing references it) and does not otherwise rewrite the file, so the manual prune is stable.
Summary
gh aw compileadds newly-referenced action SHAs to.github/aw/actions-lock.jsonbut never removes entries that no workflow references anymore. After an action version bump, the old pin lingers indefinitely. There is nogh awcommand to prune it, so the lock accumulates stale, unreferenced SHA pins that must be hand-edited out.Steps to reproduce
microsoft/apm-action@v1.7.2→@v1.9.1.gh aw compile..github/aw/actions-lock.json.Expected
The lock contains only pins referenced by the compiled workflows — the
v1.7.2entry is removed when nothing references it.Actual
Both
v1.7.2andv1.9.1entries are present. The compiled.lock.ymlreferences onlyv1.9.1; thev1.7.2entry is orphaned and never removed by recompiling.This is an additive rewrite, not a no-op: the same compile added the
v1.9.1pin (it was not in the lock beforehand), so it demonstrably rewroteactions-lock.json— and in that same pass it retainedv1.7.2, which the recompiled.lock.ymlno longer references. Compile adds newly-referenced pins but does not remove orphaned ones.Note:
gh aw compile --purgedeletes stale.lock.ymlfiles, not orphaned entries insideactions-lock.json— there is no flag for the latter, so the orphan must be removed by hand.Impact
Stale pins accumulate one per bump. In supply-chain / compliance review, a lock file listing SHA pins that no workflow uses is misleading — an auditor can't tell at a glance which pins are live versus dead weight, and dead pins read as unexplained surface area. Removing them is currently a manual JSON edit (easy to get wrong; no tooling guard).
Proposed change
Either of:
gh aw compilegarbage-collectsactions-lock.jsonentries not referenced by any compiled workflow in the target directory (the default — keeps the lock a faithful reflection of what's actually used).--pruneflag oncompile, or agh aw lock --prunesubcommand, for opt-in cleanup (safer if there are intended-but-not-yet-referenced pins).Option 1 matches the mental model that the lock mirrors current
uses:references; option 2 is the conservative alternative if silent removal is a concern.Workaround (today)
Manually delete the orphaned entry from
.github/aw/actions-lock.jsonafter a version bump. A subsequentgh aw compiledoes not re-add it (nothing references it) and does not otherwise rewrite the file, so the manual prune is stable.