gha-lint
Static analyzer for GitHub Actions workflows. It scans .github/workflows/*.yml / *.yaml, parses YAML, and runs deterministic checks. It DOES NOT include network requests, dry-runs, or command execution. It's a linter. So no network requests, no dry-run, no command execution.
Status
V0 static analysis implemented. Exits non-zero if any error-level diagnostic occurs.
Install
From source:
Optionally, once published:
Usage
# analyze current repo
# or provide a path
# version / help
Diagnostics follow a Clippy-like style:
error[ci::missing-on]: workflow is missing the top-level 'on:' trigger (file: .github/workflows/ci.yml, line: 12)
help: add an 'on:' block (push/pull_request/schedule/etc)
error[ci::invalid-uses]: invalid 'uses:' value: "checkout@v4" (file: .github/workflows/build.yml, line: 12)
help: actions must follow 'owner/repo@ref', e.g. 'actions/checkout@v4'
Exit codes:
0: no error-level diagnostics1: at least one error-level diagnostic
Checks (v0)
- Missing
on:block - Missing jobs or empty
jobs: - Invalid
needs:references (unknown job ids or wrong types) - Invalid
uses:syntax (owner/repo@ref, docker://, or ./local-path) - Rust workflow hint: uses
cargo/rustcwithout toolchain setup (warning) - Missing checkout when steps run commands (warning)
- Invalid
working-directorypaths - Steps referencing files that do not exist (e.g.,
./scripts/foo.sh, local actions)
What gets analyzed
What gets analyzed?
- gha-lint reads all .yml / .yaml files under .github/workflows/
Scope / Non-Goals
- Static analysis only (no workflow execution, no dry-run, no network)
- No secret resolution, no runtime simulation, no undocumented fields
License
Dual-licensed under MIT and Apache-2.0.