Repository navigation
feat: lightweight gh aw lint — actionlint-only over existing .lock.yml files (no recompile, no zizmor/poutine) #30704
Copy link
Copy link
Closed
Labels
Description
Summary
Provide a lightweight gh aw lint (or gh aw validate --lock-only) subcommand that runs only actionlint over existing .lock.yml files on disk, without recompiling the .md source, running zizmor/poutine, or emitting frontmatter-related warnings. This is the smallest CI gate that would have caught #30695 at PR time.
Motivation
Today there are three options, none of which fit the "pre-merge, fast, lock-file-only" niche:
| Command | What it does | Fit for "is the on-disk lock file parseable?" |
|---|---|---|
gh aw validate |
recompile + zizmor + actionlint + poutine | Heavy. Also rejects hand-patched lock files because they no longer match a fresh recompile. |
gh aw compile --no-emit --actionlint |
recompile in memory + actionlint on the in-memory output | Doesn't validate the file on disk. Also surfaces unrelated frontmatter warnings (e.g. "This workflow grants id-token: write permission"). |
actionlint .github/workflows/*.lock.yml directly |
external tool | Works (we just shipped this in microsoft/vscode-engineering#2733) but loses the benefit of gh-aw managing the actionlint version and any awareness of gh-aw-specific constructs (e.g. the job.workflow_repository / workflow_sha / workflow_ref / workflow_file_path properties newer lock files reference, which v1.7.12 doesn't know about — so we had to add -ignore flags). |
Concrete asks
A new subcommand, e.g.:
gh aw lint # actionlint all .github/workflows/*.lock.yml
gh aw lint .github/workflows/foo.lock.yml
gh aw lint --dir .github/workflowsBehavior:
- Read existing
.lock.ymlfiles from disk. Do not recompile. Do not require the matching.mdto be present or up-to-date. - Run only actionlint (the same actionlint instance gh-aw already vendors / wraps, with whatever ignore-list / type-extensions are needed for gh-aw-emitted contexts like
job.workflow_*). No zizmor, no poutine, no compile-time validators. - Exit non-zero on any actionlint error. Suppress shellcheck/pyflakes integrations by default (or expose flags) since lock-file
run:blocks are machine-generated. - Be fast (≤1s for ~30 lock files). No Docker, no network.
Why this matters
- Catches the Compiler JSON-encodes
&&to\u0026\u0026inside${{ }}expressions in AWF config printf, breaking workflow parse #30695 class of bug pre-merge, even when the bad lock file came fromgh aw compilewith a buggy compiler version, or from a deliberate manual patch (which is sometimes necessary as a stopgap while waiting for an upstream fix — exactly what we did for Compiler JSON-encodes&&to\u0026\u0026inside${{ }}expressions in AWF config printf, breaking workflow parse #30695). - Removes the per-consumer maintenance burden of pinning their own actionlint version and discovering gh-aw-specific context properties via trial-and-error CI failures.
- Keeps the door open for manual lock-file patches, unlike
gh aw validate, which would fail a hand-patched lock file because it no longer matches a fresh compile.
Related
- Bug that motivated this: Compiler JSON-encodes
&&to\u0026\u0026inside${{ }}expressions in AWF config printf, breaking workflow parse #30695 (compiler emitted\u0026\u0026inside a${{ }}expression). - Downstream CI workaround: microsoft/vscode-engineering#2733.
Reactions are currently unavailable
Activity