एम्बेड git कमिट हैश में एक .net dll


102

मैं अपने संस्करण नियंत्रण के रूप में Git का उपयोग करके C # एप्लिकेशन बना रहा हूं।

क्या मैं अपने आवेदन का निर्माण करते समय निष्पादन योग्य में अंतिम प्रतिबद्ध हैश को स्वचालित रूप से एम्बेड करने का एक तरीका है?

उदाहरण के लिए, कंसोल को कमिट हैश प्रिंट करना कुछ इस तरह दिखाई देगा:

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

ध्यान दें कि यह बिल्ड समय पर किया जाना है , रनटाइम के रूप में नहीं , क्योंकि मेरे तैनात निष्पादन योग्य में git रेपो सुलभ नहीं होगा।

C ++ के लिए संबंधित प्रश्न यहां पाया जा सकता है

संपादित

प्रति @ mattanja के अनुरोध, मैं Git हुक स्क्रिप्ट मैं अपनी परियोजनाओं में उपयोग पोस्टिंग कर रहा हूँ। स्थापित करना:

  • हुक लिनेक्स शेल स्क्रिप्ट हैं, जिन्हें नीचे रखा गया है: path_to_project \ .it \ हुक
  • यदि आप msysgit का उपयोग कर रहे हैं , तो हुक फ़ोल्डर में पहले से ही कुछ नमूना स्क्रिप्ट हैं। Git को कॉल करने के लिए, स्क्रिप्ट नाम से '.sample' एक्सटेंशन को हटा दें।
  • हुक स्क्रिप्ट के नाम उस घटना से मेल खाते हैं जो उन्हें आमंत्रित करता है। मेरे मामले में, मैंने पोस्ट-कमिट और पोस्ट-मर्ज को संशोधित किया ।
  • मेरी असेंबलीइन्फो.कॉन्सेस फ़ाइल सीधे प्रोजेक्ट पथ (समान स्तर .it फ़ोल्डर) के अंतर्गत है । इसमें 23 लाइनें शामिल हैं, और मैं 24 वें को जेनरेट करने के लिए गिट का उपयोग करता हूं।

जैसा कि मेरा linux- थोड़ा सा जंग खा रहा है, स्क्रिप्ट बस विधानसभा की पहली 23 पंक्तियाँ पढ़ती है। Info.cs एक अस्थायी फ़ाइल में, अंतिम पंक्ति में git हैश को इकोस करती है, और फ़ाइल को असेंबली में वापस भेज देती है । Incs । मुझे यकीन है कि ऐसा करने के बेहतर तरीके हैं:

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

उम्मीद है की यह मदद करेगा।

जवाबों:


63

हम संस्करणों को ट्रैक करने के लिए git में टैग का उपयोग करते हैं।

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

आप संस्करण को हैश के साथ git से प्राप्त कर सकते हैं:

git describe --long

हमारी निर्माण प्रक्रिया असेंबली की सूचना में असमानता प्रदान करती है।

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

एक बार जब आप संकलित करते हैं, तो आप विंडोज़ एक्सप्लोरर से संस्करण देख सकते हैं:

यहां छवि विवरण दर्ज करें

आप इसे प्रोग्रामेटिक रूप से भी प्राप्त कर सकते हैं:

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

जहां YourTYPE असेंबली में किसी भी प्रकार की असेंबली है।


14
नमस्ते, मैं एक महीने पहले पूछना चाहता था, लेकिन, मेरे पास टिप्पणी करने के लिए पर्याप्त प्रतिनिधि नहीं था। जब आप कहते हैं, "हमारी निर्माण प्रक्रिया असेंबली की सूचना में असमानता को बढ़ाती है, तो वास्तव में वहां क्या चल रहा है?" तुम सिर्फ एक दृश्य स्टूडियो निर्माण कर रहे हैं, या, आप NAnt या किसी अन्य उपकरण की तरह कुछ का उपयोग कर रहे हैं?
जॉन यीशु

3
हम अपने निर्माण को स्वचालित करने के लिए माणिक (रेक) का उपयोग करते हैं। हमारे रेक बिल्ड कार्यों में से एक CommonAssemblyInfo.cs फ़ाइल को अद्यतन करता है जो समाधान में सभी परियोजनाओं में उपयोग किया जाता है। यह कार्य CommonAssemblyInfo.cs फ़ाइल का उपयोग करता है, जिसमें अल्बाकोर - github.com/derickbailey/Albacore असेंबलीइन्फो मानों में से एक कार्य सेट असेंबलीफॉर्मेशन वर्जन है ।
हैंडक्राफ्ट्समैन

3
@ जॉन यीशु - जैसा कि आलसी बेजर ने सुझाव दिया, आप कमिट / मर्ज आदि के बाद असेंबलीइन्फो.फॉर्क्स को बदलने के लिए गिट हुक का भी उपयोग कर सकते हैं (यह वही है जो मैंने समाप्त किया है)। देखें kernel.org/pub/software/scm/git/docs/githooks.html
bavaza

बस FYI करें,
अल्बाकोर

5
निम्नलिखित परियोजना https://github.com/jeromerg/NGitVersionGlobalAssemblyInfo.* C # और C ++ प्रोजेक्ट्स के लिए संकलित समय पर फ़ाइलें जनरेट करने के लिए एक पूर्ण समाधान प्रदान करता है : डिफ़ॉल्ट रूप से, जनरेट किए गए असेंबली संस्करण में शामिल हैं: प्रतिबद्ध हैश, एक फ़्लैग सिग्नलिंग स्थानीय परिवर्तन, और वृद्धिशील जड़ से वर्तमान प्रतिबद्ध करने के लिए वेतन वृद्धि की गणना।
जेरोमर्ज

77

आप निष्पादन योग्य में एक version.txt फ़ाइल को एम्बेड कर सकते हैं और फिर निष्पादन योग्य से version.txt को पढ़ सकते हैं । Version.txt फ़ाइल बनाने के लिए , का उपयोग करेंgit describe --long

यहाँ कदम हैं:

कॉल करने के लिए बिल्ड ईवेंट का उपयोग करें

  • प्रोजेक्ट पर राइट-क्लिक करें और गुण चुनें

  • बिल्ड ईवेंट में, प्री-बिल्ड ईवेंट जोड़ें, (उद्धरण चिह्नों पर ध्यान दें):

    "C: \ Program Files \ Git \ bin \ git.exe" का वर्णन करें - long> "$ (ProjectDir) \ _.tit"

    जो आपके प्रोजेक्ट डायरेक्टरी में एक version.txt फाइल बनाएगा ।

निष्पादन योग्य में version.txt को एम्बेड करें

  • प्रोजेक्ट पर राइट क्लिक करें और Add Existing Item चुनें
  • Version.txt फ़ाइल जोड़ें (सभी फ़ाइल देखने के लिए फ़ाइल चयनकर्ता फ़िल्टर बदलें)
  • Version.txt जोड़े जाने के बाद , सॉल्यूशन एक्सप्लोरर में इस पर राइट-क्लिक करें और प्रॉपर्टीज चुनें
  • एंबेडेड संसाधन के लिए बिल्ड एक्शन बदलें
  • कॉपी को हमेशा आउटपुट निर्देशिका में बदलें
  • अपने .gitignore फ़ाइल में version.txt जोड़ें

एम्बेडेड पाठ फ़ाइल संस्करण स्ट्रिंग पढ़ें

यहाँ एम्बेडेड पाठ फ़ाइल संस्करण स्ट्रिंग पढ़ने के लिए कुछ नमूना कोड दिए गए हैं:

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
यह दृष्टिकोण काफी अच्छी तरह से काम करता है। मैंने "git Rev-parse --short HEAD" का उपयोग किया, हालाँकि।
ब्रायन रेइटर

3
आह अच्छा। मैंने "गिट वर्णन" का उपयोग किया क्योंकि यह वास्तव में दिलचस्प है (मेरे लिए) जब आपके पास एक टैग होता है; संस्करण की जानकारी में टैग लागू होने के बाद टैग प्लस की संख्या होती है; एससीएम में ऐसा कुछ पहले कभी नहीं देखा गया।
जॉन यीशु

7
मैं उपयोग करता हूं git describe --dirty, जो एक झंडा जोड़ता है जब डेवलपर्स एक गंदे काम करने वाले पेड़ के साथ काम कर रहे हैं।
पौलमेलनिकोव

2
@ TamásSzelei प्रोजेक्ट नेमस्पेस TryGitDescribe है। Version.txt फ़ाइल के निष्पादन योग्य / असेंबली विरूपण साक्ष्य में अन्तर्निहित हो जाने के बाद, आपको इसे बाहर निकालने के लिए नामस्थान को पूर्व-निर्धारित करने की आवश्यकता है।
जॉन यीशु

2
सम्पूर्ण समाधान के लिए धन्यवाद। मेरे मामले में मुझे GetEntryAssemblyविधानसभा मिलती थी। किसी भी मामले में आप GetName().Nameनाम को हार्डकोड करने से बचने के लिए कॉल कर सकते हैं ।
ज्योतिषी

51

अपडेट करें:

जब से मैंने मूल रूप से इस प्रश्न का उत्तर दिया है तब से चीजें विकसित हुई हैं। Microsoft.NET.Sdk(जिसका अर्थ है कि आप एक एसडीके शैली परियोजना का उपयोग करना चाहिए) अब जोड़ने के लिए समर्थन शामिल अच्छी तरह से nuget पैकेज मेटाडाटा के रूप में के रूप में विधानसभा सूचना के संस्करण दोनों को हैश प्रतिबद्ध है, अगर कुछ शर्तें पूरी की जाएं:

  1. <SourceRevisionId>संपत्ति परिभाषित किया जाना चाहिए। यह इस तरह एक लक्ष्य को जोड़कर किया जा सकता है:
<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>

यह लक्ष्य एक कमांड निष्पादित करता SourceRevisionIdहै जो संक्षिप्त (8 वर्ण) हैश पर सेट होगा । इससे पहले कि विधानसभा सूचना संस्करण बनाया जाता है इससे पहले कि यह कारण चलाया जा सकता है।

  1. हैग को नगेट पैकेज मेटाडेटा में शामिल करने के लिए <RepositoryUrl>भी परिभाषित किया जाना चाहिए।

  2. <SourceControlInformationFeatureSupported>प्रॉपर्टी होनी चाहिए true, इससे नूगट पैक टास्क के लिए SourceRevisionId भी लिया जा सकता है।

मैं MSBuildGitHash पैकेज का उपयोग करने से लोगों को दूर कर दूंगा, क्योंकि यह नई तकनीक क्लीनर और सबसे सुसंगत है।

मूल:

मैंने एक साधारण नगेट पैकेज बनाया है जिसे आप अपनी परियोजना में शामिल कर सकते हैं जो आपके लिए इसका ध्यान रखेगा: https://www.nuget.org/packages/MSBuildGitHash/

यह नगेट पैकेज एक "शुद्ध" MSBuild समाधान लागू करता है। यदि आप एक नगेट पैकेज पर निर्भर नहीं हैं, तो आप बस इन टारगेट्स को अपनी csproj फाइल में कॉपी कर सकते हैं और इसमें git हैश को कस्टम असेंबली विशेषता के रूप में शामिल करना चाहिए:

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

यहां दो लक्ष्य हैं। पहले एक, "गेटगिटहैश", बिल्ड हैश में एक MSBuild संपत्ति में git हैश को लोड करता है , यह केवल तभी करता है जब BuildHash पहले से परिभाषित नहीं है। यदि आप चाहें तो यह आपको MSBuild को कमांड लाइन पर पारित करने की अनुमति देता है। आप इसे MSBuild की तरह पास कर सकते हैं:

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

दूसरा लक्ष्य, "WriteGitHash", "CustomAssemblyInfo.cs" नाम के अस्थायी "obj" फ़ोल्डर में एक फ़ाइल के लिए हैश मान लिखेगा। इस फ़ाइल में एक पंक्ति होगी जो इस तरह दिखाई देती है:

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

इस CustomAssemblyInfo.cs फ़ाइल को आपकी असेंबली में संकलित किया जाएगा, ताकि आप AssemblyMetadataरनटाइम को देखने के लिए प्रतिबिंब का उपयोग कर सकें । निम्न कोड दिखाता है कि जब AssemblyInfoकक्षा को एक ही विधानसभा में शामिल किया जाता है तो यह कैसे किया जा सकता है ।

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

इस डिजाइन के कुछ लाभ यह है कि यह आपके प्रोजेक्ट फ़ोल्डर में किसी भी फाइल को नहीं छूता है, सभी उत्परिवर्तित फाइलें "obj" फ़ोल्डर के अंतर्गत हैं। आपका प्रोजेक्ट विजुअल स्टूडियो के भीतर या कमांड लाइन से भी पहचान बनाएगा। यह आपकी परियोजना के लिए भी आसानी से अनुकूलित किया जा सकता है, और आपके csproj फ़ाइल के साथ स्रोत को नियंत्रित करेगा।


2
यह पूरी तरह से काम किया। मैंने नगेट पैकेज स्थापित किया और git हैश का उपयोग कर बाहर निकालने में सक्षम था Assembly.GetExecutingAssembly(), फिर विधानसभा की जांच की CustomAttributes
गेविन एच।

1
यदि यह मेरा प्रश्न होता, तो मैं इस उत्तर को स्वीकार कर लेता। उत्तम सामग्री।
ड्रू नोक

1
@ गेविन, आपको कैसे मिला GitHash? मैं देख सकता हूं कि मूल्य मौजूद है लेकिन क्या नाम से कस्टम विशेषता प्राप्त करने के लिए कोई शुद्ध विधि है? ऐसा लगता है कि मुझे लंबे समय का चयन करना होगा जहां पर क्वेरी का चयन करें CustomAttributes, धन्यवाद।
ओकेन कोकिजीत

1
@ocanal हाँ - दुर्भाग्य से मुझे इसे पढ़ने की तुलना में एक क्लीनर तरीका नहीं मिला CustomAttributes। उदाहरण के लिए, यहाँ मैं हैश स्ट्रिंग निकालने के लिए उपयोग किया जाने वाला कार्य है: pastebin.com/nVKGLhJC
Gavin H

2
@danmiser मुझे पता नहीं है कि "UseMerge / SingleAssemblyName" क्या है, इसलिए मैं आपकी मदद नहीं कर सकता। Github.com/MarkPflug/MSBuildGitHash पर एक मुद्दा बनाएं और मैं इसे देख सकता हूं (यह एक वादा नहीं है)।
MarkPflug

14

ऐसा करने का एक और तरीका कुछ ऑन-बोर्ड विज़ुअल स्टूडियो जादू के साथ NetRevisionTool का उपयोग करना है । मैं इसे यहां विजुअल स्टूडियो 2013 प्रोफेशनल एडिशन के लिए प्रदर्शित करूंगा, लेकिन यह अन्य संस्करणों के साथ भी काम करेगा।

तो सबसे पहले NetRevisionTool डाउनलोड करें। आप अपने PATH में NetRevisionTool.exe को शामिल करें या इसे अपने रिपॉजिटरी में चेक करें और एक विजुअल स्टूडियो प्री-बिल्ड और एक पोस्ट-बिल्ड एक्शन बनाएं और अपने असेंबलीइनफोक्स को बदलें।

एक उदाहरण जो आपके git-hash को आपके असेंबली में जोड़ेगा। InVersionVersion निम्नलिखित होगा: आपकी परियोजना सेटिंग्स में:

यहां छवि विवरण दर्ज करें

अपनी परियोजना के असेम्बलीइन्फो.इन.क्यू में आप परिवर्तन / लाइन जोड़ें:

[असेंबली: असेंबली इंफॉर्मेशनवैल्यूशन ("1.1। {dmin: 2015}}। {chash: 6}}!} - {शाखा}")]

एक्सटर्नल / बिन फोल्डर में NetRevisionTool.exe में दिखाए गए स्क्रीनशॉट में दिखाया गया है

निर्माण के बाद, यदि आप फिर अपने बाइनरी पर राइट-क्लिक करते हैं और संपत्तियों पर जाते हैं, तो आपको निम्न जैसा कुछ देखना चाहिए:

यहां छवि विवरण दर्ज करें

आशा है कि यह वहाँ किसी को मदद करता है


मेरे लिए प्रतिबद्ध हैश हमेशा 00000 के रूप में समाप्त होता है। मैंने सोचा कि यह इसलिए था क्योंकि मेरे पास परिवर्तनहीन थे लेकिन फिर भी वही था। कोई विचार क्यों?
विक्टर

3
समस्या यह थी कि NetRevision मेरे गिट निष्पादन योग्य नहीं था। कारण यह है कि हम SourceTree का उपयोग कर रहे हैं और git इसके साथ एम्बेडेड आता है। समाधान USRPROFILE% \ AppData \ Local \ Atlassian \ SourceTree \ git_local% बिन से NetRevision.exe वाले फ़ोल्डर में git.exe और libiconv-2.dll की प्रतिलिपि बनाने के लिए था। मुझे भी इस तरह की घटनाओं को संशोधित करना पड़ा: प्री-बिल्ड इवेंट: cd $ (प्रोजेक्टडिर) लाइब्रेरी नेटरविज़नटूल। Ex / पैच $ (प्रोजेक्टडिअर) पोस्ट-बिल्ड इवेंट: सीडी $ (प्रोजेक्टडिर) लाइब्रेरी नेटवर्क्सविलेटीटूल। Exe / पुनर्स्थापना $ (प्रोजेक्टडिअर)
विक्टर

भविष्य के संदर्भ के लिए, प्रोजेक्ट रेपो URL कुछ समय पहले github.com/ygoe/NetRevisionTool में बदल गया है । अधिक जानकारी भी अवर्गीकृत पर उपलब्ध नहीं है । सुरक्षित / apps/netrevisiontool
ygoe

14

मुझे लगता है कि यह सवाल कदम से कदम का जवाब देने के लायक है। प्री-बिल्ड ईवेंट से एक पॉवरशेल स्क्रिप्ट को चलाने के लिए यहां रणनीति एक टेम्पलेट फ़ाइल में ले जाती है और एक असेंबलीइन्फो.चेक फाइल बनाती है जिसमें git टैग + कमिट जानकारी शामिल होती है।

चरण 1: अपने मूल असेंबलीInfo.cs के आधार पर Project \ Properties फ़ोल्डर में एक विधानसभाInfo_template.cs फ़ाइल बनाएं: जिसमें शामिल हैं:

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

चरण 2: InjectGitVersion.ps1 नामक एक पॉवरशेल स्क्रिप्ट बनाएँ जिसका स्रोत है:

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

चरण 3: InjectGitVersion.ps1 फ़ाइल को BuildScripts फ़ोल्डर में अपनी समाधान निर्देशिका में सहेजें

चरण 4: प्रोजेक्ट की प्री-बिल्ड घटनाओं में निम्न पंक्ति जोड़ें

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

चरण 5: अपनी परियोजना बनाएँ।

चरण 6: वैकल्पिक रूप से, असेंबलीInfo.cs को अपनी git उपेक्षा फ़ाइल में जोड़ें


और अपने git टैग्स को फ़ाइल संस्करणों के साथ संगत बनाने के लिए याद रखें: जैसे 1.2.3। यदि आपके पास अधिक जटिल टैग हैं, तो आपको बस संगत भागों को पार्स करना होगा
Atilio Jobson

2
टेम्प्लेट का उपयोग करने और वास्तविक रूप AssemblyInfo.csसे gitignoring करने के बजाय AssemblyInfo.cs, AssemblyInfo.csअंतिम कमिट किए गए संस्करण में git रीसेट कर सकते हैं। तो रेपो में वहाँ हमेशा होगा AssemblyInfo.cs, साथ $..$ही निर्माण के समय के लिए प्रतिस्थापित किया।
कुबा व्यारोसेक

इसने बहुत अच्छा काम किया। मैंने git describe --match "v[0-9]*" --long --always --dirtyकुछ टैग्स के लिए फ़िल्टर करने के लिए उपयोग किया (जो एक संस्करण संख्या वाले हैं) और इंगित करने के लिए, यदि कार्यशील पेड़ साफ था।
पैकमैन

आपको अपने RegEx को PS स्क्रिप्ट में भी बदलना होगा:$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
packoman

4

इसके साथ बहुत आसान अब MSBuild के लिए .NET संशोधन कार्य और विजुअल स्टूडियो 2019 के साथ काम।

बस NuGet पैकेज Unclassified.NetRevisionTask स्थापित करें , फिर AssemblyInfo.csफ़ाइल में इच्छित जानकारी कॉन्फ़िगर करें जैसा कि GitHub प्रलेखन में वर्णित है ।

यदि आप केवल अंतिम वचन (लंबाई = 8) का हैश चाहते हैं:

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

अपना प्रोजेक्ट / समाधान बनाएं और आपके पास कुछ इस तरह होगा:

यहां छवि विवरण दर्ज करें


एक NET.core अनुप्रयोग में प्रारूप कॉन्फ़िगर करने के लिए जोड़ने PropertyGroupके लिए .csproj फ़ाइल README में देखा की तरह github.com/ygoe/NetRevisionTask/blob/master/README.md
sc911

3

जैसा कि अन्य उत्तर में पहले से ही गिट बिट का उल्लेख है, एक बार जब आपके पास SHA होता है तो आप AssemblyInfo.csअपने प्रोजेक्ट की फाइल को प्री-बिल्ड हुक में बनाने पर विचार कर सकते हैं ।

ऐसा करने का एक तरीका AssemblyInfo.cs.tmplटेम्पलेट फ़ाइल बनाना है , जिसमें आपके SHA के लिए प्लेसहोल्डर के साथ $ $ GITSHA $ $ लिखा हो।

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

आपके प्री बिल्ड हूक को तब इस प्लेसहोल्डर को बदलना है और सी # कंपाइलर को लेने के लिए असेंबलीइन्फो.ऑक्स फाइल को आउटपुट करना है।

यह देखने के लिए कि SVN के लिए SubWCRev का उपयोग करके यह कैसे किया जा सकता है, इस उत्तर को देखें । जीआईटी के लिए कुछ ऐसा ही करना कठिन नहीं होना चाहिए।

अन्य तरीकों से एक "मंच बनाना" होगा जैसा कि उल्लेख किया गया है, अर्थात एक MSBuild कार्य लिखें जो कुछ इसी तरह करता है। फिर भी एक और तरीका हो सकता है कि किसी तरह DLL को प्रोसेस किया जाए (ildasm + ilasm say), लेकिन मुझे लगता है कि ऊपर दिए गए विकल्प शायद सबसे आसान हैं।


@ नहीं, जेनिट असेंबलीइंफो.फिट को git में न जोड़ें। यदि आप ऐसा करते हैं तो गैर-गंदा निर्माण करना असंभव होगा: P
jokedst

3

पूरी तरह से स्वचालित और लचीली विधि के लिए चेकआउट https://github.com/Fody/Stamp । हमने अपने Git प्रोजेक्ट्स के लिए इसका सफलतापूर्वक उपयोग किया है (साथ ही SVN प्रोजेक्ट्स के लिए यह संस्करण )

अद्यतन: यह स्टाम्प के बाद से पुराना है। अब कोई रखरखाव नहीं किया गया है


1
स्टाम्प के जीथब पृष्ठ पर। यह कहता है: "यह परियोजना अब नहीं बनी है।" मेरे प्रोजेक्ट में इसे शामिल करने से एक CA0052 और CA0055
sc911

2

आप सभी हैशनेट फाइल्स को अपडेट करने के लिए एक पॉवरशेल वन-लाइनर का उपयोग कमिट हैश के साथ कर सकते हैं।

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

1
  1. मुझे आशा है कि आप जानते हैं कि बाहरी कार्यक्रमों को कैसे कॉल करें और निर्माण-समय पर आउटपुट को इंटरसेप्ट करें।
  2. मुझे उम्मीद है कि आपको पता होगा कि git की वर्किंग डायरेक्टरी में अनवॉन्टेड फाइल्स को कैसे अनदेखा किया जाता है।

जैसा कि @ learath2 ने कहा है, का आउटपुट git rev-parse HEADआपको सादे हैश देगा।

यदि आप Git-repository में टैग का उपयोग करते हैं (और आप टैग का उपयोग करते हैं, तो यह अधिक वर्णनात्मक और पढ़ने योग्य नहीं है git rev-parse), आउटपुट प्राप्त किया जा सकता है git describe(जबकि बाद में सफलतापूर्वक उपयोग किया गया git checkout)

आप रिवाइज-पार्स कह सकते हैं।

  • कुछ मंच बनाते हैं
  • बाद के हुक में
  • धब्बा फ़िल्टर में, यदि आप कार्यान्वयन का स्मूद / क्लीन फ़िल्टर तरीका चुनेंगे

0

मैं स्वीकृत उत्तर और एक छोटे से संयोजन के संयोजन का उपयोग कर रहा हूं। निर्माण से पहले टेम्प्लेट को फिर से चलाने के लिए मेरे पास वें AutoT4 एक्सटेंशन स्थापित है ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 )।

जीआईटी से संस्करण प्राप्त करना

मैं git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"परियोजना के गुणों में अपने पूर्व-निर्माण कार्यक्रम में हूं। Git_version.txt और VersionInfo.cs को .gitignore में जोड़ना काफी अच्छा विचार है।

मेटाडाटा में एम्बेडिंग संस्करण

मैंने VersionInfo.ttअपने प्रोजेक्ट में एक टेम्प्लेट जोड़ा है :

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

#>

अब मेरे पास "ProductVersion" में मेरा git टैग + हैश है।


0

एक अन्य उत्तर ( https://stackoverflow.com/a/44278482/4537127 ) का हवाला देते हुए मैंने ऑटो VersionInfo.ttटेम्पलेट 4 के AssemblyInformationalVersionबिना उत्पन्न करने के लिए पाठ टेम्पलेट का उपयोग किया ।

(कम से कम मेरे C # WPF एप्लिकेशन में काम करता है)

समस्या यह थी कि प्री-बिल्ड इवेंट टेम्प्लेट परिवर्तनों के बाद चलाए गए थे, इसलिए क्लोनिंग के बाद, git_version.txtफ़ाइल नहीं थी और बिल्ड विफल हो गया था। परिवर्तन को मैन्युअल रूप से एक बार पास करने की अनुमति देने के लिए इसे बनाने के बाद, यह परिवर्तन के बाद अद्यतन किया गया था, और हमेशा एक ही पीछे था

मुझे .csproj फ़ाइल में दो समायोजन करने थे (यह विजुअल स्टूडियो कम्युनिटी 2017 के लिए कम से कम लागू होता है)

1) पाठ परिवर्तन लक्ष्य आयात करें और प्रत्येक बिल्ड पर चलने के लिए टेम्प्लेट रूपांतरण करें: (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>

और बाद में <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

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

2) git describeटेम्प्लेट ट्रांसफॉर्मेशन से पहले रन बनाएं (ताकि ट्रांसफॉर्म होने git_version.txtपर वहां VersionInfo.ttमौजूद हो):

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

.. और C # कोड प्राप्त करने के लिए 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;
    }
}

..और उत्पन्न फ़ाइलों को .gitignore में जोड़ें

VersionInfo.cs
git_version.txt

0

एक अन्य तरीका एक पूर्व-बिल्ड चरण से एक Version.cs फ़ाइल उत्पन्न करना होगा। मैंने इसे एक छोटे से प्रूफ-ऑफ-कॉन्सेप्ट प्रोजेक्ट में खोजा, जो इसके वर्तमान कमिट हैश को प्रिंट करता है।

Tha प्रोजेक्ट https://github.com/sashoalm/GitCommitHashPrinter पर अपलोड किया गया है ।

जो बैच कोड Version.cs फ़ाइल बनाता है, वह यह है:

@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

जगह

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

में 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;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.