简体   繁体   English

是否有一个 C# 命令行命令可以帮助我获得应用程序的 GIT 提交 hash?

[英]Is there a C# commandline command one-liner which can help me get the GIT commit hash of an application?

This question is a follow-up of this other one .这个问题是另一个问题的后续问题。

In that question, one mentions the usage of [assembly: AssemblyVersion(...)] to the file AssemblyInfo.cs file, and in the meanwhile I've found out that it's forbidden to execute any processing before such a line, the only thing which is allowed is something like:在那个问题中,有人提到文件AssemblyInfo.cs文件中的[assembly: AssemblyVersion(...)]的用法,同时我发现禁止在这样一行之前执行任何处理,唯一的允许的事情是这样的:

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

Original question:原始问题:
So my question: is there a Namespace.Class.Attribute or Namespace.Class.Method() which contains the commit hash (or sha or shortened sha) of a C# application? So my question: is there a Namespace.Class.Attribute or Namespace.Class.Method() which contains the commit hash (or sha or shortened sha) of a C# application?

Edit after more investigation更多调查后编辑
In the meantime I've learnt that the command git describe --always gives me the information I'm looking for, so what I need is something like:与此同时,我了解到命令git describe --always为我提供了我正在寻找的信息,所以我需要的是这样的:

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

... but how can I execute that Launch() ? ...但是我该如何执行Launch()

I already know that I can launch a commandline command using System.Diagnostics.Process() , like this example:我已经知道我可以使用System.Diagnostics.Process()启动命令行命令,如下例所示:

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

... but this way does not catch the result of that command. ...但是这种方式不会捕获该命令的结果。

New question:新问题:
So, does anybody know a C# one-liner for launching commandline commands and getting their result?那么,有人知道用于启动命令行命令并获得结果的 C# 单行代码吗?

Thanks in advance提前致谢

Instead of using the AssemblyVersionAttribute , you can now use MsBuild properties to set the version (among other attributes).您现在可以使用 MsBuild 属性来设置版本(以及其他属性),而不是使用AssemblyVersionAttribute The advantage of using MsBuild, is that you can calculate these values as part of the build process.使用 MsBuild 的优势在于您可以在构建过程中计算这些值。

This will work for any "new style"/"SDK style" project .这适用于任何“新风格”/“SDK 风格”项目

Check out: Assembly attribute properties .签出: 程序集属性属性

You'll end up with something along these lines:你最终会得到一些类似的东西:

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>

A file is generated in the obj folder and it's automatically included in the build.obj文件夹中生成一个文件,它会自动包含在构建中。 You can open this file in your editor to look at the generated content:您可以在编辑器中打开此文件以查看生成的内容:

在此处输入图像描述

Generated content:生成的内容:

//------------------------------------------------------------------------------
// <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.

To me the advantage is that all of the logic is nicely encapsulated in the build files themselves and won't depend on my having to run any commands prior to build or putting build logic into another script, like a powershell script, scripts that Visual Studio isn't aware of.对我来说,优点是所有逻辑都很好地封装在构建文件本身中,并且不依赖于我必须在构建之前运行任何命令或将构建逻辑放入另一个脚本,如 powershell 脚本,Visual Studio 的脚本不知道。

Do make sure you remove your existing, manually added, AssemblyVersion etc attributes from your project, or you'll end up with a warning the attribute was specified twice.请确保从项目中删除现有的、手动添加的、 AssemblyVersion等属性,否则最终会收到警告,该属性被指定了两次。

As Lasse V. Karslen already commented, your code will trigger a compiler error CS0182 .正如 Lasse V. Karslen 已经评论的那样,您的代码将触发编译器错误CS0182 Next problem is the required format for AssemblyVersion - major[.minor[.build[.revision]]], there are other assembly metadata fields that can be used for strings - eg InformationalVersion .下一个问题是 AssemblyVersion 所需的格式 - major[.minor[.build[.revision]]],还有其他可用于字符串的程序集元数据字段 - 例如InformationalVersion

There is more than one way to add assembly meta data while building... there are probably more then these five:在构建时添加程序集元数据的方法不止一种……可能不止这五种:

  • assembly attribute程序集属性
  • dotnet-cli parameter dotnet-cli 参数
  • msbuild parameter msbuild参数
  • csproj config entry csproj 配置条目
  • Build Events / Scripting is also a way to reach your goal, but is more fiddeling.构建事件/脚本也是实现目标的一种方式,但更麻烦。

The problem with the assembly attribute is that it need to be constant expression... not realy that what you asked for.程序集属性的问题在于它需要是常量表达式......不是你所要求的。

I tested to change InformationalVersion using the dotnet-cli and by modifieing the csproj file.我测试了使用 dotnet-cli 并通过修改 csproj 文件来更改 InformationalVersion。

Using dotnet-cli (using powershell)使用 dotnet-cli(使用 powershell)

Thats straight forward.那是直截了当的。

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

Modified csproj修改后的csproj

Modified csproj files are a common approach used in ci.修改后的 csproj 文件是 ci 中常用的方法。

Add 'InformationVersion' to your csproj:将“InformationVersion”添加到您的 csproj:

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

Set the enviroment variable 'GitHash' before building to the output of 'git describe --always':在构建到“git describe --always”的 output 之前设置环境变量“GitHash”:

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

Eg GithubactionsHellowWord is a project example that uses github actions built in environment variable to write sha1 hash to the assembly metadata .例如GithubactionsHellowWord是一个项目示例,它使用 github 内置在环境变量中的操作将 sha1 hash 写入程序集元数据

The explorer will show the value of informationalVersion in the field 'Product Version'.资源管理器将在“产品版本”字段中显示 informationalVersion 的值。

装配体属性

Not a one liner, but this article https://galdin.dev/blog/show-git-commit-sha-in-net-applications/ shows a simple way to execute the command and access the result.不是一个班轮,但这篇文章https://galdin.dev/blog/show-git-commit-sha-in-net-applications/展示了一种执行命令和访问结果的简单方法。 The steps described in this article are as follows,本文描述的步骤如下,

To do this we create a pre-build event that'll execute a git command and save it in a text file. 
We then add that generated text file as a string resource.
The resource can will now be accessible from C#.

1. Right click on the web application and click on properties.
2. Go to the build events tab and type the following in the Pre-build event command line:
git rev-parse HEAD --short > "$(ProjectDir)\CurrentCommit.txt"
The command can obviously be replaced by anything you see fit.
3. Save and build the project. (Ctrl+Shift+S, Ctrl+Shift+B)
4. A new file called CurrentCommit.txt should be created in the root of your project.
5. Go ahead and exclude it from Source Control
6. In the projects properties page, go to the Resources tab and Add Existing File CurrentCommit.txt as a resource.

The contents of the generated file can now be accessed as:
Your.NameSpace.Properties.Resources.CurrentCommit;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM