Top Related Projects
Set up your GitHub Actions workflow with a specific version of Go
Fast linters runner for Go
🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Go security checker
Quick Overview
The golangci/golangci-lint-action is a GitHub Action that runs golangci-lint on your Go code. It provides an easy way to integrate static code analysis into your GitHub workflow, helping to maintain code quality and catch potential issues early in the development process.
Pros
- Easy integration with GitHub Actions workflows
- Customizable linting rules and configuration
- Supports caching to improve performance on subsequent runs
- Provides detailed output and annotations for identified issues
Cons
- Limited to Go programming language
- May require additional setup for complex projects
- Can potentially increase CI/CD pipeline execution time
- Occasional false positives in linting results
Getting Started
To use the golangci-lint-action in your GitHub workflow, add the following step to your .github/workflows/go.yml file:
name: Go
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.20'
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
This configuration will run golangci-lint on your Go code whenever there's a push to the main branch or a pull request is opened. You can customize the linting rules by adding a .golangci.yml file to your repository root.
Competitor Comparisons
Set up your GitHub Actions workflow with a specific version of Go
Pros of setup-go
- More versatile, allowing setup of Go environment for various tasks
- Simpler to use for general Go development workflows
- Integrates seamlessly with other Go-related actions
Cons of setup-go
- Doesn't provide linting functionality out of the box
- Requires additional configuration for code analysis tasks
- May need to be combined with other actions for comprehensive CI/CD pipelines
Code Comparison
setup-go:
steps:
- uses: actions/setup-go@v3
with:
go-version: '1.17'
- run: go build .
golangci-lint-action:
steps:
- uses: actions/checkout@v3
- uses: golangci/golangci-lint-action@v3
with:
version: v1.29
Key Differences
- Purpose: setup-go is for setting up Go environment, while golangci-lint-action is specifically for linting
- Functionality: setup-go is more general-purpose, golangci-lint-action is focused on code quality
- Usage: setup-go is typically used in combination with other actions, golangci-lint-action can be used standalone for linting tasks
Use Cases
- Use setup-go when you need a Go environment for building, testing, or running Go applications
- Choose golangci-lint-action when your primary goal is to perform linting and code quality checks on Go projects
Both actions have their place in Go development workflows, often complementing each other in comprehensive GitHub Actions pipelines.
Fast linters runner for Go
Pros of golangci-lint
- Standalone CLI tool that can be used in various environments
- More flexible configuration options for linting rules
- Can be integrated into different CI/CD pipelines and workflows
Cons of golangci-lint
- Requires manual setup and configuration in CI/CD environments
- May need additional scripting to parse and report results effectively
- Updates need to be managed manually
Code comparison
golangci-lint:
golangci-lint run
golangci-lint-action:
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3
with:
version: latest
Key differences
- golangci-lint is the core linting tool, while golangci-lint-action is a GitHub Action wrapper
- golangci-lint-action simplifies integration with GitHub Actions workflows
- golangci-lint offers more direct control over the linting process
- golangci-lint-action handles version management and result reporting automatically
Use cases
- Use golangci-lint for local development, custom CI/CD pipelines, or when more control is needed
- Use golangci-lint-action for quick and easy integration with GitHub Actions workflows
Conclusion
Both tools serve important purposes in the Go development ecosystem. golangci-lint provides the core functionality and flexibility, while golangci-lint-action offers a streamlined experience for GitHub Actions users.
🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Pros of Revive
- Highly customizable with over 70 rules and the ability to create custom rules
- Faster execution time, especially for large codebases
- Provides more detailed and actionable error messages
Cons of Revive
- Narrower focus on linting compared to the comprehensive toolset of golangci-lint
- Less integration with other Go tools and CI/CD pipelines out of the box
- Requires more manual configuration to achieve the same coverage as golangci-lint
Code Comparison
Revive configuration:
ignoreGeneratedHeader = false
severity = "warning"
confidence = 0.8
errorCode = 1
warningCode = 0
[rule.blank-imports]
[rule.context-as-argument]
[rule.context-keys-type]
[rule.error-return]
[rule.error-strings]
golangci-lint configuration:
linters:
enable:
- deadcode
- errcheck
- gosimple
- govet
- ineffassign
- staticcheck
- structcheck
- typecheck
- unused
- varcheck
Both tools offer powerful linting capabilities for Go projects, but they differ in their approach and feature set. Revive focuses on customization and speed, while golangci-lint provides a more comprehensive and integrated solution for Go code analysis.
Go security checker
Pros of gosec
- Focused specifically on security-related issues in Go code
- Provides detailed explanations and recommendations for each security issue found
- Can be integrated into CI/CD pipelines for automated security checks
Cons of gosec
- Limited to security-related checks, not a comprehensive linter
- May produce false positives in some cases, requiring manual review
- Less frequent updates compared to golangci-lint-action
Code Comparison
gosec:
package main
import (
"github.com/securego/gosec/v2"
"github.com/securego/gosec/v2/rules"
)
func main() {
analyzer := gosec.NewAnalyzer(rules.NewRuleSet(), nil)
// ... (additional configuration and analysis code)
}
golangci-lint-action:
name: golangci-lint
on: [push, pull_request]
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
The code comparison shows that gosec is typically used as a Go package within your code, while golangci-lint-action is primarily configured as a GitHub Action in your workflow YAML file. This reflects their different approaches: gosec as a focused security analyzer and golangci-lint-action as a more comprehensive linting tool integrated into CI/CD workflows.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
golangci-lint-action
It's the official GitHub Action for golangci-lint from its authors.
The action runs golangci-lint and reports issues from linters.


Supporting Us
golangci-lint is a free and open-source project built by volunteers.
If you value it, consider supporting us; we appreciate it! :heart:
How to use
We recommend running this action in a job separate from other jobs (go test, etc.)
because different jobs run in parallel.
Add a .github/workflows/golangci-lint.yml file with the following contents:
Simple Example
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@v5
- uses: actions/setup-go@v6
with:
go-version: stable
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: v2.1
Multiple OS Example
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@v5
- uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go }}
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: v2.1
You will also likely need to add the following .gitattributes file to ensure that line endings for Windows builds are properly formatted:
*.go text eol=lf
Go Workspace Example
name: golangci-lint
on:
pull_request:
push:
branches:
- main
- master
env:
GO_VERSION: stable
GOLANGCI_LINT_VERSION: v2.1
jobs:
detect-modules:
runs-on: ubuntu-latest
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v5
- 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@v5
- uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v8
with:
version: ${{ env.GOLANGCI_LINT_VERSION }}
working-directory: ${{ matrix.modules }}
Go Workspace Example (Multiple OS)
# ./.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.1
# ./.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.1'
jobs:
detect-modules:
runs-on: ${{ inputs.os }}
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v5
- 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@v5
- uses: actions/setup-go@v6
with:
go-version: ${{ inputs.go-version }}
- name: golangci-lint ${{ matrix.modules }}
uses: golangci/golangci-lint-action@v8
with:
version: ${{ inputs.golangci-lint-version }}
working-directory: ${{ matrix.modules }}
You will also likely need to add the following .gitattributes file to ensure that line endings for Windows builds are properly formatted:
*.go text eol=lf
Compatibility
v8.0.0works withgolangci-lintversion >=v2.1.0v7.0.0supports golangci-lint v2 only.v6.0.0+removesannotationsoption, removes the default output format (github-actions).v5.0.0+removesskip-pkg-cacheandskip-build-cachebecause the cache related to Go itself is already handled byactions/setup-go.v4.0.0+requires an explicitactions/setup-goinstallation step before using this action:uses: actions/setup-go@v5. Theskip-go-installationoption has been removed.v2.0.0+works withgolangci-lintversion >=v1.28.3v1.2.2is deprecated because we forgot to change the minimum version ofgolangci-linttov1.28.3(issue)v1.2.1works withgolangci-lintversion >=v1.14.0(issue)
Options
version
(optional)
The version of golangci-lint to use.
When install-mode is:
binary(default): the value can be v2.3, v2.3.4, orlatestto use the latest version.goinstall: the value can be v2.3.4,latest, or the hash of a commit.none: the value is ignored.
Example
uses: golangci/golangci-lint-action@v8
with:
version: v2.1
# ...
install-mode
(optional)
The mode to install golangci-lint: it can be binary, goinstall, or none.
The default value is binary.
Example
uses: golangci/golangci-lint-action@v8
with:
install-mode: "goinstall"
# ...
github-token
(optional)
When using the only-new-issues option, the GitHub API is used, so a token is required.
By default, it uses the github.token from the action.
Example
uses: golangci/golangci-lint-action@v8
with:
github-token: xxx
# ...
verify
(optional)
This option is true by default.
If the GitHub Action detects a configuration file, validation will be performed unless this option is set to false.
If there is no configuration file, validation is skipped.
The JSON Schema used to validate the configuration depends on the version of golangci-lint you are using.
Example
uses: golangci/golangci-lint-action@v8
with:
verify: false
# ...
only-new-issues
(optional)
Show only new issues.
The default value is false.
pull_requestandpull_request_target: the action gets the diff of the PR content from the GitHub API and uses it with--new-from-patch.push: the action gets the diff of the push content (the difference between commits before and after the push) from the GitHub API and uses it with--new-from-patch.merge_group: the action gets the diff by using the--new-from-revoption (relies on git). You should add the optionfetch-depth: 0to theactions/checkoutstep.
Example
uses: golangci/golangci-lint-action@v8
with:
only-new-issues: true
# ...
working-directory
(optional)
The golangci-lint working directory, useful for monorepos. The default is the project root.
Example
uses: golangci/golangci-lint-action@v8
with:
working-directory: somedir
# ...
args
(optional)
golangci-lint command line arguments.
[!NOTE] By default, the
.golangci.ymlfile should be at the root of the repository. The location of the configuration file can be changed by using--config=.
[!IMPORTANT] Adding a
=between the flag name and its value is important because the action parses the arguments on spaces.
Example
uses: golangci/golangci-lint-action@v8
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
# ...
problem-matchers
(optional)
Forces the usage of the embedded problem matchers.
By default, the problem matcher of Go (actions/setup-go) already handles the default golangci-lint output (text).
Works only with the text format (the golangci-lint default).
https://golangci-lint.run/usage/configuration/#output-configuration
The default value is false.
Example
uses: golangci/golangci-lint-action@v8
with:
problem-matchers: true
# ...
skip-cache
(optional)
If set to true, all caching functionality will be completely disabled.
This takes precedence over all other caching options.
The default value is false.
Example
uses: golangci/golangci-lint-action@v8
with:
skip-cache: true
# ...
skip-save-cache
(optional)
If set to true, caches will not be saved, but they may still be restored, requiring skip-cache: false.
The default value is false.
Example
uses: golangci/golangci-lint-action@v8
with:
skip-save-cache: true
# ...
cache-invalidation-interval
(optional)
Periodically invalidate a cache every cache-invalidation-interval days to ensure that outdated data is removed and fresh data is loaded.
The default value is 7.
If the number is <= 0, the cache will always be invalidated (not recommended).
Example
uses: golangci/golangci-lint-action@v8
with:
cache-invalidation-interval: 15
# ...
Annotations
Currently, GitHub parses the action's output and creates annotations.
The restrictions of annotations are as follows:
- Currently, they don't support Markdown formatting (see the feature request).
- They aren't shown in the list of comments. If you would like to have comments, please up-vote the issue.
- The number of annotations is limited.
Permissions required:
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
For annotations to work, use the default format output (text) and either use actions/setup-go in the job or enable the internal problem matchers.
Performance
The action was implemented with performance in mind:
- We cache data from golangci-lint analysis between builds by using @actions/cache.
- We don't use Docker because image pulling is slow.
- We do as much as we can in parallel, e.g., we download the cache and the golangci-lint binary in parallel.
- We rely on
actions/setup-gofor Go module cache.
Internals
We use a JavaScript-based action. We don't use a Docker-based action because:
- Pulling Docker images is currently slow.
- It is easier to use caching from @actions/cache.
We support different platforms, such as ubuntu, macos, and windows with x32 and x64 architectures.
Inside our action, we perform three steps:
- Set up the environment in parallel:
- Restore the cache from previous analyses.
- Fetch the action config and find the latest
golangci-lintpatch version for the required version (users of this action can specify only the minor version ofgolangci-lint). After that, install golangci-lint using @actions/tool-cache.
- Run
golangci-lintwith the argumentsargsspecified by the user. - Save the cache for later builds.
Caching internals
- We save and restore the following directory:
~/.cache/golangci-lint. - The primary caching key looks like
golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-{go.mod_hash}. The interval number ensures that we periodically invalidate our cache (every 7 days). Thego.modhash ensures that we invalidate the cache early â as soon as dependencies have changed. - We use restore keys:
golangci-lint.cache-{runner_os}-{working_directory}-{interval_number}-. GitHub matches keys by prefix if there is no exact match for the primary cache.
This scheme is basic and needs improvements. Pull requests and ideas are welcome.
Top Related Projects
Set up your GitHub Actions workflow with a specific version of Go
Fast linters runner for Go
🔥 ~6x faster, stricter, configurable, extensible, and beautiful drop-in replacement for golint
Go security checker
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot