Nhúng băm git commit trong dll .Net


102

Tôi đang xây dựng một ứng dụng C #, sử dụng Git làm điều khiển phiên bản của mình.

Có cách nào để tự động nhúng mã băm cam kết cuối cùng vào tệp thực thi khi tôi xây dựng ứng dụng của mình không?

Ví dụ: in mã băm cam kết ra bảng điều khiển sẽ trông giống như sau:

class PrintCommitHash
{
    private String lastCommitHash = ?? // What do I put here?
    static void Main(string[] args)
    {
        // Display the version number:
        System.Console.WriteLine(lastCommitHash );
    }
}

Lưu ý rằng điều này phải được thực hiện tại thời điểm xây dựng , không phải thời gian chạy , vì tệp thực thi đã triển khai của tôi sẽ không thể truy cập được git repo.

Một câu hỏi liên quan cho C ++ có thể được tìm thấy ở đây .

CHỈNH SỬA

Theo yêu cầu của @ mattanja, tôi đang đăng đoạn mã git hook mà tôi sử dụng trong các dự án của mình. Việc thiết lập:

  • Các hook là các tập lệnh shell linux, được đặt dưới: path_to_project \ .git \ hooks
  • Nếu bạn đang sử dụng msysgit , thư mục hooks đã chứa một số tập lệnh mẫu. Để gọi git cho chúng, hãy xóa phần mở rộng '.sample' khỏi tên tập lệnh.
  • Tên của các tập lệnh hook khớp với sự kiện gọi chúng. Trong trường hợp của tôi, tôi đã sửa đổi sau cam kếtsau hợp nhất .
  • Tệp AssemblyInfo.cs của tôi nằm ngay dưới đường dẫn dự án (cùng cấp với thư mục .git ). Nó chứa 23 dòng và tôi sử dụng git để tạo dòng thứ 24.

Vì việc bắn linux của tôi hơi bị gỉ, tập lệnh chỉ đọc 23 dòng đầu tiên của AssemblyInfo.cs vào một tệp tạm thời, lặp lại hàm băm git đến dòng cuối cùng và đổi tên tệp trở lại AssemblyInfo.cs . Tôi chắc rằng có nhiều cách tốt hơn để làm điều này:

#!/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

Hi vọng điêu nay co ich.

Câu trả lời:


63

Chúng tôi sử dụng các thẻ trong git để theo dõi các phiên bản.

git tag -a v13.3.1 -m "version 13.3.1"

Bạn có thể tải phiên bản có hàm băm từ git qua:

git describe --long

Quy trình xây dựng của chúng tôi đặt băm git vào thuộc tính AssemblyInformationalVersion của tệp AssemblyInfo.cs:

[assembly: AssemblyInformationalVersion("13.3.1.74-g5224f3b")]

Sau khi biên dịch, bạn có thể xem phiên bản từ windows explorer:

nhập mô tả hình ảnh ở đây

Bạn cũng có thể lấy nó theo chương trình thông qua:

var build = ((AssemblyInformationalVersionAttribute)Assembly
  .GetAssembly(typeof(YOURTYPE))
  .GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false)[0])
  .InformationalVersion;

trong đó YOURTYPE là bất kỳ Loại nào trong Assembly có thuộc tính AssemblyInformationalVersion.


14
Xin chào, tôi muốn hỏi một tháng trước, nhưng tôi không có đủ đại diện để nhận xét. Khi bạn nói, "Quy trình xây dựng của chúng tôi đặt băm git vào thuộc tính AssemblyInformationalVersion của AssemblyInfo.cs", chính xác thì điều gì đang xảy ra ở đó? Bạn chỉ đang xây dựng một studio trực quan, hay bạn đang sử dụng một thứ như NAnt hoặc một số công cụ khác?
John Jesus,

3
Chúng tôi sử dụng ruby ​​(rake) để tự động hóa bản dựng của mình. Một trong những nhiệm vụ xây dựng rake của chúng tôi cập nhật tệp CommonAssemblyInfo.cs được sử dụng trên tất cả các dự án trong giải pháp. Tác vụ tạo tệp CommonAssemblyInfo.cs bằng cách sử dụng albacore - github.com/derickbailey/Albacore Một trong những giá trị AssemblyInfo mà tác vụ đặt là AssemblyInformationalVersion.
Thợ thủ công

3
@John Jesus - như Lazy Badger đã đề xuất, bạn cũng có thể sử dụng git hook để thay đổi AssemblyInfo.cs sau khi commit / merge, v.v. (đây là những gì tôi đã làm). Xem kernel.org/pub/software/scm/git/docs/githooks.html
bavaza

Chỉ là FYI, Albacore đã chuyển sang một tổ chức trung tâm mới: github.com/Albacore/albacore
kornman00

5
Dự án sau https://github.com/jeromerg/NGitVersion cung cấp giải pháp hoàn chỉnh để tạo GlobalAssemblyInfo.*tệp tại thời điểm biên dịch cho các dự án C # và C ++: Theo mặc định, phiên bản hợp ngữ được tạo chứa: băm cam kết, cờ báo hiệu các thay đổi cục bộ và tăng đếm số lượng cam kết từ gốc kho lưu trữ đến cam kết hiện tại.
jeromerg

77

Bạn có thể nhúng tệp version.txt vào tệp thực thi và sau đó đọc phiên bản.txt ra khỏi tệp thực thi. Để tạo tệp version.txt , hãy sử dụnggit describe --long

Đây là các bước:

Sử dụng Sự kiện xây dựng để gọi git

  • Nhấp chuột phải vào dự án và chọn Thuộc tính

  • Trong Sự kiện xây dựng, hãy thêm sự kiện Xây dựng trước có chứa (chú ý các dấu ngoặc kép):

    "C: \ Program Files \ Git \ bin \ git.exe" description --long> "$ (ProjectDir) \ version.txt"

    Điều đó sẽ tạo tệp version.txt trong thư mục dự án của bạn.

Nhúng phiên bản.txt vào tệp thực thi

  • Nhấp chuột phải vào dự án và chọn Thêm mục hiện có
  • Thêm tệp version.txt (thay đổi bộ lọc trình chọn tệp để cho phép bạn xem Tất cả các tệp)
  • Sau version.txt được thêm vào, nhấp chuột phải vào nó trong Solution Explorer và chọn Properties
  • Thay đổi Hành động xây dựng thành Tài nguyên được nhúng
  • Thay đổi bản sao thành thư mục đầu ra để sao chép luôn
  • Thêm version.txt vào tệp .gitignore của bạn

Đọc chuỗi phiên bản tệp văn bản nhúng

Đây là một số mã mẫu để đọc chuỗi phiên bản tệp văn bản được nhúng:

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
Cách tiếp cận này hoạt động hợp lý. Tuy nhiên, tôi đã sử dụng "git rev-parse --short HEAD".
Brian Reiter,

3
À! Giỏi. Tôi đã sử dụng "git description" bởi vì nó thực sự thú vị (đối với tôi) khi bạn có một thẻ; thông tin phiên bản có thẻ cộng với số lần cam kết sau khi thẻ được áp dụng; chưa bao giờ thấy một cái gì đó giống như trong một SCM trước đây.
John Jesus

7
Tôi sử dụng git describe --dirty, thêm một cờ khi các nhà phát triển đang làm việc với một cây làm việc bẩn.
paulmelnikow

2
@ TamásSzelei không gian tên của dự án là TryGitDescribe. Sau khi tệp version.txt được nhúng vào cấu phần thực thi / lắp ráp, bạn cần thêm không gian tên để lấy nó ra.
John Jesus

2
Cảm ơn bạn cho giải pháp hoàn chỉnh. Trong trường hợp của tôi, tôi đã từng GetEntryAssemblynhận lắp ráp. Trong mọi trường hợp, bạn có thể gọi GetName().Nameđể tránh mã cứng tên.
astrowalker

51

CẬP NHẬT:

Mọi thứ đã phát triển kể từ khi tôi trả lời câu hỏi này ban đầu. Các Microsoft.NET.Sdk(có nghĩa là bạn phải sử dụng một dự án sdk-style) hiện nay bao gồm hỗ trợ cho việc thêm các cam kết băm để cả hai phiên bản lắp ráp cung cấp thông tin cũng như các siêu dữ liệu gói NuGet, nếu một số điều kiện được đáp ứng:

  1. Các <SourceRevisionId>bất động sản phải được xác định. Điều này có thể được thực hiện bằng cách thêm một mục tiêu như sau:
<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>

Mục tiêu này thực thi một lệnh sẽ được đặt thành SourceRevisionIdbăm (8 ký tự) viết tắt. Các BeforeTargets làm cho điều này được chạy trước khi phiên bản thông tin lắp ráp được tạo.

  1. Để bao gồm băm trong siêu dữ liệu gói nuget, <RepositoryUrl>cũng phải được xác định.

  2. <SourceControlInformationFeatureSupported>phải là thuộc tính true, điều này khiến nhiệm vụ gói nuget cũng nhận SourceRevisionId.

Tôi sẽ hướng mọi người tránh sử dụng gói MSBuildGitHash, vì kỹ thuật mới này rõ ràng hơn và nhất quán nhất.

NGUYÊN:

Tôi đã tạo một gói nuget đơn giản mà bạn có thể đưa vào dự án của mình, gói này sẽ giải quyết việc này cho bạn: https://www.nuget.org/packages/MSBuildGitHash/

Gói nuget này thực hiện một giải pháp MSBuild "thuần túy". Nếu bạn không muốn phụ thuộc vào gói nuget, bạn có thể chỉ cần sao chép các Mục tiêu này vào tệp csproj của mình và nó phải bao gồm băm git dưới dạng thuộc tính lắp ráp tùy chỉnh:

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

Có hai mục tiêu ở đây. Cái đầu tiên, "GetGitHash", tải git băm vào một thuộc tính MSBuild có tên BuildHash, nó chỉ thực hiện điều này nếu BuildHash chưa được định nghĩa. Điều này cho phép bạn chuyển nó đến MSBuild trên dòng lệnh, nếu bạn thích. Bạn có thể chuyển nó cho MSBuild như vậy:

MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL

Đích thứ hai, "WriteGitHash", sẽ ghi giá trị băm vào một tệp trong thư mục "obj" tạm thời có tên "CustomAssemblyInfo.cs". Tệp này sẽ chứa một dòng giống như sau:

[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]

Tệp CustomAssemblyInfo.cs này sẽ được biên dịch vào tập hợp của bạn, vì vậy bạn có thể sử dụng phản chiếu để tìm kiếm AssemblyMetadata thời gian chạy. Đoạn mã sau đây cho thấy cách này có thể được thực hiện khi AssemblyInfolớp được bao gồm trong cùng một assembly.

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;
    }
}

Một số lợi ích của thiết kế này là nó không chạm vào bất kỳ tệp nào trong thư mục dự án của bạn, tất cả các tệp bị đột biến đều nằm trong thư mục "obj". Dự án của bạn cũng sẽ xây dựng giống hệt nhau từ trong Visual Studio hoặc từ dòng lệnh. Nó cũng có thể được tùy chỉnh dễ dàng cho dự án của bạn và sẽ được kiểm soát nguồn cùng với tệp csproj của bạn.


2
Điều này đã hoạt động hoàn hảo. Tôi đã cài đặt gói nuget và có thể sử dụng git băm bằng cách sử dụng Assembly.GetExecutingAssembly(), sau đó kiểm tra lắp ráp CustomAttributes .
Gavin H

1
Nếu đây là câu hỏi của tôi, tôi đã chấp nhận câu trả lời này. Công cụ tuyệt vời.
Drew Noakes

1
@GavinH, Làm thế nào bạn có được GitHash? Tôi có thể thấy giá trị đó tồn tại nhưng có phương thức thuần túy nào để lấy thuộc tính tùy chỉnh theo tên không? Có vẻ như tôi phải viết truy vấn where-select dài CustomAttributes, cảm ơn.
Okan Kocyigit

1
@ocanal vâng - tiếc là tôi không thể tìm thấy cách nào rõ ràng hơn để làm điều đó ngoài việc đọc CustomAttributes. Ví dụ: đây là hàm tôi sử dụng để trích xuất chuỗi băm: pastebin.com/nVKGLhJC
Gavin H

2
@danmiser Tôi không biết "UseMerge / SingleAssemblyName" là gì, vì vậy tôi không thể giúp bạn. Tạo vấn đề tại github.com/MarkPflug/MSBuildGitHash và tôi có thể xem xét vấn đề đó (đó không phải là một lời hứa).
MarkPflug

14

Một cách khác để làm điều này là sử dụng NetRevisionTool với một số phép thuật Visual Studio On-Board. Tôi sẽ giới thiệu điều này ở đây cho Visual Studio 2013 Professional Edition, nhưng điều này cũng sẽ hoạt động với các phiên bản khác.

Vì vậy, trước tiên hãy tải xuống NetRevisionTool. Bạn bao gồm NetRevisionTool.exe trong PATH của mình hoặc kiểm tra nó vào kho lưu trữ của bạn và tạo một bản dựng trước studio trực quan và một hành động hậu bản và thay đổi AssemblyInfo.cs của bạn.

Một ví dụ sẽ thêm git-hash của bạn vào AssemblyInformationVersion sẽ như sau: Trong cài đặt dự án của bạn:

nhập mô tả hình ảnh ở đây

trong AssemblyInfo.cs của dự án, bạn thay đổi / thêm dòng:

[assembly: AssemblyInformationalVersion ("1.1. {dmin: 2015}. {chash: 6} {!} - {branch}")]

trong ảnh chụp màn hình hiển thị, tôi đã kiểm tra trong NetRevisionTool.exe trong thư mục Bên ngoài / bin

Sau khi xây dựng, nếu sau đó bạn nhấp chuột phải vào tệp nhị phân của mình và đi đến thuộc tính thì bạn sẽ thấy một cái gì đó như sau:

nhập mô tả hình ảnh ở đây

Hy vọng điều này sẽ giúp ai đó ngoài kia


Băm cam kết đối với tôi luôn kết thúc là 00000. Tôi nghĩ đó là do tôi đã có những thay đổi chưa cam kết nhưng vẫn như vậy. Bất kỳ ý tưởng tại sao?
Viktor

3
Vấn đề là NetRevision không tìm thấy tệp thực thi git của tôi. Lý do là vì chúng tôi đang sử dụng SourceTree và git đi kèm với nó. Giải pháp là sao chép git.exe và libiconv-2.dll từ% USERPROFILE% \ AppData \ Local \ Atlassian \ SourceTree \ git_local \ bin vào thư mục chứa NetRevision.exe. Tôi cũng phải sửa đổi các sự kiện như vậy: Sự kiện trước khi xây dựng: cd $ (ProjectDir) Thư viện NetRevisionTool.exe / bản vá $ (ProjectDir) Sự kiện sau xây dựng: cd $ (ProjectDir) Thư viện NetRevisionTool.exe / khôi phục $ (ProjectDir)
Viktor

Chỉ để tham khảo trong tương lai, URL repo của dự án đã thay đổi một thời gian trước thành github.com/ygoe/NetRevisionTool . Thông tin thêm cũng có sẵn trên unslassified.software/apps/netrevisiontool .
ygoe

14

Tôi nghĩ rằng câu hỏi này đáng để trả lời từng bước một. Chiến lược ở đây là chạy một tập lệnh powershell từ các sự kiện xây dựng trước có trong tệp mẫu và tạo tệp AssemblyInfo.cs có bao gồm thẻ git + thông tin số lượng cam kết.

Bước 1: Tạo tệp AssemblyInfo_template.cs trong thư mục Project \ Properties, dựa trên AssemblyInfo.cs ban đầu của bạn nhưng có chứa:

[assembly: AssemblyVersion("$FILEVERSION$")]
[assembly: AssemblyFileVersion("$FILEVERSION$")]
[assembly: AssemblyInformationalVersion("$INFOVERSION$")]

Bước 2: Tạo một tập lệnh powershell có tên InjectGitVersion.ps1 có nguồn là:

# 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;       
}

Bước 3: Lưu tệp InjectGitVersion.ps1 vào thư mục giải pháp của bạn trong thư mục BuildScripts

Bước 4: Thêm dòng sau vào các sự kiện Pre-Build của dự án

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

Bước 5: Xây dựng dự án của bạn.

Bước 6: Theo tùy chọn, thêm AssemblyInfo.cs vào tệp bỏ qua git của bạn


Và hãy nhớ làm cho các thẻ git của bạn tương thích với các phiên bản tệp: chẳng hạn như 1.2.3. Nếu bạn có thẻ phức tạp hơn, bạn sẽ phải phân tích ra chỉ là phần tương thích
Atilio Jobson

2
Thay vì sử dụng một mẫu và gitignoring thực, AssemblyInfo.csngười ta có thể sửa đổi AssemblyInfo.cstại chỗ, xây dựng, sau đó đặt lại git AssemblyInfo.csvề phiên bản được cam kết cuối cùng. Vì vậy, trong repo sẽ luôn có AssemblyInfo.cs, $..$chỉ được thay thế cho thời điểm xây dựng.
Kuba Wyrostek

Điều này làm việc tuyệt vời. Tôi đã kết thúc bằng cách sử dụng git describe --match "v[0-9]*" --long --always --dirtyđể lọc các thẻ nhất định (những thẻ có chứa số phiên bản) và để cho biết, cây làm việc có sạch không.
packoman

Bạn cũng phải sửa đổi RegEx của mình trong tập lệnh PS:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman

4

Giờ đây, rất dễ dàng với .NET Revision Task cho MSBuild và làm việc với Visual Studio 2019.

Chỉ cần cài đặt gói NuGet Unclassified.NetRevisionTask , sau đó định cấu hình thông tin bạn muốn trong AssemblyInfo.cstệp như được mô tả trong tài liệu GitHub .

Nếu bạn chỉ muốn băm của lần cam kết cuối cùng (length = 8):

[assembly: AssemblyInformationalVersion("1.0-{chash:8}")]

Xây dựng dự án / giải pháp của bạn và bạn sẽ có một thứ như sau:

nhập mô tả hình ảnh ở đây


Để cấu hình định dạng trong một ứng dụng NET.core thêm PropertyGroupvào csproj tập tin giống như nhìn thấy trong README github.com/ygoe/NetRevisionTask/blob/master/README.md
sc911

3

Như câu trả lời khác đã đề cập đến bit git, khi bạn có SHA, bạn có thể cân nhắc tạo AssemblyInfo.cstệp dự án của mình trong một hook trước khi xây dựng.

Một cách để thực hiện việc này là tạo AssemblyInfo.cs.tmpltệp mẫu, có trình giữ chỗ cho SHA của bạn, chẳng hạn như $$ GITSHA $$, ví dụ:

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

Sau đó, móc tạo trước của bạn phải thay thế trình giữ chỗ này và xuất tệp AssemblyInfo.cs để trình biên dịch C # nhận.

Để xem cách này có thể được thực hiện bằng cách sử dụng SubWCRev cho SVN, hãy xem câu trả lời này . Không khó để làm điều gì đó tương tự cho git.

Các cách khác sẽ là "thực hiện giai đoạn" như đã đề cập, tức là viết một nhiệm vụ MSBuild thực hiện một cái gì đó tương tự. Tuy nhiên, một cách khác có thể là đăng quá trình DLL bằng cách nào đó (ildasm + ilasm nói), nhưng tôi nghĩ các tùy chọn được đề cập ở trên có lẽ là dễ dàng nhất.


@Wint no, không thêm AssemblyInfo.cs đã tạo vào git. Nếu bạn làm điều đó sẽ không thể nào làm một xây dựng phi bẩn: P
jokedst

3

Để có phương thức thanh toán hoàn toàn tự động và linh hoạt, hãy https://github.com/Fody/Stamp . Chúng tôi đã sử dụng thành công điều này cho các dự án Git của chúng tôi (cũng như phiên bản này cho các dự án SVN)

Cập nhật: Điều này đã lỗi thời vì Stamp.Fody không còn được duy trì


1
trên trang github của Stamp.Fody có nội dung: "Dự án này không còn được duy trì.". Bao gồm nó trong dự án của tôi đã nâng một CA0052 và CA0055
sc911

2

Bạn có thể sử dụng một lớp lót PowerShell để cập nhật tất cả các tệp assemblyinfo với mã băm cam kết.

$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }

1
  1. Tôi hy vọng bạn biết cách gọi các chương trình bên ngoài và chặn đầu ra tại thời điểm xây dựng.
  2. Tôi hy vọng bạn biết cách để trong thư mục làm việc của git bỏ qua các tệp không phiên bản.

Như đã lưu ý bởi @ learath2, đầu ra của git rev-parse HEADsẽ cung cấp cho bạn hàm băm đơn giản.

Nếu bạn sử dụng các thẻ trong Git-repository (và bạn sử dụng các thẻ, không phải nó mang tính mô tả và dễ đọc hơn git rev-parse), kết quả có thể nhận được từ git describe(đồng thời được sử dụng thành công sau này git checkout)

Bạn có thể gọi phân tích cú pháp lại | mô tả trong:

  • một số làm sân khấu
  • trong hook post-commit
  • trong bộ lọc nhòe, nếu bạn chọn cách triển khai bộ lọc nhòe / sạch

0

Tôi đang sử dụng sự kết hợp giữa câu trả lời được chấp nhận và một lời quảng cáo nhỏ. Tôi đã cài đặt tiện ích mở rộng AutoT4 ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ) để chạy lại các mẫu trước khi xây dựng.

nhận phiên bản từ GIT

Tôi có git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"trong sự kiện trước khi xây dựng của mình trong thuộc tính dự án. Thêm git_version.txt và VersionInfo.cs vào .gitignore là một ý tưởng khá hay.

nhúng phiên bản vào siêu dữ liệu

Tôi đã thêm một VersionInfo.ttmẫu vào dự án của mình:

<#@ 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"));
}

#>

Bây giờ tôi có thẻ git + băm của mình trong "ProductVersion".


0

Đề cập đến một câu trả lời khác ( https://stackoverflow.com/a/44278482/4537127 ), tôi cũng đã sử dụng VersionInfo.ttmẫu văn bản để tạoAssemblyInformationalVersion mà không có AutoT4.

(Ít nhất hoạt động trong ứng dụng C # WPF của tôi)

Vấn đề là các sự kiện Trước khi xây dựng được chạy sau khi chuyển đổi mẫu, vì vậy sau khi nhân bản, git_version.txttệp không có ở đó và quá trình xây dựng không thành công. Sau khi tạo nó theo cách thủ công để cho phép quá trình chuyển đổi diễn ra một lần, nó đã được cập nhật sau khi chuyển đổi và luôn ở sau một lần cam kết .

Tôi đã phải thực hiện hai điều chỉnh đối với tệp .csproj (điều này áp dụng ít nhất cho Visual Studio Community 2017)

1) Nhập Mục tiêu chuyển đổi văn bản và thực hiện chuyển đổi mẫu để chạy trên mọi bản dựng: (Tham khảo 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>

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

<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />

2) Thực hiện git describechạy trước khi chuyển đổi mẫu (để git_version.txtcó khi VersionInfo.ttđược chuyển đổi):

<Target Name="PreBuild" BeforeTargets="ExecuteTransformations">
  <Exec Command="git -C $(ProjectDir) describe --long --always --dirty &gt; $(ProjectDir)git_version.txt" />
</Target>

..Và mã C # để lấy AssemblyInformationalVersion(Tham khảo https://stackoverflow.com/a/7770189/4537127 )

public string AppGitHash
{
    get
    {
        AssemblyInformationalVersionAttribute attribute = (AssemblyInformationalVersionAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyInformationalVersionAttribute), false).FirstOrDefault();

        return attribute.InformationalVersion;
    }
}

..Và thêm các tệp đã tạo vào .gitignore

VersionInfo.cs
git_version.txt

0

Một cách khác là tạo tệp Version.cs từ bước Pre-Build. Tôi đã khám phá điều này trong một dự án bằng chứng về khái niệm nhỏ in ra mã băm cam kết hiện tại của nó.

Tha dự án được tải lên https://github.com/sashoalm/GitCommitHashPrinter .

Mã lô tạo tệp Version.cs là:

@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

Địa điểm

<Target Name="UpdateVersion" BeforeTargets="CoreCompile">
  <Exec Command="php &quot;$(SolutionDir)build.php&quot; $(SolutionDir) &quot;$(ProjectDir)Server.csproj&quot;" />
</Target>

trong 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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.