Sematkan git commit hash di dll .Net

102

Saya sedang membangun aplikasi C #, menggunakan Git sebagai kontrol versi saya.

Adakah cara untuk secara otomatis menyematkan hash komit terakhir di eksekusi saat saya membangun aplikasi saya?

Misalnya, mencetak hash komit ke konsol akan terlihat seperti ini:

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

Perhatikan bahwa ini harus dilakukan pada waktu pembuatan , bukan runtime , karena file executable yang saya terapkan tidak akan memiliki repo git yang dapat diakses.

Pertanyaan terkait untuk C ++ dapat ditemukan di sini .

EDIT

Sesuai permintaan @ mattanja, saya memposting skrip git hook yang saya gunakan dalam proyek saya. Pengaturan:

  • Hooks adalah skrip shell linux, yang ditempatkan di bawah: path_to_project \ .git \ hooks
  • Jika Anda menggunakan msysgit , folder hooks sudah berisi beberapa contoh skrip. Untuk membuat git memanggil mereka, hapus ekstensi '.sample' dari nama skrip.
  • Nama-nama skrip hook cocok dengan acara yang memanggilnya. Dalam kasus saya, saya memodifikasi pasca-komit dan pasca-penggabungan .
  • File AssemblyInfo.cs saya langsung di bawah jalur proyek (level yang sama dengan folder .git ). Ini berisi 23 baris, dan saya menggunakan git untuk menghasilkan baris ke-24.

Karena linux-shelling saya sedikit berkarat, skrip hanya membaca 23-baris pertama dari AssemblyInfo.cs ke file sementara, menggemakan git hash ke baris terakhir, dan mengganti nama file kembali ke AssemblyInfo.cs . Saya yakin ada cara yang lebih baik untuk melakukan ini:

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

Semoga ini membantu.

bavaza
sumber

Jawaban:

63

Kami menggunakan tag di git untuk melacak versi.

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

Anda bisa mendapatkan versi dengan hash dari git melalui:

git describe --long

Proses build kami menempatkan git hash di atribut AssemblyInformationalVersion dari file AssemblyInfo.cs:

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

Setelah Anda mengkompilasi, Anda dapat melihat versinya dari windows explorer:

masukkan deskripsi gambar di sini

Anda juga bisa mendapatkannya secara terprogram melalui:

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

di mana YOURTYPE adalah Jenis apa pun di Assembly yang memiliki atribut AssemblyInformationalVersion.

Pengrajin
sumber
14
Hai, saya ingin bertanya sebulan yang lalu, tapi, saya tidak punya cukup perwakilan untuk berkomentar. Saat Anda berkata, "Proses build kami menempatkan git hash di atribut AssemblyInformationalVersion di AssemblyInfo.cs", apa sebenarnya yang terjadi di sana? Apakah Anda hanya melakukan pembuatan studio visual, atau, apakah Anda menggunakan sesuatu seperti NAnt atau alat lainnya?
John Jesus
3
Kami menggunakan ruby ​​(rake) untuk mengotomatiskan build kami. Salah satu tugas rake build kami memperbarui file CommonAssemblyInfo.cs yang digunakan di semua proyek dalam solusi tersebut. Tugas menghasilkan file CommonAssemblyInfo.cs menggunakan albacore - github.com/derickbailey/Albacore Salah satu nilai AssemblyInfo yang ditetapkan tugas adalah AssemblyInformationalVersion.
Pengrajin
3
@ John Jesus - seperti yang disarankan oleh Lazy Badger, Anda juga dapat menggunakan git hooks untuk mengubah AssemblyInfo.cs setelah komit / penggabungan dll (inilah yang akhirnya saya lakukan). Lihat kernel.org/pub/software/scm/git/docs/githooks.html
bavaza
Sekadar informasi, Albacore telah pindah ke organisasi hub baru: github.com/Albacore/albacore
kornman00
5
Proyek berikut https://github.com/jeromerg/NGitVersion menawarkan solusi lengkap untuk menghasilkan GlobalAssemblyInfo.*file pada waktu kompilasi untuk proyek C # dan C ++: Secara default, versi perakitan yang dihasilkan berisi: hash komit, bendera yang menandakan perubahan lokal, dan increment menghitung jumlah komit dari root repositori ke komit saat ini.
jeromerg
77

Anda dapat menyematkan file version.txt ke file yang dapat dieksekusi dan kemudian membaca version.txt dari file yang dapat dieksekusi. Untuk membuat file version.txt , gunakangit describe --long

Berikut langkah-langkahnya:

Gunakan Build Event untuk memanggil git

  • Klik kanan pada proyek dan pilih Properties

  • Dalam Build Events, tambahkan event Pre-Build yang berisi (perhatikan tanda kutipnya):

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

    Itu akan membuat file version.txt di direktori proyek Anda.

Sematkan version.txt di file yang dapat dieksekusi

  • Klik kanan pada proyek dan pilih Add Existing Item
  • Tambahkan file version.txt (ubah filter pemilih file agar Anda dapat melihat Semua File)
  • Setelah version.txt ditambahkan, klik kanan di Solution Explorer dan pilih Properties
  • Ubah Build Action menjadi Embedded Resource
  • Ubah Salin ke Direktori Output menjadi Salin Selalu
  • Tambahkan version.txt ke file .gitignore Anda

Baca string versi file teks yang disematkan

Berikut beberapa contoh kode untuk membaca string versi file teks yang disematkan:

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();
        }
    }
}
Yohanes Yesus
sumber
9
Pendekatan ini bekerja dengan cukup baik. Saya menggunakan "git rev-parse --short HEAD".
Brian Reiter
3
Ah bagus. Saya menggunakan "git gambarkan" karena sangat menarik (bagi saya) jika Anda memiliki tag; info versi memiliki tag ditambah jumlah komit setelah tag diterapkan; belum pernah melihat sesuatu seperti di SCM sebelumnya.
John Jesus
7
Saya menggunakan git describe --dirty, yang menambahkan tanda saat pengembang bekerja dengan pohon kerja yang kotor.
paulmelnikow
2
@ TamásSzelei proyek namespace adalah TryGitDescribe. Setelah file version.txt disematkan ke artefak yang dapat dieksekusi / perakitan, Anda perlu menambahkan namespace untuk mengeluarkannya.
John Jesus
2
Terima kasih untuk solusi lengkapnya. Dalam kasus saya, saya biasa GetEntryAssemblymendapatkan perakitan. Bagaimanapun, Anda dapat menelepon GetName().Nameuntuk menghindari hardcode nama.
astrowalker
52

MEMPERBARUI:

Banyak hal telah berkembang sejak saya pertama kali menjawab pertanyaan ini. The Microsoft.NET.Sdk(artinya Anda harus menggunakan project gaya sdk) sekarang menyertakan dukungan untuk menambahkan hash commit ke versi informasi assembly serta ke metadata paket nuget, jika beberapa kondisi terpenuhi:

  1. The <SourceRevisionId>properti harus didefinisikan. Ini dapat dilakukan dengan menambahkan target seperti ini:
<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>

Target ini mengeksekusi perintah yang akan SourceRevisionIddisingkat menjadi hash yang disingkat (8 karakter). SebelumTarget menyebabkan ini dijalankan sebelum versi informasi rakitan dibuat.

  1. Untuk menyertakan hash dalam metadata paket nuget, <RepositoryUrl>harus juga ditentukan.

  2. <SourceControlInformationFeatureSupported>properti harus true, ini menyebabkan tugas paket nuget untuk mengambil SourceRevisionId juga.

Saya akan menjauhkan orang dari penggunaan paket MSBuildGitHash, karena teknik baru ini lebih bersih dan paling konsisten.

ASLI:

Saya telah membuat paket nuget sederhana yang dapat Anda sertakan dalam proyek Anda yang akan menangani ini untuk Anda: https://www.nuget.org/packages/MSBuildGitHash/

Paket nuget ini mengimplementasikan solusi MSBuild "murni". Jika Anda lebih suka tidak bergantung pada paket nuget Anda cukup menyalin Target ini ke dalam file csproj Anda dan itu harus menyertakan git hash sebagai atribut perakitan khusus:

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

Ada dua target di sini. Yang pertama, "GetGitHash", memuat git hash ke dalam properti MSBuild bernama BuildHash, ini hanya melakukan ini jika BuildHash belum ditentukan. Ini memungkinkan Anda untuk meneruskannya ke MSBuild pada baris perintah, jika Anda mau. Anda bisa meneruskannya ke MSBuild seperti ini:

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

Target kedua, "WriteGitHash", akan menulis nilai hash ke sebuah file di folder "obj" sementara bernama "CustomAssemblyInfo.cs". File ini akan berisi baris yang terlihat seperti:

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

File CustomAssemblyInfo.cs ini akan dikompilasi ke dalam assembly Anda, sehingga Anda dapat menggunakan refleksi untuk mencari AssemblyMetadatasaat runtime. Kode berikut menunjukkan bagaimana hal ini dapat dilakukan ketika AssemblyInfokelas disertakan dalam rakitan yang sama.

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

Beberapa manfaat desain ini adalah tidak menyentuh file apa pun di folder proyek Anda, semua file yang dimutasi berada di bawah folder "obj". Proyek Anda juga akan dibangun secara identik dari dalam Visual Studio atau dari baris perintah. Ini juga dapat dengan mudah disesuaikan untuk proyek Anda, dan akan dikontrol sumbernya bersama dengan file csproj Anda.

MarkPflug
sumber
2
Ini bekerja dengan sempurna. Saya menginstal paket nuget dan dapat mencabut git hash menggunakan Assembly.GetExecutingAssembly(), lalu memeriksa perakitannya CustomAttributes .
Gavin H
1
Jika ini pertanyaan saya, saya akan menerima jawaban ini. Barang bagus.
Drew Noakes
1
@GavinH, Bagaimana Anda mendapatkan GitHash? Saya dapat melihat nilai itu ada tetapi apakah ada metode murni untuk mendapatkan atribut khusus berdasarkan nama? Sepertinya saya harus menulis kueri pemilihan mana yang panjang CustomAttributes, terima kasih.
Okan Kocyigit
1
@ocanal ya - sayangnya saya tidak dapat menemukan cara yang lebih bersih untuk melakukannya selain membaca CustomAttributes. Misalnya, berikut adalah fungsi yang saya gunakan untuk mengekstrak string hash: pastebin.com/nVKGLhJC
Gavin H
2
@danmiser Saya tidak tahu apa itu "UseMerge / SingleAssemblyName", jadi saya tidak dapat membantu Anda. Buat masalah di github.com/MarkPflug/MSBuildGitHash dan saya mungkin akan memeriksanya (itu bukan janji).
MarkPflug
14

Cara lain untuk melakukannya adalah dengan menggunakan NetRevisionTool dengan beberapa keajaiban Visual Studio On-Board. Saya akan menampilkan ini di sini untuk Visual Studio 2013 Professional Edition, tetapi ini juga akan berfungsi dengan versi lain.

Jadi, unduh NetRevisionTool terlebih dahulu. Anda menyertakan NetRevisionTool.exe di PATH Anda atau memeriksanya ke dalam repositori Anda dan membuat studio visual pra-bangun dan tindakan pasca-pembangunan dan mengubah AssemblyInfo.cs Anda.

Contoh yang akan menambahkan git-hash Anda ke AssemblyInformationVersion adalah sebagai berikut: Dalam pengaturan proyek Anda:

masukkan deskripsi gambar di sini

di AssemblyInfo.cs proyek Anda, Anda mengubah / menambahkan baris:

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

di tangkapan layar yang ditampilkan saya memeriksa NetRevisionTool.exe di folder Eksternal / bin

Setelah membangun, jika Anda kemudian mengklik kanan biner Anda dan membuka properti, maka Anda akan melihat sesuatu seperti berikut:

masukkan deskripsi gambar di sini

Semoga ini bisa membantu seseorang di luar sana

schmendrick
sumber
Hash commit untuk saya selalu berakhir sebagai 00000. Saya pikir itu karena saya memiliki perubahan yang belum dilakukan tetapi masih sama. Tahu kenapa?
Viktor
3
Masalahnya adalah NetRevision tidak menemukan git saya dapat dieksekusi. Alasannya adalah karena kami menggunakan SourceTree dan git disertakan dengannya. Solusinya adalah menyalin git.exe dan libiconv-2.dll dari% USERPROFILE% \ AppData \ Local \ Atlassian \ SourceTree \ git_local \ bin ke folder yang berisi NetRevision.exe. Saya juga harus memodifikasi acara seperti ini: Acara pra-pembuatan: cd $ (ProjectDir) Perpustakaan NetRevisionTool.exe / patch $ (ProjectDir) Acara pasca-pembuatan: cd $ (ProjectDir) Perpustakaan NetRevisionTool.exe / restore $ (ProjectDir)
Viktor
Hanya untuk referensi di masa mendatang, URL repo proyek telah berubah beberapa waktu lalu menjadi github.com/ygoe/NetRevisionTool . Info selengkapnya juga tersedia di unclassified.software/apps/netrevisiontool .
ygoe
14

Saya pikir pertanyaan ini layak diberikan jawaban lengkap langkah demi langkah. Strategi di sini adalah menjalankan skrip PowerShell dari peristiwa pra-build yang mengambil file template dan menghasilkan file AssemblyInfo.cs dengan menyertakan informasi git tag + commit count.

Langkah 1: buat file AssemblyInfo_template.cs di folder Project \ Properties, berdasarkan AssemblyInfo.cs asli Anda tetapi berisi:

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

Langkah 2: Buat skrip PowerShell bernama InjectGitVersion.ps1 yang sumbernya adalah:

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

Langkah 3: Simpan file InjectGitVersion.ps1 ke direktori solusi Anda di folder BuildScripts

Langkah 4: Tambahkan baris berikut ke acara Pra-Bangun proyek

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

Langkah 5: Bangun proyek Anda.

Langkah 6: Secara opsional, tambahkan AssemblyInfo.cs ke file abaikan git Anda

Atilio Jobson
sumber
Dan ingatlah untuk membuat tag git Anda kompatibel dengan versi file: seperti 1.2.3. Jika Anda memiliki tag yang lebih rumit, Anda harus mengurai hanya bagian yang kompatibel
Atilio Jobson
2
Alih-alih menggunakan template dan gitignoring yang asli AssemblyInfo.csdapat memodifikasi AssemblyInfo.csdi tempat, build, lalu git reset AssemblyInfo.cske versi terakhir yang dikomit. Jadi dalam repo akan selalu ada AssemblyInfo.cs, dengan $..$diganti hanya untuk waktu build.
Kuba Wyrostek
Ini bekerja dengan baik. Saya akhirnya menggunakan git describe --match "v[0-9]*" --long --always --dirtyuntuk menyaring tag tertentu (yang berisi nomor versi) dan untuk menunjukkan, jika pohon kerja bersih.
packoman
Anda juga harus mengubah RegEx Anda dalam skrip PS:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman
4

Sekarang sangat mudah dengan .NET Revision Task untuk MSBuild dan bekerja dengan Visual Studio 2019.

Cukup instal paket NuGet Unclassified.NetRevisionTask , lalu konfigurasikan informasi yang Anda inginkan dalam AssemblyInfo.csfile seperti yang dijelaskan dalam dokumentasi GitHub .

Jika Anda hanya menginginkan hash dari komit terakhir (panjang = 8):

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

Bangun proyek / solusi Anda dan Anda akan mendapatkan sesuatu seperti ini:

masukkan deskripsi gambar di sini

krlzlx.dll
sumber
Untuk mengkonfigurasi format dalam aplikasi NET.core menambahkan PropertyGroupke .csproj file seperti terlihat di README github.com/ygoe/NetRevisionTask/blob/master/README.md
sc911
3

Karena jawaban lain sudah menyebutkan bit git, setelah Anda memiliki SHA, Anda dapat mempertimbangkan untuk membuat AssemblyInfo.csfile proyek Anda di hook pra-bangun.

Salah satu cara untuk melakukannya adalah dengan membuat AssemblyInfo.cs.tmplfile template, dengan placeholder untuk SHA Anda misalnya $$ GITSHA $$, mis.

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

Kemudian kait pra-build Anda harus mengganti placeholder ini dan mengeluarkan file AssemblyInfo.cs untuk diambil oleh compiler C #.

Untuk melihat bagaimana ini dapat dilakukan dengan menggunakan SubWCRev untuk SVN, lihat jawaban ini . Seharusnya tidak sulit melakukan hal serupa untuk git.

Cara lain akan menjadi "membuat panggung" seperti yang disebutkan, yaitu menulis tugas MSBuild yang melakukan sesuatu yang serupa. Namun cara lain mungkin untuk memposting proses DLL entah bagaimana (ildasm + ilasm katakan), tetapi saya pikir opsi yang disebutkan di atas mungkin paling mudah.

Marcus
sumber
@Wint no, jangan tambahkan AssemblyInfo.cs yang dihasilkan ke git. Jika Anda melakukannya, tidak mungkin untuk melakukan build yang tidak kotor: P
lelucon
3

Untuk metode pembayaran yang sepenuhnya otomatis dan fleksibel https://github.com/Fody/Stamp . Kami telah berhasil menggunakan ini untuk proyek Git kami (serta versi ini untuk proyek SVN)

Pembaruan: Ini sudah usang sejak Stamp.Fody tidak lagi dipertahankan

mamuesstack
sumber
1
di halaman github Stamp.Fody tertulis: "Proyek ini tidak lagi dipertahankan.". Termasuk dalam proyek saya mengangkat CA0052 dan CA0055
sc911
2

Anda dapat menggunakan satu-liner PowerShell untuk memperbarui semua file assemblyinfo dengan hash komit.

$hash = git describe --long --always;gci **/AssemblyInfo.* -recurse | foreach { $content = (gc $_) -replace "\[assembly: Guid?.*", "$&`n[assembly: AssemblyMetadata(`"commithash`", `"$hash`")]" | sc $_ }
roh85
sumber
1
  1. Saya harap Anda tahu cara memanggil program eksternal dan mencegat keluaran pada waktu pembuatan.
  2. Saya harap Anda tahu bagaimana caranya agar di direktori kerja git mengabaikan file tidak berversi.

Seperti dicatat oleh @ learath2, keluaran dari git rev-parse HEADakan memberi Anda hash biasa.

Jika Anda menggunakan tag di Git-repository (dan Anda menggunakan tag, bukankah itu lebih deskriptif dan mudah dibaca daripada git rev-parse), keluaran dapat diterima dari git describe(sementara juga berhasil digunakan nanti git checkout)

Anda dapat memanggil rev-parse | gambarkan dalam:

  • beberapa membuat panggung
  • di hook pasca-komit
  • di filter noda, jika Anda akan memilih cara penerapan filter noda / bersih
Malas Badger
sumber
0

Saya menggunakan kombinasi jawaban yang diterima dan sedikit tambahan. Saya telah menginstal ekstensi AutoT4 ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ) untuk menjalankan ulang template sebelum membangun.

mendapatkan versi dari GIT

saya sudah git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt" di acara pra-bangun saya di properti proyek. Menambahkan git_version.txt dan VersionInfo.cs ke .gitignore adalah ide yang cukup bagus.

menyematkan versi dalam metadata

Saya telah menambahkan VersionInfo.tttemplate ke proyek saya:

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

#>

Sekarang saya memiliki git tag + hash di "ProductVersion".

jelinek.01
sumber
0

Mengacu pada jawaban lain ( https://stackoverflow.com/a/44278482/4537127 ) saya juga menggunakan VersionInfo.tttemplate teks untuk menghasilkan AssemblyInformationalVersiontanpa AutoT4.

(Atleast berfungsi di aplikasi C # WPF saya)

Masalahnya adalah bahwa kejadian Pra-bangun dijalankan setelah transformasi template, jadi setelah kloning, git_version.txtfile tersebut tidak ada dan build gagal. Setelah membuatnya secara manual untuk memungkinkan transformasi lewat sekali, itu diperbarui setelah transformasi, dan selalu satu komit di belakang .

Saya harus membuat dua penyesuaian pada file .csproj (ini berlaku setidaknya untuk Visual Studio Community 2017)

1) Impor Target Transformasi Teks dan buat transformasi template untuk dijalankan di setiap build: (Ref 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>

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

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

2) Lakukan proses git describesebelum transformasi template (sehingga git_version.txtada saat VersionInfo.ttdiubah):

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

..Dan kode C # untuk mendapatkan 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;
    }
}

..Dan tambahkan file yang dihasilkan ke .gitignore

VersionInfo.cs
git_version.txt
kimmoli
sumber
0

Cara lain adalah menghasilkan file Version.cs dari langkah Pra-Pembuatan. Saya menjelajahi ini dalam proyek bukti konsep kecil yang mencetak hash komit saat ini.

Proyek ini diunggah di https://github.com/sashoalm/GitCommitHashPrinter .

Kode batch yang membuat file Version.cs adalah ini:

@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    
sashoalm
sumber
0

Tempat

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

di 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;
PeratX
sumber