에 깃 커밋 해시를 포함합니다.NET dll
저는 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 );
}
}
이 작업은 런타임이 아니라 빌드 시에 수행해야 합니다. 배포된 실행 파일에서는 gitrepo에 액세스할 수 없기 때문입니다.
C++와 관련된 질문은 여기에서 확인할 수 있습니다.
@mattanja님의 요청에 따라 프로젝트에서 사용하는 git hook 스크립트를 올립니다.설정:
- 후크는 path_to_project\.git\hooks 아래에 있는 리눅스 셸 스크립트입니다.
- msysgit를 사용하는 경우 후크 폴더에 이미 샘플 스크립트가 일부 포함되어 있습니다.git를 호출하려면 스크립트 이름에서 '.sample' 확장자를 제거합니다.
- 후크 스크립트의 이름은 후크 스크립트를 호출하는 이벤트와 일치합니다.저 같은 경우에는 사후 커밋과 사후 합병을 수정했습니다.
- 내 AssemblyInfo.cs 파일은 프로젝트 경로 바로 아래에 있습니다(.git 폴더와 동일한 수준).23개의 라인을 포함하고 있으며, 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
업데이트:
제가 처음에 이 질문에 대답을 한 이후로 상황이 발전했습니다.Microsoft.NET.Sdk
( project를 을 의미함) 조건이 를 추가할 수 포함되었습니다 (sdk 스타일 프로젝트를 사용해야 함을 의미함) 다음 조건이 충족되는 경우 nuget 패키지 메타데이터에 커밋 해시를 추가할 수 있습니다.
<SourceRevisionId>
속성을 정의해야 합니다.은 다음과할 수 :은과은을여다수할이다수ess:이ta할g은ny
<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(BeforeTargets)를 사용하면 어셈블리 정보 버전이 생성되기 전에 이 작업이 실행됩니다.
메타데이터에 nuget 에 를 시키기 시키기,
<RepositoryUrl>
또한 정의해야 합니다.<SourceControlInformationFeatureSupported>
속성은 다음과 같습니다.true
nuget pack 이 SourceRevisionId.를.
저는 이 새로운 기술이 더 깨끗하고 일관적이기 때문에 사람들이 MSBuildGitHash 패키지를 사용하지 않도록 할 것입니다.
원본:
프로젝트에 포함시킬 수 있는 간단한 nuget 패키지를 만들었습니다. https://www.nuget.org/packages/MSBuildGitHash/
이 nuget 패키지는 "순수한" MSBuild 솔루션을 구현합니다.nuget 패키지에 의존하지 않는 것이 좋다면 csproj 파일에 이러한 Targets를 복사할 수 있으며 사용자 지정 어셈블리 속성으로 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"는 GitHash를 BuildHash라는 MSBuild 속성에 로드합니다. 이것은 BuildHash가 아직 정의되지 않은 경우에만 수행됩니다.원하는 경우 명령줄의 MSBuild로 전달할 수 있습니다.다음과 같이 MSBuild에 전달할 수 있습니다.
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
두 번째 대상인 "WriteGitHash"는 "CustomAssemblyInfo.cs "이라는 임시 "obj" 폴더에 있는 파일에 해시 값을 쓸 것입니다.이 파일에는 다음과 같은 행이 포함됩니다.
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
하여 은 reflection 하여 할 되므로 에 할 하여 AssemblyMetadata
⑤ 는 ⑥ ⑦ 다음 보여줍니다 수 있는지를 실행될 코드는 어떻게 이것이 해질녘에 the 보여줍니다 있는지를 this can be how shows when done 해질녘에 the 다음 code following 코드는 이것이 수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 파일과 함께 소스 제어가 가능합니다.
버전을 내장할 수 있습니다.txt 파일을 실행 파일에 넣은 다음 버전을 읽습니다.실행 파일에서 txt를 내보냅니다.버전을 만들기 위해서.txt 파일, 사용git describe --long
단계는 다음과 같습니다.
빌드 이벤트를 사용하여 깃 호출
프로젝트를 마우스 오른쪽 버튼으로 클릭하고 Properties(속성)를 선택합니다.
Build Events(빌드 이벤트)에서 다음을 포함하는 Pre-Build 이벤트를 추가합니다(따옴표 참고).
"C:\Program Files\Git\bin\git.exe"는 --long > "$(ProjectDir)\version을 설명합니다.txt"
그러면 버전이 생성됩니다.프로젝트 디렉토리에 있는 txt 파일.
버전을 포함합니다.실행 파일의 txt
- 프로젝트를 마우스 오른쪽 단추로 클릭하고 기존 항목 추가를 선택합니다.
- 버전을 추가합니다.txt 파일(모든 파일을 볼 수 있도록 파일 선택 필터 변경)
- After version.txt가 추가되고 Solution Explorer에서 마우스 오른쪽 버튼을 클릭하고 Properties(속성)를 선택합니다.
- 빌드 작업을 내장된 리소스로 변경
- 복사를 항상 복사하도록 출력 디렉토리로 변경
- 버전 추가..gitignore 파일에 txt
내장된 텍스트 파일 버전 문자열 읽기
내장된 텍스트 파일 버전 문자열을 읽을 수 있는 샘플 코드는 다음과 같습니다.
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();
}
}
}
우리는 버전을 추적하기 위해 태그를 사용합니다.
git tag -a v13.3.1 -m "version 13.3.1"
git에서 해시로 버전을 얻을 수 있는 방법은 다음과 같습니다.
git describe --long
우리의 빌드 프로세스는 git 해시를 AssemblyInfo.cs 파일의 AssemblyInformationVersion 특성에 넣습니다.
[assembly: AssemblyInformationalVersion("13.3.1.74-g5224f3b")]
컴파일이 끝나면 Windows 탐색기에서 버전을 볼 수 있습니다.
다음을 통해 프로그래밍 방식으로 얻을 수도 있습니다.
var build = ((AssemblyInformationalVersionAttribute)Assembly
.GetAssembly(typeof(YOURTYPE))
.GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
.InformationalVersion;
여기서 YOURTYPE은 AssemblyInformationVersion 특성을 가진 Assembly의 임의의 유형입니다.
저는 이 질문이 단계별로 완벽한 답을 줄 가치가 있다고 생각합니다.여기서의 전략은 템플릿 파일을 가져와 git 태그 + 커밋 카운트 정보가 포함된 AssemblyInfo.cs 파일을 생성하는 빌드 전 이벤트에서 파워셸 스크립트를 실행하는 것입니다.
1단계: 어셈블리를 만듭니다.원래 AssemblyInfo.cs 을 기반으로 하지만 다음을 포함하는 Project\Properties 폴더의 Info_template.cs 파일.
[assembly: AssemblyVersion("$FILEVERSION$")]
[assembly: AssemblyFileVersion("$FILEVERSION$")]
[assembly: AssemblyInformationalVersion("$INFOVERSION$")]
2단계: InjectGitVersion.ps1이라는 이름의 파워셸 스크립트를 생성합니다.
# 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단계: InjectionGitVersion.ps1 파일을 BuildScripts 폴더의 솔루션 디렉토리에 저장합니다.
4단계: 프로젝트의 Pre-Build 이벤트에 다음 행 추가
powershell -ExecutionPolicy ByPass -File $(SolutionDir)\BuildScripts\InjectGitVersion.ps1 $(ProjectDir)
5단계: 프로젝트를 구축합니다.
6단계: 선택적으로 git ignore 파일에 AssemblyInfo.cs 추가
이를 위한 또 다른 방법은 NetRevision을 사용하는 것입니다.On-Board Visual Studio 마법이 있는 도구입니다.Visual Studio 2013 Professional Edition을 위해 이 제품을 소개하지만 다른 버전에서도 사용할 수 있습니다.
먼저 NetRevision Tool을 다운로드합니다.NetRevisionTool.exe를 PATH에 포함하거나 저장소에 체크인한 후 비주얼 스튜디오 사전 빌드 및 빌드 후 작업을 생성하고 AssemblyInfo.cs 을 변경합니다.
Assembly Information Version에 git-hash를 추가하는 예는 다음과 같습니다.프로젝트 설정에서:
프로젝트의 AssemblyInfo.cs 에서 행을 변경/추가합니다.
[어셈블리:어셈블리 정보 버전("1.1.{dmin:2015.{chash:6}{!}-{branch})")]
표시된 스크린샷에서 외부/빈 폴더의 NetRevisionTool.exe에서 선택했습니다.
빌드 후 바이너리를 마우스 오른쪽 버튼으로 클릭하고 속성으로 이동하면 다음과 같은 것이 표시됩니다.
누군가에게 도움이 되길 바랍니다
여기 비주얼 스튜디오 2019에서 작동하며 깃 커밋 해시를 C# 파일로 직접 가져오는 간단한 솔루션이 있습니다.솔루션에 다음 C# 코드를 추가합니다.
namespace MyNameSpace
{
[System.AttributeUsage(System.AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)]
sealed class GitHashAttribute : System.Attribute
{
public string Hash { get; }
public GitHashAttribute(string hsh)
{
this.Hash = hsh;
}
}
var hash = Assembly.GetEntryAssembly().GetCustomAttribute<GitHashAttribute>().Hash;
}
변수 hash
을는이다하면에 다음 행을 됩니다..csproj
파일.파일.
<Target Name="SetSourceRevisionId" BeforeTargets="InitializeSourceControlInformation">
<Exec Command="git.exe describe --long --always --dirty --exclude='*' --abbrev=40"
ConsoleToMSBuild="True" IgnoreExitCode="False">
<Output PropertyName="SourceRevisionId" TaskParameter="ConsoleOutput" />
</Exec>
</Target>
<Target Name="SetHash" AfterTargets="InitializeSourceControlInformation">
<ItemGroup>
<AssemblyAttribute Include="MyNameSpace.GitHashAttribute">
<_Parameter1>$(SourceRevisionId)</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
</Target>
확실히 .MyNameSpace
두 파일 모두 당신의 요구에 부합합니다.서한은et한ee서stt 입니다.ItemGroup
a에 끼워 넣어야 .Target
게로AfterTargets
세트.
이제 아주 쉬워졌습니다.MSBuild를 위한 NET 개정 작업 및 Visual Studio 2019와 함께 작업.
NuGet 패키지 Unclassified를 설치하기만 하면 됩니다.NetRevisionTask에서 원하는 정보를 구성합니다.AssemblyInfo.cs
GitHub 문서에 설명된 파일입니다.
마지막 커밋의 해시(length=8)만 원하는 경우:
[assembly: AssemblyInformationalVersion("1.0-{chash:8}")]
프로젝트/솔루션을 구축하면 다음과 같은 이점을 얻을 수 있습니다.
bit에 언급하고 , 에 했듯이 을 해 에서 를 해 을 에서 AssemblyInfo.cs
프로젝트의 파일을 빌드 전 후크에 저장합니다.
이를 위한 한 가지 방법은AssemblyInfo.cs.tmpl
템플릿 파일, SHA에 대한 자리 표시자(예: $$GITSHA$$).
[assembly: AssemblyDescription("$$GITSHA$$")]
그러면 사전 빌드 후크가 이 자리 표시자를 교체하고 C# 컴파일러가 선택할 수 있도록 AssemblyInfo.cs 파일을 출력해야 합니다.
SubWCrev for SVN을 사용하여 이 작업을 수행할 수 있는 방법은 다음 답변을 참조하십시오.비슷한 일을 하는 것은 어렵지 않을 것입니다.
다른 방법으로는 언급한 대로 "만들기 단계", 즉 유사한 작업을 수행하는 MSBuild 작업을 작성하는 것이 있습니다.또 다른 방법은 DLL을 어떻게든 후처리하는 것일 수도 있지만(idasm+ilasm say), 위에서 언급한 옵션이 아마도 가장 쉬울 것이라고 생각합니다.
완전 자동화되고 유연한 방법은 https://github.com/Fody/Stamp 에서 확인할 수 있습니다.Git 프로젝트에 이 버전을 성공적으로 사용했습니다(SVN 프로젝트에도 이 버전이 적용됨).
업데이트: 이것은 스탬프 이후로 구식입니다.Fody가 더 이상 유지되지 않습니다.
파워셸 원라이너를 사용하여 커밋 해시로 모든 assemblyinfo 파일을 업데이트할 수 있습니다.
$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }
또 다른 방법은 Pre-Build 단계에서 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
- 빌드 시 외부 프로그램 호출 및 출력 차단 방법을 알고 계시기 바랍니다.
- init의 작업 디렉토리가 버전이 없는 파일을 무시하도록 하는 방법을 아셨으면 좋겠습니다.
@의해 와 같이, @learath2의 와 한 은 에서, git rev-parse HEAD
당신에게 평범한 해시를 줄 겁니다
Git-respository에서 태그를 사용하는 경우(그리고 태그를 사용하는 경우), 에서 출력을 수신할 수 있습니다(또한 나중에 성공적으로 사용됨).git checkout
)
rev-parse를 호출할 수 있습니다.
- 를 .
.csproj
를 .<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
PropertyGroup
- 이미 생성된 내용을 복사할 수 있습니다.
AssemblyInfo.cs
obj
폴더를 직접 작성할 필요가 없습니다.
- 이미 생성된 내용을 복사할 수 있습니다.
- 만들기
AssemblyInfo.tt
(T4 템플릿) 속성 폴더에 있습니다. - 다음 내용 + 이전에 자동으로 생성된 이전 내용을 붙여넣기
AssemblyInfo.cs
<#@ template debug="true" hostspecific="True" language="C#" #>
<#@ assembly name="System.Core" #>
<# /*There's a bug with VS2022 where you have to be real specific about envDTE.*/ #>
<#@ assembly name="./PublicAssemblies/envdte.dll" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Globalization" #>
<#@ output extension=".cs" #>
<#
var dte = ((IServiceProvider)this.Host).GetService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
string buildConfig = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
string solutionDirectory = Path.GetDirectoryName(dte.Solution.FullName);
var (gitRevision, gitBranch, gitCompactRevision) = ("", "", "");
using(var process = new System.Diagnostics.Process() {
StartInfo = new System.Diagnostics.ProcessStartInfo() {
WorkingDirectory = solutionDirectory,
FileName = @"cmd.exe",
Arguments = "/C git rev-parse HEAD & git rev-parse --abbrev-ref HEAD",
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true
}
}) {
process.Start();
string[] lines = process.StandardOutput.ReadToEnd().Split();
gitRevision = lines[0].Trim();
gitBranch = lines[1].Trim();
gitCompactRevision = gitRevision.Substring(0, 6);
}
string appPurpose = "Launcher"; // & Updater
string companyShort = "todo";
string companyFull = "todo";
string productNameShort = "todo";
string productName = $"{companyShort} {productNameShort}";
string fileName = $"{companyShort}{productNameShort}";
string exeNAME = $"{fileName}Launch";
string originalFilename = $"{exeNAME}.exe";
string CALLEXE = $"{fileName}.exe";
string BROWSEREXE = $"{fileName}Browser.exe";
string FULLINSTALLER = $"{fileName}Setup.exe";
DateTime dtBuiltDate = DateTime.UtcNow;
string cBuildYear = dtBuiltDate.Year.ToString();
string cBuildDay = dtBuiltDate.ToString("dd");
string cBuildMonth = dtBuiltDate.ToString("MM");
string cBuildTime = dtBuiltDate.ToString("T", DateTimeFormatInfo.InvariantInfo);
string assemblyVersion = $"3.0.{cBuildYear}.{cBuildMonth}{cBuildDay}";
string JOB_NAME = System.Environment.GetEnvironmentVariable("JOB_NAME") ?? "0.0";
string buildVersion = System.Environment.GetEnvironmentVariable("BUILD_NUMBER") ?? "0-dev";
string buildSeries = Regex.Replace(JOB_NAME, @"[^0-9\.]+", "");
string buildNumber = Regex.Replace(buildVersion, @"[^0-9\.]+", "");
string InternalVersion = $"{JOB_NAME}.{buildVersion}";
string fileVersion = Regex.Replace(InternalVersion, @"[^0-9\.]+", "");
#>
using System.Reflection;
[assembly: System.Runtime.InteropServices.ComVisible(false)]
[assembly: System.Resources.NeutralResourcesLanguageAttribute("en")]
[assembly: AssemblyConfigurationAttribute("<#= buildConfig #>")]
[assembly: AssemblyProduct("<#= productName #>")]
[assembly: AssemblyTitle("<#= $"{companyShort}{productNameShort}" #>")]
[assembly: AssemblyCompany("<#= companyFull #>")]
[assembly: AssemblyDescription("<#= $"{companyShort} {productNameShort} .... {appPurpose} - ...... by {companyFull}" #>")]
[assembly: AssemblyCopyright("<#= $"© 1983-{cBuildYear} {companyFull}" #>")]
[assembly: AssemblyTrademark("<#= $"{productName} is a trademark of {companyFull}, Inc." #>")]
[assembly: AssemblyInformationalVersion("<#= InternalVersion #>")]
[assembly: AssemblyVersion("<#= assemblyVersion #>")]
[assembly: AssemblyFileVersion("<#= fileVersion #>")]
[assembly: AssemblyMetadataAttribute("OriginalFilename", "<#= originalFilename #>")]
[assembly: AssemblyMetadataAttribute("NAME", "<#= $"{productName} {appPurpose}" #>")]
[assembly: AssemblyMetadataAttribute("EXENAME", "<#= exeNAME #>")]
[assembly: AssemblyMetadataAttribute("DIRNAME", "<#= productNameShort #>")]
[assembly: AssemblyMetadataAttribute("CALLEXE", "<#= $"{fileName}.exe" #>")]
[assembly: AssemblyMetadataAttribute("BROWSEREXE", "<#= $"{fileName}Browser.exe" #>")]
[assembly: AssemblyMetadataAttribute("FULLINSTALLER", "<#= $"{fileName}Setup.exe" #>")]
[assembly: AssemblyMetadataAttribute("COMPANY", "<#= companyFull #>")]
[assembly: AssemblyMetadataAttribute("License", "<#= $"Contains copyrighted code and applications ..." #>")]
[assembly: AssemblyMetadataAttribute("TermsOfUse", "<#= "https://www.company.com/en-us/terms-of-use/" #>")]
[assembly: AssemblyMetadataAttribute("Website", "<#= "https://www.company.com/en-us" #>")]
[assembly: AssemblyMetadataAttribute("UpdateURL", "https://subdomain.product.net/version_check")]
[assembly: AssemblyMetadataAttribute("BuildYear", "<#= cBuildYear #>")]
[assembly: AssemblyMetadataAttribute("BuildDay", "<#= cBuildDay #>")]
[assembly: AssemblyMetadataAttribute("BuildMonth", "<#= cBuildMonth #>")]
[assembly: AssemblyMetadataAttribute("BuildTime", "<#= cBuildTime #>")]
[assembly: AssemblyMetadataAttribute("DateModified", "<#= $"{dtBuiltDate.ToString("MMM dd, yyyy", DateTimeFormatInfo.InvariantInfo)} at {cBuildTime}" #>")]
[assembly: AssemblyMetadataAttribute("BuildSeries", "<#= buildSeries #>")]
[assembly: AssemblyMetadataAttribute("BuildNumber", "<#= buildNumber #>")]
[assembly: AssemblyMetadataAttribute("BuildDate", "<#= dtBuiltDate.ToString("s") #>")]
[assembly: AssemblyMetadataAttribute("BuildMachine", "<#= Environment.MachineName #>")]
[assembly: AssemblyMetadataAttribute("BuildMachineUser", "<#= Environment.UserName #>")]
[assembly: AssemblyMetadataAttribute("BuildOSVersion", "<#= Environment.OSVersion #>")]
[assembly: AssemblyMetadataAttribute("BuildPlatform", "<#= Environment.OSVersion.Platform #>")]
[assembly: AssemblyMetadataAttribute("BuildClrVersion", "<#= Environment.Version #>")]
[assembly: AssemblyMetadataAttribute("BuildBranch", "<#= gitBranch #>")]
[assembly: AssemblyMetadataAttribute("BuildRevision", "<#= gitCompactRevision #>")]
[assembly: AssemblyMetadataAttribute("CommitHash", "<#= gitRevision #>")]
[assembly: AssemblyMetadataAttribute("RepositoryUrl", "")]
[assembly: AssemblyMetadataAttribute("RepositoryType", "")]
<#+
#>
이제 C#의 풀 파워를 사용하여 현재 사용 중인 git 브랜치, 리비전 등 원하는 모든 것을 생성할 수 있습니다.몇 가지 팁:
- 는 는 A 의 에서나 될 는 의 될 에서나 안
<# #>
을 - 은 파일 하고자 는 의 에 되어야 되어야 하고자 에
<#+ #>
(록.)+
사인은 매우 중요하며 파일의 마지막에 표시되어야 합니다.) - 것
<# #>
blocks는 그냥 평문입니다. - VS2019는 구문 강조나 지능이 없습니다.
.tt
file은 평문입니다.i를 설치한 후에 vScode로 편집하는 것을 합니다.T4 Support
확장(vs2019에서 사용할 수 없음...)
한 줄, , 만에 대한 Microsoft.SourceLink.GitHub
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
git commit hash는 에 자동으로 포함됩니다.망 dll.
자세한 내용은 문서 참조
저는 합격된 답변과 약간의 추가사항을 조합해서 사용하고 있습니다.빌드 전 템플릿을 다시 실행하기 위해 AutoT4 확장(https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4) 을 설치했습니다.
Git에서 버전 가져오기
있습니다git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"
프로젝트 부동산의 건설 전 이벤트에서 말입니다..에git_version.의하는을와s 을 추가하는 은 꽤 입니다txt와 VersionInfo.cs 에서 .gitignore 는 꽤 생각입니다 좋은 생각입니다 는 좋은 t . 꽤 xt to ore git .
메타데이터에 버전 포함
를 했습니다.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"에 git tag + hash가 있습니다.
다른 답변을 참고하여(https://stackoverflow.com/a/44278482/4537127) 또한 다음과 같이 활용했습니다.VersionInfo.tt
할트릿릿트할AssemblyInformationalVersion
자동 T4가 없는 경우
(적어도 내 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" />
the 2) git describe
변환을기에행을 를)).git_version.txt
언제 거기에 있습니까?VersionInfo.tt
cyclic):
<Target Name="PreBuild" BeforeTargets="ExecuteTransformations">
<Exec Command="git -C $(ProjectDir) describe --long --always --dirty > $(ProjectDir)git_version.txt" />
</Target>
..그리고 C# 코드는AssemblyInformationalVersion
(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
장소
<Target Name="UpdateVersion" BeforeTargets="CoreCompile">
<Exec Command="php "$(SolutionDir)build.php" $(SolutionDir) "$(ProjectDir)Server.csproj"" />
</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;
@John Jesus answer에서 큰 영감을 받아, 나는 조립 버전을 현재 Git 태그로 조정하기 위해 각 빌드에서 실행되는 파워셸 v1 스크립트를 만들었습니다.
파워셸 대본
# Get build running directory
$scriptPath = split-path -parent $MyInvocation.MyCommand.Path
try {
$v = git describe --tags
}
catch [System.Management.Automation.CommandNotFoundException] {
# Git not found
exit
}
# Letters are incompatible with AssemblyVersion.cs so we remove them
$v = $v -replace "v", ""
# Version format is major[.minor[.build[.revision]] so we remove them
$v = $v -replace "-(\D.*)", ''
$v = $v -replace "-", '.'
# We replace versions inside AssemblyInfo.cs content
$info = (Get-Content ($scriptPath + "/properties/AssemblyInfo.cs"))
$av = '[assembly: AssemblyVersion("'+$v+'")]'
$avf = '[assembly: AssemblyFileVersion("'+$v+'")]'
$info = $info -replace '\[assembly: AssemblyVersion\("(.*)"\)]', $av
$info = $info -replace '\[assembly: AssemblyFileVersion\("(.*)"\)]', $avf
Set-Content -Path ($scriptPath + "/properties/AssemblyInfo.cs") -Value $info -Encoding UTF8
솔루션 폴더에 저장하고 Prebuild Event를 설정하여 실행합니다.
다음 파일을 개발/스테이지 시스템에 배포하여 간단히 확인합니다.
git.exe -C "$(ProjectDir.TrimEnd('\'))" describe --long > "$(ProjectDir)_Version.info":
내 결과: 10.02.0.3-247-gbeadd082
git.exe -C "$(ProjectDir.TrimEnd('\'))" branch --show-current > "$(ProjectDir)_Branch.info"
내 결과: 피쳐/JMT-3931-jaguar
(Visual Studio PreBuild 이벤트)
더 편리하게 추가할 수 있는 방법을 찾았습니다.
<ItemGroup>
<PackageReference Include="GitVersion.MsBuild" Version="5.10.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
.csproj
. 이것은 매우 유연한 GitVersion 툴 위에 구축됩니다.
이것은 다음을 설정합니다.Product Version
생성된 에서 어떤 다음과 작성하여 제어할 수 있습니다 같이 정보를 출력할지는 a 있습니다 수 creating which by ation to inform control output be 에서 you 생성된 can dll 어떤 제어할 정보를 작성하여 출력할지는 다음과 같이GitVersion.yml
파일이 들어 있는
assembly-informational-format: '{Sha}'
다른 형식도 있습니다.GitVersion 설명서의 Version 변수에 나열되어 있습니다.
다른 옵션은 마이크로소프트가 자체적으로 제공하는 소스링크를 사용하는 것입니다.하지만 솔직히 이 접근 방식에서 많은 특이점과 제한점을 발견했습니다(예: SourceLinks는 레포가 어디에서 호스팅되는지 알고 싶어하고, Azure DevOps, GitHub, GitLab, BitBucket, gitea 등에 따라 다르게 구성해야 하는 것 같습니다).
언급URL : https://stackoverflow.com/questions/15141338/embed-git-commit-hash-in-a-net-dll
'programing' 카테고리의 다른 글
도커 파일에서 변수를 정의하는 방법은? (0) | 2023.09.07 |
---|---|
jQuery UI 없이 자동 완성 (0) | 2023.09.07 |
Angular2 QuickStart npm 시작이 올바르게 작동하지 않음 (0) | 2023.09.07 |
콘솔에서 변수를 추적할 때 새 줄을 만드는 방법은? (0) | 2023.09.07 |
배열 키에 문자열을 사용하도록 PHP를 강제하려면 어떻게 해야 합니까? (0) | 2023.09.07 |