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.
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.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 , gunakan
git 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
Baca string versi file teks yang disematkan
Berikut beberapa contoh kode untuk membaca string versi file teks yang disematkan:
sumber
git describe --dirty
, yang menambahkan tanda saat pengembang bekerja dengan pohon kerja yang kotor.GetEntryAssembly
mendapatkan perakitan. Bagaimanapun, Anda dapat meneleponGetName().Name
untuk menghindari hardcode nama.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:<SourceRevisionId>
properti harus didefinisikan. Ini dapat dilakukan dengan menambahkan target seperti ini:Target ini mengeksekusi perintah yang akan
SourceRevisionId
disingkat menjadi hash yang disingkat (8 karakter). SebelumTarget menyebabkan ini dijalankan sebelum versi informasi rakitan dibuat.Untuk menyertakan hash dalam metadata paket nuget,
<RepositoryUrl>
harus juga ditentukan.<SourceControlInformationFeatureSupported>
properti harustrue
, 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:
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
AssemblyMetadata
saat runtime. Kode berikut menunjukkan bagaimana hal ini dapat dilakukan ketikaAssemblyInfo
kelas disertakan dalam rakitan yang sama.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.
sumber
Assembly.GetExecutingAssembly()
, lalu memeriksa perakitannyaCustomAttributes
.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 panjangCustomAttributes
, terima kasih.CustomAttributes
. Misalnya, berikut adalah fungsi yang saya gunakan untuk mengekstrak string hash: pastebin.com/nVKGLhJCCara 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:
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:
Semoga ini bisa membantu seseorang di luar sana
sumber
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:
Langkah 2: Buat skrip PowerShell bernama InjectGitVersion.ps1 yang sumbernya adalah:
Langkah 3: Simpan file InjectGitVersion.ps1 ke direktori solusi Anda di folder BuildScripts
Langkah 4: Tambahkan baris berikut ke acara Pra-Bangun proyek
Langkah 5: Bangun proyek Anda.
Langkah 6: Secara opsional, tambahkan AssemblyInfo.cs ke file abaikan git Anda
sumber
AssemblyInfo.cs
dapat memodifikasiAssemblyInfo.cs
di tempat, build, lalu git resetAssemblyInfo.cs
ke versi terakhir yang dikomit. Jadi dalam repo akan selalu adaAssemblyInfo.cs
, dengan$..$
diganti hanya untuk waktu build.git describe --match "v[0-9]*" --long --always --dirty
untuk menyaring tag tertentu (yang berisi nomor versi) dan untuk menunjukkan, jika pohon kerja bersih.$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
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.cs
file seperti yang dijelaskan dalam dokumentasi GitHub .Jika Anda hanya menginginkan hash dari komit terakhir (panjang = 8):
Bangun proyek / solusi Anda dan Anda akan mendapatkan sesuatu seperti ini:
sumber
PropertyGroup
ke .csproj file seperti terlihat di README github.com/ygoe/NetRevisionTask/blob/master/README.mdKarena jawaban lain sudah menyebutkan bit git, setelah Anda memiliki SHA, Anda dapat mempertimbangkan untuk membuat
AssemblyInfo.cs
file proyek Anda di hook pra-bangun.Salah satu cara untuk melakukannya adalah dengan membuat
AssemblyInfo.cs.tmpl
file template, dengan placeholder untuk SHA Anda misalnya $$ GITSHA $$, mis.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.
sumber
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
sumber
Anda dapat menggunakan satu-liner PowerShell untuk memperbarui semua file assemblyinfo dengan hash komit.
sumber
Seperti dicatat oleh @ learath2, keluaran dari
git rev-parse HEAD
akan 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 darigit describe
(sementara juga berhasil digunakan nantigit checkout
)Anda dapat memanggil rev-parse | gambarkan dalam:
sumber
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.tt
template ke proyek saya:Sekarang saya memiliki git tag + hash di "ProductVersion".
sumber
Mengacu pada jawaban lain ( https://stackoverflow.com/a/44278482/4537127 ) saya juga menggunakan
VersionInfo.tt
template teks untuk menghasilkanAssemblyInformationalVersion
tanpa AutoT4.(Atleast berfungsi di aplikasi C # WPF saya)
Masalahnya adalah bahwa kejadian Pra-bangun dijalankan setelah transformasi template, jadi setelah kloning,
git_version.txt
file 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 )
dan kemudian
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
2) Lakukan proses
git describe
sebelum transformasi template (sehinggagit_version.txt
ada saatVersionInfo.tt
diubah):..Dan kode C # untuk mendapatkan
AssemblyInformationalVersion
(Ref https://stackoverflow.com/a/7770189/4537127 )..Dan tambahkan file yang dihasilkan ke .gitignore
sumber
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:
sumber
Tempat
di
YOUR_PROJECT_NAME.csproj
sumber