在.Net dll中嵌入git commit哈希


102

我正在使用Cit作为版本控制来构建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。

有关C ++的相关问题,请参见此处

编辑

根据@mattanja的请求,我发布了我在项目中使用的git hook脚本。设置:

  • 挂钩是Linux Shell脚本,位于以下位置:path_to_project \ .git \ hooks
  • 如果您使用的是msysgit,则hooks文件夹已经包含一些示例脚本。为了让git调用它们,请从脚本名称中删除扩展名“ .sample”。
  • 挂钩脚本的名称与调用它们的事件相匹配。就我而言,我修改了post-commitpost-merge
  • 我的AssemblyInfo.cs文件直接位于项目路径下(与.git文件夹相同级别)。它包含23行,我使用git生成第24行。

由于我的linux shell有点生锈,该脚本只是将AssemblyInfo.cs的前23行读取到一个临时文件,将git hash回显到最后一行,然后将该文件重命名为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

希望这可以帮助。

Answers:


63

我们在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;

其中YOURTYPE是Assembly中具有AssemblyInformationalVersion属性的任何类型。


14
嗨,我想在一个月前问一下,但是我没有足够的代表发表评论。当您说“我们的构建过程将git哈希放入AssemblyInfo.cs的AssemblyInformationalVersion属性”时,到底发生了什么?您只是在进行Visual Studio构建,还是在使用类似NAnt之类的工具或其他工具?
约翰·耶稣

3
我们使用ruby(rake)来自动化我们的构建。我们的瑞克构建任务之一是更新在解决方案中的所有项目中使用的CommonAssemblyInfo.cs文件。该任务会生成使用长鳍金枪鱼的CommonAssemblyInfo.cs文件- github.com/derickbailey/Albacore 的集信息的一个值该任务组是AssemblyInformationalVersion。
Handcraftsman

3
@John Jesus-正如Lazy Badger所建议的那样,您还可以在提交/合并等之后使用git钩子来更改AssemblyInfo.cs(这是我最终要做的)。参见kernel.org/pub/software/scm/git/docs/githooks.html
bavaza 2013年

仅供参考,Albacore已移至新的枢纽组织:github.com/Albacore/albacore
kornman00 2014年

5
以下项目https://github.com/jeromerg/NGitVersion提供了一个完整的解决方案,可GlobalAssemblyInfo.*在编译时为C#和C ++项目生成文件:默认情况下,生成的程序集版本包含:提交哈希,表示本地更改的标志以及计算从存储库根目录到当前提交的提交量的增量。
jeromerg'2

77

您可以将version.txt文件嵌入到可执行文件中,然后从可执行文件中读取version.txt文件。要创建version.txt文件,请使用git describe --long

步骤如下:

使用Build Event调用git

  • 右键单击项目,然后选择属性

  • 在构建事件中,添加包含以下内容的预构建事件(注意引号):

    “ C:\ Program Files \ Git \ bin \ git.exe”描述--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

2
@TamásSzelei项目名称空间是TryGitDescribe。将version.txt文件嵌入到可执行文件/程序集工件中之后,您需要在名称空间之前添加它才能将其取出。
约翰·耶稣

2
感谢您提供完整的解决方案。就我而言,我曾经GetEntryAssembly获得过组装。无论如何,您都可以致电GetName().Name以避免对该名称进行硬编码。
astrowalker

51

更新:

自从我最初回答这个问题以来,事情已经发生了变化。的Microsoft.NET.Sdk(这意味着你必须使用一个SDK风格的项目),现在包括用于添加支持提交哈希两个组件的版本信息以及到NuGet包的元数据,如果某些条件得到满足:

  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. 要将哈希包括在nuget包元数据中,<RepositoryUrl>还必须定义。

  2. <SourceControlInformationFeatureSupported>属性必须为true,这将导致nuget pack任务也选择SourceRevisionId。

由于这种新技术更干净,最一致,因此我将使人们远离使用MSBuildGitHash软件包。

原版的:

我创建了一个简单的nuget程序包,您可以将其包含在项目中,它将为您解决此问题:https ://www.nuget.org/packages/MSBuildGitHash/

此nuget软件包实现了“纯” MSBuild解决方案。如果您不想依赖nuget包,则可以将这些Targets复制到csproj文件中,并且应将git hash作为自定义程序集属性包括在内:

<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”将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文件一起进行源代码控制。


2
这工作得很好。我安装了nuget软件包,并能够使用提取git哈希Assembly.GetExecutingAssembly(),然后检查程序集CustomAttributes
加文H

1
如果这是我的问题,我会接受这个答案。好东西。
德鲁·诺阿克斯

1
@GavinH,你是怎么得到的GitHash?我可以看到该值存在,但是是否有任何纯方法可以按名称获取自定义属性?看来我必须在上写很长的where-select查询CustomAttributes,谢谢。
Okan Kocyigit,

1
@ocanal是-不幸的是,我找不到比阅读《圣经》更干净的方法了CustomAttributes。例如,这是我用来提取哈希字符串的函数:pastebin.com/nVKGLhJC
Gavin H,

2
@danmiser我不知道“ UseMerge / SingleAssemblyName”是什么,所以我不能帮助您。在github.com/MarkPflug/MSBuildGitHash上创建一个问题,我可能会看一下(这不是一个承诺)。
MarkPflug

14

另一种方法是将NetRevisionTool与On-Board Visual Studio魔术配合使用。我将在此处针对Visual Studio 2013 Professional Edition展示此功能,但这也可以与其他版本一起使用。

因此,首先下载NetRevisionTool。您可以将NetRevisionTool.exe包含在PATH中,或者将其检入到存储库中,然后创建Visual Studio的预构建和后构建动作,并更改AssemblyInfo.cs。

将git哈希添加到AssemblyInformationVersion的示例如下:在项目设置中:

在此处输入图片说明

在项目的AssemblyInfo.cs中,更改/添加以下行:

[assembly:AssemblyInformationalVersion(“ 1.1。{dmin:2015}。{chash:6} {!}-{branch}”)]]

在显示的屏幕截图中,我在“外部/ bin”文件夹中的NetRevisionTool.exe中进行了检查

生成后,如果您右键单击二进制文件并转到属性,则应该看到类似以下内容:

在此处输入图片说明

希望这可以帮助某人


对我而言,提交哈希始终以00000结尾。我认为这是因为我尚未提交更改,但仍然相同。知道为什么吗?
维克多

3
问题是NetRevision找不到我的git可执行文件。原因是因为我们使用的是SourceTree,并且git内嵌了它。解决方案是将git.exe和libiconv-2.dll从%USERPROFILE%\ AppData \ Local \ Atlassian \ SourceTree \ git_local \ bin复制到包含NetRevision.exe的文件夹中。我还必须这样修改事件:生成前事件:cd $(ProjectDir)Libraries NetRevisionTool.exe / patch $(ProjectDir)生成后事件:cd $(ProjectDir)Libraries NetRevisionTool.exe / restore $(ProjectDir)
维克多

仅供将来参考,项目回购URL不久前已更改为github.com/ygoe/NetRevisionTool。在unclassified.software/apps/netrevisiontool上也可以找到更多信息。
ygoe '16

14

我认为这个问题值得给出完整的循序渐进的答案。这里的策略是从构建前事件运行powershell脚本,该事件将接收模板文件并生成带有git标签+提交计数信息的AssemblyInfo.cs文件。

步骤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:将以下行添加到项目的Pre-Build事件中

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

步骤5:建立专案。

步骤6:(可选)将AssemblyInfo.cs添加到您的git ignore文件中


并记住使git标签与文件版本兼容:例如1.2.3。如果您有更复杂的标签,则只需解析兼容部分
Atilio Jobson

2
除了使用模板而不是gitignore之外,还AssemblyInfo.cs可以AssemblyInfo.cs在原地进行修改,构建,然后将git重置AssemblyInfo.cs为最后提交的版本。因此,在仓库中将始终存在AssemblyInfo.cs$..$仅在构建时用代替。
库巴·怀罗斯泰克

这很棒。我最终使用git describe --match "v[0-9]*" --long --always --dirty来过滤某些标签(包含版本号的标签),并指出工作树是否干净。
packoman

您还必须在PS脚本中修改RegEx:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman

4

现在,使用MSBuild的.NET修订任务以及使用Visual Studio 2019 变得非常容易。

只需安装NuGet软件包Unclassified.NetRevisionTask,然后AssemblyInfo.cs按照GitHub文档中的说明在文件中配置所需的信息。

如果只需要最后一次提交的哈希(长度= 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模板文件,并为您的SHA使用占位符,例如$$ GITSHA $$,例如

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

然后,您的预构建钩子必须替换此占位符并输出AssemblyInfo.cs文件,以供C#编译器使用。

若要查看如何使用SubWCRev for SVN来完成此操作,请参阅此答案。为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 '18

2

您可以使用powershell单行代码用提交哈希值更新所有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存储库中使用标签(并且使用标签,它的描述性和可读性是否比更高git rev-parse),则可能会收到来自的输出git describe(虽然稍后会在git checkout)中成功使用

您可以在以下方式调用rev-parse | describe:

  • 一些舞台
  • 在提交后挂钩中
  • 在污迹过滤器中,如果您选择污迹/清洁过滤器,则实施方式

0

我正在使用已接受的答案和少量费用。我安装了AutoT4扩展名(https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4),以便在构建之前重新运行模板。

从GIT获取版本

git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"在项目属性的构建前事件中。将git_version.txt和VersionInfo.cs添加到.gitignore是一个好主意。

在元数据中嵌入版本

我已将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标签+哈希。


0

关于另一个答案(https://stackoverflow.com/a/44278482/4537127),我还利用了VersionInfo.tt文本模板来生成AssemblyInformationalVersion没有AutoT4 的文本。

(Atleast在我的C#WPF应用程序中工作)

问题在于,预生成事件是在模板转换后运行的,因此克隆后,git_version.txt文件不存在并且生成失败。手动创建它以使转换能够一次通过后,在转换后对其进行了更新,并且始终是一次提交

我必须对.csproj文件进行两次调整(这至少适用于Visual Studio Community 2017)

1)导入文本转换目标并进行模板转换以在每个版本上运行:(Ref https://msdn.microsoft.com/zh-cn/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.txtVersionInfo.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文件。我在一个概念验证项目中对此进行了探索,该项目打印了其当前的提交哈希。

Tha项目已上传到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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.