Atualizar dependências
O objetivo é um projeto cujas dependências estejam atualizadas e sem vulnerabilidades conhecidas, entregue como uma mudança na qual o usuário possa confiar: cada etapa verificada pelas próprias verificações do projeto e cada etapa arriscada isolada para que possa ser revisada ou revertida por conta própria.
O trabalho com dependências falha de duas maneiras típicas. Uma é a atualização "big bang", onde tudo é atualizado de uma vez, algo quebra e ninguém consegue identificar qual atualização causou o problema. A outra é uma "correção" que esconde o problema, como --force, --legacy-peer-deps, afrouxar um intervalo de versão ou suprimir um aviso. O fluxo de trabalho abaixo é construído para evitar ambos.
0. Decidir o que foi solicitado
- Apenas verificar ("alguma vulnerabilidade?", "o que está desatualizado?"): execute os passos 1–3, relate e pare. Não modifique arquivos.
- Atualizar (padrão para "atualizar minhas dependências", "corrigir os avisos de auditoria", "manter pacotes atualizados"): execute todo o fluxo de trabalho.
- Um pacote ("atualizar vite para v8"): execute os passos 1–2, depois o passo 6 para esse pacote (junto com quaisquer pacotes que devam se mover com ele), depois 7–8.
1. Pré-voo
-
Leia os documentos de contribuição do repositório (
AGENTS.md,CLAUDE.md,CONTRIBUTING.md) e a configuração de CI (.github/workflows/*) para aprender os comandos de verificação (lint, typecheck, teste, build) e a convenção de mensagens de commit. Use o que o repositório realmente executa no CI. Se nada estiver documentado, use os scripts definidos no manifesto. -
Certifique-se de que a árvore de trabalho esteja limpa. Se não estiver, pare e pergunte. Misturar o trabalho não commitado do usuário em commits de dependência causa danos reais.
-
Detecte os ecossistemas por seus lockfiles e manifestos (um repositório pode ter vários):
Arquivos Referência package-lock.json,pnpm-lock.yaml,yarn.lock,bun.lockreferences/node.mdrequirements*.txt,pyproject.toml,uv.lock,poetry.lock,Pipfile.lockreferences/python.mdCargo.toml/Cargo.lockreferences/rust.mdgo.mod/go.sumreferences/go.mdqualquer outro (Gemfile.lock, composer.lock, ...) use a ferramenta nativa do ecossistema, além de scripts/osv_check.pypara a auditoriaLeia o arquivo de referência correspondente. Ele lista os comandos exatos e as armadilhas desse ecossistema.
-
Encontre a versão do runtime que o projeto visa:
.nvmrc,engines,.python-version,requires-python,rust-version, a diretivagoou a versão no CI. Alguns pacotes devem acompanhar o runtime, não o lançamento mais recente. Por exemplo,@types/nodedeve corresponder à versão principal do Node que o projeto executa, então atualizá-lo para uma versão principal mais nova do Node permite que o código use APIs que quebram em produção. Trate "mais recente" como um candidato, não um alvo. -
Execute os comandos de verificação antes de mudar qualquer coisa e anote o resultado. Se algo já falhar, você precisa saber disso agora. Caso contrário, você culpará uma atualização por uma falha que já estava lá ou enviará um branch vermelho. Se a linha de base estiver vermelha, informe o usuário e pergunte se deseja continuar.
2. Inventário
Colete duas listas com as ferramentas do ecossistema (veja a referência):
- Vulnerabilidades: a ferramenta de auditoria nativa. Se não estiver instalada e não puder ser executada efemeramente, use o scanner incluído:
python3 <skill-dir>/scripts/osv_check.py <lockfile>...(consulta osv.dev; apenas stdlib). Executar a varredura OSV além da ferramenta nativa é barato e muitas vezes vale a pena, porque as ferramentas nativas às vezes perdem avisos em cópias aninhadas ou duplicadas de um pacote. - Pacotes desatualizados: atual → desejada (dentro do intervalo declarado) → mais recente.
Para cada vulnerabilidade, descubra qual dependência direta puxa o pacote vulnerável e qual versão dessa dependência direta o corrige. Os usuários agem sobre dependências diretas. Um nome de pacote transitivo sozinho não é acionável.
3. Planejar e relatar
Classifique tudo em três categorias e mostre o plano como uma tabela curta antes de fazer alterações:
- Correções de segurança: qualquer coisa que remova um aviso. Mais urgente. Se a correção precisar de um bump principal, é um major (categoria 3), mas liste-o primeiro lá e diga que é orientado por segurança.
- Bumps seguros: patch/minor dentro do semver (para pacotes 0.x, um minor conta como quebra).
- Majors: todo o resto, uma linha cada. Agrupe pacotes que devem se mover juntos (um framework e seus plugins, uma ferramenta e suas definições de tipo, pacotes que compartilham uma dependência de pares) e trate cada grupo como uma unidade.
A gravidade importa para a ordenação, e a acessibilidade importa para a explicação. Um aviso crítico em um executor de teste apenas de desenvolvimento ainda vale a pena ser corrigido, mas diga claramente que é apenas de desenvolvimento, em vez de alarmar o usuário. Para solicitações de apenas verificação, este relatório é a entrega. Inclua a gravidade, o ID do aviso, o caminho da dependência e a versão da correção.
4. Branch
Crie chore/deps-YYYY-MM-DD (data de hoje) a partir do branch padrão atualizado, a menos que o usuário já esteja em um branch criado para este trabalho.
5. Correções de segurança e bumps seguros
- Aplique correções de segurança dentro do intervalo, execute novamente os comandos de verificação e faça commit.
- Aplique os bumps seguros de patch/minor juntos, execute novamente os comandos de verificação e faça commit. Se a verificação falhar, faça bissecção: reverta metade do lote e tente novamente até encontrar o culpado, depois retire-o e trate-o como um major.
Deixe o gerenciador de pacotes escrever o lockfile. Nunca edite lockfiles manualmente.
6. Majors, uma unidade de cada vez
Para cada unidade major, em ordem (orientada por segurança primeiro, depois ferramentas fundamentais antes das coisas que dependem delas, por exemplo, o compilador antes do plugin de linter que depende dele):
- Leia o que mudou. Encontre o guia de migração ou notas de lançamento para cada major que você está cruzando (v2→v5 significa ler v3, v4 e v5). Boas fontes são o
CHANGELOG.mddo projeto, os lançamentos do GitHub e a página de "migração" do site de documentação. Extraia as mudanças de quebra que se aplicam a este código: pesquise por APIs e chaves de configuração removidas ou renomeadas. - Verifique os pares. Certifique-se de que a nova versão satisfaça os requisitos de pares e engine de tudo ao seu redor. Às vezes, o major mais recente ainda não pode ser adotado porque um plugin não o acompanhou. Então pegue a versão mais nova que funciona e registre o que está bloqueando o resto.
- Atualize e corrija. Atualize a unidade, aplique a migração (renomeações de configuração, mudanças de API, codemods se o projeto os fornecer) e execute novamente os comandos de verificação até que passem. Corrija o código adequadamente. Não enfraqueça testes, adicione
skips ou silencie erros de tipo comanyou escapes estilo@ts-ignorepara ficar verde. - Faça commit da unidade por conta própria, com as notas de migração no corpo.
- Saiba quando parar. Se uma unidade precisar de um grande refatoração ou uma decisão de produto (recurso removido, comportamento de runtime alterado que você não pode verificar), ou você não conseguir deixá-la verde com esforço razoável, reverta-a limpa (
git checkout -- .de volta ao último commit) e registre-a como adiada, com o bloqueador específico. Um major adiado com um motivo claro é um bom resultado. Um meio feito não é.
7. Re-verificar e re-auditar
Execute os comandos completos de verificação e a auditoria novamente no estado final. Cada aviso agora deve estar corrigido ou explicado. Para um aviso que você não conseguiu corrigir:
- Se for transitivo e o pacote pai não lançou uma correção, uma substituição/resolução que fixa a versão transitiva corrigida é aceitável apenas se essa versão for compatível com semver com o que o pai espera. Verifique e anote no PR para que alguém a remova depois.
- Se não existir versão corrigida em lugar nenhum, diga isso e avalie se o caminho de código vulnerável é acessível neste projeto.
- Nunca use mecanismos de ignorar/lista de permissões para fazer a auditoria passar silenciosamente.
8. Entregar
Os commits seguem a convenção do repositório. Se o repositório usar Commits Convencionais e não disser nada mais específico, use:
fix(deps): ...para uma correção de segurança em uma dependência de runtimebuild(deps): ...para atualizações e para correções de segurança em ferramentas apenas de desenvolvimento- o resumo nomeia o pacote e o alvo, por exemplo
build(deps): bump vitest para v5. O corpo lista os avisos corrigidos e quaisquer alterações de migração feitas.
Envie e abra um PR (gh pr create) a menos que o usuário tenha solicitado o contrário ou não haja remoto. Use este corpo:
## Resumo
<uma ou duas frases: o que moveu, quantos avisos foram resolvidos>
## Segurança
| Aviso | Gravidade | Pacote (caminho) | Corrigido por |
|---|---|---|---|
## Atualizações
| Pacote | De | Para | Tipo | Notas |
|---|---|---|---|---|
<Tipo = segurança / patch / minor / major; Notas = alterações de migração feitas>
## Adiados
| Pacote | Mais recente | Por que agora não |
|---|---|---|
<par bloqueado, precisa de refatoração, fixação de runtime, ...; "nenhum" se vazio>
## Avisos restantes
<nenhum, ou cada um com motivo e avaliação de acessibilidade>
## Verificação
<os comandos exatos executados no commit final e seu resultado>
Finalize com um breve resumo no chat: o link do PR, o número de avisos corrigidos vs. restantes e os majors adiados com razões de uma linha.