Skip to content

SHA-pin the last three floating action refs (supersedes #550) - #562

Merged
Zyrtnin merged 1 commit into
mainfrom
chore/pin-mutation-checkout-to-sha
Sep 1, 2026
Merged

SHA-pin the last three floating action refs (supersedes #550)#562
Zyrtnin merged 1 commit into
mainfrom
chore/pin-mutation-checkout-to-sha

Conversation

@Zyrtnin

@Zyrtnin Zyrtnin commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Supersedes #550.

Dependabot proposed actions/checkout@v4@v7 in mutation.yml. That is an improvement in version and a regression in posture: every other checkout in this repo is pinned to a full commit SHA, and merging it would have left two pinned to a movable tag.

Whoever controls a tag controls what executes in CI, with the repository checked out and the job's secrets in scope — which is what SHA pinning exists to prevent, and which this repo already runs Scorecard over.

Pinning them to the SHA the rest of the repo already uses gets the version bump and the consistency.

A third straggler

setup-python@v7, in the same file, was the last floating ref in the entire repository. It turned up only because fixing the two prompted a sweep for the whole set rather than the two the PR named.

before:  actions/checkout@v4      ×2      actions/setup-python@v7  ×1
after:   0 floating refs across .github/workflows/

The check is a test, not a script

Deliberately. This repo has already learned twice that a checker wired to nothing is not a checker — two mutation groups were added to scripts/mutation_groups.py and never to the CI matrix, and check_coverage_omissions.py sat as a taskipy task nothing invoked. The weakest link in detect is the wiring, and pytest tests/ runs in CI unconditionally, so a test has none to forget.

tests/test_workflow_actions_are_sha_pinned.py asserts:

  1. no floating ref anywhere in .github/workflows/ (local ./ composite actions and docker:// refs excluded, with the reasons in the file);
  2. one SHA per action across all workflows — two SHAs for one action means a bump landed in some lanes and not others, leaving a stale version running wherever nobody looked;
  3. a guard-the-guard check that the glob matched some workflows at all, since a glob matching nothing passes every assertion after it.

Each of (1) and (2) was verified by its own plant. Worth noting: the first plant attempt silently did not land (wrong target string) and the suite stayed green — indistinguishable from a test that fails to catch. Re-planted against the real line before trusting either assertion.

… pinned

Supersedes Dependabot #550, which proposed `actions/checkout@v4` -> `@v7` in
mutation.yml.

That bump would have been an improvement in version and a REGRESSION IN POSTURE.
Every other checkout in this repo is pinned to a full commit SHA; #550 would
have left two pinned to a movable tag. Whoever controls a tag controls what
executes in CI, with the repository checked out and the job's secrets in scope —
which is the thing SHA pinning exists to prevent, and which this repo already
runs Scorecard over.

Pinning them to the SHA the rest of the repo already uses gets the version bump
AND the consistency, so #550 is closed rather than merged.

A THIRD STRAGGLER turned up only because fixing the two prompted a sweep for the
whole set instead of the two the PR named: `setup-python@v7` in the same file
was the last floating ref in the repository. Fixing the class, not the instance.

THE CHECK IS A TEST, NOT A SCRIPT, and that is deliberate. This repo has already
learned twice that a checker wired to nothing is not a checker — two mutation
groups were added to `scripts/mutation_groups.py` and never to the CI matrix,
and `check_coverage_omissions.py` sat as a taskipy task nothing invoked. The
weakest link in "detect" is the wiring; `pytest tests/` runs in CI
unconditionally, so a test has no separate wiring to forget.

Two assertions, each verified by its own plant:
  * a floating ref anywhere in .github/workflows/ fails
  * the same action pinned to TWO different SHAs fails — the drift that leaves a
    stale version running in whichever lane nobody looked at
plus a guard-the-guard check that the glob actually matched some workflows, since
a glob matching nothing passes every assertion after it.

The first plant attempt did not land (wrong target string) and the suite stayed
green — which looks identical to a test that fails to catch. Re-planted against
the real line before trusting either assertion.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Zyrtnin
Zyrtnin merged commit 18d113a into main Sep 1, 2026
19 checks passed
@Zyrtnin
Zyrtnin deleted the chore/pin-mutation-checkout-to-sha branch September 1, 2026 07:24
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.

1 participant