Add self-CI actionlint gate to satisfy ci/ci ruleset

The org ruleset requires the 'ci / ci' status check on every repo, but this
.github repo only houses reusable (workflow_call) workflows and emitted no such
check — so every PR sat 'Expected — Waiting for status to be reported' and was
unmergeable, including the open Dependabot bumps (#58, #59, #60).

Add a workflow that runs actionlint (pinned, checksum-verified) over the
workflow files. The ruleset matches the required check against the JOB's
check-run name, so the job is named literally 'ci / ci' to emit that exact
context (a job named 'ci' emits context 'ci', which the UI only cosmetically
shows as 'ci / ci'). shellcheck integration is disabled for now; 4 pre-existing
run-step findings are left for a separate cleanup.

Pre-existing checkov IAM findings in oidc-deploy-roles.yaml are accepted-risk
and suppressed via machine-level security-review config, intentionally NOT
committed to this repo.
This commit is contained in:
Adam Moussa 2026-06-16 15:09:48 -04:00
parent 31bb01d1e9
commit 2f25ac3535

60
.github/workflows/ci.yaml vendored Normal file
View file

@ -0,0 +1,60 @@
name: ci
# Self-CI for this org `.github` repo.
#
# The org ruleset "main branch protection" requires the `ci / ci` status check on
# every repo. Consumer repos satisfy it via a short caller workflow that invokes
# the reusable workflows here. This repo only HOUSES those reusable workflows
# (all `workflow_call`-only), so nothing emitted `ci / ci` and every PR sat
# permanently "Expected — Waiting for status to be reported" and could not merge.
#
# This workflow produces that check by linting the workflow files with actionlint
# — genuinely useful CI for a repo whose whole product is GitHub Actions YAML.
#
# Naming is load-bearing: the ruleset matches the required status check against
# the JOB's check-run name, NOT "workflow / job". For a normal (non-reusable) job
# the check-run name IS the job name, so the job must be named literally "ci / ci"
# to emit that exact context. (A job named "ci" emits the context "ci" — which the
# PR UI cosmetically *displays* as "ci / ci" but does NOT satisfy the requirement.)
# This mirrors the org's aggregator-job convention.
#
# actionlint is pinned to a tagged release and installed by downloading the
# release tarball and verifying its SHA256 — not `curl | bash` — to keep the
# supply-chain surface auditable. Bump ACTIONLINT_VERSION + ACTIONLINT_SHA256
# together (checksum from the release's *_checksums.txt).
#
# actionlint's shellcheck integration is disabled (`-shellcheck=`) for now: it
# reports 4 pre-existing findings in the deploy/CI run-steps (SC2044 find-in-for
# loops, SC2046/SC2086 quoting, one of which is intentional word-splitting in the
# SAM deploy step). Those deserve a separate, tested cleanup rather than being
# bundled into the gate that unblocks the repo. Re-enable shellcheck once fixed.
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
jobs:
ci:
name: ci / ci
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install actionlint
env:
ACTIONLINT_VERSION: 1.7.12
ACTIONLINT_SHA256: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8
run: |
curl -fsSL -o actionlint.tar.gz \
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
echo "${ACTIONLINT_SHA256} actionlint.tar.gz" | sha256sum -c -
tar -xzf actionlint.tar.gz actionlint
shell: bash
- name: Lint workflows
run: ./actionlint -color -shellcheck=
shell: bash