Estou procurando por ponteiros, sugestões e até ditados sobre como gerenciar os três números de versão de montagem diferentes para um assembly .NET. A versão do produto é a mais simples, pois isso normalmente seria ditado pelos negócios. Em seguida, a versão do arquivo parece ser para controle de versão entre implantações, onde a versão real do assembly é usada apenas no envio.
No momento, estou apenas procurando um meio simples de rotular as liberações de teste e manutenção de uma montagem da qual nenhuma depende, por isso estou analisando os números de compilação e revisão com incremento automático na versão do arquivo e a versão final, copiando a versão atual. versão do arquivo para a versão do assembly. O produto está em uso de produção, mas ainda está em desenvolvimento - você sabe - uma dessas pequenas empresas, sem situações de infraestrutura de controle de alterações.
Respostas:
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:
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.
AssemblyVersion
eAssemblyFileVersion
de todos os arquivos AssemblyInfo.cs do projeto.AssemblyVersion
eAssemblyFileVersion
atributos à versão com valores "0.0.0.0".Com o subversion:
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.
fonte
O [AssemblyVersion] é um grande negócio no .NET. Uma filosofia, incentivada pela Microsoft, é que você permite o incremento automático, forçando a recompilação de todos os projetos que dependem da montagem. Funciona bem se você usar um servidor de compilação. Nunca é a coisa errada a fazer, mas cuidado com as pessoas carregando espadas.
O outro, mais intimamente associado ao seu significado real, é que o número é representativo para a versão da interface pública do assembly. Em outras palavras, você só o altera quando altera uma interface ou classe pública. Uma vez que apenas essa alteração requer que os clientes da montagem sejam recompilados. Porém, isso precisa ser feito manualmente, o sistema de compilação não é inteligente o suficiente para detectar automaticamente essa alteração.
Você pode estender ainda mais essa abordagem incrementando apenas a versão quando a montagem foi implantada em máquinas fora do seu alcance. Essa é a abordagem usada pela Microsoft; os números de versão dos assemblies .NET raramente mudam. Principalmente por causa da dor considerável que causa em seus clientes.
Portanto, o que a Microsoft prega não é o que pratica. No entanto, seu processo de construção e controle de versão são incomparáveis; eles ainda têm um engenheiro de software dedicado que monitora o processo. Não funcionou tão bem, a sobrecarga WaitHandle.WaitOne (int), em particular, causou bastante dor . Corrigido no .NET 4.0 com uma abordagem muito diferente, mas isso está ficando um pouco além do escopo.
Depende de você e de sua confiança em quão bem você pode controlar o processo de compilação e os ciclos de lançamento para fazer sua própria escolha. Fora isso, o incremento automático do [AssemblyFileVersion] automaticamente é muito apropriado. No entanto, com a inconveniência de que isso não é suportado.
fonte
Você pode usar a parte Build do número da versão para incremento automático.
[assembly: AssemblyVersion("1.0.*")]
No seu ambiente, uma versão de teste é uma versão que possui uma versão de construção! = 0. Na liberação, você incrementa a peça secundária e define a peça de construção como 0, é assim que você identifica os assemblies liberados.
Se você instalar seus assemblies no GAC, o GAC será inundado com várias versões diferentes ao longo do tempo, lembre-se disso. Mas se você usar as DLLs apenas localmente, acho que é uma boa prática.
fonte
Acrescentando à resposta de Bronumskis , quero ressaltar que após o padrão Semantic Versioning 2.0 em semver.org ,
Major.Minor.Build.Revision
seria ilegal devido à regra de que, após aumentar um número, todos os valores regulares à direita precisariam ser redefinidos para zero.Uma maneira melhor de seguir o padrão seria usar
Major.Minor+Build.Revision
. Obviamente, isso não é para ser usadoAssemblyVersionAttribute
, mas um atributo personalizado ou classe estática pode ser usada.Semver no TeamCity deve estar disponível usando o Meta-runner Power Pack. Para o git com git-flow (especialmente no mundo .NET), achei o GitVersion útil.
fonte
Não existe uma regra rígida e rápida no que diz respeito aos conjuntos de versões, portanto, sinta-se à vontade para tentar o que funcionaria para você, mas eu sugiro que você faça uso da abordagem de 4 partes, pois você terá a flexibilidade, caso você queira fazer algumas alterações. no futuro.
... por ex: 1.0.0. *
Reservado - Isso adiciona flexibilidade adicional, caso você queira fazer alterações no futuro. Mas como padrão, mantenha-o como 0.
Além disso, considere assinar a montagem com uma chave forte. Isso resolverá o problema de conflito de montagem, caso você tenha várias versões de montagem registradas no GAC. Link MSDN
fonte