如何从 VS/msbuild 中提取 Git 提交哈希?

Jez*_*Jez 1 git msbuild powershell hash visual-studio-2015

场景是:

开发人员从他们的计算机上运行 PowerShell 脚本,通过 MSBuild 将各种 Nuget 包发布到 OctopusDeploy。我们希望将当前 git 提交的哈希(Git 存储库的基础与目录相同.sln)作为生成的版本号的一部分。为此,我们可能需要提取当前提交的哈希值并将其插入到版本号字符串中,然后将其作为参数传递给 MSBuild。

那么问题是,我们如何从 MSBuild 或 Visual Studio 中获取它?不能保证开发人员会安装 Git 命令行,但他们至少会安装 VS2015 并且内置了 Git 支持,所以您认为有某种方法可以从中获取最新的 Git 提交的哈希值吗?如果您进入 Visual Studio GUI 并查看源代码管理部分,您可以看到哈希值。

是否有一些与 Visual Studio 2015 或更高版本捆绑在一起的命令行工具可以返回当前 Git 提交的哈希值?

Mic*_*ker 5

您不依赖的要求git.exe使事情变得复杂。但是,如果您想使用 Visual Studio 使用的库 LibGit2Sharp 并与 Visual Studio 集成,您可以做一些像这样的疯狂的事情。

将新目标添加到您的项目文件中。我假设您使用的是 C#,因此将其添加到您的 csproj 中

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

  <PropertyGroup>
    <CodeFile>$(MSBuildProjectDirectory)\HelloGit.cs</CodeFile>
    <CodeFileText>$([System.IO.File]::ReadAllText("$(CodeFile)"))</CodeFileText>
    <CodeFileText>$([MSBuild]::Unescape("$(CodeFileText)"))</CodeFileText>
  </PropertyGroup>

  <UsingTask TaskName="HelloGit" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
    <ParameterGroup>
      <Sha1 ParameterType="System.String" Required="False" Output="True" />
      <Repository ParameterType="System.String" Required="True" Output="False" />
    </ParameterGroup>
    <Task>
      <Reference Include="System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
      <Reference Include="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\LibGit2Sharp.dll" />
      <Using Namespace="System" />
      <Using Namespace="System.IO" />
      <Code Type="Class" Language="cs">
        $(CodeFileText)
      </Code>
    </Task>
  </UsingTask>

  <Target Name="RunTask" AfterTargets="BeforeBuild">

    <HelloGit Repository="$(MSBuildProjectDirectory)">
      <Output TaskParameter="Sha1" PropertyName="CommitId" />
    </HelloGit>
    <Warning Text="Your commit is: $(CommitId)" />

  </Target>
Run Code Online (Sandbox Code Playgroud)

其作用是在当前项目目录中查找“HelloGit.cs”。其内容看起来像这样......

您可以使用内联代码任务(例如在 XML 中嵌入 C#)来完成此操作,但由于该任务相当长,我想在 VS Code 中将其作为单独的文件进行编辑。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using LibGit2Sharp;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;


namespace GitIntrospection {
    public class HelloGit : Task {
        public override bool Execute() {
            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
                if (args.Name.Contains("LibGit2Sharp")) {
                    return Assembly.LoadFrom("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer\\LibGit2Sharp.dll");
                }
                return null;
            };

            GetCommit();

            return !Log.HasLoggedErrors;
        }

        // [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
        private void GetCommit() {
            Repository repository = new Repository(Repository);

            this.Sha1 = repository.Commits.First().Id.Sha;
        }

        [Output]
        public string Sha1 { get; set; }

        [Required]
        public string Repository { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,当您构建项目时,最新的提交将被提取并记录为警告。这在 Visual Studio 和 MS Build 中都有效。

在命令行上工作 在命令行上工作

在 Visual Studio 中工作 在 Visual Studio 中工作

结果甚至似乎同意git.exe......这很方便 结果甚至似乎与 git.exe 一致......这很方便

替代方案 1 您可以只使用git.exe一个<Exec>任务!

替代方案 2 您可以使用 PowerShell 加载 LibGit2Sharp 程序集并调用相同的方法。