我正在构建一个C#应用程序,使用Git作为版本控制。
当我构建我的应用程序时,有没有办法自动将最后一个提交散列嵌入到可执行文件中?
例如,将提交散列打印到控制台将如下所示:
class PrintCommitHash
{
private String lastCommitHash = ?? // What do I put here?
static void Main(string[] args)
{
// Display the version number:
System.Console.WriteLine(lastCommitHash );
}
}
请注意,这必须在build时完成,而不是在运行时,因为我部署的可执行文件将无法访问git存储库。
关于C++的一个相关问题可以在here上找到。
编辑
根据@mattanja的请求,我发布了我在项目中使用的git钩子脚本。设置:
钩子是linux shell脚本,放在: path_to_project.git\hooks
由于我的linux外壳有点生疏,该脚本简单地将AssemblyInfo.cs的前23行读取到一个临时文件,将git散列回显到最后一行,然后将该文件重命名为AssemblyInfo.cs。我相信有更好的方法可以做到这一点:
#!/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
希望这能有所帮助。
发布于 2013-03-01 03:14:54
我们在git中使用标签来跟踪版本。
git tag -a v13.3.1 -m "version 13.3.1"
您可以通过以下方式从git获取带有散列的版本:
git describe --long
我们的构建过程将git散列放在AssemblyInfo.cs文件的AssemblyInformationalVersion属性中:
[assembly: AssemblyInformationalVersion("13.3.1.74-g5224f3b")]
编译完成后,您可以从windows资源管理器中查看版本:
您也可以通过以下方式以编程方式获取它:
var build = ((AssemblyInformationalVersionAttribute)Assembly
.GetAssembly(typeof(YOURTYPE))
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
.InformationalVersion;
其中,您的类型是程序集中具有AssemblyInformationalVersion属性的任何类型。
发布于 2013-03-01 04:33:28
您可以将version.txt文件嵌入到可执行文件中,然后从可执行文件中读取version.txt。要创建version.txt文件,请使用git describe --long
以下是步骤:
使用Build事件调用git
"C:\Program Files\Git\bin\git.exe“describe --long > "$(ProjectDir)\version.txt”
这将在项目目录中创建一个version.txt文件。
在可执行文件中嵌入version.txt
Build
读取嵌入的文本文件版本字符串
下面是读取嵌入式文本文件版本字符串的一些示例代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace TryGitDescribe
{
class Program
{
static void Main(string[] args)
{
string gitVersion= String.Empty;
using (Stream stream = Assembly.GetExecutingAssembly()
.GetManifestResourceStream("TryGitDescribe." + "version.txt"))
using (StreamReader reader = new StreamReader(stream))
{
gitVersion= reader.ReadToEnd();
}
Console.WriteLine("Version: {0}", gitVersion);
Console.WriteLine("Hit any key to continue");
Console.ReadKey();
}
}
}
发布于 2017-07-22 07:23:55
更新:
自从我最初回答这个问题以来,事情发生了变化。Microsoft.NET.Sdk
(意味着您必须使用sdk样式的项目)现在支持将提交散列添加到程序集信息版本以及nuget包元数据,前提是满足以下条件:
<SourceRevisionId>
属性。这可以通过像这样添加一个目标来完成:<Target Name="SetSourceRevisionId" BeforeTargets="InitializeSourceControlInformation">
<Exec
Command="git describe --long --always --dirty --exclude=* --abbrev=8"
ConsoleToMSBuild="True"
IgnoreExitCode="False"
>
<Output PropertyName="SourceRevisionId" TaskParameter="ConsoleOutput"/>
</Exec>
</Target>
此目标执行一个命令,该命令将SourceRevisionId
设置为缩写(8个字符)散列。BeforeTargets使其在创建程序集信息版本之前运行。
<RepositoryUrl>
。<SourceControlInformationFeatureSupported>
属性必须为true
,这会导致nuget pack任务也拾取SourceRevisionId。我会引导人们远离使用MSBuildGitHash包,因为这种新技术更干净、最一致。
原件:
我已经创建了一个简单的nuget包,您可以将它包含在您的项目中,它将为您解决这个问题:https://www.nuget.org/packages/MSBuildGitHash/
这个nuget包实现了一个“纯”MSBuild解决方案。如果你不想依赖nuget包,你可以简单地将这些目标复制到你的csproj文件中,并且它应该包含git散列作为自定义程序集属性:
<Target Name="GetGitHash" BeforeTargets="WriteGitHash" Condition="'$(BuildHash)' == ''">
<PropertyGroup>
<!-- temp file for the git version (lives in "obj" folder)-->
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
</PropertyGroup>
<!-- write the hash to the temp file.-->
<Exec Command="git -C $(ProjectDir) describe --long --always --dirty > $(VerFile)" />
<!-- read the version into the GitVersion itemGroup-->
<ReadLinesFromFile File="$(VerFile)">
<Output TaskParameter="Lines" ItemName="GitVersion" />
</ReadLinesFromFile>
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
<PropertyGroup>
<BuildHash>@(GitVersion)</BuildHash>
</PropertyGroup>
</Target>
<Target Name="WriteGitHash" BeforeTargets="CoreCompile">
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
<PropertyGroup>
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
</PropertyGroup>
<!-- includes the CustomAssemblyInfo for compilation into your project -->
<ItemGroup>
<Compile Include="$(CustomAssemblyInfoFile)" />
</ItemGroup>
<!-- defines the AssemblyMetadata attribute that will be written -->
<ItemGroup>
<AssemblyAttributes Include="AssemblyMetadata">
<_Parameter1>GitHash</_Parameter1>
<_Parameter2>$(BuildHash)</_Parameter2>
</AssemblyAttributes>
</ItemGroup>
<!-- writes the attribute to the customAssemblyInfo file -->
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
</Target>
这里有两个目标。第一个是"GetGitHash",它将git散列加载到一个名为BuildHash的MSBuild属性中,只有在还没有定义BuildHash的情况下才会这样做。如果您愿意,这允许您在命令行上将其传递给MSBuild。您可以将其传递给MSBuild,如下所示:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
第二个目标"WriteGitHash“将把散列值写入名为"CustomAssemblyInfo.cs”的临时"obj“文件夹中的文件。此文件将包含一行代码,如下所示:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
此CustomAssemblyInfo.cs文件将编译到您的程序集中,因此您可以在运行时使用反射来查找AssemblyMetadata
。下面的代码演示如何在同一程序集中包含AssemblyInfo
类时执行此操作。
using System.Linq;
using System.Reflection;
public static class AssemblyInfo
{
/// <summary> Gets the git hash value from the assembly
/// or null if it cannot be found. </summary>
public static string GetGitHash()
{
var asm = typeof(AssemblyInfo).Assembly;
var attrs = asm.GetCustomAttributes<AssemblyMetadataAttribute>();
return attrs.FirstOrDefault(a => a.Key == "GitHash")?.Value;
}
}
这种设计的一些好处是,它不会接触项目文件夹中的任何文件,所有变异的文件都在"obj“文件夹下。您的项目也将从Visual Studio内部或从命令行以相同的方式生成。它还可以很容易地为您的项目定制,并将与您的csproj文件一起进行源代码控制。
https://stackoverflow.com/questions/15141338
复制相似问题