[go-fan] Go Module Review: actionlint (github.com/rhysd/actionlint) #22839
Closed
Replies: 2 comments 1 reply
-
|
/plan |
Beta Was this translation helpful? Give feedback.
1 reply
-
|
This discussion has been marked as outdated by Go Fan. A newer discussion is available at Discussion #23073. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
🐹 Go Fan Report:
github.com/rhysd/actionlintSelected via round-robin (most recently pushed of unreviewed direct deps: pushed 2026-03-23). Run §23529573616.
Module Overview
actionlint is a static checker for GitHub Actions workflow files. It validates YAML syntax, type-checks
$\{\{ }}expressions, validates action inputs/outputs against a curated dataset of popular actions, checks reusable workflow calls, and integrates withshellcheck/pyflakesfor shell and Python script linting. It also performs security checks for script injection and hard-coded credentials.Current version in
go.mod: v1.7.11 (released 2026-02-14).Current Usage in gh-aw
rhysd/actionlint:latestThe module is used in two distinct ways:
1. Version pinning only (
tools.go)JSON output is unmarshalled into an
actionlintErrorstruct and reformatted for display. Exit codes are handled: 0 = clean, 1 = lint errors found, other = tooling failure.Key implementation features:
max(5, len(files))minutesActionlintStatstracks totals + per-kind breakdowngetActionlintDocsURL(kind)maps error kind → docs anchorResearch Findings
Recent Updates (v1.7.9–v1.7.11)
v1.7.11 (2026-02-14) — current pinned version
case()expression function supportmacos-26-large,windows-2025-vs2026./foo/bar.txtpath filter now reported as error (never matches anything)v1.7.10 (2025-12-30)
&anchor/*alias) support — unused/undefined anchors detectedworkflow_dispatchmax inputs raised from 10 → 25artifact-metadatapermission supportif:conditions (e.g.,if: true) now detected as error<<reported as error (GitHub Actions doesn't support it)v1.7.9 (2025-11-21)
ubuntu-slimrunner supportdeprecationMessagemetadataimage_versiontrigger +jobs.<id>.snapshotsyntaxactionlint.AllContextsconstant added to Go APIanthropics/claude-code-actionadded to popular actions dataset*-xlrunner labels removedGo API — Rich and Underutilized
actionlint provides a comprehensive Go library that's currently unused in production code:
actionlint.Linteractionlint.Parse()actionlint.ValidateRefGlob()actionlint.ValidatePathGlob()actionlint.PopularActionsactionlint.AllContextsImprovement Opportunities
🏃 Quick Wins
1. Pin Docker image version to match go.mod
pkg/cli/docker_images.goline 21:The actionlint docs explicitly note it doesn't follow semver: "any patch version bump may introduce breaking changes." Using
:latestmeans Docker could silently upgrade between CI runs while go.mod stays pinned — an inconsistency that could cause unexpected lint failures. All three Docker image constants (ZizmorImage,PoutineImage,ActionlintImage) use:latest; the same concern applies.2. Eliminate redundant file reads in output parser
parseAndDisplayActionlintOutputinpkg/cli/actionlint.go:390-407reads each workflow file from disk to build context lines around the error:But the
actionlintErrorstruct already has aSnippetfield populated from the JSON output:The
Snippetfield is parsed but never used. Displayingerr.Snippetdirectly would eliminate the disk reads entirely.3. Fix the
syntax-checkdocs URL mappinggetActionlintDocsURLmaps"syntax-check"tocheck-syntax-expression— the expression check anchor. But[syntax-check]is actionlint's general YAML syntax error kind (wrong keys, missing required fields, etc.), not expression-specific. These are different checks with different docs sections. The mapping should either point to the top-level checks page or the correctsyntax-checkanchor.✨ Feature Opportunities
4. In-process glob validation at compile time
The workflow compiler generates branch/tag/path glob patterns (e.g., in
on.push.branches). These patterns are validated by actionlint at lint time, but could be validated immediately at compile time using:This would catch glob errors before even writing the
.lock.ymlfile, without needing Docker.5. Use
actionlint.AllContextsfor expression validationactionlint.AllContexts(added v1.7.9) is a map of workflow key → available context names. The compiler currently avoids generating certainneeds.*expressions to prevent actionlint errors (there are comments about this inknown_needs_expressions.go). Using this map in-process could make those avoidance rules more precise and maintainable.6. Consider
actionlint.Linterto eliminate Docker for actionlintSince actionlint is already a direct Go dependency, running it in-process via
actionlint.Linterwould:This is a larger change but fits the existing tool architecture well. The JSON format parsing would be replaced by direct access to
[]actionlint.Error.📐 Best Practice Alignment
7. Stderr not logged alongside parse failures
When
parseAndDisplayActionlintOutputfails, the code falls back to showing rawstdoutbut dropsstderr(pkg/cli/actionlint.go:293-297). actionlint may write diagnostic info to stderr (e.g., when shellcheck binary is missing). Showing both would help debug integration failures.Recommendations (Prioritized)
ActionlintImageto"rhysd/actionlint:v1.7.11"— prevents silent version drifterr.Snippetinstead of re-reading files for error context displaysyntax-check→ docs URL mappingactionlint.ValidateRefGlob()/actionlint.ValidatePathGlob()calls in the compiler for compile-time glob validationactionlint.Linterfor in-process lintingNext Steps
ActionlintImagetov1.7.11getActionlintDocsURLkind mappings against actionlint's current check listValidateRefGlob()/ValidatePathGlob()integration in the compiler./path filter errors,case()support) against generated workflow patternsModule summary saved to:
scratchpad/mods/actionlint.mdReferences:
Beta Was this translation helpful? Give feedback.
All reactions