.NET DLL에 git 커밋 해시 포함


102

Git을 버전 제어로 사용하여 C # 애플리케이션을 구축하고 있습니다.

애플리케이션을 빌드 할 때 실행 파일에 마지막 커밋 해시를 자동으로 포함하는 방법이 있습니까?

예를 들어, 커밋 해시를 콘솔에 인쇄하는 것은 다음과 같습니다.

class PrintCommitHash
{
    private String lastCommitHash = ?? // What do I put here?
    static void Main(string[] args)
    {
        // Display the version number:
        System.Console.WriteLine(lastCommitHash );
    }
}

배포 된 실행 파일은 git repo에 액세스 할 수 없으므로 이는 runtime이 아닌 빌드 타임에 수행 해야합니다.

C ++ 관련 질문은 여기 에서 찾을 수 있습니다 . @mattanja의 요청에 따라

편집

내 프로젝트에서 사용하는 git hook 스크립트를 게시하고 있습니다. 설정:

  • 후크는 Linux 쉘 스크립트이며 path_to_project \ .git \ hooks 아래에 있습니다.
  • msysgit 을 사용 하는 경우 hooks 폴더에는 이미 몇 가지 샘플 스크립트가 포함되어 있습니다. git에서 호출하도록하려면 스크립트 이름에서 '.sample'확장자를 제거하십시오.
  • 후크 스크립트의 이름은이를 호출하는 이벤트와 일치합니다. 제 경우에는 post-commitpost-merge를 수정 했습니다 .
  • AssemblyInfo.cs 파일은 프로젝트 경로 바로 아래에 있습니다 ( .git 폴더 와 동일한 수준 ). 여기에는 23 줄이 포함되어 있으며 git을 사용하여 24 번째 줄을 생성합니다.

내 리눅스 쉘링이 약간 녹슬었기 때문에 스크립트는 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

도움이 되었기를 바랍니다.

답변:


63

버전을 추적하기 위해 git에서 태그를 사용합니다.

git tag -a v13.3.1 -m "version 13.3.1"

다음을 통해 git에서 해시 버전을 가져올 수 있습니다.

git describe --long

빌드 프로세스는 AssemblyInfo.cs 파일의 AssemblyInformationalVersion 속성에 git 해시를 넣습니다.

[assembly: AssemblyInformationalVersion("13.3.1.74-g5224f3b")]

컴파일 한 후에는 Windows 탐색기에서 버전을 볼 수 있습니다.

여기에 이미지 설명 입력

다음을 통해 프로그래밍 방식으로 가져올 수도 있습니다.

var build = ((AssemblyInformationalVersionAttribute)Assembly
  .GetAssembly(typeof(YOURTYPE))
  .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
  .InformationalVersion;

여기서 YOURTYPE은 AssemblyInformationalVersion 특성이있는 어셈블리의 모든 유형입니다.


14
안녕하세요, 한 달 전에 물어보고 싶었지만 댓글을 달 담당자가 충분하지 않았습니다. "우리 빌드 프로세스는 AssemblyInfo.cs의 AssemblyInformationalVersion 속성에 자식 해시를 넣습니다."라고 말하면 정확히 무슨 일이 벌어지고 있습니까? Visual Studio 빌드를 수행하고 있습니까, 아니면 NAnt 또는 다른 도구와 같은 것을 사용하고 있습니까?
존 예수

3
우리는 빌드를 자동화하기 위해 루비 (갈퀴)를 사용합니다. 레이크 빌드 작업 중 하나는 솔루션의 모든 프로젝트에서 사용되는 CommonAssemblyInfo.cs 파일을 업데이트합니다. 이 작업은 날개 다랑어를 사용하여 CommonAssemblyInfo.cs 파일을 생성 - github.com/derickbailey/Albacore 어셈블리 정보 중 하나는 해당 작업 세트가 AssemblyInformationalVersion입니다 값.
Handcraftsman 2013 년

3
@John Jesus-Lazy Badger가 제안했듯이 커밋 / 병합 후 git hooks를 사용하여 AssemblyInfo.cs를 변경할 수도 있습니다 (이것이 내가 한 일입니다). 참조 kernel.org/pub/software/scm/git/docs/githooks.html
bavaza

: 그냥 참고로, 날개 다랑어는 새로운 허브 조직으로 이동했다 github.com/Albacore/albacore
kornman00

5
다음 프로젝트 https://github.com/jeromerg/NGitVersionGlobalAssemblyInfo.*C # 및 C ++ 프로젝트의 컴파일 타임에 파일 을 생성하는 완벽한 솔루션을 제공합니다 . 기본적으로 생성 된 어셈블리 버전에는 커밋 해시, 로컬 변경 사항을 알리는 플래그 및 저장소 루트에서 현재 커밋까지의 커밋 양을 계산합니다.
jeromerg

77

version.txt 파일을 실행 파일에 포함시킨 다음 실행 파일에서 version.txt 를 읽을 수 있습니다 . version.txt 파일 을 생성하려면git describe --long

단계는 다음과 같습니다.

빌드 이벤트를 사용하여 git 호출

  • 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 속성을 선택합니다.

  • 빌드 이벤트에서 다음을 포함하는 빌드 전 이벤트를 추가하십시오 (따옴표에 유의하십시오).

    "C : \ Program Files \ Git \ bin \ git.exe"describe --long> "$ (ProjectDir) \ version.txt"

    그러면 프로젝트 디렉토리에 version.txt 파일 이 생성됩니다 .

실행 파일에 version.txt 포함

  • 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 기존 항목 추가를 선택합니다.
  • version.txt 파일 추가 (모든 파일을 볼 수 있도록 파일 선택기 필터 변경)
  • version.txt 가 추가 된 후 솔루션 탐색기에서 마우스 오른쪽 단추로 클릭하고 속성을 선택합니다.
  • 빌드 작업을 포함 된 리소스로 변경
  • 항상 복사하도록 출력 디렉토리로 복사 변경
  • 추가 의 version.txt 당신에 .gitignore의 파일

포함 된 텍스트 파일 버전 문자열 읽기

다음은 포함 된 텍스트 파일 버전 문자열을 읽는 몇 가지 샘플 코드입니다.

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();
        }
    }
}

9
이 접근 방식은 상당히 잘 작동합니다. 그래도 "git rev-parse --short HEAD"를 사용했습니다.
Brian Reiter 2014 년

3
오 굿. 태그가있을 때 정말 흥미 롭기 때문에 "git describe"를 사용했습니다. 버전 정보에는 태그가 적용된 후 커밋 수와 태그가 포함됩니다. 전에 SCM에서와 같은 것을 본 적이 없습니다.
존 예수

7
내가 사용하는 git describe --dirty개발자가 더러운의 작업 나무 작업 할 때 플래그를 추가한다.
paulmelnikow 17:06에

2
@ TamásSzelei 프로젝트 네임 스페이스는 TryGitDescribe입니다. version.txt 파일이 실행 파일 / 어셈블리 아티팩트에 포함 된 후 네임 스페이스를 앞에 추가해야합니다.
존 예수

2
완전한 솔루션에 감사드립니다. 제 경우에는 GetEntryAssembly조립을 사용 했습니다. 어쨌든 GetName().Name이름을 하드 코딩하지 않도록 호출 할 수 있습니다 .
astrowalker

51

최신 정보:

이 질문에 처음 답변 한 이후로 상황이 발전했습니다. Microsoft.NET.Sdk몇 가지 조건이 충족되는 경우는 잘 nuget 패키지 메타 데이터 등으로 모두 어셈블리 정보 버전을 해시를 커밋 지금 추가하기위한 지원이 포함되어 있습니다 (당신이 SDK 스타일의 프로젝트를 사용해야 의미) :

  1. <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는 어셈블리 정보 버전이 생성되기 전에 실행되도록합니다.

  1. 너겟 패키지 메타 데이터에 해시를 포함하려면을 <RepositoryUrl>정의해야합니다.

  2. <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 &gt; $(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 파일과 함께 소스 제어됩니다.


2
이것은 완벽하게 작동했습니다. 나는 너겟 패키지를 설치하고을 사용하여 git 해시를 꺼내어 Assembly.GetExecutingAssembly()어셈블리를 검사 할 수 있었다 CustomAttributes .
Gavin H

1
이것이 내 질문이라면이 대답을 수락했을 것입니다. 훌륭한 물건.
Drew Noakes

1
@ GavinH, 어떻게 얻었 GitHash습니까? 값이 존재한다는 것을 알 수 있지만 이름으로 사용자 정의 속성을 얻는 순수한 방법이 있습니까? 에 대한 긴 where-select 쿼리를 작성 해야하는 것 같습니다 CustomAttributes.
Okan Kocyigit

1
@ocanal 예-불행히도 .NET Framework를 읽는 것보다 더 깨끗한 방법을 찾을 수 없습니다 CustomAttributes. 예를 들어 다음은 해시 문자열을 추출하는 데 사용하는 함수입니다. pastebin.com/nVKGLhJC
Gavin H

2
@danmiser "UseMerge / SingleAssemblyName"이 뭔지 몰라서 도와 드릴 수 없습니다. github.com/MarkPflug/MSBuildGitHash 에서 문제를 작성하면 한 번 살펴볼 수 있습니다 (약속이 아님).
MarkPflug

14

이를 수행하는 또 다른 방법은 On-Board Visual Studio 마법과 함께 NetRevisionTool 을 사용하는 입니다. Visual Studio 2013 Professional Edition에 대해 여기에서 보여줄 것이지만 다른 버전에서도 작동합니다.

따라서 먼저 NetRevisionTool을 다운로드하십시오. PATH에 NetRevisionTool.exe를 포함하거나 리포지토리에 체크인하고 Visual Studio 사전 빌드 및 사후 빌드 작업을 만들고 AssemblyInfo.cs를 변경합니다.

AssemblyInformationVersion에 git-hash를 추가하는 예는 다음과 같습니다. 프로젝트 설정에서 :

여기에 이미지 설명 입력

프로젝트의 AssemblyInfo.cs에서 다음 줄을 변경 / 추가합니다.

[어셈블리 : AssemblyInformationalVersion ( "1.1. {dmin : 2015}. {chash : 6} {!}-{branch}")]

표시된 스크린 샷에서 External / bin 폴더의 NetRevisionTool.exe에서 확인했습니다.

빌드 후 바이너리를 마우스 오른쪽 버튼으로 클릭하고 속성으로 이동하면 다음과 같은 내용이 표시됩니다.

여기에 이미지 설명 입력

이것이 누군가를 돕기를 바랍니다.


저를위한 커밋 해시는 항상 00000으로 끝납니다. 커밋되지 않은 변경 사항이 있지만 여전히 동일하기 때문이라고 생각했습니다. 왜 그런지 아세요?
Viktor

3
문제는 NetRevision이 내 자식 실행 파일을 찾지 못했다는 것입니다. 그 이유는 SourceTree를 사용하고 있고 git이 포함되어 있기 때문입니다. 해결책은 % USERPROFILE % \ AppData \ Local \ Atlassian \ SourceTree \ git_local \ bin에서 NetRevision.exe가 포함 된 폴더로 git.exe 및 libiconv-2.dll을 복사하는 것이 었습니다. 또한 다음과 같이 이벤트를 수정해야했습니다. 빌드 전 이벤트 : cd $ (ProjectDir) Libraries NetRevisionTool.exe / patch $ (ProjectDir) 빌드 후 이벤트 : cd $ (ProjectDir) Libraries NetRevisionTool.exe / restore $ (ProjectDir)
Viktor

향후 참조를 위해 프로젝트 리포지토리 URL이 얼마 전에 github.com/ygoe/NetRevisionTool로 변경되었습니다 . 더 많은 정보는 unclassified.software/apps/netrevisiontool 에서도 확인할 수 있습니다 .
ygoe

14

이 질문은 단계별 답변을 제공 할 가치가 있다고 생각합니다. 여기서 전략은 템플릿 파일을 가져 와서 git 태그 + 커밋 수 정보가 포함 된 AssemblyInfo.cs 파일을 생성하는 빌드 전 이벤트에서 powershell 스크립트를 실행하는 것입니다.

1 단계 : 원본 AssemblyInfo.cs를 기반으로하지만 다음을 포함하는 Project \ Properties 폴더에 AssemblyInfo_template.cs 파일을 만듭니다.

[assembly: AssemblyVersion("$FILEVERSION$")]
[assembly: AssemblyFileVersion("$FILEVERSION$")]
[assembly: AssemblyInformationalVersion("$INFOVERSION$")]

2 단계 : 소스가 다음과 같은 InjectGitVersion.ps1이라는 powershell 스크립트를 만듭니다.

# InjectGitVersion.ps1
#
# Set the version in the projects AssemblyInfo.cs file
#


# Get version info from Git. example 1.2.3-45-g6789abc
$gitVersion = git describe --long --always;

# Parse Git version info into semantic pieces
$gitVersion -match '(.*)-(\d+)-[g](\w+)$';
$gitTag = $Matches[1];
$gitCount = $Matches[2];
$gitSHA1 = $Matches[3];

# Define file variables
$assemblyFile = $args[0] + "\Properties\AssemblyInfo.cs";
$templateFile =  $args[0] + "\Properties\AssemblyInfo_template.cs";

# Read template file, overwrite place holders with git version info
$newAssemblyContent = Get-Content $templateFile |
    %{$_ -replace '\$FILEVERSION\$', ($gitTag + "." + $gitCount) } |
    %{$_ -replace '\$INFOVERSION\$', ($gitTag + "." + $gitCount + "-" + $gitSHA1) };

# Write AssemblyInfo.cs file only if there are changes
If (-not (Test-Path $assemblyFile) -or ((Compare-Object (Get-Content $assemblyFile) $newAssemblyContent))) {
    echo "Injecting Git Version Info to AssemblyInfo.cs"
    $newAssemblyContent > $assemblyFile;       
}

3 단계 : InjectGitVersion.ps1 파일을 BuildScripts 폴더의 솔루션 디렉터리에 저장합니다.

4 단계 : 프로젝트의 빌드 전 이벤트에 다음 줄 추가

powershell -ExecutionPolicy ByPass -File  $(SolutionDir)\BuildScripts\InjectGitVersion.ps1 $(ProjectDir)

5 단계 : 프로젝트를 빌드합니다.

6 단계 : 선택적으로 git ignore 파일에 AssemblyInfo.cs 추가


그리고 git 태그를 1.2.3과 같은 파일 버전과 호환되도록 만들어야합니다. 좀 더 복잡한 태그가있는 경우, 당신은 호환 부분을 분석해야합니다
Atilio Jobson

2
템플릿을 사용하고 실제 템플릿을 무시하는 대신 제자리에서 AssemblyInfo.cs수정 AssemblyInfo.cs하고 빌드 한 다음 AssemblyInfo.cs마지막 커밋 된 버전으로 git 재설정 할 수 있습니다. 그래서 REPO 항상있을 것입니다 AssemblyInfo.cs으로 $..$만 빌드시 대체.
Kuba Wyrostek

이것은 훌륭하게 작동했습니다. 내가 사용하여 종료 git describe --match "v[0-9]*" --long --always --dirty(버전 번호를 포함하는) 특정 태그 필터와 작업 트리가 깨끗하고 있다면, 나타냅니다.
packoman

또한 PS 스크립트에서 RegEx를 수정해야합니다.$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman

4

이제 MSBuild 용 .NET Revision Task를 사용하고 Visual Studio 2019로 작업하는 것이 매우 쉽습니다 .

NuGet 패키지 Unclassified.NetRevisionTask를 설치 한 다음 GitHub 설명서에AssemblyInfo.cs 설명 된대로 파일 에서 원하는 정보를 구성하면 됩니다.

마지막 커밋의 해시 만 원하는 경우 (길이 = 8) :

[assembly: AssemblyInformationalVersion("1.0-{chash:8}")]

프로젝트 / 솔루션을 빌드하면 다음과 같은 결과가 나타납니다.

여기에 이미지 설명 입력


NET.core 응용 프로그램 형식을 구성하려면 추가 PropertyGroup받는 .csproj에 있는 README에서 볼처럼 파일 github.com/ygoe/NetRevisionTask/blob/master/README.md
sc911

3

다른 답변에서 이미 git 비트를 언급했듯이 SHA가 있으면 AssemblyInfo.cs사전 빌드 후크에서 프로젝트 파일을 생성하는 것을 고려할 수 있습니다 .

이를 수행하는 한 가지 방법은 AssemblyInfo.cs.tmpl예를 들어 $$ GITSHA $$와 같이 SHA에 대한 자리 표시자가 있는 템플릿 파일 을 만드는 것입니다.

[assembly: AssemblyDescription("$$GITSHA$$")]

그런 다음 사전 빌드 후크가이 자리 표시자를 대체하고 C # 컴파일러가 선택할 수 있도록 AssemblyInfo.cs 파일을 출력해야합니다.

SVN 용 SubWCRev를 사용하여이 작업을 수행하는 방법을 보려면 이 답변을 참조하십시오 . git에게 비슷한 일을하는 것은 어렵지 않습니다.

다른 방법은 언급 한대로 "만들기 단계"입니다. 즉, 유사한 작업을 수행하는 MSBuild 작업을 작성합니다. 또 다른 방법은 어떻게 든 DLL을 후 처리하는 것일 수 있지만 (ildasm + ilasm 말), 위에서 언급 한 옵션이 아마도 가장 쉬울 것이라고 생각합니다.


@Wint 아니요, 생성 된 AssemblyInfo.cs를 git에 추가하지 마십시오. 그렇게하면 더럽지 않은 빌드를 할 수 없습니다. : P
jokedst

3

완전히 자동화되고 유연한 방법 체크 아웃 https://github.com/Fody/Stamp . 우리는 이것을 Git 프로젝트에 성공적으로 사용했습니다 ( SVN 프로젝트에도이 버전 ).

업데이트 : Stamp.Fody가 더 이상 유지되지 않기 때문에 이것은 구식입니다.


1
Stamp.Fody의 github 페이지에 "이 프로젝트는 더 이상 유지되지 않습니다."라고되어 있습니다. CA0052과 CA0055 내 프로젝트에서 그것을 제기 포함
sc911

2

powershell one-liner를 사용하여 커밋 해시로 모든 assemblyinfo 파일을 업데이트 할 수 있습니다.

$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }

1
  1. 빌드시 외부 프로그램을 호출하고 출력을 가로채는 방법을 알고 있기를 바랍니다.
  2. git의 작업 디렉토리에서 버전이 지정되지 않은 파일을 무시하는 방법을 알고 있기를 바랍니다.

@ learath2에서 언급했듯이의 출력은 git rev-parse HEAD일반 해시를 제공합니다.

당신이 망할 놈의-저장소에 태그를 사용하는 경우 (당신이 태그를 사용, 그것은 더 자세한 설명과 이상 읽을 수없는 git rev-parse), 출력에서 수신 할 수있다 git describe(도 성공적으로 나중에 사용하면서 git checkout)

다음에서 rev-parse | describe를 호출 할 수 있습니다.

  • 일부는 무대를 만든다
  • 커밋 후 후크
  • 얼룩 필터에서 얼룩 / 청소 필터 구현 방식을 선택하는 경우

0

나는 받아 들여지는 대답과 작은 adition의 조합을 사용하고 있습니다. 빌드 전에 템플릿을 다시 실행하기 위해 AutoT4 확장 프로그램 ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 )을 설치했습니다 .

GIT에서 버전 가져 오기

나는이 git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"프로젝트 속성에서 내 빌드 전 이벤트. .gitignore에 git_version.txt 및 VersionInfo.cs를 추가하는 것은 좋은 생각입니다.

메타 데이터에 버전 포함

VersionInfo.tt내 프로젝트에 템플릿을 추가했습니다 .

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #>
<#@ output extension=".cs" #>

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

<#
if (File.Exists(Host.ResolvePath("git_version.txt")))
{
    Write("[assembly: AssemblyInformationalVersion(\""+ File.ReadAllText(Host.ResolvePath("git_version.txt")).Trim() + "\")]");
}else{
    Write("// version file not found in " + Host.ResolvePath("git_version.txt"));
}

#>

이제 "ProductVersion"에 내 자식 태그 + 해시가 있습니다.


0

다른 답변 ( https://stackoverflow.com/a/44278482/4537127 )을 참조 하면 VersionInfo.tt텍스트 템플릿을 사용하여 AssemblyInformationalVersionAutoT4없이 생성 했습니다.

(Atleast는 내 C # WPF 응용 프로그램에서 작동합니다)

문제는 템플릿 변환 후에 빌드 전 이벤트가 실행 되었기 때문에 복제 후 git_version.txt파일이 존재하지 않고 빌드가 실패한다는 것입니다. 그것은 수동으로 변환 한 번에 합격 할 수 있도록 만든 후,이를 변환 한 후 업데이트, 항상이었다 한 뒤에 커밋 .

.csproj 파일을 두 가지 조정해야했습니다 (적어도 Visual Studio Community 2017에는 적용됨).

1) 텍스트 변환 대상을 가져오고 모든 빌드에서 실행할 템플릿 변환을 만듭니다. (참조 https://msdn.microsoft.com/en-us/library/ee847423.aspx )

<PropertyGroup>
    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
    <TransformOnBuild>true</TransformOnBuild>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

이후 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />

2) git describe템플릿 변환 전에 실행하십시오 ( 변환 git_version.txt될 때 거기에 있도록 VersionInfo.tt) :

<Target Name="PreBuild" BeforeTargets="ExecuteTransformations">
  <Exec Command="git -C $(ProjectDir) describe --long --always --dirty &gt; $(ProjectDir)git_version.txt" />
</Target>

.. 그리고 C # 코드는 AssemblyInformationalVersion(Ref https://stackoverflow.com/a/7770189/4537127 )

public string AppGitHash
{
    get
    {
        AssemblyInformationalVersionAttribute attribute = (AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();

        return attribute.InformationalVersion;
    }
}

.. 생성 된 파일을 .gitignore에 추가합니다.

VersionInfo.cs
git_version.txt

0

또 다른 방법은 빌드 전 단계에서 Version.cs 파일을 생성하는 것입니다. 나는 현재 커밋 해시를 출력하는 약간의 개념 증명 프로젝트에서 이것을 탐구했습니다.

프로젝트는 https://github.com/sashoalm/GitCommitHashPrinter에 업로드됩니다 .

Version.cs 파일을 생성하는 배치 코드는 다음과 같습니다.

@echo off

echo "Writing Version.cs file..."

@rem Pushd/popd are used to temporarily cd to where the BAT file is.
pushd $(ProjectDir)

@rem Verify that the command succeeds (i.e. Git is installed and we are in the repo).
git rev-parse HEAD || exit 1

@rem Syntax for storing a command's output into a variable (see https://stackoverflow.com/a/2340018/492336).
@rem 'git rev-parse HEAD' returns the commit hash.
for /f %%i in ('git rev-parse HEAD') do set commitHash=%%i

@rem Syntax for printing multiline text to a file (see https://stackoverflow.com/a/23530712/492336).
(
echo namespace GitCommitHashPrinter
echo {
echo     class Version
echo     {
echo         public static string CommitHash { get; set; } = "%commitHash%";
echo     }
echo }
)>"Version.cs"

popd    

0

장소

<Target Name="UpdateVersion" BeforeTargets="CoreCompile">
  <Exec Command="php &quot;$(SolutionDir)build.php&quot; $(SolutionDir) &quot;$(ProjectDir)Server.csproj&quot;" />
</Target>

YOUR_PROJECT_NAME.csproj

<?php

function between(string $string, string $after, string $before, int $offset = 0) : string{
    return substr($string, $pos = strpos($string, $after, $offset) + strlen($after),
        strpos($string, $before, $pos) - $pos);
}

$pipes = [];
$proc = proc_open("git rev-parse --short HEAD", [
    0 => ["pipe", "r"],
    1 => ["pipe", "w"],
    2 => ["pipe", "w"]
], $pipes, $argv[1]);

if(is_resource($proc)){
    $rev = stream_get_contents($pipes[1]);
    proc_close($proc);
}

$manifest = file_get_contents($argv[2]);
$version = between($manifest, "<Version>", "</Version>");
$ver = explode("-", $version)[0] . "-" . trim($rev);
file_put_contents($argv[2], str_replace($version, $ver, $manifest));

echo "New version generated: $ver" . PHP_EOL;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.