staticcheck & golangci-lint em CI
staticcheck é um analisador de alto sinal para bugs e uso incorreto de APIs.
Busque em todas as páginas da documentação
staticcheck é um analisador de alto sinal para bugs e uso incorreto de APIs.
golangci-lint executa staticcheck e dezenas de outras verificações por trás de um único arquivo de configuração, tornando-o o ponto de entrada usual de CI para políticas de lint em Go.
Editores locais fornecem feedback rápido; CI impõe as mesmas regras para todos os contribuidores e bots.
Comece com go vet e staticcheck, depois adicione golangci-lint com um .golangci.yml commitado.
Adote novas verificações incrementalmente em repositórios legados para que as equipes corrijam os achados em vez de desabilitar linters permanentemente.
Cartão de receita de referência rápida - pronto para copiar e colar.
go install honnef.co/go/tools/cmd/staticcheck@latest
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
staticcheck ./...
golangci-lint run ./....golangci.yml mínimo:
run:
timeout: 5m
linters:
enable:
- govet
- staticcheck
- ineffassign
- unused
issues:
max-issues-per-linter: 0Quando usar isso:
go vet com verificações de corretude (regras SA* do staticcheck).Handler problemático:
// example.com/demo/internal/api/handler.go
package api
import (
"fmt"
"net/http"
)
func Health(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "ok") // falta verificação de erro
defer r.Body.Close() // Body pode ser nil em GET
}staticcheck localmente:
staticcheck ./internal/api/...Achados típicos incluem erros não tratados e construções suspeitas.
Integre CI com golangci-lint:
name: lint
on: [push, pull_request]
jobs:
golangci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.26.x'
- run: go mod download
- uses: golangci/golangci-lint-action@v6
with:
version: latest
args: ./...Handler corrigido:
func Health(w http.ResponseWriter, r *http.Request) {
if _, err := fmt.Fprintf(w, "ok"); err != nil {
http.Error(w, "write failed", http.StatusInternalServerError)
return
}
if r.Body != nil {
defer r.Body.Close()
}
}O que isso demonstra:
go/analysis (direta ou indiretamente) para inspecionar ASTs tipados.max-issues-per-linter).| Categoria | Exemplos |
|---|---|
| Corretude | Condições impossíveis, comparações duvidosas, uso indevido de contexto |
| Desempenho | Padrões de append subótimos, conversões redundantes |
| Estilo | Uso de API depreciada com sugestões de substituição |
Execute staticcheck -explain SA1006 (exemplo de código) para ler a documentação da regra.
| Chave | Propósito |
|---|---|
linters.enable / disable | Curadoria do pacote |
linters-settings | Configuração por linter (ex: severidade do gosec) |
run.build-tags | Correspondência de builds com tags em CI |
issues.exclude-rules | Supressões mais restritas com correspondência de caminho e texto |
issues.new-from-rev | Falhar apenas em problemas introduzidos após um commit de baseline |
golangci-lint run ./... > baseline.txt e corrija os pacotes críticos primeiro.issues.new-from-rev: origin/main para que a dívida legada não bloqueie todos os PRs.nolint - exija IDs de ticket quando exceções forem inevitáveis.run:
go: "1.26"
build-tags:
- integrationAlinhe tags com jobs de teste que usam -tags=integration.
nolint excessivamente amplas - //nolint:all esconde bugs futuros. Correção: Nomeie linters específicos e justifique em um comentário.go mod download antes do job de lint.issues.exclude-rules apenas para caminhos conhecidos barulhentos.max-issues zero desde o primeiro dia - Equipes desabilitam a CI. Correção: Use new-from-rev ou modo de aviso temporário.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Apenas go vet | Scripts minúsculos, repositórios de ensino | Serviços de produção que necessitam de verificações mais profundas |
| Apenas staticcheck | Linter único, configuração mínima | Você quer gosec, misspell e lint de importação em uma única execução |
Driver go/analysis personalizado | Uma regra específica | Cobertura padrão da comunidade (use golangci-lint) |
| Política apenas de revisão | Cultura pré-lint | Escala mal além de um punhado de engenheiros |
Opcional - golangci-lint é suficiente em CI se staticcheck estiver habilitado.
Algumas equipes executam staticcheck sozinho em pre-commit para velocidade.
Use uma entrada direcionada issues.exclude-rules com chaves de caminho e linter.
Prefira corrigir o código se o padrão for arriscado em outros lugares.
Ele relata problemas; a formatação é gofmt/gofumpt.
Habilite o linter gofmt para falhar em arquivos não formatados.
Monorepos grandes precisam de 5-10 minutos.
Comece com 5m; aumente se os jobs cancelarem no meio da execução.
Exclua *.pb.go e vendor/ via run.skip-dirs ou issues.exclude-rules.
Não faça lint da saída gerada que você não pode alterar.
gopls incorpora um subconjunto para velocidade do editor.
A configuração de CI é a autoridade para requisitos de merge.
Sim, se o código de produção usar tags - espelhe as tags de teste da CI em run.build-tags.
Não, mas é o orquestrador de fato.
go vet mais staticcheck é um mínimo mais leve.
Execute a partir de cada raiz de módulo ou use um script de meta-repositório que itera sobre os caminhos de go.mod.
go.work não substitui automaticamente os jobs de CI por módulo.
Adicione gosec para serviços sensíveis à segurança; nilaway quando os panics nil são frequentes.
Habilite via plugins do golangci-lint ou jobs separados - veja as páginas dedicadas nesta seção.
Versões da Stack: Esta página foi escrita para Go 1.26.x (padrão GC Green Tea, modernizadores go fix - verifique o patch na compilação), chi (latest - verifique na compilação), gin (latest - verifique na compilação), echo (latest - verifique na compilação), google.golang.org/grpc (latest - verifique na compilação), sigs.k8s.io/controller-runtime (latest - verifique na compilação), kubebuilder (latest - verifique na compilação), tinygo (latest - verifique os alvos de placa na compilação), wazero (latest - verifique na compilação) e golangci-lint (latest - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026