name: Lint workflows # Catches GitHub Actions / shellcheck issues in workflow YAMLs before they # break a real release. Runs on push/PR that touches anything under # .github/workflows/ and on manual workflow_dispatch. Keeps non-blocking # (warnings only) initially — flip to fail-fast when the existing inventory # is clean. on: push: branches: [main] paths: - ".github/workflows/**" - "scripts/ops/**.sh" pull_request: paths: - ".github/workflows/**" - "scripts/ops/**.sh" workflow_dispatch: permissions: contents: read jobs: actionlint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - name: Run actionlint run: | # Pin to a specific actionlint version for reproducibility. # Updates: bump the version string + verify rules in CHANGELOG. ACTIONLINT_VERSION="1.7.7" curl -sSL \ "https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz" \ | tar xz actionlint ./actionlint -color # Continue-on-error initially: surface findings without blocking # while the existing workflow inventory is being cleaned up. Flip # to false (default) once the repo is actionlint-clean. continue-on-error: true - name: Run shellcheck on ops scripts # actionlint above only walks `.github/workflows/**` + the shell # snippets embedded inside their `run:` blocks; freestanding # `scripts/ops/**/*.sh` files (which are also in this workflow's # path filter via the `**.sh` glob) need their own pass. # shellcheck is pre-installed on ubuntu-latest runners. # # `find` matches the recursive `**.sh` path filter above. A bare # `scripts/ops/*.sh` glob would silently skip future scripts under # subdirectories — the workflow would trigger on them (filter # matches) but never lint them. # # `--severity=warning` blocks only on warning+ findings (actual # bugs); info/style level passes silently. This lets the existing # inventory's info-level findings (e.g. SC1091, SC2015 in # agnes-auto-upgrade.sh / agnes-tls-rotate.sh) ride through while # still catching real regressions in new scripts. run: | mapfile -t SCRIPTS < <(find scripts/ops -type f -name '*.sh' 2>/dev/null) if [ "${#SCRIPTS[@]}" -gt 0 ]; then shellcheck --severity=warning "${SCRIPTS[@]}" else echo "No scripts/ops/**/*.sh found — nothing to check." fi