최신 정보:
이 질문에 처음 답변 한 이후로 상황이 발전했습니다. Microsoft.NET.Sdk몇 가지 조건이 충족되는 경우는 잘 nuget 패키지 메타 데이터 등으로 모두 어셈블리 정보 버전을 해시를 커밋 지금 추가하기위한 지원이 포함되어 있습니다 (당신이 SDK 스타일의 프로젝트를 사용해야 의미) :
<SourceRevisionId>속성을 정의해야합니다. 다음과 같이 대상을 추가하여 수행 할 수 있습니다.
<Target Name="InitializeSourceControlInformation" BeforeTargets="AddSourceRevisionToInformationalVersion">
<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. 그러면 너겟 팩 작업이 SourceRevisionId도 선택하게됩니다.
이 새로운 기술이 가장 깨끗하고 일관성이 있기 때문에 사람들이 MSBuildGitHash 패키지를 사용하지 않도록 유도합니다.
실물:
프로젝트에 포함 할 수있는 간단한 너겟 패키지를 만들었습니다. https://www.nuget.org/packages/MSBuildGitHash/
이 너겟 패키지는 "순수한"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"는 BuildHash라는 MSBuild 속성에 git 해시를로드합니다 . 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 파일과 함께 소스 제어됩니다.