# gha-lint
[](https://github.com/thegreatbey/gha-lint/actions/workflows/ci.yml)
[](https://crates.io/crates/gha-lint)
[](https://docs.rs/gha-lint)
[](LICENSE)
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:
```bash
git clone https://github.com/thegreatbey/gha-lint.git
cd gha-lint
cargo build --release
```
Optionally, once published:
```bash
cargo install gha-lint
```
## Usage
```bash
# analyze current repo
gha-lint
# or provide a path
gha-lint C:\path\to\repo
# version / help
gha-lint --version
gha-lint --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 diagnostics
- `1`: 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`/`rustc` without toolchain setup (warning)
- Missing checkout when steps run commands (warning)
- Invalid `working-directory` paths
- 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.