Estou construindo um aplicativo C #, usando Git como meu controle de versão.
Existe uma maneira de incorporar automaticamente o último hash de confirmação no executável quando eu construo meu aplicativo?
Por exemplo, imprimir o hash de confirmação no console seria algo como:
class PrintCommitHash
{
private String lastCommitHash = ?? // What do I put here?
static void Main(string[] args)
{
// Display the version number:
System.Console.WriteLine(lastCommitHash );
}
}
Observe que isso deve ser feito em tempo de compilação , não em tempo de execução , pois meu executável implantado não terá o repositório git acessível.
Uma questão relacionada ao C ++ pode ser encontrada aqui .
EDITAR
Por solicitação de @mattanja, estou postando o script git hook que uso em meus projetos. A configuração:
- Os ganchos são scripts de shell do Linux, que são colocados em: path_to_project \ .git \ hooks
- Se você estiver usando msysgit , a pasta de ganchos já contém alguns scripts de amostra. Para fazer o git chamá-los, remova a extensão '.sample' do nome do script.
- Os nomes dos scripts de gancho correspondem ao evento que os invoca. No meu caso, eu modifiquei post-commit e post-merge .
- Meu arquivo AssemblyInfo.cs está diretamente no caminho do projeto (mesmo nível da pasta .git ). Ele contém 23 linhas e uso git para gerar a 24ª.
Como meu linux está um pouco enferrujado, o script simplesmente lê as primeiras 23 linhas de AssemblyInfo.cs em um arquivo temporário, ecoa o hash git para a última linha e renomeia o arquivo de volta para AssemblyInfo.cs . Tenho certeza de que existem maneiras melhores de fazer isso:
#!/bin/sh
cmt=$(git rev-list --max-count=1 HEAD)
head -23 AssemblyInfo.cs > AssemblyInfo.cs.tmp
echo [assembly: AssemblyFileVersion\(\"$cmt\"\)] >> AssemblyInfo.cs.tmp
mv AssemblyInfo.cs.tmp AssemblyInfo.cs
Espero que isto ajude.
GlobalAssemblyInfo.*
arquivos em tempo de compilação para projetos C # e C ++: Por padrão, a versão do assembly gerada contém: o hash de confirmação, um sinalizador que sinaliza as alterações locais e um incremento contando a quantidade de commit da raiz do repositório até o commit atual.Você pode incorporar um arquivo version.txt ao executável e então ler o version.txt do executável. Para criar o arquivo version.txt , use
git describe --long
Aqui estão as etapas:
Use um Build Event para chamar git
Clique com o botão direito no projeto e selecione Propriedades
Em Build Events, adicione o evento Pre-Build contendo (observe as aspas):
"C: \ Arquivos de programas \ Git \ bin \ git.exe" describe --long> "$ (ProjectDir) \ version.txt"
Isso criará um arquivo version.txt no diretório do projeto.
Incorpore o version.txt no executável
Leia a string de versão do arquivo de texto incorporado
Aqui está um exemplo de código para ler a string de versão do arquivo de texto incorporado:
fonte
git describe --dirty
, que adiciona um sinalizador quando os desenvolvedores estão trabalhando com uma árvore de trabalho suja.GetEntryAssembly
fazer montagem. Em qualquer caso, você pode ligarGetName().Name
para evitar a codificação do nome.ATUALIZAR:
As coisas evoluíram desde que originalmente respondi a esta pergunta. O
Microsoft.NET.Sdk
(o que significa que você deve usar um projeto no estilo sdk) agora inclui suporte para adicionar o hash de confirmação tanto à versão informativa do assembly quanto aos metadados do pacote nuget, se algumas condições forem atendidas:<SourceRevisionId>
propriedade deve ser definida. Isso pode ser feito adicionando um alvo como este:Este destino executa um comando que será definido
SourceRevisionId
como o hash abreviado (8 caracteres). O BeforeTargets faz com que isso seja executado antes que a versão informativa do assembly seja criada.Para incluir o hash nos metadados do pacote nuget, o
<RepositoryUrl>
também deve ser definido.<SourceControlInformationFeatureSupported>
deve sertrue
, isso faz com que a tarefa do pacote nuget pegue o SourceRevisionId também.Eu evitaria que as pessoas usassem o pacote MSBuildGitHash, já que essa nova técnica é mais limpa e consistente.
ORIGINAL:
Eu criei um pacote nuget simples que você pode incluir em seu projeto que cuidará disso para você: https://www.nuget.org/packages/MSBuildGitHash/
Este pacote nuget implementa uma solução MSBuild "pura". Se você preferir não depender de um pacote nuget, pode simplesmente copiar esses alvos em seu arquivo csproj e ele deve incluir o hash git como um atributo de assembly personalizado:
Existem dois alvos aqui. O primeiro, "GetGitHash", carrega o hash git em uma propriedade MSBuild chamada BuildHash, ele só faz isso se BuildHash ainda não estiver definido. Isso permite que você passe para o MSBuild na linha de comando, se preferir. Você poderia passá-lo para o MSBuild assim:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
O segundo destino, "WriteGitHash", gravará o valor hash em um arquivo na pasta temporária "obj" chamada "CustomAssemblyInfo.cs". Este arquivo conterá uma linha semelhante a:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Este arquivo CustomAssemblyInfo.cs será compilado em seu assembly, para que você possa usar a reflexão para procurar o
AssemblyMetadata
tempo de execução. O código a seguir mostra como isso pode ser feito quando aAssemblyInfo
classe está incluída no mesmo assembly.Alguns benefícios deste design é que ele não toca em nenhum arquivo na pasta do projeto, todos os arquivos modificados estão na pasta "obj". Seu projeto também será construído de forma idêntica no Visual Studio ou na linha de comando. Ele também pode ser facilmente personalizado para o seu projeto e terá o código-fonte controlado junto com o arquivo csproj.
fonte
Assembly.GetExecutingAssembly()
, em seguida, examinando o assemblyCustomAttributes
.GitHash
? Eu posso ver que esse valor existe, mas existe algum método puro para obter o atributo personalizado por nome? Parece que tenho que escrever uma longa consulta where-selectCustomAttributes
, obrigado.CustomAttributes
. Por exemplo, aqui está a função que uso para extrair a string hash: pastebin.com/nVKGLhJCOutra maneira de fazer isso é usar o NetRevisionTool com alguma mágica do Visual Studio integrado . Vou mostrar isso aqui para o Visual Studio 2013 Professional Edition, mas também funcionará com outras versões.
Portanto, primeiro baixe o NetRevisionTool. Você inclui o NetRevisionTool.exe em seu PATH ou faz o check-in em seu repositório e cria uma ação de pré-construção e pós-construção do Visual Studio e altera seu AssemblyInfo.cs.
Um exemplo que adicionaria seu git-hash à sua AssemblyInformationVersion seria o seguinte: Nas configurações do projeto:
no AssemblyInfo.cs do seu projeto, você altera / adiciona a linha:
[assembly: AssemblyInformationalVersion ("1.1. {dmin: 2015}. {chash: 6} {!} - {branch}")]
na imagem mostrada, verifiquei no NetRevisionTool.exe na pasta External / bin
Após a compilação, se você clicar com o botão direito do mouse no binário e for para as propriedades, verá algo como o seguinte:
Espero que isso ajude alguém lá fora
fonte
Acho que vale a pena dar uma resposta completa passo a passo para essa pergunta. A estratégia aqui é executar um script do PowerShell a partir dos eventos de pré-compilação que leva em um arquivo de modelo e gera um arquivo AssemblyInfo.cs com a tag git + informações de contagem de confirmação incluídas.
Etapa 1: crie um arquivo AssemblyInfo_template.cs na pasta Project \ Properties, com base em seu AssemblyInfo.cs original, mas contendo:
Etapa 2: crie um script PowerShell denominado InjectGitVersion.ps1, cuja fonte é:
Etapa 3: salve o arquivo InjectGitVersion.ps1 no diretório da solução em uma pasta BuildScripts
Etapa 4: adicione a seguinte linha aos eventos de pré-construção do projeto
Etapa 5: Construa seu projeto.
Etapa 6: opcionalmente, adicione AssemblyInfo.cs ao seu arquivo git ignore
fonte
AssemblyInfo.cs
pode-se modificarAssemblyInfo.cs
no local, construir e então fazer git resetAssemblyInfo.cs
para a última versão confirmada. Então no repo sempre haveriaAssemblyInfo.cs
, com$..$
substituído apenas pelo tempo de construção.git describe --match "v[0-9]*" --long --always --dirty
para filtrar por certas tags (aquelas que contêm um número de versão) e para indicar se a árvore de trabalho estava limpa.$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
Agora é muito fácil com a Tarefa de revisão do .NET para MSBuild e trabalhar com o Visual Studio 2019.
Basta instalar o pacote NuGet Unclassified.NetRevisionTask e configurar as informações desejadas no
AssemblyInfo.cs
arquivo conforme descrito na documentação do GitHub .Se você quiser apenas o hash do último commit (comprimento = 8):
Construa seu projeto / solução e você terá algo assim:
fonte
PropertyGroup
ao arquivo .csproj como visto no README github.com/ygoe/NetRevisionTask/blob/master/README.mdComo a outra resposta já menciona o git bit, uma vez que você tenha o SHA, você pode considerar a geração do
AssemblyInfo.cs
arquivo do seu projeto em um gancho de pré-construção.Uma maneira de fazer isso é criar um
AssemblyInfo.cs.tmpl
arquivo de modelo, com um espaço reservado para seu SHA, digamos $$ GITSHA $$, por exemploSeu gancho de pré-compilação deve então substituir esse espaço reservado e gerar o arquivo AssemblyInfo.cs para o compilador C # selecionar.
Para ver como isso pode ser feito usando SubWCRev para SVN, consulte esta resposta . Não deve ser difícil fazer algo semelhante para o git.
Outras formas seriam um "estágio de criação" conforme mencionado, ou seja, escrever uma tarefa MSBuild que faça algo semelhante. Ainda outra maneira pode ser postar o processo de alguma forma (digamos ildasm + ilasm), mas acho que as opções mencionadas acima são provavelmente as mais fáceis.
fonte
Para um método totalmente automatizado e flexível, verifique https://github.com/Fody/Stamp . Nós usamos isso com sucesso para nossos projetos Git (bem como esta versão para projetos SVN)
Atualização: desatualizado, pois Stamp.Fody não é mais mantido
fonte
Você pode usar um powerhell one-liner para atualizar todos os arquivos assemblyinfo com o hash de confirmação.
fonte
Conforme observado por @ learath2, a saída de
git rev-parse HEAD
fornecerá um hash simples.Se você usar tags no repositório Git (e usar tags, não é mais descritivo e legível do que
git rev-parse
), a saída pode ser recebida degit describe
(embora também seja usada com sucesso posteriormente emgit checkout
)Você pode chamar rev-parse | describe em:
fonte
Estou usando uma combinação da resposta aceita e uma pequena adição. Eu tenho a extensão AutoT4 instalada ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ) para executar novamente os modelos antes de construir.
obtendo versão do GIT
Tenho
git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"
no meu evento de pré-construção nas propriedades do projeto. Adicionar git_version.txt e VersionInfo.cs a .gitignore é uma boa ideia.incorporando versão em metadados
Eu adicionei um
VersionInfo.tt
modelo ao meu projeto:Agora eu tenho minha tag git + hash em "ProductVersion".
fonte
Referindo-me à outra resposta ( https://stackoverflow.com/a/44278482/4537127 ), também usei o
VersionInfo.tt
modelo de texto para gerarAssemblyInformationalVersion
sem AutoT4.(Pelo menos funciona em meu aplicativo C # WPF)
O problema era que os eventos de pré-construção foram executados após as transformações do modelo, portanto, após a clonagem, o
git_version.txt
arquivo não estava lá e a construção falhou. Depois de criá-lo manualmente para permitir que a transformação passasse uma vez, ele foi atualizado após a transformação e sempre foi um commit por trás .Tive que fazer dois ajustes no arquivo .csproj (isso se aplica pelo menos para Visual Studio Community 2017)
1) Importe os Text Transformation Targets e faça transformações de modelo para executar em cada compilação: (Ref https://msdn.microsoft.com/en-us/library/ee847423.aspx )
e depois
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
2) Faça a
git describe
execução antes das transformações do modelo (para quegit_version.txt
esteja lá quandoVersionInfo.tt
for transformado):..E o código C # para obter o
AssemblyInformationalVersion
(Ref https://stackoverflow.com/a/7770189/4537127 )..E adicionar os arquivos gerados a .gitignore
fonte
Outra maneira seria gerar um arquivo Version.cs a partir de uma etapa de pré-construção. Eu explorei isso em um pequeno projeto de prova de conceito que imprime seu hash de commit atual.
O projeto está carregado em https://github.com/sashoalm/GitCommitHashPrinter .
O código de lote que cria o arquivo Version.cs é este:
fonte
Lugar, colocar
no
YOUR_PROJECT_NAME.csproj
fonte