Add lint CI gate: shellcheck, shfmt, actionlint, yaml #7

Merged
stephen merged 2 commits from ci/lint-gate into main 2026-07-01 12:24:18 +00:00
Owner

Adds the static-analysis gate codex-1's audit flagged as P1 hardening. test.yml already gates behavior (offline unit suite + e2e docker build); this adds a .forgejo/workflows/lint.yml that gates form.

Four checks, all strict (any issue fails the job):

  • shellcheck on the shell scripts
  • shfmt -i 2 -ci -d (formatting)
  • actionlint on the workflows
  • yq parse of action.yml, the workflows, and the example workflows

This mirrors the existing Makefile lint target but strict: the Makefile masks tool failures with || echo skipping, so it is a local convenience, not a gate. That leniency is why two files had drifted from shfmt; the first commit here normalizes them (spaces around case-pattern pipes, subshell parens, one stray blank line, no behavior change) so the tree is clean, and the unit suite still passes 46/46.

Runner and tooling:

  • runs-on: [self-hosted, Linux], not ubuntu-latest. The audit note said ubuntu-latest, but the fleet has no runner with that label (the same gap the mission-control audit found), so such a job would sit unpicked. Every fleet workflow, including this repo's own test.yml and examples, uses [self-hosted, Linux].
  • The tools are fetched as pinned static binaries into ~/.local/bin (shellcheck 0.10.0, shfmt 3.13.1, actionlint 1.7.7, yq latest), so the gate is deterministic and needs no runner preinstalls or root.

Verified locally: all four linters clean, and the repo's own pre-commit hook (which runs the same four plus the unit suite) passes on both commits.

Adds the static-analysis gate codex-1's audit flagged as P1 hardening. `test.yml` already gates behavior (offline unit suite + e2e docker build); this adds a `.forgejo/workflows/lint.yml` that gates form. Four checks, all strict (any issue fails the job): - `shellcheck` on the shell scripts - `shfmt -i 2 -ci -d` (formatting) - `actionlint` on the workflows - `yq` parse of `action.yml`, the workflows, and the example workflows This mirrors the existing Makefile `lint` target but strict: the Makefile masks tool failures with `|| echo skipping`, so it is a local convenience, not a gate. That leniency is why two files had drifted from shfmt; the first commit here normalizes them (spaces around case-pattern pipes, subshell parens, one stray blank line, no behavior change) so the tree is clean, and the unit suite still passes 46/46. Runner and tooling: - `runs-on: [self-hosted, Linux]`, not `ubuntu-latest`. The audit note said ubuntu-latest, but the fleet has no runner with that label (the same gap the mission-control audit found), so such a job would sit unpicked. Every fleet workflow, including this repo's own `test.yml` and examples, uses `[self-hosted, Linux]`. - The tools are fetched as pinned static binaries into `~/.local/bin` (shellcheck 0.10.0, shfmt 3.13.1, actionlint 1.7.7, yq latest), so the gate is deterministic and needs no runner preinstalls or root. Verified locally: all four linters clean, and the repo's own pre-commit hook (which runs the same four plus the unit suite) passes on both commits.
No behavior change: spaces around case-pattern pipes and inside subshell
parens, and a stray blank line removed. Brings the tree clean for the new
shfmt lint gate; the unit suite still passes (46/46).
Add lint CI gate: shellcheck, shfmt, actionlint, yaml
All checks were successful
test / unit (pull_request) Successful in 5s
lint / lint (pull_request) Successful in 7s
test / e2e (pull_request) Successful in 4s
b28e72471f
The test.yml suite gates behavior; this adds a static-analysis gate for
shell scripts, workflows, and action.yml, per the audit's P1 hardening.
Runs on [self-hosted, Linux] (the fleet has no ubuntu-latest runner) and
fetches pinned tool binaries so it needs no runner preinstalls or root.
Verified locally: all four linters clean.
stephen deleted branch ci/lint-gate 2026-07-01 12:24:18 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rasterstate/docker-build-action!7
No description provided.