Buduję aplikację C #, używając Git jako mojej kontroli wersji.
Czy istnieje sposób na automatyczne osadzenie ostatniego skrótu zatwierdzenia w pliku wykonywalnym podczas kompilowania aplikacji?
Na przykład wypisanie skrótu zatwierdzenia do konsoli wyglądałoby mniej więcej tak:
class PrintCommitHash
{
private String lastCommitHash = ?? // What do I put here?
static void Main(string[] args)
{
// Display the version number:
System.Console.WriteLine(lastCommitHash );
}
}
Należy pamiętać, że należy to zrobić w czasie kompilacji , a nie w czasie wykonywania , ponieważ mój wdrożony plik wykonywalny nie będzie miał dostępu do repozytorium git.
Powiązane pytanie dotyczące C ++ można znaleźć tutaj .
EDYTUJ
Żądanie @ mattanja, wysyłam skrypt git hook, którego używam w moich projektach. Ustawić:
- Punkty zaczepienia to skrypty powłoki systemu Linux, które są umieszczone w: ścieżka_do_projektu \ .git \ hooks
- Jeśli używasz msysgit , folder hooks zawiera już kilka przykładowych skryptów. Aby wywołać je git, usuń rozszerzenie „.sample” z nazwy skryptu.
- Nazwy skryptów przechwytujących odpowiadają zdarzeniu, które je wywołuje. W moim przypadku zmodyfikowałem post-commit i post-merge .
- Mój plik AssemblyInfo.cs znajduje się bezpośrednio pod ścieżką projektu (na tym samym poziomie co folder .git ). Zawiera 23 linie, a do wygenerowania 24 używam gita.
Ponieważ mój Linux-shelling jest nieco zardzewiały, skrypt po prostu wczytuje pierwsze 23 wiersze AssemblyInfo.cs do pliku tymczasowego, wyświetla echo skrótu git do ostatniej linii i zmienia nazwę pliku z powrotem na AssemblyInfo.cs . Jestem pewien, że istnieją lepsze sposoby na zrobienie tego:
#!/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
Mam nadzieję że to pomoże.
GlobalAssemblyInfo.*
plików w czasie kompilacji dla projektów C # i C ++: Domyślnie wygenerowana wersja zestawu zawiera: skrót zatwierdzenia, flagę sygnalizującą lokalne zmiany oraz przyrost zliczający ilość zatwierdzenia z katalogu głównego repozytorium do bieżącego zatwierdzenia.Możesz osadzić plik version.txt w pliku wykonywalnym, a następnie odczytać plik version.txt z pliku wykonywalnego. Aby utworzyć plik version.txt , użyj
git describe --long
Oto kroki:
Użyj zdarzenia kompilacji, aby zadzwonić do gita
Kliknij projekt prawym przyciskiem myszy i wybierz Właściwości
W Zdarzeniach kompilacji dodaj zdarzenie przed kompilacją zawierające (zwróć uwagę na cudzysłowy):
„C: \ Program Files \ Git \ bin \ git.exe” opisać --long> „$ (ProjectDir) \ version.txt”
Spowoduje to utworzenie pliku version.txt w katalogu projektu.
Osadź wersję.txt w pliku wykonywalnym
Przeczytaj informację o wersji osadzonego pliku tekstowego
Oto przykładowy kod do odczytywania ciągu wersji osadzonego pliku tekstowego:
źródło
git describe --dirty
, co dodaje flagę, gdy programiści pracują z brudnym drzewem roboczym.GetEntryAssembly
dostawałem montaż. W każdym razie możesz zadzwonić,GetName().Name
aby uniknąć zakodowania nazwy na stałe.AKTUALIZACJA:
Rzeczy uległy zmianie, odkąd pierwotnie odpowiedziałem na to pytanie.
Microsoft.NET.Sdk
(Czyli należy używać projekt SDK-style) zawiera teraz wsparcie dla dodanie popełnić hash zarówno wersję montaż informacyjną, jak również metadanych pakietu Nuget, jeśli spełnione są pewne warunki:<SourceRevisionId>
Właściwość musi być określona. Można to zrobić, dodając taki cel:Ten cel wykonuje polecenie, które ustawi
SourceRevisionId
jako skrócony (8-znakowy) skrót. BeforeTargets powoduje, że zostanie to uruchomione przed utworzeniem wersji informacyjnej zestawu.Aby uwzględnić skrót w metadanych pakietu NuGet,
<RepositoryUrl>
należy również zdefiniować plik.<SourceControlInformationFeatureSupported>
musi byćtrue
, powoduje to, że zadanie pakietu NuGet pobiera również SourceRvisionId.Odciągnąłbym ludzi od korzystania z pakietu MSBuildGitHash, ponieważ ta nowa technika jest czystsza i najbardziej spójna.
ORYGINALNY:
Stworzyłem prosty pakiet nuget, który możesz dołączyć do swojego projektu, który zajmie się tym za Ciebie: https://www.nuget.org/packages/MSBuildGitHash/
Ten pakiet NuGet implementuje „czyste” rozwiązanie MSBuild. Jeśli wolisz nie polegać na pakiecie nuget, możesz po prostu skopiować te elementy docelowe do pliku csproj i powinny one zawierać skrót git jako atrybut zestawu niestandardowego:
Są tu dwa cele. Pierwsza z nich, „GetGitHash”, ładuje skrót git do właściwości programu MSBuild o nazwie BuildHash, robi to tylko wtedy, gdy BuildHash nie jest jeszcze zdefiniowany. Dzięki temu możesz przekazać go do programu MSBuild w wierszu polecenia, jeśli wolisz. Możesz przekazać to do MSBuild w następujący sposób:
MSBuild.exe myproj.csproj /p:BuildHash=MYHASHVAL
Drugi cel, „WriteGitHash”, zapisze wartość skrótu do pliku w tymczasowym folderze „obj” o nazwie „CustomAssemblyInfo.cs”. Ten plik będzie zawierał linię, która wygląda następująco:
[assembly: AssemblyMetadata("GitHash", "MYHASHVAL")]
Ten plik CustomAssemblyInfo.cs zostanie skompilowany do zestawu, dzięki czemu można użyć odbicia, aby wyszukać plik
AssemblyMetadata
w czasie wykonywania. Poniższy kod pokazuje, jak można to zrobić, gdyAssemblyInfo
klasa jest uwzględniona w tym samym zestawie.Niektóre zalety tego projektu to to, że nie zmienia on żadnych plików w folderze projektu, wszystkie zmutowane pliki znajdują się w folderze „obj”. Twój projekt będzie również kompilowany identycznie z poziomu programu Visual Studio lub z wiersza polecenia. Można go również łatwo dostosować do projektu i będzie on kontrolowany wraz z plikiem csproj.
źródło
Assembly.GetExecutingAssembly()
, a następnie zbadałem zestawCustomAttributes
.GitHash
? Widzę, że ta wartość istnieje, ale czy istnieje czysta metoda uzyskania atrybutu niestandardowego według nazwy? Wygląda na to, że muszę napisać długie zapytanie gdzie-wybierzCustomAttributes
, dzięki.CustomAttributes
. Na przykład tutaj jest funkcja, której używam do wyodrębnienia ciągu skrótu: pastebin.com/nVKGLhJCInnym sposobem, aby to zrobić, jest użycie narzędzia NetRVisionTool z pewną magią wbudowanego programu Visual Studio. Przedstawię to tutaj dla Visual Studio 2013 Professional Edition, ale będzie to działać również z innymi wersjami.
Więc najpierw pobierz NetRvisionTool. Uwzględniasz NetRvisionTool.exe w PATH lub wpisujesz go do repozytorium i tworzysz prekompilację programu Visual Studio i akcję po kompilacji oraz zmieniasz plik AssemblyInfo.cs.
Przykładem, który dodałby twój git-hash do twojego AssemblyInformationVersion, byłby następujący: W ustawieniach projektu:
w AssemblyInfo.cs twojego projektu zmieniasz / dodajesz linię:
[assembly: AssemblyInformationalVersion ("1.1. {dmin: 2015}. {chash: 6} {!} - {branch}")]
na pokazanym zrzucie ekranu sprawdziłem w NetRvisionTool.exe w folderze External / bin
Po kompilacji, jeśli następnie klikniesz prawym przyciskiem myszy plik binarny i przejdziesz do właściwości, powinieneś zobaczyć coś takiego:
Mam nadzieję, że to komuś pomoże
źródło
Myślę, że na to pytanie warto udzielić pełnej odpowiedzi krok po kroku. Strategia w tym miejscu polega na uruchomieniu skryptu PowerShell ze zdarzeń przed kompilacją, które pobierają plik szablonu i generują plik AssemblyInfo.cs z tagiem git + dołączonymi informacjami o liczbie zatwierdzeń.
Krok 1: utwórz plik AssemblyInfo_template.cs w folderze Project \ Properties, na podstawie oryginalnego pliku AssemblyInfo.cs, ale zawierający:
Krok 2: Utwórz skrypt PowerShell o nazwie InjectGitVersion.ps1, którego źródłem jest:
Krok 3: Zapisz plik InjectGitVersion.ps1 w katalogu rozwiązania w folderze BuildScripts
Krok 4: Dodaj następujący wiersz do wydarzeń przed kompilacją projektu
Krok 5: Zbuduj swój projekt.
Krok 6: Opcjonalnie dodaj AssemblyInfo.cs do pliku ignorowania git
źródło
AssemblyInfo.cs
można modyfikowaćAssemblyInfo.cs
w miejscu, budować, a następnie resetować gitAssemblyInfo.cs
do ostatniej zatwierdzonej wersji. Czyli w repozytorium zawsze będzieAssemblyInfo.cs
, z$..$
podstawieniem tylko na czas kompilacji.git describe --match "v[0-9]*" --long --always --dirty
do filtrowania określonych tagów (zawierających numer wersji) i do wskazywania, czy drzewo robocze jest czyste.$gitVersion -match '[v](.*)-(\d+)-[g](.+)$';
Teraz jest to bardzo łatwe zadaniu .NET Revision Task dla MSBuild i pracy z programem Visual Studio 2019.
Po prostu zainstaluj Nuget pakiet Unclassified.NetRevisionTask , a następnie skonfigurować żądane informacje w
AssemblyInfo.cs
pliku w sposób opisany w dokumentacji GitHub .Jeśli chcesz tylko hash ostatniego zatwierdzenia (długość = 8):
Zbuduj swój projekt / rozwiązanie, a będziesz miał coś takiego:
źródło
PropertyGroup
do pliku .csproj , jak widać w pliku README github.com/ygoe/NetRvdTask/blob/master/README.mdPonieważ druga odpowiedź już wspomina bit git, kiedy już masz SHA, możesz rozważyć wygenerowanie
AssemblyInfo.cs
pliku projektu w haku przed kompilacją.Jednym ze sposobów jest utworzenie
AssemblyInfo.cs.tmpl
pliku szablonu z elementem zastępczym dla twojego SHA, np. $$ GITSHA $$, np.Następnie hak przed kompilacją musi zastąpić ten symbol zastępczy i wyprowadzić plik AssemblyInfo.cs, aby kompilator C # mógł go pobrać.
Aby zobaczyć, jak można to zrobić za pomocą SubWCRev dla SVN, zobacz tę odpowiedź . Nie powinno być trudno zrobić coś podobnego dla gita.
Innymi sposobami byłoby „tworzenie etapu”, jak wspomniano, tj. Napisanie zadania MSBuild, które robi coś podobnego. Jeszcze innym sposobem może być jakoś przetworzenie biblioteki DLL (powiedzmy ildasm + ilasm), ale myślę, że opcje wymienione powyżej są prawdopodobnie najłatwiejsze.
źródło
Aby uzyskać w pełni zautomatyzowaną i elastyczną metodę płatności, https://github.com/Fody/Stamp . Z powodzeniem wykorzystaliśmy to w naszych projektach Git (a także w tej wersji dla projektów SVN)
Aktualizacja: To jest nieaktualne, ponieważ Stamp.Fody nie jest już utrzymywane
źródło
Możesz użyć jednowierszowego programu PowerShell, aby zaktualizować wszystkie pliki informacji o zespole za pomocą skrótu zatwierdzenia.
źródło
Jak zauważył @ learath2, wynik polecenia
git rev-parse HEAD
da ci zwykły hash.Jeśli używasz tagów w repozytorium Git (i używasz tagów, czy nie jest to bardziej opisowe i czytelne niż
git rev-parse
), dane wyjściowe mogą być odbierane zgit describe
(chociaż również z powodzeniem używane późniejgit checkout
)Możesz wywołać rev-parse | opisać w:
źródło
Używam kombinacji zaakceptowanej odpowiedzi i małego dodatku. Mam zainstalowane rozszerzenie AutoT4 ( https://marketplace.visualstudio.com/items?itemName=BennorMcCarthy.AutoT4 ), aby ponownie uruchomić szablony przed kompilacją.
pobieranie wersji z GIT
Mam
git -C $(ProjectDir) describe --long --always > "$(ProjectDir)git_version.txt"
w moim zdarzeniu przed kompilacją we właściwościach projektu. Dodanie git_version.txt i VersionInfo.cs do .gitignore to całkiem niezły pomysł.osadzanie wersji w metadanych
Dodałem
VersionInfo.tt
szablon do mojego projektu:Teraz mam swój tag git + hash w „ProductVersion”.
źródło
Odnosząc się do innej odpowiedzi ( https://stackoverflow.com/a/44278482/4537127 ) wykorzystałem również
VersionInfo.tt
szablon tekstowy do wygenerowaniaAssemblyInformationalVersion
bez AutoT4.(Atleast działa w mojej aplikacji C # WPF)
Problem polegał na tym, że zdarzenia przed kompilacją były uruchamiane po transformacji szablonu, więc po sklonowaniu
git_version.txt
pliku nie było i kompilacja kończyła się niepowodzeniem. Po utworzeniu go ręcznie, aby umożliwić jednokrotne przejście transformacji, był aktualizowany po transformacji i zawsze pozostawał za jednym zatwierdzeniem .Musiałem dokonać dwóch zmian w pliku .csproj (dotyczy to przynajmniej Visual Studio Community 2017)
1) Zaimportuj cele transformacji tekstu i wykonaj transformacje szablonów, które będą uruchamiane w każdej kompilacji: (patrz https://msdn.microsoft.com/en-us/library/ee847423.aspx )
oraz po
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
2) Wykonaj
git describe
przebieg przed transformacją szablonu (tak, abygit_version.txt
był tam, kiedyVersionInfo.tt
jest transformowany):.. I kod C #, aby uzyskać
AssemblyInformationalVersion
(patrz https://stackoverflow.com/a/7770189/4537127 )..I dodaj wygenerowane pliki do .gitignore
źródło
Innym sposobem byłoby wygenerowanie pliku Version.cs z etapu przed kompilacją. Zbadałem to w małym projekcie weryfikującym koncepcję, który wypisuje bieżący skrót zatwierdzenia.
Projekt jest załadowany na https://github.com/sashoalm/GitCommitHashPrinter .
Kod wsadowy, który tworzy plik Version.cs, to:
źródło
Miejsce
w
YOUR_PROJECT_NAME.csproj
źródło