Github Actions Linter
/install github-actions-linter
GitHub Actions Linter
Lint GitHub Actions workflow files for syntax errors, security issues, deprecated actions, and best practices violations.
Commands
All commands use the bundled Python script at scripts/gha_linter.py.
1. Lint a workflow file
python3 scripts/gha_linter.py lint \x3Cfile-or-directory> [--strict] [--format text|json|markdown]
Runs all lint rules against one or more workflow files. If given a directory, scans for *.yml and *.yaml files recursively.
Flags:
--strict— exit code 1 on any warning (not just errors)--format— output format:text(default),json,markdown
2. Audit for security issues
python3 scripts/gha_linter.py security \x3Cfile> [--format text|json|markdown]
Focused security audit: shell injection via ${{ }} in run:, hardcoded secrets, overly permissive permissions, untrusted event contexts in expressions.
3. Check for deprecated actions
python3 scripts/gha_linter.py deprecated \x3Cfile> [--format text|json|markdown]
Detect outdated action versions (e.g., actions/checkout@v2, actions/setup-node@v3 when v4 exists) and suggest upgrades.
4. Validate workflow structure
python3 scripts/gha_linter.py validate \x3Cfile> [--format text|json|markdown]
Structural validation only: required keys (on, jobs), valid trigger events, valid runs-on labels, job dependency graph (circular deps, missing refs).
Lint Rules (28 total)
Syntax & Structure (8 rules)
- missing-on — Workflow missing
ontrigger - missing-jobs — Workflow missing
jobssection - empty-jobs — Jobs section is empty
- missing-runs-on — Job missing
runs-on - missing-steps — Job missing
steps - empty-steps — Steps list is empty
- invalid-trigger — Unknown trigger event name
- circular-deps — Circular job dependency via
needs
Security (8 rules)
- shell-injection —
${{ }}expression inrun:(potential injection) - hardcoded-secret — Hardcoded password/token/key patterns in workflow
- permissive-permissions —
permissions: write-allor no permissions block - untrusted-context — Dangerous contexts in expressions (
github.event.issue.title,github.event.pull_request.body, etc.) - pull-request-target —
pull_request_targetwith checkout of PR head (known attack vector) - third-party-action — Non-verified third party action without pinned SHA
- env-in-run — Secret used directly in
run:instead of viaenv: - excessive-permissions — Job requests more permissions than needed
Deprecated & Outdated (4 rules)
- deprecated-action — Action version is outdated (v1/v2 when v4 exists)
- deprecated-runner — Using deprecated runner labels (ubuntu-18.04, macos-10.15)
- set-output-deprecated — Using deprecated
::set-output::command - save-state-deprecated — Using deprecated
::save-state::command
Best Practices (8 rules)
- missing-timeout — Job without
timeout-minutes(default 6h is dangerous) - missing-name — Step without
name(harder to debug) - latest-tag — Action pinned to
@mainor@master(unstable) - no-concurrency — Workflow without
concurrency(can waste resources) - hardcoded-runner — Hardcoded runner version instead of
-latest - long-run-command —
run:block exceeds 50 lines (should be a script) - duplicate-step-id — Duplicate
idin steps within same job - missing-if-continue —
continue-on-error: truewithout explanation comment
Output Formats
Text (default)
workflow.yml:12:3 error [shell-injection] Expression ${{ github.event.issue.title }} in run: is vulnerable to injection
workflow.yml:25:5 warning [missing-timeout] Job 'build' has no timeout-minutes (default: 360 min)
workflow.yml:31:7 warning [missing-name] Step at index 2 has no name
3 issues (1 error, 2 warnings)
JSON
{
"file": "workflow.yml",
"issues": [...],
"summary": {"errors": 1, "warnings": 2, "info": 0}
}
Markdown
Summary table with severity, rule, location, and message.
CI Integration
# .github/workflows/lint-actions.yml
name: Lint Workflows
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: python3 scripts/gha_linter.py lint .github/workflows/ --strict
Exit codes: 0 = clean, 1 = errors found (or warnings in --strict mode).
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install github-actions-linter - After installation, invoke the skill by name or use
/github-actions-linter - Provide required inputs per the skill's parameter spec and get structured output
What is Github Actions Linter?
Lint and validate GitHub Actions workflow YAML files for common mistakes, security issues, deprecated actions, and best practices. Use when asked to lint, va... It is an AI Agent Skill for Claude Code / OpenClaw, with 86 downloads so far.
How do I install Github Actions Linter?
Run "/install github-actions-linter" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Github Actions Linter free?
Yes, Github Actions Linter is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Github Actions Linter support?
Github Actions Linter is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Github Actions Linter?
It is built and maintained by charlie-morrison (@charlie-morrison); the current version is v1.0.0.