Goal
Add actionlint as a CI gate that lints every .github/workflows/*.yml file on each push/PR. Provide a durable replacement for the assistant-side actionlint check that gated PR #55 (Issue #41 implementation).
Your Task
- In
.github/workflows/ci.yml, add a new job validate-workflows (parallel to existing validate-template, test-backend, test-frontend, docker-build, security) that runs rhysd/actionlint against .github/workflows/.
- Address the 6 pre-existing shellcheck findings currently emitted by
actionlint 1.7.1 against .github/workflows/deploy-production.yml:
Describe pending changeset step (around run: |): SC2016 (grep -oE 'arn:aws:cloudformation:[...]' — actionlint flags single-quoted regex thinking expansion was intended).
Get Stack Outputs step (around run: |): SC2129 + SC2086 × 3 (recommend { cmd1; cmd2; } >> "$GITHUB_OUTPUT" and double-quote variable expansions when redirecting).
- Verify CI is green after the fixes; intentionally break a workflow YAML (e.g. wrong indent) on a throwaway commit to confirm the gate catches it; revert.
Context
PR #55 (chore(infra): add in-deploy CloudFormation drift detection) was the trigger to add actionlint. The plan that produced PR #55 used local docker run rhysd/actionlint:1.7.1 -color .github/workflows/deploy-production.yml as a pre-push lint, which caught zero issues in the new code but surfaced the 6 pre-existing findings noted above. That assistant-side check covered PR #55 specifically; it does NOT survive across future PRs. A CI-side gate is the durable fix.
This Issue is the Phase 5 follow-up from .plans/pr-delegated-pretzel.md (Codex review finding #2 long-term resolution).
Suggested workflow shape
validate-workflows:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: actionlint
run: |
docker run --rm -v "$PWD:/repo" -w /repo rhysd/actionlint:1.7.1 -color
(rhysd/actionlint is a third-party action. Per the #42 close comment, third-party Actions must be SHA-pinned at introduction. Using the Docker image with a pinned tag is one way; using rhysd/actionlint-action@<SHA> is another. Either is fine — pick the smaller surface.)
Acceptance
- New
validate-workflows CI job present and passes on main after the 6 pre-existing findings are addressed.
- An intentional malformed workflow file on a test PR fails the gate.
- The 6 pre-existing shellcheck findings in
deploy-production.yml are resolved (or scoped via inline # shellcheck disable=... with rationale, if the warning is intentional).
Warning
- Bumping
rhysd/actionlint over time will surface new rules. Bumps are PR-scoped (Dependabot or manual); do not auto-merge unread.
- Some shellcheck warnings (e.g., SC2016) are genuinely intentional in this codebase (literal regex with single quotes); silence with
# shellcheck disable=SC2016 on the line, not a global ignore, so future genuine matches still surface.
Goal
Add
actionlintas a CI gate that lints every.github/workflows/*.ymlfile on each push/PR. Provide a durable replacement for the assistant-sideactionlintcheck that gated PR #55 (Issue #41 implementation).Your Task
.github/workflows/ci.yml, add a new jobvalidate-workflows(parallel to existingvalidate-template,test-backend,test-frontend,docker-build,security) that runsrhysd/actionlintagainst.github/workflows/.actionlint 1.7.1against.github/workflows/deploy-production.yml:Describe pending changesetstep (aroundrun: |): SC2016 (grep -oE 'arn:aws:cloudformation:[...]'— actionlint flags single-quoted regex thinking expansion was intended).Get Stack Outputsstep (aroundrun: |): SC2129 + SC2086 × 3 (recommend{ cmd1; cmd2; } >> "$GITHUB_OUTPUT"and double-quote variable expansions when redirecting).Context
PR #55 (
chore(infra): add in-deploy CloudFormation drift detection) was the trigger to addactionlint. The plan that produced PR #55 used localdocker run rhysd/actionlint:1.7.1 -color .github/workflows/deploy-production.ymlas a pre-push lint, which caught zero issues in the new code but surfaced the 6 pre-existing findings noted above. That assistant-side check covered PR #55 specifically; it does NOT survive across future PRs. A CI-side gate is the durable fix.This Issue is the Phase 5 follow-up from
.plans/pr-delegated-pretzel.md(Codex review finding #2 long-term resolution).Suggested workflow shape
(
rhysd/actionlintis a third-party action. Per the #42 close comment, third-party Actions must be SHA-pinned at introduction. Using the Docker image with a pinned tag is one way; usingrhysd/actionlint-action@<SHA>is another. Either is fine — pick the smaller surface.)Acceptance
validate-workflowsCI job present and passes onmainafter the 6 pre-existing findings are addressed.deploy-production.ymlare resolved (or scoped via inline# shellcheck disable=...with rationale, if the warning is intentional).Warning
rhysd/actionlintover time will surface new rules. Bumps are PR-scoped (Dependabot or manual); do not auto-merge unread.# shellcheck disable=SC2016on the line, not a global ignore, so future genuine matches still surface.