Sou desenvolvedor Java full stack júnior e quero contar um pouco das práticas que estou utilizando para revisar PRs automáticas em um projeto pessoal meu. Eu utilizo o Dependabot para checar semanalmente atualizações das bibliotecas e pacotes utilizados no meu projeto. A cada semana ele abre cerca de 4 a 7 PRs de forma automática, e decidi utilizar isso a meu favor para aprender um pouco mais sobre como revisar PRs.

Aprendendo a revisar PR como júnior

Identificar a Finalidade

Identificar primeiramente a finalidade. Se é correção, feature nova, documentação ou atualização de versão.

Verificar os Arquivos Alterados

Ver quais arquivos foram alterados. Confirmar se as mudanças afetam o projeto atual (de longe a parte mais chata).

Confirmar Impacto das Mudanças

Conferir o que os testes cobrem e, se novos testes foram adicionados, confirmar se eles verificam o comportamento afetado na aplicação.

Analisar as Notas de Release

Claro, o título chore(deps-dev): bump @eslint/js from 9.39.5 to 10.0.1 já era bastante intuitivo. A descrição do PR também confirmava essa atualização, todos os checks estavam verdes e apenas os arquivos package.json e package-lock.json tinham sido alterados. Era só fazer o merge já que tudo estava aparentemente OK, mas o questionamento que resolvi fazer foi:

É uma atualização da versão 9 para a versão 10. Será que os testes cobrem o que pode dar errado nessa mudança?

Foi quando eu decidi olhar as notas de release. Na passagem para a versão 10.0.0, havia uma lista com 22 BREAKING CHANGES! Isso já era motivo para olhar com mais atenção.

Analisar o Impacto das Mudanças

Aqui o primeiro passo é não julgar o impacto do commit pela quantidade de arquivos alterados. Mesmo alterando somente os arquivos de dependências, o importante é saber o que essa nova versão introduziu e como ela poderia afetar o seu projeto.

Antes mesmo de abrir os commits citados nas releases, acabei encontrando um possível problema nos arquivos alterados. Tanto o package.json quanto o package-lock.json trocavam a faixa de versões permitida do @eslint/js de ^9.39.3 para ^10.0.1, porém o ESLint por si só não acompanhava a atualização. Ficou assim:

Na entrada de @eslint/js, a versão exata mudou de 9.39.5 para 10.0.1. O ESLint continuou registrado como 9.39.5. Além disso, a entrada do pacote atualizado passou a incluir este requisito:

Compare o antes e depois. Os dois arquivos atualizavam o @eslint/js e nenhum dos dois atualizava o ESLint. Mas isso, sozinho, não prova um erro: pacotes com números de versão diferentes podem ser compatíveis.

O problema estava no peerDependencies: o próprio @eslint/js declarava que precisava do ESLint na faixa ^10.0.0. Ou seja, a partir de 10.0.0 e abaixo de 11.0.0, e não qualquer versão superior a 10.

Já o meu projeto pedia ^9.39.3, que não permite chegar à versão 10. O package.json dizia quais versões eram permitidas, e o lockfile registrava a versão exata escolhida: 9.39.5.

Para não confundir os dois pacotes: o eslint executa a análise do código, enquanto o @eslint/js fornece configurações de regras, como a configuração recomendada que eu utilizo.

Para ter certeza de que era um erro, fui reproduzi-lo localmente. Usei uma worktree com a branch desse PR para investigar sem mexer na minha pasta principal. Até então, as verificações do CI tinham passado. Mas, ao simular a resolução dos pacotes com este comando, o erro apareceu:

O comando não instala os pacotes nem grava as alterações propostas no lockfile. Pode consultar o registro do npm e gerar logs ou cache, mas permite testar a resolução sem aplicar a atualização.

Agora sim apareceu o ERESOLVE, apontando a incompatibilidade. Na comparação local, essa verificação passou antes da mudança e falhou com os arquivos do PR.

Provavelmente você iria se perguntar: “Por que um pacote tão utilizado pela comunidade JS iria cometer um erro desse? Ninguém revisou essa joça de comparar a versão dos dois pacotes antes de colocar dentro da release não?”

Foi aí que precisei separar as coisas. O pacote tinha declarado a compatibilidade dele. A proposta de atualização do meu projeto é que não atendia ao requisito.

E aquele optional: true? Ele declara o ESLint como opcional (só voltar lá no exemplo do código que você vai ver). Para ter o @eslint/js instalado, não é obrigatório ter o ESLint também. Mas, se ele estiver instalado, a versão precisa ser compatível.

Você não é obrigado a ter um controle para jogar um jogo que também aceita teclado, mas precisa ter um controle compatível com ele.

Conclusão

Revisar PRs de atualizações de pacotes é uma parte crucial do processo de manutenção de projetos de software. Ao identificar a finalidade, verificar os arquivos alterados, confirmar o impacto das mudanças e analisar as notas de release, é possível garantir que o projeto esteja sempre em conformidade com as atualizações de pacotes.

Conclusão

Revisar PRs de atualizações de pacotes é uma parte crucial do processo de manutenção de projetos de software. Ao identificar a finalidade, verificar os arquivos alterados, confirmar o impacto das mudanças e analisar as notas de release, é possível garantir que o projeto esteja sempre em conformidade com as atualizações de pacotes.

Aprendendo Desenvolvedor Java Junior Revisar