Skip to content

test(ci): guard the workflow action pins against regressing to tags - #96

Closed
DeepDiver1975 wants to merge 1 commit into
mainfrom
ci/guard-action-sha-pins
Closed

test(ci): guard the workflow action pins against regressing to tags#96
DeepDiver1975 wants to merge 1 commit into
mainfrom
ci/guard-action-sha-pins

Conversation

@DeepDiver1975

Copy link
Copy Markdown
Member

Follow-up to #94, which fixed the pins but left nothing guarding them.

Why

The org Actions policy sets allowed_actions: selected together with
sha_pinning_required: true (owncloud/admin:actions-allowlist.yml). An action
referenced by a movable tag is therefore rejected even though actions/* is
allowed as GitHub-owned — github_owned_allowed and the SHA-pinning requirement
are independent gates, which is the non-obvious part.

GitHub enforces this before it creates any job, so the failure mode is unusually
opaque:

  • run ends as startup_failureno jobs, no logs, no check-runs
  • the required build check therefore never reports, and every PR silently
    becomes unmergeable, on main and Dependabot branches alike
  • the only trace is an annotation on the run page, which the REST API does not
    expose (/actions/runs/{id}/jobs returns [], --log returns "log not found")

That combination made #94 disproportionately expensive to diagnose. This asserts
the invariant somewhere cheap instead: npm test.

What it checks

  • every uses: is pinned to a full-length (40 hex) commit SHA
  • every pin carries a # vX.Y.Z comment, so the SHA stays reviewable and
    Dependabot knows which version it currently represents
  • the workflows yield at least one uses: ref, so a parse that matches nothing
    cannot make the two assertions above vacuously pass

Local (./) and container (docker://) refs are not action repositories and are
out of scope for the policy, so they are skipped.

Verification

Written before #94's fix and confirmed to fail on exactly the four offending refs
(ci.yml:27, :30, :49, :70). Re-checked on this branch by reverting one pin
to actions/checkout@v7:

not ok 2 - every action is pinned to a full-length commit SHA
    0: 'ci.yml:27: actions/checkout@v7'

npm test on this branch: 20 tests, 16 pass, 0 fail, 4 skipped (the pre-existing
public/-not-built skips).

No workflow or runtime change — test-only.

🤖 Generated with Claude Code

The org Actions policy sets `allowed_actions: selected` together with
`sha_pinning_required: true` (owncloud/admin:actions-allowlist.yml), so an
action referenced by a movable tag is rejected even though `actions/*` is
allowed as GitHub-owned. GitHub enforces that *before* it creates any job: the
run ends as `startup_failure` with no jobs, no logs and no check-runs at all,
so the required `build` check never reports and every PR silently becomes
unmergeable -- the outage #94 fixed.

The only trace is an annotation on the run page, which the REST API does not
expose, so a repeat of #94 is disproportionately expensive to diagnose from the
Actions UI. Assert the invariant where it is cheap to see instead -- `npm test`:

  - every `uses:` is pinned to a full-length (40 hex) commit SHA
  - every pin carries a `# vX.Y.Z` comment, so the SHA stays reviewable and
    Dependabot knows which version it currently represents
  - the workflows yield at least one `uses:` ref, so a parse that matches
    nothing cannot make the two assertions above vacuously pass

Local (`./`) and container (`docker://`) refs are not action repositories and
are out of scope for the policy, so they are skipped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Signed-off-by: Thomas Müller <1005065+DeepDiver1975@users.noreply.github.com>
@DeepDiver1975
DeepDiver1975 deleted the ci/guard-action-sha-pins branch August 21, 2026 09:49
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