Automatizando o versionamento no Build – Parte 1

Objetivo

Conforme comentei no post anterior sobre a documentação do MSBuildCodeMetrics, uma outra coisa que eu queria fazer era automatizar o versionamento durante o Build.

O que eu quero dizer com isso é que eu queria “carimbar” meus binários com a localização em que eles estão no controle de versão.

A idéia deste post (ou série) é ilustrar como fazer isso na prática.

Adotando uma política de versionamento

O que eu chamo de política de versionamento é estruturar a organização de branches da aplicação, conforme explicado no post “Gestão de configuração e versões (SCM)”.

Apesar do projeto estar no GitHub adotei a política de branches de estabilização. Meu branch “master” possuirá a maior quantidade de features e será mais instável, e de tempos em tempos cortarei branches para “congelar” e estabilizar as features. No caso criei um branch 0.0 quando ainda não tinha nem documentação, e um branch 0.1 quando concluí o “básico” para soltar meu primeiro release.

A cada release que fizer, gerarei uma nova tag e o fonte compilado e publicado partirá desta tag. No meu caso, a versão 0.1.0 é a primeira tag e o primeiro release.

AssemblyInfo.cs

Muitos de vocês já devem ter visto o arquivo AssemblyInfo.cs. Geralmente ele fica jogado na pasta Properties e ninguém dá bola pra ele.

Ele tem mais ou menos essa estrutura:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following 
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EricLemes.MSBuildTasks")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("EricLemes.MSBuildTasks")]
[assembly: AssemblyCopyright("Copyright ©  2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible 
// to COM components.  If you need to access a type in this assembly from 
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("dabe2f23-a2e2-4249-ad24-f597d0bd36eb")]

// Version information for an assembly consists of the following four values:
//
//      Major Version
//      Minor Version 
//      Build Number
//      Revision
//
// You can specify all the values or you can default the Build and Revision Numbers 
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

Na verdade essas propriedades no final das contas ficam em locais especiais nos binários e podem ser inspecionadas ao clicarmos com o botão direito num arquivo no Windows Explorer e depois em detalhes:

AssemblyInfo

Centralizando propriedades comuns a diversos assemblies

A primeira coisa interessante a fazer para automatizar a geração destes números é centralizar algumas das propriedades entre todos os assemblies. Pra mim essa idéia faz sentido porque sempre que lançamos uma nova versão do produto, queremos que todos os artefatos dessa versão sejam carimbados com a versão. Em outras palavras, nosso produto não é composto por um único binário e sim por um conjunto de binários.

Para tornarmos isso possível, primeiro devemos criar um novo arquivo em nossa solution. Eu achei interessante deixá-lo junto com os “Solution Items”. Clique com o botão direito, Add | New Item | Visual C# Class. No meu caso, chamei o arquivo de SharedAssemblyInfo.cs.

O arquivo contém a seguinte estrutura:

[assembly: System.Reflection.AssemblyProduct("MSBuildCodeMetrics - master - b1e4cbf")]
[assembly: System.Reflection.AssemblyCopyright("Copyright © 2013 Eric Lemes de Godoy Cintra")]
[assembly: System.Reflection.AssemblyVersion("0.0.0.0")]
[assembly: System.Reflection.AssemblyConfiguration("Release")]
[assembly: System.Reflection.AssemblyDescription("MSBuildCodeMetrics - master - b1e4cbf")]

Os atributos contidos neste arquivos são aqueles que devem ser iguais para todos os assemblies do projeto.

Em seguida, em cada um dos projetos (.csproj), clicamos com o botão direito, Add | Existing Item e escolhemos o SharedAssemblyInfo.cs. Invés de clicarmos em “Add”, clicamos na setinha de drop down e escolhemos “Add as Link”. Será adicionada somente uma referência do arquivo para o projeto. Por convenção a deixei dentro da pasta “Properties”.

Em seguida, cada um dos AssemblyInfo.cs contém a seguinte estrutura:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle("MSBuildCodeMetrics.Core")]
[assembly: AssemblyCulture("")]
[assembly: Guid("4c6e2a2c-9e70-4b9f-a2fa-01bfdfdc577b")]
[assembly: ComVisible(false)]

Esses atributos, eu entendo que são de cada um dos assemblies.

Ao compilar o projeto agora, perceberemos que o Assembly possuirá todas as propriedades, mas apenas um arquivo precisa ser alterado para mexer no identificador de versão.

Por enquanto era isso.

Advertisement

One thought on “Automatizando o versionamento no Build – Parte 1

  1. Muito legal, Eric.
    É exatamente um dos assuntos que me interessa. Quero fazer com que a build versione para mim ao invés de ter que alterar manualmente a versão no AssemblyInfo.
    Aguardando o restante da série.
    []s

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s