Skip to content

fix(release): read runner and Action pins from the lines Dependabot rewrites - #517

Merged
kyle-sexton merged 3 commits into
mainfrom
feat/510-pins-single-source
Oct 30, 2026
Merged

kyle-sexton merged 3 commits into
mainfrom
feat/510-pins-single-source

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Closes #510

Summary

Every Dependabot bump of a workflow uses: SHA or the Dockerfile FROM digest failed Product policy, because the release checks required those pins to match release/dependencies.json, which Dependabot cannot edit (#505, #506 and #514 were the replacement PRs). The pins are now read from the lines Dependabot rewrites.

Fix

  • scripts/ReleasePinSources.ps1 reads the runner image, version and digest from the single FROM ghcr.io/actions/actions-runner:<v>@sha256:<d> line, and each external Action's commit and version from its uses: ...@<sha> # vX.Y.Z lines. It fails with file:line when an Action has no release comment or two uses name different releases.
  • Test-ReleasePins.ps1, Test-DependencyFreshness.ps1 and New-CompatibilityManifest.ps1 use those values. verify-worker-image.sh and verify-existing-release.sh read the FROM line. The compatibility.json shape is unchanged.
  • release/dependencies.json drops runner and githubActions, and Test-ReleasePins.ps1 refuses them if they come back. Checksums, tooling digests, sources and the ci-workflows repositoryPins stay.
  • Runner archive checksum: the image is pulled by digest and never built from the archive, so the hand-copied archiveSha256 only fed the freshness gate. The gate now compares the asset digest GitHub reports with the SHA-256 published in the runner release notes (<!-- BEGIN SHA linux-x64 -->). Both values matched for v2.338.2, v2.338.1, v2.337.0, v2.336.0 and v2.334.0 (gh api repos/actions/runner/releases/tags/<tag>). A runner bump therefore needs no checksum edit.
  • Docs: Action bumps can now pass, so the existing vendor-actions lane (pr-automerge-dependabot.yml) will auto-merge minor and patch actions/*, github/* and anthropics/* bumps once ci-status passes. docs/releases.md and README.md said no update is ever auto-merged. They now describe that lane. The lane's config is unchanged.

Verification

  • pwsh scripts/Test-ReleasePins.ps1 passes.
  • node --test .github/scripts/*.test.cjs passes (27 tests). The new release-pins.test.cjs covers a grouped Action bump and a runner bump with no manifest edit, mismatched SHAs across files, and a missing release comment.
  • go test ./..., shellcheck and shfmt are clean.
  • Reversing build: bump actions/actions-runner from 2.338.0 to 2.338.2 in the worker-image group #500's Dockerfile diff and moving zizmor-action to its v0.7.1 pin, with no manifest edit, passes Test-ReleasePins.ps1.
  • The derived Action set is identical to the removed githubActions entries. New-CompatibilityManifest.ps1 emits the same dependencies object (runnerVersion 2.338.2).
  • Not run locally: the full Test-DependencyFreshness.ps1, which needs a release token. It runs at the next tag.

Related

🤖 Generated with Claude Code

https://claude.ai/code/session_01VcupojEVPjg9zYgTTu3TNk

…ewrites

Dependabot bumps of a workflow `uses:` SHA or the Dockerfile FROM digest
failed Product policy because Test-ReleasePins.ps1 and
verify-worker-image.sh required those pins to match
release/dependencies.json, which Dependabot cannot edit.

scripts/ReleasePinSources.ps1 now reads the runner image, version and
digest from the Dockerfile FROM line, and each external Action's commit
and version from its `uses: ...@<sha> # vX.Y.Z` lines, requiring one
release per repository. The release checks, freshness gate and
compatibility manifest use those values; the manifest drops its runner
and githubActions entries. The freshness gate checks the runner archive
digest against the SHA-256 the runner release notes publish instead of a
hand-copied checksum.

Closes #510

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcupojEVPjg9zYgTTu3TNk
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T22:45:55.441625Z 2013532 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2013532ac0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/scripts/release-pins.test.cjs Resolved
Comment thread scripts/verify-worker-image.sh Resolved
With Action bumps now passing Product policy, the vendor-actions lane
armed by pr-automerge-dependabot.yml merges minor and patch bumps once
ci-status passes; the docs said no update is ever auto-merged. The
freshness gate also excludes reusable-workflow repositories, as
Test-ReleasePins.ps1 does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcupojEVPjg9zYgTTu3TNk
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

claude-security-review reviewed 30e6c02461ca722fd595a13a5eed5adf876e54b4: 0 finding(s), 0 as inline comments.

Security review: PR #517, incremental since 04d9109

I found no security issues in the three files changed since the last review: .github/scripts/release-pins.test.cjs, Dockerfile and scripts/verify-worker-image.sh. I read .claude-lane/incremental.diff and used the full PR diff only for context.

  • Dockerfile: the change removes the org.opencontainers.image.base.name and base.digest labels. The FROM ghcr.io/actions/actions-runner:<ver>@sha256:… line still pins the base by digest, and that line is what determines which base image is built. The labels were self-declared metadata, so removing them does not weaken the supply-chain control. No token, scope, trust control or runtime invariant (user, hooks, entrypoint) changed.
  • scripts/verify-worker-image.sh: the verifier still requires exactly one FROM line with a pinned version and a @sha256:<64 hex> digest. It only stops comparing a label to that digest. The new check, (.Labels | has("org.opencontainers.image.base.digest") | not), makes sure a stale label is not left in the image. The checks on user, working directory, command, entrypoint, volumes and hook environment variables are unchanged. Nothing in the script takes new untrusted input, and the sed and jq calls take no attacker-controlled values.
  • .github/scripts/release-pins.test.cjs: the test now reads its fixture pins from the repository's own workflows and Dockerfile instead of hard-coded values. It runs only against a temporary copy of the repository and does not run in a credentialed context. It adds no network, exec or secret handling. The regexes are anchored and run on repository-owned files.

Trust-control and manifest lens: none of the changed files is a trusted-path or hold-path file. There is no plugin manifest or instruction-surface change. No pin was loosened, and no action, permission or token scope changed.

critical-findings: 0

Comment thread .github/scripts/release-pins.test.cjs Resolved
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

claude-review reviewed 30e6c02461ca722fd595a13a5eed5adf876e54b4: 0 finding(s), 0 as inline comments.

Incremental review of .github/scripts/release-pins.test.cjs, Dockerfile and scripts/verify-worker-image.sh since 04d9109. I found nothing to report.

  • Tests: the tests now read the actions/checkout pin and the runner FROM line from the repository, so they stay valid after the bumps they simulate. readdirSync is imported. The Dockerfile has exactly one FROM line, so the runner regex and replaceAll rewrite behave. The new paths.length > 1 assertion fails clearly if the pin ever stops being shared across workflows. The mismatch-message regex is loosened to v[0-9.]+ so it matches the v999.0.0 bump.
  • Dockerfile and verify-worker-image.sh:
    • The base.name and base.digest labels are removed from the Dockerfile and from the version check in verify-worker-image.sh.
    • verify-worker-image.sh now asserts that base.digest is absent. The image still has the source and description labels, so .Labels is never null.
    • A repo-wide grep found no other reader of the removed labels, so nothing else breaks.
  • Not run: I did not run the Node tests or shellcheck in this session, because the Bash call was blocked. My conclusions come from reading the diff and the current files.
  • Closing issue Derive release pins from the workflow and Dockerfile so Dependabot bumps pass Product policy #510: the incremental change is consistent with its goal that Dependabot bumps of the uses: SHA or the Dockerfile FROM digest pass without a manifest edit. Nothing in this delta regresses a criterion.

…ests

Dependabot rewrites only the Dockerfile FROM line, so the hard-coded
base.name and base.digest labels went stale on a runner bump and failed
verify-worker-image.sh. Drop them (release provenance records the
resolved base digest) and assert they stay absent. release-pins.test.cjs
now reads the checkout pin and FROM line from the repository instead of
hard-coding them, so it passes after the bumps it models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VcupojEVPjg9zYgTTu3TNk
@kyle-sexton
kyle-sexton merged commit 909b6ff into main Oct 30, 2026
28 checks passed
@kyle-sexton
kyle-sexton deleted the feat/510-pins-single-source branch October 30, 2026 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Derive release pins from the workflow and Dockerfile so Dependabot bumps pass Product policy

1 participant