Skip to content

ci: lint GitHub Actions workflows with pinned actionlint - #15677

Merged
atomantic merged 3 commits into
mainfrom
claim/issue-15658
Nov 10, 2026
Merged

atomantic merged 3 commits into
mainfrom
claim/issue-15658

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

GitHub silently skips a workflow it rejects, so a bad file can merge and never run. PR #15657 shipped a runner context in job-level env, which GitHub refuses; actionlint reports it immediately. This adds actionlint to CI and to pregate.

  • CI lint job installs the pinned actionlint 1.7.12 (linux/amd64 archive, SHA-256 verified, same pattern as the scanner tools in runtime-image-security.yml), lints every workflow, then proves the linter still rejects a known-bad fixture with the expected context "runner" is not allowed here diagnostic.
  • Pregate adds a workflow lint (actionlint) stage whenever the plan lints workflow files. If the pinned binary or shellcheck is missing it is reported as not covered, with the remedy, instead of passing silently. The receipt records whether the stage ran.
  • release.yml: quotes $GITHUB_OUTPUT and the tag/variable expansions that produced the six pre-existing SC2086 notes. No shellcheck rule is disabled.
  • scripts/lib/actionlint.js holds the pin and the probe; scripts/run-actionlint.js is the shared runner. A parity test keeps the ci.yml literals equal to the JS constants.

Test plan

  • scripts/run-actionlint.test.js: pin parity with ci.yml, version parsing, probe states (missing binary, wrong version, missing shellcheck, available), workflow selection and target resolution.
  • scripts/pregate.test.js: actionlint stage selection, skip under --skip-lint, uncovered entry when the tool is unavailable, and updated stage-order expectations.
  • scripts/ci-test-plan.test.js: a workflow change runs the full lint job.
  • npm run pregate passes on the committed tree (includes workflow lint (actionlint)).
  • actionlint 1.7.12 (the pinned darwin_arm64 archive, checked against the release checksums file) passes on all six workflows and rejects the fixture with the expected diagnostic.
  • Workflow-reading guard tests (github-actions-pinned, workflow-timeouts, release-ci-permissions, and related) pass.

Local review

  • Rounds run: 2 of 2 budgeted (gpt-6.1-terra, high effort).
  • Round 1 (reviewed b9b755f992): one finding, accepted. The fixture proof passed on any nonzero exit, so a missing shellcheck could look like success. Fixed in f1c89e4909: the step now requires the expected runner-context diagnostic.
  • Round 2 (reviewed f1c89e4909): clean, no findings.
  • Last reviewed revision: f1c89e4909. No findings were rejected.
  • Remaining: nothing from the review. Hosted CI remains the gate for the ubuntu runner's shellcheck version, which local pregate cannot pin.

Closes #15658

GitHub silently skips a workflow it rejects, so a bad file (the
runner context in job-level env that #15657 shipped) merged and never
ran. CI's lint job now installs the pinned actionlint 1.7.12 (archive
SHA-256 verified), lints every workflow, and proves the linter still
rejects a known-bad fixture. Pregate runs the same check as a stage
when a plan lints workflow files; when the pinned binary or shellcheck
is missing it reports actionlint as not covered with the remedy.

Also quotes the GitHub output and tag variables in release.yml so the
six shellcheck SC2086 notes no longer fire.
… proof (#15658)

A nonzero exit alone also covers a missing shellcheck or a broken launch,
so the proof step now fails unless actionlint rejects the fixture with the
expected diagnostic.
@atomantic atomantic added reviewer:gpt-6-1-terra Locally reviewed by the gpt-6-1-terra model implementer:haiku-5-5 PR opened by the haiku-5-5 model labels Nov 10, 2026
@atomantic
atomantic enabled auto-merge November 10, 2026 16:50
@atomantic atomantic added reviewer:gpt-6-1-terra Locally reviewed by the gpt-6-1-terra model implementer:haiku-5-5 PR opened by the haiku-5-5 model labels Nov 10, 2026
@atomantic
atomantic disabled auto-merge November 10, 2026 17:02
)

The runtime image scan contract requires ci.yml never to reference that
workflow; describe the pinning pattern without naming the file.
@atomantic

Copy link
Copy Markdown
Owner Author

Ready to merge: CI Gate and every selected suite passed on 20ba044. The automated merge was refused because the PortOS agent's GitHub token lacks the workflow scope this PR needs, since it edits .github/workflows/* (tracked in #15680). It needs a merge from an account with that scope.

@atomantic
atomantic merged commit 94fdd86 into main Nov 10, 2026
20 checks passed
@atomantic
atomantic deleted the claim/issue-15658 branch November 10, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

implementer:haiku-5-5 PR opened by the haiku-5-5 model reviewer:gpt-6-1-terra Locally reviewed by the gpt-6-1-terra model

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lint GitHub Actions workflows with actionlint in CI and pregate

1 participant