Como manter suas bibliotecas de terceiros atualizadas?

28

Digamos que eu tenho um projeto que depende de 10 bibliotecas e, dentro do tronco do meu projeto, estou livre para usar qualquer versão dessas bibliotecas. Então eu começo com as versões mais recentes. Em seguida, cada uma dessas bibliotecas recebe uma atualização uma vez por mês (em média). Agora, manter meu tronco completamente atualizado exigiria a atualização de uma referência de biblioteca a cada três dias.

Isso é obviamente demais. Embora geralmente a versão 1.2.3 seja um substituto para a versão 1.2.2, você nunca sabe disso sem testar. Testes de unidade não são suficientes; se for um mecanismo de banco de dados / arquivo, você deve garantir que ele funcione corretamente com arquivos criados com versões mais antigas e talvez vice-versa. Se isso tem algo a ver com a GUI, você deve inspecionar visualmente tudo. E assim por diante.

Como você lida com isso? Algumas abordagens possíveis:

  • Se não estiver quebrado, não conserte . Fique com sua versão atual da biblioteca, desde que você não note nada de errado com ela quando usada em seu aplicativo, independentemente da frequência com que o fornecedor da biblioteca publique atualizações. Pequenas mudanças incrementais são apenas desperdícios.
  • Atualize com frequência para manter as alterações pequenas. Como você terá que atualizar algum dia, em qualquer caso, é melhor atualizar com frequência para detectar problemas mais cedo, quando são fáceis de corrigir, em vez de pular várias versões e deixar acumular problemas em potencial.
  • Algo no meio. Existe um ponto ideal?
Joonas Pulakka
fonte
1
+1: Gostaria de saber se, como "caça ao erro", você poderia ter uma iteração de "Atualizar Sprint" em um projeto. Curioso sobre respostas :)
Matthieu

Respostas:

25

Estou chocado - e realmente chocado - com o número de respostas aqui dizendo "não atualize a menos que você precise". Eu fiz isso e, embora seja mais fácil no curto prazo, queima como o inferno a longo prazo. As atualizações menores e mais frequentes são muito, muito mais fáceis de gerenciar do que as grandes ocasionais, e você obtém o benefício de novos recursos, correções de bugs e assim por diante.

Não acredito que as alterações na biblioteca sejam mais difíceis de testar do que as alterações no código. É a mesma coisa - você está fazendo uma alteração na base de código e precisa validá-la antes de se comprometer e mais profundamente antes de lançar. Mas você já deve ter processos para fazer isso, pois está fazendo alterações no código!

Se você estiver trabalhando em iterações, com duração de duas a quatro semanas, sugiro que faça a atualização das bibliotecas uma tarefa uma vez por iteração, a ser feita o mais rápido possível após o início, quando as coisas estiverem um pouco mais relaxadas do que antes da iteração prazo e o projeto tem mais capacidade de absorver mudanças. Faça com que alguém (ou um par, se você emparelhe a programação) se sente, observe quais bibliotecas foram atualizadas e tente trazer cada uma delas e executar uma reconstrução e teste. Faça um orçamento de meio dia a um dia para cada iteração, talvez. Se as coisas funcionarem, verifique as alterações (presumo que você mantenha as bibliotecas no controle de origem, como fazemos; não sei como propagaria a alteração de maneira controlada, se não). Obviamente, isso será muito mais fácil se você tiver testes automatizados do que se o teste for totalmente manual.

Agora, a pergunta é o que você faz se uma atualização quebra as coisas - você gasta algum tempo corrigindo ou deixando de fora? Eu sugeriria inclinar-se para o último; se puder ser corrigido em uma hora, faça-o, mas se uma atualização exigir um trabalho significativo para integrar, crie-a como sua própria tarefa de desenvolvimento, a ser estimada, priorizada e agendada como qualquer outra. As chances são de que, a menos que traga alguma correção ou melhoria muito crucial, a prioridade será baixa e você nunca conseguirá contornar isso. Mas você nunca sabe que, no momento em que o próximo dia de atualização iterativa chegar, o problema pode ter se resolvido; mesmo se não, pelo menos agora você sabe que há um obstáculo no caminho da atualização e não o pegará de surpresa.

Se você não estiver fazendo iterações dessa duração, eu configuraria algum tipo de agendamento independente para atualizações - não mais que mensalmente. Existe algum outro ritmo de projeto ao qual você possa associá-lo, como uma revisão mensal de status ou uma reunião do conselho de arquitetura? Dia do pagamento? Noite de pizza? Lua cheia? Seja como for, você precisa encontrar algo muito mais curto que um ciclo de lançamento tradicional, porque tentar atualizar tudo de uma vez a cada 6-18 meses será doloroso e desmoralizante.

Desnecessário dizer que, se você fizer ramificações de estabilização antes dos lançamentos, não aplicará essa política a eles. Lá, você atualiza apenas as bibliotecas para obter correções críticas.

Tom Anderson
fonte
3
+1. Eu trabalhei em um projeto em que os desenvolvedores aplicavam a política "se não está quebrado, não conserte". Em seguida, encontramos um problema com uma biblioteca de terceiros (relativamente pequena, mas era necessária para um novo recurso), que foi corrigido apenas em uma versão muito posterior, que por sua vez dependia de uma jvm muito posterior. Com a jvm posterior, encontramos problemas com outras bibliotecas de terceiros, que agora precisavam ser atualizadas por vez. Também tivemos que atualizar nosso hardware, pois o Oracle não possui mais uma jvm de 32 bits para Solaris. Era uma bagunça e poderia tão facilmente ter sido evitado mantendo simplesmente as coisas atualizadas.
firtydank
+1 for "whilst it's easier in the short term, it burns like hell in the long run". I've experienced both approaches and while many small updates may seem like a nuisance, not performing upgrades and then having to upgrade 10 libraries from versions which are 2 years old is often not possible in any reasonable amount of time. You end up with a system which depends on outdated and unmaintained libraries, you can't use some other libraries since they require a newer version of that library which you can't upgrade and at some point you lose the ability to fix some issues at all.
Michał Kosmulski
@firtydank Estou curioso para saber o que vocês fizeram para resolver esse problema depois de implementarem novas políticas? Qual foi a mudança funcional na organização?
buddyp450 12/03
10

Eu avalio.

  • Primeiro, procuro bugs que levantamos contra essa biblioteca e verificamos se foram corrigidos.
  • Em segundo lugar, procuro outras correções de erros na biblioteca da qual possamos nos beneficiar (talvez algo que seja um possível caso de canto).
  • Em terceiro lugar, procuro melhorias na lib / API e, em seguida, investigo o impacto da alteração de nosso código para utilizar isso e a troca benéfica. Muitas vezes, nas versões anteriores, atualizei as bibliotecas sem realmente utilizar seus novos recursos, realmente bobo!

Eu peso tudo isso contra ficar com a lib existente.

Sempre teste - espero que seus testes de unidade / integração garantam que não ocorram grandes regressões.

Martijn Verburg
fonte
7

O principal problema com bibliotecas de terceiros é que você precisa testar novamente o SEU aplicativo quando atualizá-los, antes que ele possa entrar em produção. Portanto, a menos que você tenha um bug relatado, que exija atualização de uma biblioteca, você não os toca até ter tempo para executar um ciclo completo de garantia de qualidade.

Isso geralmente é feito ao liberar uma nova versão.

Sugiro, no entanto, que você tenha um conjunto de testes para compilação contínua que permita atualizar as bibliotecas no ramo de desenvolvimento e fazê-lo automaticamente. Isso garantirá que você descubra cedo quando ele quebrar, para que você possa registrar relatórios de erros no projeto.


fonte
3

Parcialmente, conforme descrito nas ramificações do fornecedor svn . O procedimento descrito lá é muito útil quando você continua usando bibliotecas de terceiros de código aberto por um longo tempo e fez alterações para ajustá-lo às suas necessidades.

duros
fonte
2
Por favor, não solte links. Os links tendem a desaparecer. Por favor, considere pelo menos resumir o que você está vinculando. Se esse link se romper, qual seria a utilidade .. talvez daqui a alguns anos?
Tim Post
E com votos positivos :)
Tim Post
2

Eu pensaria em atualizar todas as bibliotecas de um projeto antes ou logo após o lançamento. No entanto, isso pode ficar fora de controle se você contar com mais de 10 ou 15 bibliotecas; nesse caso, algum tipo de mecanismo de verificação de atualização ajudaria bastante. A vantagem disso é que você tem um tempo dedicado ao teste de suas bibliotecas e pode corrigir qualquer problema de uma só vez. Você também não precisa acompanhar constantemente as atualizações de todas as bibliotecas; basta verificar em um determinado dia se há atualizações.

Eu também iria contra qualquer tipo de recurso de atualização automática, mesmo em um ramo de desenvolvimento. Seria frustrante se, no meio de mim, trabalhando em algo que o projeto quebrou porque uma biblioteca se atualizou automaticamente, ou de repente recebi avisos de depreciação por usar uma API que foi substituída por outra coisa.

TheLQ
fonte
2

Você tem que perguntar, o que você realmente quer da atualização? A maioria das correções de segurança são na verdade patches triviais, na forma de correção:

  • Desativado por um erro em que o código arbitrário pode ser copiado para um espaço não utilizado em um buffer
  • Indicadores pendentes, ou qualquer outra coisa que desencadeia comportamento indefinido, mas (antes) determinístico
  • Erros que permitem algum tipo de DoS
  • Erros que acidentalmente facilitam a espionagem de dados privados
  • Erros de matemática
  • Mantenedores tocando coisas que não deveriam (bug do Debian SSL, alguém?)

Se você examinar a maioria dos CVEs nos últimos cinco anos, os patches que os corrigem são geralmente bastante triviais, se você estiver usando bibliotecas abertas, o que eu espero que você esteja.

Então você tem correções de erros reais, o que provavelmente deseja, mas talvez você já tenha corrigido você mesmo. Se não estiver quebrado, não conserte.

Finalmente, você tem novos recursos ... e talvez recursos obsoletos. Você precisa examinar essas notas de versão e as diferenças com cuidado. Você pode usá-los, mesmo que eles quebrem uma API da qual dependem muitas outras coisas? Se sim, é hora da cirurgia. Se não, escolha o que deseja e siga em frente.

Alguns podem discordar de mim, mas eu me recuso a usar uma biblioteca sem código fonte.

Tim Post
fonte
Certamente prefiro bibliotecas de código aberto, mas eu também usar algumas bibliotecas comerciais que o custo como US $ 100 sem fonte ou US $ 10 mil com a fonte, então ...
Joonas Pulakka
2

Isso varia dependendo das coisas nas bibliotecas, para que são usadas, quão difundidas são no seu código, o custo (em termos de tempo e dinheiro) da execução da atualização e assim por diante.

Idealmente, você sempre terá as mais recentes o tempo todo, mas se a nova versão não for compatível com versões anteriores, o que acontece? Talvez você precise arquivar essa atualização para uma versão futura até poder lidar com a alteração com cuidado. Pode haver alguma alteração sutil no comportamento (como "agora você precisa definir a propriedade X antes de chamar o método Y ou obtém um vazamento de memória lento") que é difícil de verificar nos testes.

Por outro lado, a nova versão pode ter algumas correções de segurança sérias, então você deve levar isso em conta também.

Versão curta: leve-a caso a caso.

JohnL
fonte
1

Isso dependeria dos seus horários de lançamento.

Mas meu conselho seria instalar um conjunto de bibliotecas em todas as máquinas dos desenvolvedores. Considere isso como um padrão-ouro, se você quiser chamar alguma coisa, e comece o desenvolvimento para esse lançamento.

Somente após a implantação do release e você estar na fase de pós-lançamento, reavalie suas bibliotecas, suas versões e recursos. Se eles oferecerem melhorias significativas ou novas funcionalidades, instale-os antes do início do próximo ciclo de desenvolvimento.

Instale apenas novas versões se houver um problema ou bug grave que precise ser corrigido antes da implantação do software.

Isso significa que você perderá algumas versões, mas deve evitar algumas dores de cabeça e problemas de controle de versão, permitindo que você se concentre no desenvolvimento de seu aplicativo.

GrumpyMonkey
fonte
1

Externos do Subversion

O que é ótimo nesse recurso é que você pode especificar a revisão que deseja.

Observe que as atualizações serão mais lentas se você tiver muitos recursos externos.


fonte
Na verdade, estou usando-os, e eles são muito úteis e muito lentos X-) Mas eles não resolvem o problema de quando devo atualizar para a versão mais recente.
Joonas Pulakka
Eles podem ser muito lentos, sim. Normalmente, atualizo bibliotecas externas quando: (uma versão principal OU uma correção de bug que me afeta está disponível) E estou na primeira metade da iteração.
1

Atualmente, estou configurando algo assim:

  • 1 repositório mercurial para cada extensão do meu aplicativo
  • um repositório mercurial que reúne versões específicas de várias bibliotecas de terceiros
  • um repositório SVN para recursos gráficos / obras (mas pode mudar para outra coisa)
  • um repositório mercurial para meu aplicativo, que usa o recurso subrepos mercurial para usar uma versão específica do terceiro repositório pary e algumas das extensões básicas

Agora, quando preciso trabalhar em uma extensão que não é "básica" (incluída implicitamente como um subrepo no repositório de aplicativos), simplesmente clono o repositório na pasta de extensões e deixo o CMake gerar os projetos e soluções para todo o aplicativo.

Dessa forma, eu posso:

  • altere terceiros em um clone, verifique se ele funciona com o aplicativo, envie-o no terceiro repositório de transações e atualize a versão subrepo do repositório de aplicativos para a nova versão de repositório de terceiros
  • trabalhe em extensões de forma independente, todas juntas ou apenas escolha algumas
  • não precisa se preocupar em vincular projetos, isso é feito pelo Cmake apenas com a digitalização dos subrepos dos projetos com todo o repositório de aplicativos.

Ainda não tem muita experiência com essa organização, mas acho que é bastante útil.

Klaim
fonte
1

Se o seu software é crítico para a segurança, você deve atualizar o mais rápido possível, sem desculpas. Você não quer um pequeno bug em uma biblioteca de gráficos para tornar todo o seu programa vulnerável.

Caso contrário, quando a biblioteca estiver madura, é "Se não está quebrado, não conserte". para mim. Mais cedo ou mais tarde, talvez eu precise de um recurso de uma versão posterior e não tenha escolha a não ser atualizar, mas até então, é difícil justificar o esforço. Por outro lado, quando trabalho com uma lib ou estrutura relativamente nova, como Grails ou ExtJS, permaneço atualizado com a versão mais recente porque esses produtos ainda não parecem completamente maduros, portanto a atualização provavelmente me salvará de executar em um desses bugs corrigidos pela versão posterior.

user281377
fonte
1

Eu uso o NuGet para manter minhas bibliotecas de terceiros atualizadas.

Quando um amigo, colega de trabalho ou blog me avisa que uma das minhas DLLs de terceiros está desatualizada, o NuGet facilita muito a atualização.

Jim G.
fonte