Quando as dependências devem ser atualizadas?


30

Tivemos duas grandes crises relacionadas à dependência com duas bases de código diferentes (Android e um aplicativo da web Node.js.). O repositório do Android precisava migrar do Flurry para o Firebase, o que exigiu a atualização da biblioteca do Google Play Services em quatro versões principais. O mesmo aconteceu com o aplicativo Nó hospedado pelo Heroku, onde nossa pilha de produção (cedar) foi descontinuada e precisava ser atualizada para cedar-14. Nosso banco de dados PostgreSQL também precisava atualizar de 9.2 para 9.6.

As dependências de cada um desses aplicativos ficaram obsoletas por quase dois anos e, quando algumas foram preteridas e chegamos ao período de "pôr do sol", foi uma grande dor de cabeça atualizá-las ou substituí-las. Passei mais de 30 horas no mês passado ou dois resolvendo lentamente todos os conflitos e códigos quebrados.

Obviamente, deixar as coisas descansarem por dois anos é muito tempo. A tecnologia se move rapidamente, especialmente quando você está usando um provedor de plataforma como o Heroku. Vamos supor que temos um conjunto de testes completo e um processo de IC como o Travis CI, que tira muitas das suposições da atualização. Por exemplo, se uma função foi removida após uma atualização e você a estava usando, seus testes falhariam.

Com que frequência as dependências devem ser atualizadas ou quando devem ser atualizadas? Atualizamos porque fomos forçados a fazê-lo, mas parece que algum tipo de abordagem preventiva seria melhor. Devemos atualizar quando versões menores são lançadas? Versões principais? Todo mês, se houver atualizações disponíveis? Quero evitar uma situação como a que acabei de experimentar a todo custo.

PS - para um dos meus projetos pessoais do Rails, eu uso um serviço chamado Gemnasium que rastreia suas dependências para que você possa ser notificado de, por exemplo, vulnerabilidades de segurança. É um ótimo serviço, mas teríamos que verificar manualmente as dependências dos projetos que mencionei.

Respostas:


32

Você geralmente deve atualizar as dependências quando:

  1. É requerido
  2. Há uma vantagem em fazer isso
  3. Não fazer isso é desvantajoso

(Eles não são mutuamente exclusivos.)

A motivação 1 ("quando você precisar") é o motorista mais urgente. Algum componente ou plataforma da qual você depende (por exemplo, Heroku) exige, e você precisa se alinhar. As atualizações necessárias geralmente saem em cascata de outras opções; você decide atualizar para a versão PostgreSQL. Agora você precisa atualizar seus drivers, sua versão do ORM, etc.

A atualização porque você ou sua equipe percebe uma vantagem é mais suave e mais opcional. Mais um julgamento: "O novo recurso, habilidade, desempenho ... vale o esforço e a deslocação que o trazem causarão?" No Olden Times, havia um forte viés contra atualizações opcionais. Eles eram manuais e difíceis, não havia boas maneiras de experimentá-los em uma caixa de areiaou ambiente virtual, ou reverter a atualização, se não der certo, e não houve testes automáticos rápidos para confirmar que as atualizações não "perturbaram o carrinho da apple". Atualmente, o viés é direcionado para ciclos de atualização muito mais rápidos e agressivos. Métodos ágeis adoram tentar coisas; instaladores automatizados, gerenciadores de dependências e repositórios tornam o processo de instalação rápido e quase invisível; ambientes virtuais e controle de versão onipresente facilitam ramificações, bifurcações e reversões; e testes automatizados, vamos tentar uma atualização e avaliar de forma fácil e substancial "Funcionou? Estragou alguma coisa?" O viés mudou de atacado, de "se não está quebrado, não conserte" para "atualize cedo, atualize com frequência"

A motivação 3 é a mais suave. As histórias de usuários não se preocupam com "o encanamento" e nunca mencionam "e mantêm a infraestrutura não mais que N lançamentos atrás da atual". As desvantagens da deriva de versão (aproximadamente, a dívida técnica associada a ficar atrás da curva) invadem silenciosamente e, em seguida, se anunciam por meio de quebra. "Desculpe, essa API não é mais suportada!" Mesmo nas equipes ágeis, pode ser difícil motivar o incrementalismo e "ficar em cima" do frescor dos componentes quando não é visto como essencial para concluir um determinado sprint ou release. Se ninguém advogar por atualizações, elas podem não ser atendidas. Essa roda pode não chiar até que esteja pronta para quebrar, ou mesmo até quebrar.

De uma perspectiva prática, sua equipe precisa prestar mais atenção ao problema de desvio de versão. 2 anos é muito longo. Não há mágica. É apenas uma questão de "me pague agora ou me pague depois". Aborde o problema de desvio de versão de forma incremental ou sofra e supere os solavancos maiores a cada poucos anos. Eu prefiro o incrementalismo, porque alguns dos solavancos da plataforma são enormes. Uma API ou plataforma essencial da qual você depende não está mais funcionando pode realmente arruinar o seu dia, semana ou mês. Eu gosto de avaliar a atualização dos componentes pelo menos 1-2 vezes por ano. Você pode agendar revisões explicitamente ou permitir que elas sejam acionadas organicamente pelos ciclos de atualização relativamente metronômicos, geralmente anuais dos principais componentes, como Python, PostgreSQL e node.js. Se as atualizações de componentes não acionarem sua equipe com muita força, as atualizações de versões importantes serão lançadas, nos platôs naturais do projeto, ou todos os k lançamentos também podem funcionar. O que quer que dê atenção à correção da versão deriva em uma cadência mais regular.


5

As bibliotecas devem ser atualizadas quando precisam ser atualizadas. Isso significa que, se a atualização não trazer valor, você não deve.

No seu caso particular, você estava migrando de uma pilha de tecnologia antiga para uma nova e, para fazer isso, foi forçado a atualizar suas dependências. Nesse exato momento é o momento correto para atualizar dependências.

Se você estivesse atualizando suas dependências ao longo do tempo, para "não ter dor de cabeça agora", teria que investir muito tempo de trabalho (codificação) sem valor de retorno. E quando você deveria fazer a última atualização (a que você está fazendo agora, mas atualizando 1 versão principal em vez de 4), provavelmente ainda sentiria dor de cabeça em algum lugar (afinal, a versão principal significa quebrar as alterações). Então eu acho que você está no caminho certo.

No entanto, se você achar muito difícil migrar e precisar refatorar bastante, é provável que o problema esteja na sua base de código. É muito comum que os projetos Android não tenham uma arquitetura geral em termos de estrutura de código. Uma boa estrutura de injeção de dependência, como o Dagger 2 , e alguns princípios de engenharia de software, como o SOLID , facilitariam a alteração da implementação do código, mantendo o mesmo comportamento / requisitos.

Além disso, como estamos refatorando, leia um pouco sobre o teste de unidade, pois isso ajudaria muito ao fazer esse tipo de trabalho.


4

Se você estiver usando ferramentas de gerenciamento de pacotes (por exemplo, npm, NuGet) e tiver um conjunto abrangente de testes automatizados, a atualização das dependências deve ser uma atividade de baixo esforço, basta atualizar o pacote, executar o conjunto de testes e verificar se há algum problema. Se houver reversão e aumente um item de trabalho para investigar e corrigir o problema.

Desde que o custo da atualização de dependências seja baixo, vale a pena manter-se atualizado:

  • Se houver problemas com a atualização, você deseja saber o quanto antes, caso sejam necessárias alterações no upstream.
  • Deixar atualizações de dependência para o último minuto geralmente significa que você está fazendo essas atualizações no momento de processamento (por exemplo, em resposta a um bug crítico de segurança). Manter o controle de suas dependências significa que você controla quando gasta esse esforço e pode executar essas atualizações em momentos em que não está tão ocupado.
  • As versões mais recentes podem ter melhorias de produtividade, por exemplo, melhor documentação, API mais fácil de usar, correções de bugs (embora o inverso também seja possível).

Se a atualização de dependências não for um esforço baixo (por exemplo, porque você precisa testar manualmente a atualização ou porque existem problemas conhecidos / alterações recentes), será necessário ponderar os prós e os contras em relação às outras tarefas. As antigas dependências são uma espécie de dívida técnica com juros baixos e, portanto, devem ser tratadas de acordo.


2

Você não deve fazer um lançamento em que use conscientemente versões antigas de suas dependências, a menos que essas versões sejam alternativas suportadas.

ou seja, se você estiver na V1 e ainda for suportado, ainda poderá usar a versão mais recente da v1.

A única vez que você deve estar desatualizado é se:

A: Você não faz um lançamento há algum tempo.

B: Você está na v1 há tanto tempo que não é mais suportado

As atualizações são lançadas por um motivo; elas contêm correções de segurança que você deve levar em consideração.

Se uma nova versão de sua dependência for lançada, você também deverá fazer um lançamento


1

Eu acho que deve depender da biblioteca em questão até certo ponto, mas eu também sofri dores de cabeça semelhantes.

O senso comum me diz que uma versão principal provavelmente é a hora certa para atualizar, e uma versão secundária que soluciona uma falha séria ou inclui um benefício significativo substitui isso.

Às vezes, não temos o luxo de trabalhar em todos os aplicativos que exigem manutenção, ou mesmo desimplementar um aplicativo de missão crítica, mas eles acabam mordendo você eventualmente e um grama de prevenção muitas vezes supera a cura!


0

As bibliotecas devem ser atualizadas quando oferecer uma vantagem que o software utilizará para compensar o trabalho gasto na mudança.

Até pequenas atualizações de versão de biblioteca podem quebrar ou inserir inconsistências nos aplicativos. Nessa perspectiva, não há pequenas alterações.

Não há vergonha em usar bibliotecas antigas. Quando a mudança é necessária, pode ser dolorosa, mas faz parte do trabalho.


Concordo que toda atualização deve ser bem compreendida. E não há problema em ter dívidas técnicas, se você puder pagar de volta. Não somos contratados para estar na versão mais recente (e apenas perseguindo versões mais recentes o tempo todo, sem pensamento ou análise), mas as versões mais recentes podem ajudar nas coisas que somos contratados para fazer.
geoaxis 26/10
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.