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