golangci-lint-action
这是由 golangci-lint 作者提供的官方 GitHub action。
该 action 运行 golangci-lint 并报告 linter 发现的问题。
支持我们
golangci-lint
是一个由志愿者构建的免费开源项目。
如果你觉得它有价值,请考虑支持我们,我们非常感谢!:heart:
使用方法
我们建议在与其他作业(如 go test
等)分开的作业中运行此 action,因为不同的作业并行运行。
添加 .github/workflows/golangci-lint.yml
文件,内容如下:
简单示例
name: golangci-lint
on:
push:
branches:
- main
- master
pull_request:
permissions:
contents: read
# 可选:允许读取 pull request。与 `only-new-issues` 选项一起使用。
# pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: stable
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.60
多操作系统示例
name: golangci-lint
on:
push:
branches:
- main
- master
pull_request:
permissions:
contents: read
# 可选:允许读取 pull request。与 `only-new-issues` 选项一起使用。
# 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@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: v1.60
你可能还需要添加以下 .gitattributes
文件,以确保 Windows 构建的行尾格式正确:
*.go text eol=lf
Go 工作区示例
name: golangci-lint
on:
pull_request:
push:
branches:
- "main"
- "master"
env:
GO_VERSION: stable
GOLANGCI_LINT_VERSION: v1.60
jobs:
detect-modules:
runs-on: ubuntu-latest
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
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@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v6
with:
version: ${{ env.GOLANGCI_LINT_VERSION }}
working-directory: ${{ matrix.modules }}
Go 工作区示例(多操作系统)
# ./.github/workflows/golangci-lint.yml
name: golangci-lint (多操作系统)
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: v1.60
# ./.github/workflows/.golangci-lint-reusable.yml
name: golangci-lint-reusable
on:
workflow_call:
inputs:
os:
description: '操作系统'
required: true
type: string
go-version:
description: 'Go 版本'
required: true
type: string
default: stable
golangci-lint-version:
description: 'Golangci-lint 版本'
type: string
default: 'v1.60'
jobs:
detect-modules:
runs-on: ${{ inputs.os }}
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ inputs.go-version }}
- id: set-modules
shell: bash # 需要在 Windows 上使用 $GITHUB_OUTPUT https://github.com/actions/runner/issues/2224
run: echo "modules=$(go list -m -json | jq -s '.' | jq -c '[.[].Dir]')" >> $GITHUB_OUTPUT
您可能还需要添加以下 .gitattributes
文件以确保 Windows 构建的行尾正确格式化:
*.go text eol=lf
兼容性
v6.0.0+
移除了annotations
选项,移除了默认输出格式 (github-actions
)。v5.0.0+
移除了skip-pkg-cache
和skip-build-cache
,因为与 Go 本身相关的缓存已由actions/setup-go
处理。v4.0.0+
在使用此操作前需要显式安装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
(问题)v1.2.1
适用于golangci-lint
版本 >=v1.14.0
(问题)
选项
version
(必填)
要使用的 golangci-lint 版本。
当 install-mode
为:
binary
(默认): 值可以是 v1.2 或 v1.2.3 或latest
以使用最新版本。goinstall
: 值可以是 v1.2.3、latest
或提交的哈希值。none
: 该值将被忽略。
示例
uses: golangci/golangci-lint-action@v6
with:
version: v1.58
# ...
install-mode
(可选)
安装 golangci-lint 的模式: 可以是 binary
、goinstall
或 none
。
默认值为 binary
。
示例
uses: golangci/golangci-lint-action@v6
with:
install-mode: "goinstall"
# ...
github-token
(可选)
使用 only-new-issues
选项时,会使用 GitHub API,因此需要令牌。
默认情况下,它使用操作中的 github.token
。
示例
uses: golangci/golangci-lint-action@v6
with:
github-token: xxx
# ...
only-new-issues
(可选)
仅显示新问题。
默认值为 false
。
pull_request
和pull_request_target
: 操作从 GitHub API 获取 PR 内容的差异,并将其与--new-from-patch
一起使用。push
: 操作从 GitHub API 获取推送内容的差异(推送前后提交的差异),并将其与--new-from-patch
一起使用。merge_group
: 操作使用--new-from-rev
选项获取差异(依赖于 git)。 您应该在actions/checkout
步骤中添加fetch-depth: 0
选项。
示例
uses: golangci/golangci-lint-action@v6
with:
only-new-issues: true
# ...
working-directory
(可选)
工作目录,对于单体仓库很有用。
示例
uses: golangci/golangci-lint-action@v6
with:
working-directory: somedir
# ...
args
(可选)
golangci-lint 命令行参数。
注意:默认情况下,.golangci.yml
文件应位于仓库的根目录。
可以使用 --config=
更改配置文件的位置。
示例
uses: golangci/golangci-lint-action@v6
with:
args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0
# ...
problem-matchers
(可选)
强制使用嵌入的问题匹配器。
默认情况下,Go 的问题匹配器(actions/setup-go
)已经处理了 golangci-lint 的输出(colored-line-number
)。
仅适用于 colored-line-number
(golangci-lint 默认值)。
https://golangci-lint.run/usage/configuration/#output-configuration
默认值为 false
。
示例
uses: golangci/golangci-lint-action@v6
with:
problem-matchers: true
# ...
skip-cache
(可选)
如果设置为 true
,则所有缓存功能将被完全禁用,优先于所有其他缓存选项。
默认值为 false
。
示例
uses: golangci/golangci-lint-action@v6
with:
skip-cache: true
# ...
skip-save-cache
(可选)
如果设置为 true
,缓存将不会被保存,但仍可能被恢复,需要 skip-cache: false
。
默认值为 false
。
示例
uses: golangci/golangci-lint-action@v6
with:
skip-save-cache: true
# ...
cache-invalidation-interval
(可选)
每隔 cache-invalidation-interval
天定期使缓存失效,以确保删除过时数据并加载新数据。
默认值为 7
。
如果设置的数字 <= 0
,缓存将始终失效(不推荐)。
示例
uses: golangci/golangci-lint-action@v6
with:
cache-invalidation-interval: 15
# ...
注释
目前,GitHub 解析操作的输出并创建注释。
注释的限制如下:
要启用注释,你需要在你的action中添加checks
权限。
permissions:
# 必需:允许读取内容以进行分析。
contents: read
# 可选:允许读取拉取请求。与"only-new-issues"选项一起使用。
pull-requests: read
# 可选:允许对检查进行写入访问,以便action可以在PR中注释代码。
checks: write
性能
这个action的实现考虑到了性能:
- 我们使用@actions/cache在构建之间缓存golangci-lint分析的数据。
- 我们不使用Docker,因为拉取镜像很慢。
- 我们尽可能并行执行,例如,我们并行下载缓存和golangci-lint二进制文件。
例如,在golangci-lint的仓库中运行此action,不使用缓存需要50秒,但使用缓存只需要14秒:
- 并行执行:
- 4秒恢复50 MB的缓存
- 1秒找到并安装
golangci-lint
- 1秒运行
golangci-lint
(不使用缓存需要35秒)
内部原理
我们使用基于JavaScript的action。 我们不使用基于Docker的action,因为:
- 目前Docker拉取速度较慢
- 使用@actions/cache进行缓存更容易
我们支持不同的平台,如ubuntu
、macos
和windows
,以及x32
和x64
架构。
在我们的action内部,我们执行3个步骤:
- 并行设置环境:
- 恢复之前分析的缓存
- 获取action配置并为所需版本找到最新的
golangci-lint
补丁版本 (此action的用户只能指定golangci-lint
的次要版本)。 之后使用@actions/tool-cache安装golangci-lint
- 使用用户指定的
args
运行golangci-lint
- 为后续构建保存缓存
缓存内部原理
- 我们保存和恢复以下目录:
~/.cache/golangci-lint
。 - 主要缓存键格式如下:
golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-{go.mod_hash}
。 间隔数确保我们定期(每7天)使缓存失效。go.mod
哈希确保我们在依赖项更改时尽早使缓存失效。 - 我们使用恢复键:
golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-
。 如果主缓存没有精确匹配,GitHub会按前缀匹配键。
这个方案是基本的,需要改进。欢迎提出拉取请求和想法。
此action的开发
- 安装act
- 为了让
act
正常工作,创建一个符号链接:ln -s . golangci-lint-action
- 首次准备依赖:
npm run prepare-deps
- 每次修改后运行
npm run local
进行测试