Automatizando o versionamento no Build – Parte 2

Objetivo

Na parte 1, entendemos como o .NET faz para marcar a versão nos binários e como criar um arquivo para centralizar as propriedades comuns entre os assemblies.

Agora vamos brincar um pouco de como automatizar isso com o MSBuild. Se vc não sabe o que é o MSBuild, sugiro a leitura de MSBuild in a nutshell.

Automatizando o versionamento

A parte legal de utilizar uma ferramenta como o MSBuild é que é muito simples customizar a ferramenta e tem muita gente que contribui com tasks customizadas.

Nessa linha existe um projeto chamado MSBuild Community Tasks. Esse projeto possui além de uma centena de tasks, uma que iremos utilizar, a chamada AssemblyInfo.

Essa task nada mais faz do que gerar um arquivo com os atributos de versionamento. Ela tem a seguinte estrutura:

		<AssemblyInfo CodeLanguage="CS" OutputFile="$(MSBuildProjectDirectory)\..\src\SharedAssemblyInfo.cs"
			AssemblyProduct="MSBuildCodeMetrics - $(Branch) - $(CommitHash)" AssemblyCopyright="Copyright © 2013 Eric Lemes de Godoy Cintra" AssemblyTrademark=""
			AssemblyVersion="$(Version)" AssemblyConfiguration="$(Configuration)" AssemblyDescription="MSBuildCodeMetrics - $(Branch) - $(CommitHash)" />

Neste exemplo (usado no MSBuildCodeMetrics), gerarei um arquivo que sobrescreve o SharedAssemblyInfo.cs. No atributo AssemblyProduct, jogaremos além do nome do produto o valor das propriedades $(Branch) e $(CommitHash). A idéia é substituir estes valores neste e em outros atributos com valores gerados automaticamente pelo build.

Integrando com Git Hub

Seguindo a linha de contribuições, o MSBuild Community Tasks possui uma task que integra com o Git. A propriedade CommitHash pode ser obtida da seguinte maneira:

		<GitVersion>
			<Output TaskParameter="CommitHash" PropertyName="CommitHash" />			
		</GitVersion>

Esse trecho faz com que a task GitVersion pegue o valor do último commit hash e jogue na propriedade.

Aproveitando o conceito, mandei uma contribuição lá para o projeto, criando uma Task GitBranch. Essa task pegará o nome do branch do GitHub. Segue o exemplo:

		<GitBranch>
			<Output TaskParameter="Branch" PropertyName="Branch" />			
		</GitBranch>

Com essas combinações, podemos chegar no seguinte resultado final:

	<Target Name="assemblyinfo">
		<GitBranch>
			<Output TaskParameter="Branch" PropertyName="Branch" />			
		</GitBranch>
		<GitVersion>
			<Output TaskParameter="CommitHash" PropertyName="CommitHash" />			
		</GitVersion>
		<CreateProperty Value="0.0.0.0">
			<Output TaskParameter="Value" PropertyName="Version" Condition="$(Branch) == 'master'" />
		</CreateProperty>
		<CreateProperty Value="$(Branch)">
			<Output TaskParameter="Value" PropertyName="Version" Condition="($(Branch) != 'master')" />
		</CreateProperty>
	
		<AssemblyInfo CodeLanguage="CS" OutputFile="$(MSBuildProjectDirectory)\..\src\SharedAssemblyInfo.cs"
			AssemblyProduct="MSBuildCodeMetrics - $(Branch) - $(CommitHash)" AssemblyCopyright="Copyright © 2013 Eric Lemes de Godoy Cintra" AssemblyTrademark=""
			AssemblyVersion="$(Version)" AssemblyConfiguration="$(Configuration)" AssemblyDescription="MSBuildCodeMetrics - $(Branch) - $(CommitHash)" />
	</Target>

A idéia é simples. Pegamos o CommitHash e o Branch do GitHub. Se estamos no branch master, vamos carimbar a versão com “0.0.0.0” e no AssemblyDescription e ProductName ficaremos com algo parecido com: MSBuildCodeMetrics – master – b1e4cbf.

Se estivermos num branch ou numa tag, este número será utilizado para carimbar a versão. Por exemplo, para o meu branch 0.1, ficaremos com a versão da seguinte forma: MSBuildCodeMetrics – 0.1 – b1e4cbf. No AssemblyVersion, ficaremos com “0.1”, porém, infelizmente ao inspecionar pelo Windows, veremos a versão como 0.1.0.0. Ele sempre arredonda e coloca no formato de 4 dígitos. Eu particularmente não gosto, mas consigo ainda identificar minha versão pelo AssemblyDescription e ProductName.

Conclusão

Com um pouquinho de automação, como feito no MSBuildCodeMetrics, eu consigo com uma única execução da minha task “pack”, fazer um processo de automação do build de ponta a ponta. Eu gero o SharedAssemblyInfo.cs, realizo o build, monto a documentação e faço o pacote zip final, apertando o único botão. Acho que eu já consegui os três primeiros passos do The Joel Test.

Agora a cada vez que eu quero fazer um release de uma versão, basta criar uma nova tag e rodar o “pack” do meu build e está tudo pronto.

Segue código completo do script de build: MSBuildCodeMetrics.build

Advertisement

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