Linting em CI/CD
Execute ESLint, Prettier e verificação de tipos do TypeScript no GitHub Actions para garantir a qualidade do código em cada pull request.
Busque em todas as páginas da documentação
Execute ESLint, Prettier e verificação de tipos do TypeScript no GitHub Actions para garantir a qualidade do código em cada pull request.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
Cartão de receita de referência rápida - pronto para copiar e colar.
// scripts do package.json
{
"scripts": {
"lint": "next lint",
"format:check": "prettier --check .",
"type-check": "tsc --noEmit"
}
}# Execute todas as verificações localmente (igual à CI)
npm run lint && npm run format:check && npm run type-checkQuando usar isso: Todo projeto que usa pull requests. CI é sua rede de segurança para capturar problemas que os hooks de pré-commit perdem.
# .github/workflows/code-quality.yml
name: Code Quality
on:
pull_request:
branches: [main]
push:
branches: [main]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
quality:
name: Lint, Format & Type Check
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- name: Install dependencies
run: npm ci
- name: ESLint
run: npm run lint
- name: Prettier
run: npm run format:check
- name: TypeScript
run: npm run type-checkO que isso demonstra:
npm ci instala versões exatas do lock file (mais rápido e determinístico).cache: "npm" armazena em cache o node_modules entre as execuções para velocidade.concurrency cancela execuções em andamento quando novos commits são enviados.timeout-minutes impede que jobs travados executem indefinidamente.main.npm run lint executa next lint, que sai com o código 1 se houver erros.prettier --check sai com o código 1 se algum arquivo não estiver formatado corretamente.tsc --noEmit sai com o código 1 se houver erros de tipo.Jobs paralelos (mais rápido para projetos grandes):
jobs:
lint:
name: ESLint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: npm run lint
format:
name: Prettier
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: npm run format:check
type-check:
name: TypeScript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: "npm"
- run: npm ci
- run: npm run type-checkCom Biome (uma única verificação substitui lint + format):
- name: Biome
run: npx biome check .Comentários de revisão de PR com reviewdog:
- name: ESLint with reviewdog
uses: reviewdog/action-eslint@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
eslint_flags: "src/"Isso posta erros do ESLint como comentários de revisão de PR inline nas linhas exatas que precisam de correção.
Cache para pnpm:
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: "pnpm"
- name: Install dependencies
run: pnpm install --frozen-lockfileConfiguração de proteção de branch:
Repositório GitHub → Configurações → Branches → Regras de proteção de branch:
✓ Exigir que as verificações de status sejam aprovadas antes do merge
✓ Exigir que os branches estejam atualizados antes do merge
Verificações de status: "Lint, Format & Type Check" (ou nomes de jobs individuais)
// tsc --noEmit verifica o projeto INTEIRO, não apenas os arquivos alterados.
// Isso é intencional - uma alteração em um arquivo pode quebrar tipos em outro lugar.
// Exemplo: alterando um tipo compartilhado
// types.ts
export type User = {
name: string;
email: string;
role: "admin" | "user"; // Adicionar "moderator" aqui é seguro
};
// Mas remover "admin" quebra todos os arquivos que usam User.role === "admin"
// Apenas o tsc captura isso - o ESLint não pode.Coisas que vão te morder. Cada armadilha inclui o que dá errado, por que acontece e a correção.
CI passa mas o local falha (ou vice-versa) - Versões diferentes do Node.js, versões diferentes de dependências ou comportamento específico do sistema operacional. Correção: Fixe a versão do Node.js na CI para corresponder à local. Use npm ci (não npm install) para usar versões exatas do lock file.
Erros de lint em arquivos gerados - A CI faz lint de arquivos que são gerados durante o build (por exemplo, Prisma client, tipos GraphQL). Correção: Adicione diretórios gerados ao .eslintignore ou ao array ignores em eslint.config.mjs e .prettierignore.
tsc é lento na CI - A verificação de tipos do TypeScript pode levar 30 segundos ou mais em projetos grandes. Correção: Habilite "incremental": true em tsconfig.json e armazene em cache o arquivo .tsbuildinfo entre as execuções da CI. Alternativamente, use @vercel/next-swc que faz a verificação de tipos mais rapidamente.
Verificação do Prettier falha em quebras de linha - Desenvolvedores Windows commitem arquivos com CRLF, a CI roda em Linux com LF. Correção: Defina "endOfLine": "lf" em .prettierrc e configure o Git: git config --global core.autocrlf input.
Proteção de branch não aplicada - Verificações de status só bloqueiam o merge se a proteção de branch estiver configurada. Sem ela, qualquer um pode fazer merge de PRs falhos. Correção: Habilite as regras de proteção de branch no main e exija que o job de CI seja aprovado.
Outras maneiras de resolver o mesmo problema - e quando cada uma é a melhor escolha.
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
| Husky + lint-staged | Você quer capturar problemas antes que cheguem à CI | Você precisa de uma rede de segurança de CI (use ambos) |
| GitLab CI / CircleCI | Você não está no GitHub | Você está no GitHub (Actions é nativo) |
trunk check | Você quer uma ferramenta de CI unificada que gerencie linters para você | Você quer controle total sobre seu pipeline de CI |
| Verificações de implantação Vercel | Você só se importa com erros em tempo de build | Você quer aplicação de lint e formato |
--no-verify.npm ci instala versões exatas do lock file (determinístico).node_modules primeiro para uma instalação limpa.npm install na CI porque pula a resolução de dependências.concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: truenpm ci.npm install localmente pode resolver versões diferentes de npm ci na CI.npm ci.- name: Biome
run: npx biome check .Um único comando substitui as verificações de lint e formato.
reviewdog/action-eslint@v1."endOfLine": "lf" em .prettierrc.git config --global core.autocrlf input.tsc pode."incremental": true em tsconfig.json..tsbuildinfo entre as execuções da CI.ignores em eslint.config.mjs..prettierignore.tsconfig que tsc --noEmit impõeRevisado por Chris St. John·Última atualização: 10 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥