{{ message }}
Repository navigation
Prune deleted workflows from the lockfile on a full scan - #87
Merged
nodeselector merged 5 commits intoJul 24, 2026
Merged
nodeselector merged 5 commits into
nodeselector merged 5 commits into
Conversation
A workflow deleted from .github/workflows/ left its entry lingering in actions.lock forever. State.Save() garbage-collects orphan dependency entries but never orphan workflow entries, and discovery only ever sees files still on disk, so the stale key (and the pins it kept alive) was never removed. The only workaround was a full from-scratch regenerate, which also re-pins branch refs as a side effect. Reconcile the recorded workflow set against disk on a full-directory scan (no explicit path args) — the only invocation with the authority to declare a workflow deleted. Fix runs prune the stale keys before the lockfile is saved, letting the existing orphan-dependency GC drop the freed pins, and report the count in the summary. Read-only runs (--no-fix / --verify) surface each stale entry as a non-blocking stale-workflow info finding instead of modifying anything. Partial invocations that name specific workflows never prune out-of-scope entries. Resolves github/actions-dispatch#816
There was a problem hiding this comment.
⚠️ Not ready to approve
Empty full scans still fail before pruning the final deleted workflow.
Pull request overview
Adds full-scan cleanup of deleted workflow entries and orphaned dependencies.
Changes:
- Adds lockfile workflow enumeration and pruning.
- Reports stale workflows in read-only and JSON output.
- Adds documentation and regression tests.
File summaries
Review details
- Files reviewed: 9/9 changed files
- Comments generated: 1
- Review effort level: Medium
Note
Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
A full scan that discovers zero workflow files aborted in discoverWorkflowPaths with "no workflow files found" before the lockfile was ever loaded, so deleting the final workflow stranded its lockfile entry and orphaned deps indefinitely. Let a full scan (no explicit paths) proceed with an empty discovery so the lockfile still loads and the stale entry is pruned. When there's nothing on disk and nothing recorded, keep the original error. Explicit path runs are unchanged. Add integration coverage for deleting the last workflow (fix and --no-fix) and the empty-repo error, plus a shared catalog scenario for full-scan pruning.
The empty-scan guard ran after the resolver was built, so an empty repo with no token failed with "authentication token not found" instead of "no workflow files found" — breaking the no_workflows stub scenario in CI (which runs without auth). WorkflowKeys() needs no metadata resolver, so move the guard ahead of resolver construction. The last-deleted- workflow prune path still proceeds to the resolver as before.
The two "no workflow files found in …" strings were inlined again after the helper was extracted, so the wording could drift. Call the helper.
…6-deleted-workflows-not-pruned-from-lockfi-5a68ae # Conflicts: # README.md # cmd/gh-actions-lock/run.go # internal/pipeline/checks/category.go # internal/pipeline/checks/category_test.go # internal/pipeline/checks/finding.go
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 free
to 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.

What
Deleted workflows were never pruned from
.github/workflows/actions.lock. Their entries lingered forever because discovery only ever sees on-disk files, so a removed workflow was simply never revisited.Why
State.Save()garbage-collects orphaned dependency entries but never removes orphaned workflow entries. Once a workflow file is deleted, nothing rediscovers its key, so the stale entry stays in the lockfile indefinitely.Fix
internal/lockfile/state.go: addWorkflowKeys()andPruneWorkflows(keep)—PruneWorkflowsdrops workflow keys not present on disk and relies on the existingSave()orphan-dep GC to clean up now-unreferenced deps.cmd/gh-actions-lock/run.go: on a full-directory scan only (no explicit path args), compute the set of on-disk workflows and prune the rest before commit. Partial/targeted runs never prune, so out-of-scope workflows can't be dropped.stale-workflowinfo finding instead of removing them.internal/pipeline/checks/category.go/finding.go: add thestale-workflowcategory (additive) and map it as non-blocking inIsValid().pin_summary.go: report the pruned count.The category addition is intentionally additive-only to avoid conflicting with concurrent classification work.
Tests
internal/lockfile/prune_test.go: pruning removes stale entries + GCs orphaned deps, keeps shared deps, and no-ops when nothing is stale.cmd/gh-actions-lock/prune_workflow_test.go: full scans prune, partial runs don't, and--no-fixreports the stale entry as non-blocking.Resolves github/actions-dispatch#816