【问题标题】:Is there a C# commandline command one-liner which can help me get the GIT commit hash of an application?是否有一个 C# 命令行命令单线可以帮助我获取应用程序的 GIT 提交哈希?
【发布时间】:2021-12-14 16:00:52
【问题描述】:

这个问题是this other one的后续问题。

在那个问题中,有人提到[assembly: AssemblyVersion(...)]文件AssemblyInfo.cs文件的用法,同时我发现在这样一行之前禁止执行任何处理,唯一允许的事情是这样的:

[assembly: AssemblyVersion("1.0.0.0" + "-" + Namespace.Class.Attribute)], or:
[assembly: AssemblyVersion("1.0.0.0" + "-" + Namespace.Class.Method())]

原问题:
所以我的问题是:是否有 Namespace.Class.AttributeNamespace.Class.Method() 包含 C# 应用程序的提交哈希(或 sha 或缩短的 sha)?

经过更多调查后修改
与此同时,我了解到命令 git describe --always 为我提供了我正在寻找的信息,所以我需要的是:

[assembly: AssemblyVersion("1.0.0.0-" + Launch("git describe --always")]

...但是我该如何执行Launch()

我已经知道我可以使用System.Diagnostics.Process() 启动命令行命令,就像这个例子:

System.Diagnostics.Process.Start(foldervar + "application.exe", "inputfile.txt");

...但是这种方式不会捕获该命令的结果。

新问题:
那么,有人知道用于启动命令行命令并获取结果的 C# 单行代码吗?

提前致谢

【问题讨论】:

  • 为什么要求关闭这个问题?
  • 阅读 GitVersion 的文档。它应该可以解决您的问题。
  • .NET 中没有为此内置任何内容。通常是构建系统处理将此类内容注入代码中。
  • 您根本无法编写所显示的代码。这些属性的参数必须是常量。如果你连接常量,你可以在某个地方使用一个常量成员来添加一些东西,但是你不能调用一个方法,因此你不能启动 git。这必须在 C# 编译器之外作为前置步骤完成,然后将使用 C# 语法中的 requires 程序集属性合成一个文件,并包含在构建中。
  • 想一想,您可以将Build Events 用于解决方案中的项目。看看这里:docs.microsoft.com/en-us/visualstudio/ide/…。在那里你可以调用一个运行 git 并将完整版本号存储在文本文件中的 bat 文件。然后作为另一个预构建步骤,您可以使用新内容重新创建版本文件。检查此问题以获取版本文件创建示例:stackoverflow.com/questions/26021684/….

标签: c# .net git command-line versioning


【解决方案1】:

正如 Lasse V. Karslen 已经评论的那样,您的代码将触发编译器错误CS0182。下一个问题是 AssemblyVersion 所需的格式 - major[.minor[.build[.revision]]],还有其他可用于字符串的程序集元数据字段 - 例如InformationalVersion.

在构建时添加程序集元数据的方法不止一种……可能不止这五种:

  • 程序集属性
  • dotnet-cli 参数
  • msbuild 参数
  • csproj 配置条目
  • 构建事件/脚本也是实现目标的一种方式,但比较麻烦。

使用程序集属性

程序集属性的问题是它需要是常量表达式。这不是直接实现的,但Gitinfo 设法提供了一个解决方案。另一个缺点是需要禁用编译器来生成 AssemblyInfo.cs,这会破坏将 csproj 中配置的some values 写入最终程序集。

安装 gitinfo

PM> Install-Package GitInfo

在您的csproj 文件中设置

<GenerateAssemblyInfo>false</GenerateAssemblyInfo>

添加/创建AssemblyInfo.cs

[assembly: AssemblyInformationalVersion(ThisAssembly.Git.Commit)]

使用 dotnet-cli(使用 powershell)

这很简单。

$GitHash=git describe --always
dotnet build -p:InformationalVersion=$GitHash

使用修改后的 csproj

修改csproj文件是ci中常用的方法。

将“InformationVersion”添加到您的 csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <InformationalVersion>$(GitHash)</InformationalVersion>
  </PropertyGroup>
</Project>

在构建到“git describe --always”的输出之前设置环境变量“GitHash”:

$env:GitHash=git describe --always
dotnet build

例如GithubactionsHellowWord 是一个项目示例,它使用环境变量中内置的 github 操作将 sha1 哈希写入 assembly metadata

资源管理器将在“产品版本”字段中显示 informationalVersion 的值。

【讨论】:

    【解决方案2】:

    您现在可以使用 MsBuild 属性来设置版本(以及其他属性),而不是使用 AssemblyVersionAttribute。使用 MsBuild 的优势在于,您可以在构建过程中计算这些值。

    这适用于any "new style"/"SDK style" project

    查看:Assembly attribute properties

    你最终会得到一些类似的东西:

    ConsoleApp5.csproj:
    
    <Project Sdk="Microsoft.NET.Sdk">
    
        <PropertyGroup>
            <OutputType>Exe</OutputType>
            <TargetFramework>net6.0</TargetFramework>
            <ImplicitUsings>enable</ImplicitUsings>
            <Nullable>enable</Nullable>
        </PropertyGroup>
    
        <!-- Add the property group and the target below to your project file -->
        <PropertyGroup>
            <GenerateAssemblyVersionAttribute>true</GenerateAssemblyVersionAttribute>
            <GenerateAssemblyFileVersionAttribute>true</GenerateAssemblyFileVersionAttribute>
            <GenerateAssemblyInformationalVersionAttribute>true</GenerateAssemblyInformationalVersionAttribute>
        </PropertyGroup>
    
        <Target Name="AddGitShaToAssemblyVersions" BeforeTargets="GetAssemblyVersion" Returns="AssemblyVersion, FileVersion, InformationalVersion">
            <Exec ConsoleToMsBuild="true" Command="git describe --always">
                <Output TaskParameter="ConsoleOutput" PropertyName="GitSha" />
            </Exec>
    
            <PropertyGroup>
                <AssemblyVersion>1.1.1.1</AssemblyVersion>
                <FileVersion>1.1.1.1-$(GitSha)</FileVersion>
                <InformationalVersion>1.1.1.1-$(GitSha)</InformationalVersion>
            </PropertyGroup>
        </Target>
    
        <!-- Ignore the warning generated for the AssemblyFileVersion -->
        <PropertyGroup>
          <NoWarn>$(NoWarn);7035</NoWarn>
        </PropertyGroup>
    </Project>
    

    obj 文件夹中生成一个文件,它会自动包含在构建中。您可以在编辑器中打开此文件以查看生成的内容:

    生成的内容:

    //------------------------------------------------------------------------------
    // <auto-generated>
    //     This code was generated by a tool.
    //     Runtime Version:4.0.30319.42000
    //
    //     Changes to this file may cause incorrect behavior and will be lost if
    //     the code is regenerated.
    // </auto-generated>
    //------------------------------------------------------------------------------
    
    using System;
    using System.Reflection;
    
    [assembly: System.Reflection.AssemblyCompanyAttribute("ConsoleApp5")]
    [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
    [assembly: System.Reflection.AssemblyFileVersionAttribute("1.1.1.1-3654148")]
    [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.1.1.1-3654148")]
    [assembly: System.Reflection.AssemblyProductAttribute("ConsoleApp5")]
    [assembly: System.Reflection.AssemblyTitleAttribute("ConsoleApp5")]
    [assembly: System.Reflection.AssemblyVersionAttribute("1.1.1.1")]
    
    // Generated by the MSBuild WriteCodeFragment class.
    

    对我而言,优点是所有逻辑都很好地封装在构建文件本身中,并且不依赖于我必须在构建之前运行任何命令或将构建逻辑放入另一个脚本中,例如 powershell 脚本、脚本Visual Studio 不知道的。

    请确保从项目中删除现有的、手动添加的 AssemblyVersion 等属性,否则最终会收到警告,该属性被指定了两次。

    【讨论】:

      【解决方案3】:

      不是单行本,但这篇文章https://galdin.dev/blog/show-git-commit-sha-in-net-applications/ 展示了一种执行命令并访问结果的简单方法。本文介绍的步骤如下,

      为此,我们创建了一个预构建事件,该事件将执行一个 git 命令并将其保存在一个文本文件中。 然后,我们将生成的文本文件添加为字符串资源。 现在可以从 C# 访问资源。

      1. 右键单击 Web 应用程序并单击属性。

      2. 转到构建事件选项卡并在预构建事件命令行中键入以下内容:

        git rev-parse HEAD --short > "$(ProjectDir)\CurrentCommit.txt"
        

        该命令显然可以替换为您认为合适的任何内容。

      3. 保存并构建项目。 (Ctrl+Shift+S, Ctrl+Shift+B)

      4. 应该在项目的根目录中创建一个名为 CurrentCommit.txt 的新文件。

      5. 继续并将其从源代码管理中排除

      6. 在项目属性页面中,转到资源选项卡并添加现有文件CurrentCommit.txt 作为资源。

      生成文件的内容现在可以通过以下方式访问:

      Your.NameSpace.Properties.Resources.CurrentCommit;
      

      【讨论】:

        猜你喜欢
        • 2013-03-18
        • 1970-01-01
        • 2020-12-08
        • 1970-01-01
        • 2016-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多