staticcheck & golangci-lint en CI
staticcheck es un analizador de alta señal para errores y mal uso de API.
Busca en todas las páginas de la documentación
staticcheck es un analizador de alta señal para errores y mal uso de API.
golangci-lint ejecuta staticcheck y docenas de otras comprobaciones detrás de un único archivo de configuración, lo que lo convierte en el punto de entrada habitual de CI para la política de linting de Go.
Los editores locales proporcionan retroalimentación rápida; la CI aplica las mismas reglas para cada contribuidor y bot.
Comienza con go vet y staticcheck, luego añade golangci-lint con un .golangci.yml confirmado.
Adopta nuevas comprobaciones incrementalmente en repositorios heredados para que los equipos corrijan los hallazgos en lugar de deshabilitar linters permanentemente.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
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: 0Cuándo usar esto:
go vet con comprobaciones de corrección (reglas SA* de 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 comprobación de error
defer r.Body.Close() // Body puede ser nil en GET
}staticcheck localmente:
staticcheck ./internal/api/...Los hallazgos típicos incluyen errores mal manejados y construcciones sospechosas.
Conecta la CI con 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 corregido:
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()
}
}Lo que esto demuestra:
go/analysis (directa o indirectamente) para inspeccionar ASTs tipados.max-issues-per-linter).| Categoría | Ejemplos |
|---|---|
| Corrección | Condiciones imposibles, comparaciones dudosas, mal uso de contexto |
| Rendimiento | Patrones de append subóptimos, conversiones redundantes |
| Estilo | Uso de API obsoleta con reemplazos sugeridos |
Ejecuta staticcheck -explain SA1006 (código de ejemplo) para leer la documentación de la regla.
| Clave | Propósito |
|---|---|
linters.enable / disable | Curar el paquete |
linters-settings | Configuración por linter (ej. severidad de gosec) |
run.build-tags | Emparejar tags de compilación en CI |
issues.exclude-rules | Restricciones más estrechas con coincidencia de ruta y texto |
issues.new-from-rev | Fallar solo en problemas introducidos después de un commit de línea base |
golangci-lint run ./... > baseline.txt y corrige primero los paquetes críticos.issues.new-from-rev: origin/main para que la deuda heredada no bloquee cada PR.nolint generales - requiere IDs de ticket cuando las excepciones son inevitables.run:
go: "1.26"
build-tags:
- integrationEmpareja los tags con los trabajos de prueba que usan -tags=integration.
nolint demasiado amplias - //nolint:all oculta errores futuros. Solución: Nombra linters específicos y justifica en el comentario.go mod download antes del trabajo de linting.issues.exclude-rules solo para rutas ruidosas conocidas.max-issues cero desde el primer día - Los equipos deshabilitan la CI. Solución: Usa new-from-rev o el modo de advertencia temporal.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Solo go vet | Scripts pequeños, repositorios de enseñanza | Servicios de producción que necesitan comprobaciones más profundas |
| staticcheck solo | Linter único, configuración mínima | Quieres gosec, misspell y lint de importación en una sola ejecución |
Driver go/analysis personalizado | Una regla específica | Cobertura comunitaria estándar (usa golangci-lint) |
| Política solo de revisión | Cultura previa al linting | Escala mal más allá de un puñado de ingenieros |
Opcional - golangci-lint es suficiente en CI si staticcheck está habilitado.
Algunos equipos ejecutan staticcheck solo en pre-commit para mayor velocidad.
Usa una entrada issues.exclude-rules dirigida con claves de ruta y linter.
Prefiere corregir el código si el patrón es arriesgado en otros lugares.
Informa de problemas; el formateo es gofmt/gofumpt.
Habilita el linter gofmt para fallar en archivos sin formato.
Los monorepos grandes necesitan 5-10 minutos.
Comienza en 5m; aumenta si los trabajos se cancelan a mitad de ejecución.
Excluye *.pb.go y vendor/ mediante run.skip-dirs o issues.exclude-rules.
No hagas linting de la salida generada que no puedes cambiar.
gopls incrusta un subconjunto para la velocidad del editor.
La configuración de CI es autoritaria para los requisitos de fusión.
Sí, si el código de producción usa tags; refleja los tags de prueba de CI en run.build-tags.
No, pero es el orquestador de facto.
go vet más staticcheck es un mínimo más ligero.
Ejecuta desde la raíz de cada módulo o usa un script de meta-repositorio que itere sobre las rutas de go.mod.
go.work no reemplaza automáticamente los trabajos de CI por módulo.
Agrega gosec para servicios sensibles a la seguridad; nilaway cuando los nil panics son frecuentes.
Habilita a través de plugins de golangci-lint o trabajos separados; consulta las páginas dedicadas en esta sección.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (GC por defecto Green Tea, modernizadores de go fix - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica los objetivos de la placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026