golangci-lint-action-go
A Go reimplementation of the golangci-lint GitHub Action. Drop-in replacement that ships as a single self-contained binary — no Node.js runtime required.
Quick start
# .github/workflows/lint.yml
name: Lint
on:
push:
branches: [main]
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
- uses: StevenACoffman/golangci-lint-action-go@v1
Why a Go reimplementation?
The upstream action is a Node.js composite action. This version replaces the JS runtime with a compiled Go binary:
- No Node.js on the runner — one fewer tool in the dependency chain
- Faster startup — no module resolution or JIT warmup
- Auditable — the same
go build/go testworkflow as the rest of your project - Behaviorally identical — same inputs, same cache key format, same exit codes
Common patterns
Pin to a specific version
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
version: v2.3.4
args: --timeout=5m
Version can be v2.3 (maps to the latest v2.3.x patch), v2.3.4 (exact), latest, or empty
(auto-detected from go.mod or a version file — see Version resolution).
Lint only new issues on pull requests
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
only-new-issues: true
On pull_request and push events the action fetches the diff from the GitHub API and passes
--new-from-patch to golangci-lint so only issues touching changed lines are reported. On
merge_group events it uses --new-from-rev instead (no network call needed).
Add inline PR annotations
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
problem-matchers: true
Registers a problem matcher that parses golangci-lint output and creates inline code annotations directly on the pull request diff.
Monorepo — lint every Go module independently
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
experimental: automatic-module-directories
Globs for **/go.mod (excluding vendor/, node_modules/, .git/, dist/) and runs
golangci-lint once per discovered module directory.
Use golangci-lint already installed in the runner image
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
install-mode: none
Skips download and version resolution; uses whatever golangci-lint is already in PATH.
Install only, then run with custom flags
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
install-only: true
- name: Lint
run: golangci-lint run --fix --out-format=github-actions
Build from source with go install
- uses: StevenACoffman/golangci-lint-action-go@v1
with:
install-mode: goinstall
version: latest
Requires CGO (CGO_ENABLED=1) on the runner; useful when you need a custom build tag or are
targeting a platform without a pre-built release binary.
Inputs
| Input | Default | Description |
|---|---|---|
version |
"" |
golangci-lint version: v2.3, v2.3.4, latest, or empty for auto-detect |
version-file |
"" |
Path to .golangci-lint-version or .tool-versions; ignored when version is set |
install-mode |
binary |
binary — download release archive; goinstall — build with go install; none — expect it in PATH |
install-only |
false |
Install the binary, then exit without running the linter |
working-directory |
"" |
Directory to run the linter in; empty means the process working directory |
github-token |
${{ github.token }} |
Token used to fetch PR/push diffs when only-new-issues: true |
verify |
true |
Run golangci-lint config verify before linting |
only-new-issues |
false |
Restrict lint output to issues introduced in the current diff |
args |
"" |
Extra flags passed verbatim to golangci-lint run |
skip-cache |
false |
Disable both cache restore and save |
skip-save-cache |
false |
Disable cache save only; restore still runs |
cache-invalidation-interval |
7 |
Rotate the cache key every N days; 0 or negative gives a unique key per run |
problem-matchers |
false |
Register the built-in problem matcher for inline PR annotations |
debug |
"" |
Comma-separated: cache (print cache status), clean (purge cache before linting) |
experimental |
"" |
Comma-separated: automatic-module-directories (lint each go.mod in the repo) |
Version resolution
The version to install is determined by the first non-empty source in this order:
versioninput — used verbatim; minor-only versions (e.g.v2.3) are mapped to the latest patch via the upstream version mapping JSON.go.mod— scans for arequire github.com/golangci/golangci-lint/v2 vX.Y.Zdirective.version-file— reads.golangci-lint-version(raw version string) or.tool-versions(looks for agolangci-lint X.Y.Zline).- Latest — fetches the current latest from the upstream version mapping.
Minimum supported version is v2.1. Only the v2 major line is supported.
Caching
The action caches ~/.cache/golangci-lint (Windows: %USERPROFILE%\.cache\golangci-lint)
between runs using the GitHub Actions cache API.
Cache key format:
golangci-lint.cache-{RUNNER_OS}-{working-directory}-{interval-bucket}-{go.mod-sha1}
The interval bucket advances every cache-invalidation-interval days (default: 7). This
means the cache is shared across all runs within the same week while still rotating regularly
to pick up updated lint rules. A second restore key — the same string without the SHA-1 suffix
— allows partial hits when only go.mod has changed.
Set skip-cache: true to disable caching entirely, or skip-save-cache: true to restore but
never write back (useful when you want to build the cache only from the default branch).
Migrating from golangci-lint-action
All input names are identical. Replace:
- uses: golangci/golangci-lint-action@v6
with:
- uses: StevenACoffman/golangci-lint-action-go@v1
No other changes needed. If you previously passed cache: false (a flag unique to the upstream
action), use skip-cache: true here.
Development
# Build
go build -o golangci-lint-action-go ./...
# Test
go test ./...
# Lint
golangci-lint run ./...
See go.mod for the minimum required Go version.
Running the subcommands locally
# Phase 1 — restore cache, install, lint
INPUT_VERSION=v2.3.4 \
INPUT_ARGS="--timeout=5m" \
GITHUB_STATE=/tmp/gh-state \
GITHUB_PATH=/tmp/gh-path \
golangci-lint-action-go run
# Phase 2 — save cache (reads state written by phase 1)
STATE_CACHE_KEY=... \
GITHUB_STATE=/tmp/gh-state \
golangci-lint-action-go post-run
# Other
golangci-lint-action-go version
golangci-lint-action-go --help
Architecture
All business logic lives in internal/ as pure, testable functions. The cmd/ layer is a thin
shell that wires them together in the order the spec requires — no logic of its own.
cmd/
run/
run.go – subcommand registration and exec entry point
cache.go – cache restore (keys, GOLANGCI_LINT_CACHE, state)
install.go – binary install: binary / goinstall / none; plugin builder
lint.go – arg assembly, config verify, run, exit-code mapping
postrun/
postrun.go – cache save (reads state written by run phase)
internal/
gha/ – GitHub Actions protocol: workflow commands, env files, state
lintver/ – version string parsing, go.mod scan, version-file, mapping fetch
install/ – platform strings, asset URLs, archive helpers, ParseGoInstallBinPath
actionscache/ – GitHub Actions Cache REST API client
cache/ – cache key construction; RestoreCache / SaveCache orchestration
patch/ – PR/push diff fetch; path-prefix rewriting for working-directory
plugins/ – .custom-gcl.{yml,yaml,json} detection and custom-binary build
lint/ – ParseUserArgs, OnlyNewIssuesArgs, PathModeArg, InterpretExitCode
License
See LICENSE.
Release files for golangci_lint_action_go 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| golangci_lint_action_go-0.5.0-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-musllinux_1_2_x86_64.whl | Python 3 | none | Linux musl 1.2+ x86-64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-musllinux_1_2_aarch64.whl | Python 3 | none | Linux musl 1.2+ ARM64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| golangci_lint_action_go-0.5.0-py3-none-macosx_10_9_x86_64.whl | Python 3 | none | macOS 10.9+ x86-64 | Details |
Total release size: 57.3 MB
Release files / golangci_lint_action_go-0.5.0-py3-none-win_arm64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-win_arm64.whl |
|---|---|
| Size | 6.9 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
6785d557a89e22f869ad4c16aacffd3d450f0c4ab98cd751692bcf456d40fe5b
|
|
BLAKE2b-256 checksum How to use checksums |
0a9f5cfa82b94a1247e694c1871bb7d16b5ec7769f7e7af9343920449ea3244c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-win_amd64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-win_amd64.whl |
|---|---|
| Size | 7.6 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
c5c8bddf8e30eaadfa416880dd93522735f03545063b80e7cbe34f6b9d01399b
|
|
BLAKE2b-256 checksum How to use checksums |
a2e7ec6e888f95eeec7be8034ffad0d73be6cfb969d70205e0bdf941c583d5e1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-musllinux_1_2_x86_64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 7.4 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
dea505b846763f3dd43d9e5aa69f8dbca4c7d068a5c00ceb52acb2980d7fd62f
|
|
BLAKE2b-256 checksum How to use checksums |
0bcadcb121c3a1f85badadbd2632fc695413eaf489d37d3318d4f224fecda58b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-musllinux_1_2_aarch64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 6.8 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
e553ffefd0dcd427234cc999f564e82aa304df3cd212ec967af30b7396a71b94
|
|
BLAKE2b-256 checksum How to use checksums |
7c5aaa46901afbae633d57431b77d4653c28db607337a62cd0dd1088a9fb4a0d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 7.4 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
1b9cf497c77e106eb99499daad0a222ecadad746d9d2c21b7fbef40194429fc9
|
|
BLAKE2b-256 checksum How to use checksums |
45ebcc140b6b0b66a45be68d9843bc97b7b94c1546e56acc4e9578acbc14eef5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 6.8 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
cd9065e588ae5f0194bd82e4bf65c03a0b4b53a3a949a1d3296b3481f79983cb
|
|
BLAKE2b-256 checksum How to use checksums |
d458b8c1c83d1ee5c924fd273ea055eaf047e4238a02a92a2102477235ebced4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-macosx_11_0_arm64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 6.9 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
cc8e631792ae216f9c4f86a8fcd66de1ab041e08115f99bec1fa974da0c6db3e
|
|
BLAKE2b-256 checksum How to use checksums |
6e19deafb53cc70590d20b9dbff308d715f1408c6b9308546dbe4e44f088d594
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|
Release files / golangci_lint_action_go-0.5.0-py3-none-macosx_10_9_x86_64.whl
| Download URL | golangci_lint_action_go-0.5.0-py3-none-macosx_10_9_x86_64.whl |
|---|---|
| Size | 7.5 MB |
| Tags | Python 3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
11c7906cb028439fb6adc8da2977bce7688ad7d1e7762f7140052ff2c19ebc7a
|
|
BLAKE2b-256 checksum How to use checksums |
879063ddce157eb95e78c264559022f4173b6cc271ee0ad430b6e46f65328804
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
Go-http-client/2.0
|