Skip to content

gh aw compile never prunes orphaned entries from actions-lock.json #39882

@anthonymastreanvae

Description

@anthonymastreanvae

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

  1. In a workflow (or vendored shared workflow), bump a pinned action, e.g. microsoft/apm-action@v1.7.2@v1.9.1.
  2. gh aw compile.
  3. 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:

  1. 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).
  2. 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.

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions