From f5578db4a2592fa0cf69d5121378cc4b738ff47c Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Mon, 31 Aug 2026 09:22:26 -0400 Subject: [PATCH] ci: lint workflow files with actionlint A pull request only runs ci.yml and codeql.yml. Nothing reads release.yml or docker-publish.yml until they run for real on a tag or a push to main, which is how a broken release gate would reach main with every check green. This adds the one job that parses all five workflows on every pull request. Verified against deliberate regressions: it catches an undefined step id and malformed expression syntax, and shellcheck is preinstalled on the runner so it also covers the shell in every run: block. It does not validate inputs or outputs of third party actions, so it would not have caught the changesets v2 output rename in #233. This narrows the gap rather than closing it. actionlint is pinned by version and sha256 rather than installed through the upstream download script, which pipes an unpinned ref into bash. Dependabot tracks neither that script nor a docker:// reference, so the pair is bumped by hand and the checksum makes a swapped artifact fail loudly. --- .github/workflows/ci.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2ef9760..6d0ac66 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,6 +5,39 @@ on: branches: ['**'] jobs: + # A pull request only ever runs ci.yml and codeql.yml, so a mistake in + # release.yml or docker-publish.yml reaches main unchallenged and is not + # noticed until a release goes quiet. This is the one check that reads those + # files on every pull request. + workflows: + name: Lint workflows + runs-on: ubuntu-latest + + env: + # Pinned by version and checksum rather than installed by the upstream + # download script, which curls an unpinned ref into bash. Dependabot does + # not track either form, so this pair is bumped by hand. + ACTIONLINT_VERSION: 1.7.12 + ACTIONLINT_SHA256: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 + + steps: + - name: Checkout repo + uses: actions/checkout@v7 + + - name: Install actionlint + run: | + set -euo pipefail + ARCHIVE="actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" + curl -fsSL -o "${ARCHIVE}" \ + "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/${ARCHIVE}" + echo "${ACTIONLINT_SHA256} ${ARCHIVE}" | sha256sum -c - + tar -xzf "${ARCHIVE}" actionlint + + # shellcheck is preinstalled on the runner, so this also covers the shell + # in every run: block. + - name: Lint workflow files + run: ./actionlint -color + test: runs-on: ubuntu-latest