O controle de versão é algo pelo qual sou muito apaixonado e passei muito tempo tentando criar um sistema de controle fácil de usar. Pelo que você já disse na sua pergunta, fica claro que você entendeu um ponto importante: os números da versão do assembly não são sinônimos da versão do produto. Um é tecnicamente orientado e o outro é conduzido pelos negócios.
O seguinte pressupõe que você usa alguma forma de controle de origem e um servidor de construção. Para o contexto, usamos o TeamCity e o Subversion / Git. O TeamCity é gratuito para um número pequeno (10) de projetos e é um servidor de construção muito bom, mas existem outros, alguns dos quais são totalmente gratuitos.
O que significa um número de versão
O que uma versão significa para uma pessoa pode significar algo diferente para outra, a estrutura geral é maior, menor, macro, micro. A maneira como vejo um número de versão é dividi-lo em duas partes. A primeira metade descreve a versão principal (principal) e todas as atualizações importantes (secundária). A segunda metade indica quando foi criada e qual era a versão do código fonte. Os números de versão também significam coisas diferentes, dependendo do contexto, é uma API, um aplicativo da Web etc.
Major
. Minor
. Build
.Revision
Revision
Este é o número obtido do controle de origem para identificar o que realmente foi criado.
Build
Esse é um número cada vez maior que pode ser usado para encontrar uma construção específica no servidor de construção. É um número importante porque o servidor de compilação pode ter criado a mesma fonte duas vezes com um conjunto diferente de parâmetros. O uso do número da compilação em conjunto com o número de origem permite identificar o que foi construído e como.
Minor
Isso deve mudar apenas quando houver uma alteração significativa na interface pública. Por exemplo, se for uma API, o código de consumo ainda poderá compilar? Esse número deve ser redefinido para zero quando o número principal for alterado.
Major
indica em qual versão do produto você está. Por exemplo, o principal de todos os assemblies do VisualStudio 2008 é 9 e o VisualStudio 2010 é 10.
A exceção à regra
Sempre existem exceções à regra e você terá que se adaptar à medida que as encontrar. Minha abordagem original foi baseada no uso do subversion, mas recentemente mudei para o Git. O controle de fontes, como subversão e fontes seguras, que usam um repositório central, possui um número que pode ser usado para identificar um conjunto específico de fontes a partir de um determinado momento. Este não é o caso de um controle de origem distribuído, como o Git. Como o Git usa repositórios distribuídos que estão em cada máquina de desenvolvimento, não há um número de incremento automático que você possa usar, existe um hack que usa o número de check-ins, mas é feio. Por causa disso, tive que evoluir minha abordagem.
Major
. Minor
. Macro
.Build
O número da revisão foi agora, a compilação mudou para onde a revisão costumava estar e a Macro foi inserida. Você pode usar a macro como achar melhor, mas na maioria das vezes eu a deixo em paz. Como usamos o TeamCity, as informações perdidas no número da revisão podem ser encontradas na compilação, isso significa que há um processo em duas etapas, mas não perdemos nada e é um compromisso aceitável.
O que definir
A primeira coisa a entender é que a versão do assembly, a versão do arquivo e a versão do produto não precisam corresponder. Eu não estou defendendo ter conjuntos diferentes de números, mas facilita muito a vida ao fazer pequenas alterações em um assembly que não afeta nenhuma interface pública que você não seja forçado a recompilar os assemblies dependentes. A maneira como lida com isso é definir apenas os números Maior e Menor na Versão do Assembly, mas definir todos os valores na Versão do Arquivo. Por exemplo:
- 1.2.0.0 (AssemblyVersion)
- 1.2.3.4 (FileVersion)
Isso permite que você implante hot fixes que não quebram o código existente porque as versões do assembly não correspondem, mas permitem que você veja a revisão / construção de um assembly observando o número da versão do arquivo. Essa é uma abordagem comum e pode ser vista em alguns assemblies de código aberto quando você olha para os detalhes do assembly.
Você, como líder da equipe, precisaria ser responsável por aumentar o número menor sempre que uma mudança de última hora for necessária. Uma solução para implementar uma alteração necessária em uma interface, mas não quebrar o código anterior, é marcar a atual como obsoleta e criar uma nova interface. Isso significa que o código existente é avisado de que o método é obsoleto e pode ser removido a qualquer momento, mas não exige que você quebre tudo imediatamente. Você pode remover o método obsoleto quando tudo tiver sido migrado.
Como conectá-lo
Você pode fazer tudo isso manualmente, mas isso consumiria muito tempo; a seguir, é como automatizamos o processo. Cada etapa é executável.
- Remova os atributos
AssemblyVersion
e AssemblyFileVersion
de todos os arquivos AssemblyInfo.cs do projeto.
- Crie um arquivo de informações de montagem comum (chame-o VersionInfo.cs) e adicione-o como um item vinculado a todos os seus projetos.
- Adicione
AssemblyVersion
e AssemblyFileVersion
atributos à versão com valores "0.0.0.0".
- Crie um projeto MsBuild que cria seu arquivo de solução.
- Adicione uma tarefa antes da compilação que atualiza o VersionInfo.cs. Há várias bibliotecas MsBuild de código aberto que incluem uma tarefa AssemblyInfo que pode definir o número da versão. Basta configurá-lo para um número arbitrário e testar.
- Adicione um grupo de propriedades contendo uma propriedade para cada um dos segmentos do número da compilação. É aqui que você define o maior e o menor. O número de compilação e revisão deve ser passado como argumentos.
Com o subversion:
<PropertyGroup>
<Version-Major>0</Version-Major>
<Version-Minor>0</Version-Minor>
<Version-Build Condition=" '$(build_number)' == '' ">0</Version-Build>
<Version-Build Condition=" '$(build_number)' != '' ">$(build_number)</Version-Build>
<Version-Revision Condition=" '$(revision_number)' == '' ">0</Version-Revision>
<Version-Revision Condition=" '$(revision_number)' != '' ">$(revision_number)</Version-Revision>
</PropertyGroup>
Espero ter sido claro, mas há muito envolvido. Por favor, faça qualquer pergunta. Usarei qualquer feedback para montar um post de blog mais conciso.