From 044277818ff108f334552dd2a68584caeb1a3962 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" Date: Sun, 25 Oct 2026 20:46:27 +0000 Subject: [PATCH] fix(ci): carry a composite action's dependencies to the entry the workflow names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The lockfile blocks were restored but Pages still failed in Set up job with the same message. The reason is which entry carries the dependency list: 'actions/upload-pages-artifact@v5.0.0': <- gh actions-lock wrote `uses:` here ... uses: - 'actions/upload-artifact@bbbca2dd…' 'actions/upload-pages-artifact@fc324d35…': <- the workflow names THIS one ref: 'v5.0.0' ... The tag-keyed entry had the `uses:` list; the workflow re-pinned to the SHA, so GitHub resolved the SHA entry, found no dependency list, and refused the job. Restoring the block was necessary and not sufficient. Regeneration now copies the `uses:` list onto every entry describing the same commit, so a re-pin cannot separate an action from the actions it resolves. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com> --- .github/workflows/actions.lock | 2 ++ scripts/ci/pin-workflow-uses.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index 8c3d7e6..a044762 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -182,6 +182,8 @@ dependencies: commit: 'sha1-fc324d3547104276b827a68afc52ff2a11cc49c9' owner_id: 44036562 repo_id: 496012378 + uses: + - 'actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f' 'actions/upload-pages-artifact@v5.0.0': ref: 'v5.0.0' commit: 'sha1-fc324d3547104276b827a68afc52ff2a11cc49c9' diff --git a/scripts/ci/pin-workflow-uses.py b/scripts/ci/pin-workflow-uses.py index 7c71fc2..b3e4778 100755 --- a/scripts/ci/pin-workflow-uses.py +++ b/scripts/ci/pin-workflow-uses.py @@ -284,6 +284,34 @@ def build_lock(pins: dict[str, dict[str, str]], existing: str) -> str: out.append("dependencies:") merged = dict(preserved) merged.update(new_blocks) + + # A composite action's own dependencies are recorded on whichever entry + # `gh actions-lock` happened to write them against — in practice the + # TAG-keyed one. GitHub resolves them from the entry the workflow actually + # names, which after a re-pin is the SHA-keyed one. Carry the `uses:` list + # across to every entry describing the same commit, or a re-pinned workflow + # dies in Set up job with "lockfile missing pin for ". + deps_by_commit: dict[str, list[str]] = {} + for lines in merged.values(): + fields = block_fields(lines) + if "uses" in fields or any(l.lstrip().startswith("uses:") for l in lines): + pass + try: + idx = next(i for i, l in enumerate(lines) if l.strip() == "uses:") + except StopIteration: + continue + commit = fields.get("commit", "") + if commit: + deps_by_commit.setdefault(commit, lines[idx:]) + + for key, lines in merged.items(): + if any(l.strip() == "uses:" for l in lines): + continue + commit = block_fields(lines).get("commit", "") + extra = deps_by_commit.get(commit) + if extra: + merged[key] = lines + list(extra) + for key in sorted(merged): out.extend(merged[key]) return "\n".join(out) + "\n"