golangci/golangci-lint-action
GitHub: golangci/golangci-lint-action
golangci-lint 官方提供的 GitHub Action,用于在 CI 中自动化运行 Go 代码静态检查并报告问题。
Stars: 1434 | Forks: 188
# golangci-lint-action
[](https://github.com/golangci/golangci-lint-action/actions)
这是由其作者开发的 [golangci-lint](https://github.com/golangci/golangci-lint) 官方 GitHub Action。
该 action 会运行 [golangci-lint](https://github.com/golangci/golangci-lint) 并报告 linter 发现的问题。


## 如何使用
我们建议在一个独立于其他 job(如 `go test` 等)的 job 中运行此 action,
因为不同的 job 是[并行运行的](https://help.github.com/en/actions/getting-started-with-github-actions/core-concepts-for-github-actions#job)。
添加一个 `.github/workflows/golangci-lint.yml` 文件,内容如下:
## 兼容性
* `v9.0.0` 需要 Nodejs 运行时 [`node24`](https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/)
* `v8.0.0` 适用于 `golangci-lint` 版本 >= `v2.1.0`
* `v7.0.0` 仅支持 golangci-lint v2。
* `v6.0.0+` 移除了 `annotations` 选项,并移除了默认的输出格式 (`github-actions`)。
* `v5.0.0+` 移除了 `skip-pkg-cache` 和 `skip-build-cache`,因为与 Go 本身相关的缓存已由 `actions/setup-go` 处理。
* `v4.0.0+` 在使用此 action 之前需要一个显式的 `actions/setup-go` 安装步骤:`uses: actions/setup-go@v5`。
`skip-go-installation` 选项已被移除。
* `v2.0.0+` 适用于 `golangci-lint` 版本 >= `v1.28.3`
* `v1.2.2` 已弃用,因为我们忘记将 `golangci-lint` 的最低版本更改为 `v1.28.3`([问题](https://github.com/golangci/golangci-lint-action/issues/39))
* `v1.2.1` 适用于 `golangci-lint` 版本 >= `v1.14.0`([问题](https://github.com/golangci/golangci-lint-action/issues/39))
## 选项
### 概述
| 选项 | 描述 |
|---------------------------------------------------------------|-------------------------------------------------------|
| [`version`](#version) | 要使用的 golangci-lint 版本。 |
| [`version-file`](#version-file) | 从文件获取要使用的 golangci-lint 版本。 |
| [`install-mode`](#install-mode) | 安装 golangci-lint 的模式。 |
| [`install-only`](#install-only) | 仅安装 golangci-lint。 |
| [`verify`](#verify) | 验证 golangci-lint 配置文件。 |
| [`github-token`](#github-token) | 供 `only-new-issues` 选项使用。 |
| [`only-new-issues`](#only-new-issues) | 仅显示新问题。 |
| [`working-directory`](#working-directory) | golangci-lint 的工作目录。 |
| [`args`](#args) | golangci-lint 命令行参数。 |
| [`skip-cache`](#skip-cache) | 禁用缓存支持。 |
| [`skip-save-cache`](#skip-save-cache) | 不保存缓存。 |
| [`cache-invalidation-interval`](#cache-invalidation-interval) | 缓存失效前的天数。 |
| [`problem-matchers`](#problem-matchers) | 强制使用内置的 problem matcher。 |
| [实验性](#experimental) | 实验性选项 |
### 安装
#### `version`
(可选)
要使用的 golangci-lint 版本。
当 `install-mode` 为:
* `binary`(默认):该值可以是 v2.3、v2.3.4 或 `latest`(使用最新版本)。
* `goinstall`:该值可以是 v2.3.4、`latest` 或 commit 的 hash。
* `none`:该值将被忽略。
#### `version-file`
从文件获取要使用的 golangci-lint 版本。
路径必须相对于项目根目录,如果定义了 `working-directory`,则相对于该目录。
此参数支持 `.golangci-lint-version` 和 `.tool-versions` 文件。
仅适用于 `install-mode: binary`(默认)。
#### `install-mode`
(可选)
安装 golangci-lint 的模式:可以是 `binary`、`goinstall` 或 `none`。
默认值为 `binary`。
不推荐使用 `goinstall`,更多说明请见[此处](https://golangci-lint.run/docs/welcome/install/local/#install-from-sources)。
#### `install-only`
(可选)
如果设置为 `true`,该 action 将仅安装 golangci-lint。
它不会运行 golangci-lint。
默认值为 `false`。
### 运行
#### `verify`
(可选)
此选项默认为 `true`。
如果 GitHub Action 检测到配置文件,除非将此选项设置为 `false`,否则将进行验证。
如果没有配置文件,则跳过验证。
用于验证配置的 JSON Schema 取决于您所使用的 golangci-lint 版本。
#### `github-token`
(可选)
当使用 `only-new-issues` 选项时,需要使用 GitHub API,因此需要一个 token。
默认情况下,它使用 action 提供的 `github.token`。
#### `only-new-issues`
(可选)
仅显示新问题。
默认值为 `false`。
* `pull_request` 和 `pull_request_target`:该 action 从 [GitHub API](https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#get-a-pull-request) 获取 PR 内容的差异,并将其与 `--new-from-patch` 一起使用。
* `push`:该 action 从 [GitHub API](https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#compare-two-commits) 获取推送内容的差异(即推送前后提交之间的差异),并将其与 `--new-from-patch` 一起使用。
* `merge_group`:该 action 通过使用 `--new-from-rev` 选项获取差异(依赖于 git)。
您应该在 `actions/checkout` 步骤中添加 `fetch-depth: 0` 选项。
#### `working-directory`
(可选)
golangci-lint 的工作目录,对于 monorepo 很有用。默认为项目根目录。
#### `args`
(可选)
golangci-lint 命令行参数。
### 缓存
#### `skip-cache`
(可选)
如果设置为 `true`,将完全禁用所有缓存功能。
这将优先于所有其他缓存选项。
默认值为 `false`。
#### `skip-save-cache`
(可选)
如果设置为 `true`,将不会保存缓存,但仍可能会恢复它们,这需要将 `skip-cache` 设为 `false`。
默认值为 `false`。
#### `cache-invalidation-interval`
(可选)
每隔 `cache-invalidation-interval` 天定期使缓存失效,以确保删除过时数据并加载新数据。
默认值为 `7`。
如果数值为 `<= 0`,缓存将始终失效(不推荐)。
### 额外
#### `problem-matchers`
(可选)
强制使用内置的 problem matcher。
默认情况下,[Go 的 problem matcher (`actions/setup-go`)](https://github.com/actions/setup-go/blob/main/matchers.json) 已经处理了 golangci-lint 的默认输出 (`text`)。
仅适用于 `text` 格式(golangci-lint 的默认格式)。
https://golangci-lint.run/usage/configuration/#output-configuration
默认值为 `false`。
### 实验性
以下选项是实验性的:未来可能支持也可能不支持,因此它们要么会被转换为专门的选项,要么会被移除。
以逗号分隔的选项列表。
#### `automatic-module-directories`
(可选)
此选项将在每个模块目录中运行 golangci-lint,对于 monorepo 很有用。
模块的自动检测在定义了 `working-directory` 时会将其作为基础目录,否则使用根目录。
## 注解
目前,GitHub 会解析 action 的输出并创建[注解](https://github.blog/2018-12-14-introducing-check-runs-and-annotations/)。
注解的限制如下:
1. 目前,它们不支持 Markdown 格式(参见[功能请求](https://github.community/t5/GitHub-API-Development-and/Checks-Ability-to-include-Markdown-in-line-annotations/m-p/56704))。
2. 它们不会显示在评论列表中。
如果您希望有评论,请为[该 issue](https://github.com/golangci/golangci-lint-action/issues/5) 点赞。
3. 注解的数量是[受限的](https://github.com/actions/toolkit/blob/main/docs/problem-matchers.md#limitations))。
所需权限:
```
permissions:
# Required: allow read access to the content for analysis.
contents: read
# Optional: allow read access to pull requests. Use with `only-new-issues` option.
pull-requests: read
```
要使注解生效,请使用默认的输出格式 (`text`),并在 job 中使用 [`actions/setup-go`](https://github.com/actions/setup-go) 或启用内部的 [problem matcher](#problem-matchers)。
## Module Plugin 系统
该 action 会自动检测自定义构建配置文件 `.custom-gcl.yml`,
构建并运行自定义版本的 golangci-lint。
有关更多信息,请参见 [Module Plugin 系统](https://golangci-lint.run/docs/plugins/module-plugins/)。
## 技巧
### 使用 Renovate 更新 golangci-lint 版本
[Renovate](https://docs.renovatebot.com/) 可以通过其 [github-actions 管理器](https://docs.renovatebot.com/modules/manager/github-actions/#commonly-used-community-actions) 同时更新该 action 及其使用的
`golangci-lint` 版本,
该管理器包含在 `config:recommended` 等预设中。
也可以在 `renovate.json` 中显式启用它:
```
{
"enabledManagers": ["github-actions"]
}
```
## 性能
该 action 在实现时充分考虑了性能:
1. 我们使用 [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) 在构建之间缓存 golangci-lint 的分析数据。
2. 我们不使用 Docker,因为拉取镜像很慢。
3. 我们尽可能并行处理,例如,我们并行下载缓存和 golangci-lint 二进制文件。
4. 我们依赖 [`actions/setup-go`](https://github.com/actions/setup-go) 来处理 Go 模块缓存。
## 内部实现
我们使用基于 JavaScript 的 action。
我们不使用基于 Docker 的 action,原因如下:
1. 目前拉取 Docker 镜像速度很慢。
2. 更容易使用 [@actions/cache](https://github.com/actions/toolkit/tree/HEAD/packages/cache) 进行缓存。
我们支持不同的平台,例如 `ubuntu`、`macos` 和 `windows`,以及 `x32` 和 `x64` 架构。
在我们的 action 内部,我们执行三个步骤:
1. 并行设置环境:
* 从之前的分析中恢复[缓存](https://github.com/actions/cache)。
* 获取 [action 配置](https://github.com/golangci/golangci-lint/blob/HEAD/assets/github-action-config.json) 并为所需版本查找最新的 `golangci-lint` 补丁版本
(此 action 的用户只能指定 `golangci-lint` 的小版本)。
之后,使用 [@actions/tool-cache](https://github.com/actions/toolkit/tree/HEAD/packages/tool-cache) 安装 [golangci-lint](https://github.com/golangci/golangci-lint)。
2. 使用用户指定的 `args` 参数运行 `golangci-lint`。
3. 保存缓存以供后续构建使用。
### 缓存内部原理
1. 我们保存并恢复以下目录:`~/.cache/golangci-lint`。
2. 主缓存键类似于 `golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-{go.mod_hash}`。
间隔编号确保我们定期(每 7 天)使缓存失效。
`go.mod` hash 确保我们尽早使缓存失效 —— 一旦依赖项发生更改就失效。
3. 我们使用[恢复键](https://help.github.com/en/actions/configuring-and-managing-workflows/caching-dependencies-to-speed-up-workflows#matching-a-cache-key):
`golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-`。
如果没有与主缓存完全匹配项,GitHub 将按前缀匹配键。
这个方案很基础,需要改进。欢迎提交 Pull request 和提出想法。
简单示例
``` name: golangci-lint on: push: branches: - main - master pull_request: permissions: contents: read # Optional: allow read access to pull requests. Use with `only-new-issues` option. # pull-requests: read jobs: golangci: name: lint runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: go-version: stable - name: golangci-lint uses: golangci/golangci-lint-action@v9 with: version: v2.12 ```多操作系统示例
``` name: golangci-lint on: push: branches: - main - master pull_request: permissions: contents: read # Optional: allow read access to pull requests. Use with `only-new-issues` option. # pull-requests: read jobs: golangci: strategy: matrix: go: [stable] os: [ubuntu-latest, macos-latest, windows-latest] name: lint runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: go-version: ${{ matrix.go }} - name: golangci-lint uses: golangci/golangci-lint-action@v9 with: version: v2.12 ``` 你可能还需要添加以下 `.gitattributes` 文件,以确保 Windows 构建的换行符格式正确: ``` *.go text eol=lf ```Go Workspace 示例
``` name: golangci-lint on: pull_request: push: branches: - main - master env: GO_VERSION: stable GOLANGCI_LINT_VERSION: v2.12 jobs: detect-modules: runs-on: ubuntu-latest outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: go-version: ${{ env.GO_VERSION }} - id: set-modules run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT golangci-lint: needs: detect-modules runs-on: ubuntu-latest strategy: matrix: modules: ${{ fromJSON(needs.detect-modules.outputs.modules) }} steps: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: go-version: ${{ env.GO_VERSION }} - name: golangci-lint ${{ matrix.modules }} uses: golangci/golangci-lint-action@v9 with: version: ${{ env.GOLANGCI_LINT_VERSION }} working-directory: ${{ matrix.modules }} ```Go Workspace 示例(多操作系统)
``` # ./.github/workflows/golangci-lint.yml name: golangci-lint (multi OS) on: pull_request: push: branches: - main - master jobs: golangci-lint: strategy: matrix: go-version: [ stable, oldstable ] os: [ubuntu-latest, macos-latest, windows-latest] uses: ./.github/workflows/.golangci-lint-reusable.yml with: os: ${{ matrix.os }} go-version: ${{ matrix.go-version }} golangci-lint-version: v2.12 ``` ``` # ./.github/workflows/.golangci-lint-reusable.yml name: golangci-lint-reusable on: workflow_call: inputs: os: description: 'OS' required: true type: string go-version: description: 'Go version' required: true type: string default: stable golangci-lint-version: description: 'Golangci-lint version' type: string default: 'v2.12' jobs: detect-modules: runs-on: ${{ inputs.os }} outputs: modules: ${{ steps.set-modules.outputs.modules }} steps: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version }} - id: set-modules shell: bash # required for Windows to be able to use $GITHUB_OUTPUT https://github.com/actions/runner/issues/2224 run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT golangci-lint: needs: detect-modules runs-on: ${{ inputs.os }} strategy: matrix: modules: ${{ fromJSON(needs.detect-modules.outputs.modules) }} steps: - uses: actions/checkout@v6 - uses: actions/setup-go@v6 with: go-version: ${{ inputs.go-version }} - name: golangci-lint ${{ matrix.modules }} uses: golangci/golangci-lint-action@v9 with: version: ${{ inputs.golangci-lint-version }} working-directory: ${{ matrix.modules }} ``` 你可能还需要添加以下 `.gitattributes` 文件,以确保 Windows 构建的换行符格式正确: ``` *.go text eol=lf ```示例
``` uses: golangci/golangci-lint-action@v9 with: version: v2.12 # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: version-file: .tool-versions # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: install-mode: "none" # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: install-only: true # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: verify: false # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: github-token: xxx # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: only-new-issues: true # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: working-directory: somedir # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: # In some rare cases, # you may need to use `${{ github.workspace }}` as the base directory to reference your configuration file. args: --config=/my/path/.golangci.yml --issues-exit-code=0 # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: skip-cache: true # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: skip-save-cache: true # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: cache-invalidation-interval: 15 # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: problem-matchers: true # ... ```示例
``` uses: golangci/golangci-lint-action@v9 with: experimental: "foo,bar" ```示例
``` uses: golangci/golangci-lint-action@v9 with: experimental: "automatic-module-directories" ```标签:GitHub Actions, Go, MITM代理, Ruby工具, SOC Prime, 开发工具, 日志审计, 自动化攻击, 自动笔记, 静态检查