Repository navigation
fix(lock): follow local composite actions in the lock chain; merge relock duplicates; drop the composite refusal - #1242
Merged
Conversation
…gate standards#1122, criteria 1 and 2. A local composite action (`uses: ./.github/actions/x`) has no dependency record of its own, so the actions it uses are locked under the CALLING workflow's entry; that is where `gh actions-lock` writes them. Three scripts read only workflow files: - prune-stale.sh: both oracles (parser, literal grep) now read the workflow and every local composite it reaches, so composite refs are no longer pruned. Its parser also strips a KYAML trailing comma, as check-lock-sync.sh already did. - check-lock-sync.sh: a workflow's uses: set includes its composites'. The issue's planted negative (the two composite lines deleted from signed-push-smoke.yml's entry) now fails; it passed before. - complete-job-refs.sh: adds composite refs to the calling entry, so the chain produces them whatever the tool does. The three share one reach block word for word (check-lock-sync.sh is copied to other repos, so it stays self-contained); a test fails if the copies drift. Composites are followed transitively; a local reusable workflow (./x.yml) is its own entry and is not followed. actions.lock: complete-job-refs restored the one line prune-stale had removed: actions/create-github-app-token under signed-push-smoke.yml (used by .github/actions/signed-push). relock-sha-keys, close-lock and prune-stale then change nothing. Tests: composite fixtures, nested and KYAML-quoted, in all three suites. Composite-blind mutants fail 2 cases in each. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GqfpQtLuMczxtgG1U9PkLW
standards#1122, criterion 3. When the lock already holds a SHA-keyed
record for a commit and `gh actions-lock` adds a tag-keyed record for
the same commit, re-keying the tag to the SHA left two records under one
key, which the lockfile reader rejects ("already defined"). A new pass
keeps the first record and drops the duplicate with its body, and a list
(workflow entry, record uses:) that now names a ref twice keeps it once.
New suite scripts/tests/relock-sha-keys-test.sh: the planted duplicate
fails 5 assertions on the old script and passes on the new; plain re-key,
tag-kept-when-still-written and idempotence are covered too. On a copy of
this repo's lock the script changes nothing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GqfpQtLuMczxtgG1U9PkLW
standards#1122, criterion 4. regen-dependabot-locks.sh refused any repo with .github/actions/ as `composite-unsupported`, because the chain dropped composite refs and --verify-local still passed the result. The chain now keeps and adds them, and regen_lock runs check-lock-sync.sh after --verify-local: a lock it rejects is `unverified`, not committed. That is also the gate the PR meets in CI, and it catches job-level reusable refs, which --verify-local cannot see either. Tests: the composite fixture now regenerates (`changed`); a lock the sync check rejects is `unverified`. The issue's own acceptance run (the full chain with `gh actions-lock` on main, accepted by --verify-local) needs the tool, which is not available in the session that wrote this; it is left to the owner. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GqfpQtLuMczxtgG1U9PkLW
Contributor
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 24 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Contributor
K9 contract conformancerun https://github.com/hyperpolymath/standards/actions/runs/38496144712 K9 normative contract typecheckK9 contract self-testK9 conformance fixturesK9 corpus conformance (L2) |
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.



Closes #1122 (owner-requested 2026-10-14). There is one commit per acceptance criterion; criteria 1 and 2 share a commit.
Background. A local composite action (
uses: ./.github/actions/x) has no dependency record of its own. The actions it uses are therefore locked under the calling workflow's entry, which is wheregh actions-lockwrites them. External composites differ: their dependencies live in their own record'suses:list.1 + 2. Follow local composites (
290482f3)prune-stale.sh. Both of its oracles (the parser and the literal grep) now read the workflow plus every local composite it reaches, so composite refs are no longer pruned. Its parser also strips a KYAML trailing comma, ascheck-lock-sync.shalready did.check-lock-sync.sh. A workflow'suses:set now includes those of its composites. The issue's planted negative was the two composite lines deleted fromsigned-push-smoke.yml's entry. It now fails; before this PR it passed.complete-job-refs.sh. Adds composite refs to the calling workflow's entry, so the chain produces them whether or not the tool does.check-lock-sync.shis copied to other repos, so it has to stay self-contained, and a test fails if the three copies drift. Composites are followed transitively. A local reusable workflow (./x.yml) has its own entry and is not followed.actions.lock. Runningcomplete-job-refs.shrestored the one line prune-stale had removed:actions/create-github-app-tokenundersigned-push-smoke.yml. Re-running relock-sha-keys, close-lock and prune-stale afterwards changes nothing. With the stricter check,check-lock-sync.shpasses on the real lock.3. relock-sha-keys merges duplicates (
d2c89119)scripts/tests/relock-sha-keys-test.sh. The planted duplicate fails 5 assertions on the old script and passes on the new one. On a copy of this repo's lock, the script changes nothing.4. Composite repos no longer refused (
b07a8f5d)regen-dependabot-locks.shdropscomposite-unsupported.regen_locknow runscheck-lock-sync.shafter--verify-local. A lock the sync check rejects is reported asunverifiedand not committed. This is also the gate the PR meets in CI, and it catches job-level reusable refs, which--verify-localcannot see either.Not done here
The issue's own acceptance run, the full chain with
gh actions-lockon main accepted by--verify-local, needs the tool, which is not available in the session that wrote this PR. CI'sActions lockfile verifyjob runs--verify-localwith the real tool on this PR's lock. The owner can run the full chain locally as well.Testing
prune-stale-test18/18check-lock-sync-test13/13complete-job-refs-test16/16relock-sha-keys-test11/11regen-dependabot-locks-test35/35mainin this sandbox, which lacks KYAML-capable yq, the JCS tool, Ruby andgh actions-lock.🤖 Generated with Claude Code
https://claude.ai/code/session_01GqfpQtLuMczxtgG1U9PkLW
Generated by Claude Code