É uma boa prática armazenar números de versão de software no VCS?


22

Uma versão do produto, como v1.0.0.100, representa não apenas uma versão de produção exclusiva do software, mas ajuda a identificar conjuntos de recursos e estágios de hotfix para o referido produto. No momento, vejo duas maneiras de manter a versão final do pacote / build / binário de um produto:

  1. Controle de versão. Um arquivo em algum lugar armazena o número da versão. O servidor de criação de Integração Contínua (IC) terá um script para criar o software que usa esse número de versão com check-in para aplicá-lo a todas as áreas do software necessárias (binários, pacotes de instalação, páginas de ajuda, documentação, etc.).

  2. Ambiente e / ou parâmetros de construção. Eles são mantidos fora do controle de versão (ou seja, não estão vinculados ao snapshot / tag / branch). Os scripts de construção distribuem e usam o número da mesma maneira, mas apenas obtêm o valor de forma diferente (é fornecido ao script de construção, em vez de o script saber onde obtê-lo em relação à árvore de origem).

O problema com a primeira abordagem é que ela pode complicar as mesclagens nas ramificações da linha principal. Se você ainda mantiver duas versões paralelas do mesmo software, resolverá conflitos ao mesclar entre as duas linhas principais se a versão tiver sido alterada em ambas desde a última mesclagem.

O problema com a segunda abordagem é a reconciliação. Quando você voltar a um lançamento há um ano, dependerá exclusivamente das informações da etiqueta para identificar seu número de lançamento.

Nos dois casos, pode haver certos aspectos do número da versão desconhecidos antes da criação do IC. Por exemplo, uma compilação de IC pode incluir programaticamente um 4º componente que é realmente o número de compilação automatizado (por exemplo, 140ª compilação na ramificação). Também pode ser um número de revisão no VCS.

Qual é a melhor maneira de acompanhar o número da versão do software? As partes "conhecidas" devem sempre ser mantidas no VCS? E se sim, os conflitos entre as filiais da linha principal são um problema?

No momento, mantemos nosso número de versão por meio de parâmetros especificados e mantidos no plano de construção do IC (Atlassian Bamboo). Antes de mesclar para nossa masterfilial, precisamos ter cuidado para que os números de versão sejam configurados corretamente antes do início da criação do IC . Com relação ao fluxo de trabalho do Gitflow, acho que se o número da versão fosse rastreado no controle de origem, poderíamos garantir que ele esteja configurado corretamente quando criarmos nossa releasefilial na preparação do lançamento. O controle de qualidade executaria os testes finais de integração / fumaça / regressão nessa ramificação e, após a saída, ocorrerá uma mesclagem masterque sinaliza o compromisso de liberação.


3
Existe um conflito de mesclagem entre duas versões de um arquivo em version.txtque uma versão contém a única linha 1.0.7e a outra é 1.2.0realmente difícil de resolver? Se esse for o único conflito na fusão de dois ramos que se separaram, eu me consideraria com muita sorte. Com que frequência isso ocorre? Se isso ocorrer, não é bom que você seja forçado a pensar sobre qual número de versão a versão mesclada deve ter? (Desculpe pelo uso ambíguo da palavra "versão".)
5gon12eder 17/08/2015

1
@ 5gon12eder As dificuldades ou sentimentos sobre a fusão são irrelevantes. É apenas um aspecto negativo da solução geral.
precisa saber é o seguinte

Respostas:


28

Pessoalmente, escolho a opção 3: manter as informações de versão nos metadados do VCS , especificamente nas tags.

O Git facilita muito isso, porque existe um comando git describeque pode descrever exclusivamente uma confirmação com base em uma tag. Veja como funciona:

  • Se o commit atual estiver marcado, produza o nome do tag.
  • Caso contrário, caminhar pelas costas de história até encontrar uma tag e, em seguida, saída uma descrição no seguinte formato: <tag>-<number of commits since the tag>-g<abbreviated commit hash>.
  • Se houver alterações não confirmadas na árvore de trabalho, acrescente -dirty.

Portanto, se você estiver fazendo uma compilação de versão e tiver o commit marcado 1.2.3, ele será exibido 1.2.3. Se você está atualmente trabalhando no 1.2.4 e fez 4 confirmações desde o 1.2.3, e possui alterações não confirmadas na árvore, ele será exibido 1.2.3-4-gdeadbee-dirty.

É garantido que ele é único e monotônico, além de legível por humanos, e, portanto, pode ser usado diretamente como uma string de versão. A única coisa que você precisa garantir é uma convenção de nomenclatura adequada para tags.


Eu realmente amo essa idéia, mas isso parece difícil de gerenciar com o JIRA + Bamboo. O Bamboo funciona apenas em ramificações, não em tags, portanto, você deve garantir que uma tag seja enviada antes que uma compilação seja gerada. Isso é propenso a erros.
precisa saber é o seguinte

1
git describetambém funciona com ramificações: " --all - Em vez de usar apenas as tags anotadas, use qualquer ref encontrada no refs/espaço para nome. Esta opção permite corresponder qualquer ramificação conhecida, ramificação de rastreamento remoto ou tag leve." Não tenho certeza de como isso funciona com o Bamboo. (Isto, claro, exigem nomeação cuidado de ramos, assim como o modo normal faz com tags.)
Jörg W Mittag

1
Conheço algumas pessoas que fazem lançamentos completamente automáticos do Git. A string de versão é criada por git describe, o ChangeLog é gerado a partir de git shortlog(bem, na verdade, a partir de um script que analisa a saída de git log --pretty=tformat:<some custom format string>) e as notas de versão são geradas a partir da descrição da tag e git notesanexadas a commits de marcos importantes.
Jörg W Mittag

O que quero dizer é que a tag precisaria ser criada antes do lançamento, para que seja confirmada após a versão correta com um número base. Isso contraria o princípio da marcação durante ou no momento do lançamento. O Bamboo pega compilações automaticamente com base em confirmações para master(de develop, lembre-se de que estou usando o gitflow). E se alguém enviar uma mesclagem mastersem uma tag? Ele não vai usar a versão apropriada (na verdade ele iria usar a versão do último release)
void.pointer

Se você usar um esquema como este, a marcação será liberada. Ah, eu vejo o que você está falando, eu acho. Portanto, atualmente, seu servidor de IC é o driver de lançamento e, com essa alteração, o SCM é o driver de lançamento, mas você gostaria que ele permanecesse assim?
Jörg W Mittag

8

Sim. É uma boa prática manter a maior parte do número da versão em vcs. Se considerarmos o versionamento semântico semver.org, onde temos major.minor.patch.build, os três primeiros devem residir em vcs. O último pode ser um número incremental do servidor de construção usado para retroceder a confirmação específica da qual um binário é feito.

Para facilitar isso no .NET, criamos um pequeno exe de linha cmd comprometido com o git. Com um evento de pré-compilação, ele seleciona o número da compilação que a teamcity marcou durante a compilação. Essa ferramenta de linha de cmd gera automaticamente uma classe com uma constante contendo o número da compilação. O restante do número da versão: major.minor.patch é apenas uma constante normal em outro arquivo. Esses dois arquivos compartilhados são incluídos em cada montagem em uma solução como um link (alt + shift-drag).

Essa abordagem é poderosa o suficiente para que o teamcity construa e teste nosso código. Pressione para o azure e faça com que o kudu o construa novamente, mas com o número da versão teamcity como a versão das dlls.

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.