Oder wie man in einer einzigen entspannten Coding-Nacht schöne Badges für sein Projekt erstellt
Sicherlich hat jeder Entwickler mit mindestens einem persönlichen Projekt irgendwann den Wunsch nach schönen Badges mit Statusanzeigen, Code-Abdeckungen und Versionsnummern in NuGet… Dieser Wunsch hat mich zu diesem Artikel inspiriert. Bei der Vorbereitung dazu habe ich mir in einem meiner Projekte etwas so Schönes geholt:

Im Artikel wird die grundlegende Konfiguration von kontinuierlicher Integration und Bereitstellung für ein Klassenbibliotheksprojekt auf .NET Core in GitLab behandelt, einschließlich der Veröffentlichung der Dokumentation in GitLab Pages und der Bereitstellung der erstellten Pakete in einem privaten Feed in Azure DevOps.
Als Entwicklungsumgebung wurde VS Code mit der Erweiterung verwendet (zur Validierung der Konfigurationsdatei direkt aus der Entwicklungsumgebung).
Kurze Einführung
CD – ist das, wenn du gerade gepusht hast und beim Kunden schon alles abgestürzt ist?
Was CI/CD ist und wofür man es braucht, kann man leicht googeln. Vollständige Dokumentationen zur Einrichtung von Pipelines in GitLab findet man . Hier werde ich den Prozess der Systemarbeit aus der Vogelperspektive kurz und möglichst fehlerfrei beschreiben:
- Der Entwickler sendet einen Commit an das Repository, erstellt eine Merge-Anfrage über die Webseite, oder startet den Pipeline auf eine andere, explizite oder implizite Weise,,
- aus der Konfiguration werden alle Aufgaben ausgewählt, deren Bedingungen es ermöglichen, sie in diesem Kontext auszuführen,
- Aufgaben werden entsprechend ihren Phasen organisiert,
- die Phasen werden nacheinander ausgeführt – d.h. parallel, werden alle Aufgaben dieser Phase ausgeführt,
- wenn eine Phase fehlschlägt (d.h. wenn mindestens eine der Aufgaben der Phase fehlschlägt) – wird die Pipeline gestoppt (fast immer,),
- wenn alle Phasen erfolgreich abgeschlossen sind, gilt die Pipeline als erfolgreich durchlaufen.
Somit haben wir:
- Eine Pipeline ist ein Satz von Aufgaben, die in Phasen organisiert sind, in der Code zusammengebaut, getestet, verpackt, die fertige Version in einen Cloud-Service bereitgestellt werden kann, usw.,
- eine Phase (Kanal "stage") ist eine organisatorische Einheit der Pipeline und enthält 1+ Aufgaben,
- eine Aufgabe (job) ist eine Arbeitseinheit in der Pipeline. Sie besteht aus einem Skript (unbedingt), Auslöserbedingungen, Veröffentlichungs-/Caching-Einstellungen für Artefakte und vielem mehr.
Daher besteht die Aufgabe bei der Einrichtung von CI/CD darin, ein Set von Aufgaben zu erstellen, das alle notwendigen Schritte für das Kompilieren, Testen und Veröffentlichen von Code und Artefakten umsetzt.
Vor dem Start: Warum?
- Warum GitLab?
Weil es notwendig wurde, private Repositories für meine Pet-Projekte zu erstellen, und die bei GitHub kostenpflichtig waren, und ich — bin geizig. Repositories sind jetzt kostenlos, aber das ist für mich noch kein ausreichender Grund, zu GitHub zu wechseln.
- Warum nicht Azure DevOps Pipelines?
Weil die Einrichtung dort sehr einfach ist — man benötigt nicht einmal Kenntnisse der Kommandozeile. Die Integration mit externen Git-Anbietern erfolgt in wenigen Klicks, der Import von SSH-Schlüsseln für das Pushen von Commits ins Repository ebenfalls, und der Pipeline ist leicht einzurichten, sogar ohne Vorlage.
Ausgangssituation: Was haben wir und was wollen wir?
Wir haben:
- ein Repository in GitLab.
Wir wollen:
- eine automatische Kompilierung und Testen für jede Merge-Request,
- eine Paketerstellung für jede Merge-Request und das Pushen in den Master, vorausgesetzt, die Commit-Nachricht enthält eine bestimmte Zeile,
- die gesammelten Pakete in ein privates Feed in Azure DevOps senden,
- die Dokumentation erstellen und in GitLab Pages veröffentlichen,
- Badges!11
Die beschriebenen Anforderungen passen perfekt zu folgendem Pipeline-Modell:
- Schritt 1 — Zusammenstellung
- Wir bündeln den Code und veröffentlichen die Ausgabedateien als Artefakte.
- Schritt 2 — Testen
- Wir erhalten die Artefakte aus dem Zusammenstellungsschritt, führen Tests aus und erfassen die Codeabdeckung.
- Schritt 3 — Bereitstellung
- Aufgabe 1 — Wir erstellen das NuGet-Paket und senden es an Azure DevOps.
- Aufgabe 2 — Wir bauen die Website aus der xmldoc im Quellcode und veröffentlichen sie in GitLab Pages.
Legen wir los!
Konfiguration erstellen
Wir bereiten die Konten vor.
Wir erstellen ein Konto in
Gehen wir zu
Ein neues Projekt erstellen
- Name — beliebig
- Sichtbarkeit — beliebig

Nach dem Klicken auf die Schaltfläche Erstellen wird das Projekt erstellt, und wir werden auf dessen Seite weitergeleitet. Auf dieser Seite können unnötige Funktionen deaktiviert werden, indem wir zu den Projekteinstellungen gehen (untere Linkliste links -> Übersicht -> Azure DevOps Services-Bereich).

Gehen wir zu Artefakten, klicken wir auf Feed erstellen.
- Geben Sie den Namen der Quelle ein.
- Wählen Sie die Sichtbarkeit aus.
- Deaktivieren Sie das Kästchen. Pakete aus gemeinsamen öffentlichen Quellen einschließen., um zu vermeiden, dass die Quelle zu einer Müllhalde von NuGet-Klonen wird.

Klicken Sie auf Mit dem Feed verbinden, wählen Sie Visual Studio, und kopieren Sie die Quelle aus dem Bereich Maschinenkonfiguration.

Gehen Sie zu den Kontoeinstellungen, wählen Sie persönliches Zugriffstoken.

Erstellen Sie ein neues Zugriffstoken.
- Name — beliebig.
- Organisation – aktuell
- Gültigkeitsdauer – maximal 1 Jahr
- Anwendungsbereich (scope) – Packaging/Read & Write

Kopieren Sie das erstellte Token – nach dem Schließen des Modals ist der Wert nicht mehr verfügbar
Gehen Sie in die Repository-Einstellungen in GitLab und wählen Sie CI/CD-Einstellungen

Erweitern Sie den Bereich Variablen, fügen Sie eine neue hinzu
- Name – beliebig ohne Leerzeichen (wird in der Kommandozeile verfügbar sein)
- Wert – Zugriffstoken aus Punkt 9
- Wählen Sie Mask variable

Damit ist die Vorauskonfiguration abgeschlossen.
Wir bereiten den Konfigurationsrahmen vor
Standardmäßig wird für die CI/CD-Konfiguration in GitLab eine Datei verwendet .gitlab-ci.yml aus dem Stammverzeichnis des Repositories. Es kann ein beliebiger Pfad zu dieser Datei in den Repository-Einstellungen konfiguriert werden, aber in diesem Fall ist das nicht nötig.
Wie aus der Erweiterung ersichtlich ist, enthält die Datei die Konfiguration im Format YAML. In der Dokumentation ist ausführlich beschrieben, welche Schlüssel auf der obersten Ebene der Konfiguration und in jeder der untergeordneten Ebenen enthalten sein können.
Zuerst fügen wir der Konfigurationsdatei einen Verweis auf das Docker-Image hinzu, in dem die Aufgaben ausgeführt werden. Dazu suchen wir nach In Es gibt eine ausführliche Anleitung, welches Image für unterschiedliche Aufgaben gewählt werden sollte. Für unseren Aufbau eignet sich das Image mit .Net Core 3.1, daher fügen wir es ohne Bedenken als erste Zeile in die Konfiguration ein.
image: mcr.microsoft.com/dotnet/core/sdk:3.1Beim Starten der Pipeline wird nun das angegebene Image aus dem Microsoft-Image-Repository heruntergeladen, in dem alle Aufgaben aus der Konfiguration ausgeführt werden.
Der nächste Schritt ist das Hinzufügen von Kanal "stage"Phasen. Standardmäßig definiert GitLab 5 Phasen:
.pre— wird vor allen Phasen ausgeführt,.post— wird nach allen Phasen ausgeführt,build— die erste nach.prePhase,test— die zweite Phase,deploy— die dritte Phase.
Nichts hindert uns jedoch daran, diese explizit zu deklarieren. Die Reihenfolge, in der die Phasen angegeben werden, beeinflusst die Reihenfolge, in der sie ausgeführt werden. Zur Vollständigkeit fügen wir in die Konfiguration hinzu:
stages:
- build
- test
- deployFür das Debugging ist es sinnvoll, Informationen über die Umgebung zu erhalten, in der die Aufgaben ausgeführt werden. Fügen wir einen globalen Satz von Befehlen hinzu, der vor jeder Aufgabe ausgeführt wird, mit Hilfe von before_script:
before_script:
- $PSVersionTable.PSVersion
- dotnet --version
- nuget help | select-string VersionEs bleibt noch, mindestens eine Aufgabe hinzuzufügen, damit die Pipeline beim Einpflegen von Commits ausgelöst wird. Zunächst fügen wir eine leere Aufgabe zur Demonstration hinzu:
dummy job:
script:
- echo okWir starten die Validierung, erhalten die Nachricht, dass alles gut ist, committen, pushen und schauen uns die Ergebnisse auf der Website an… und erhalten einen Skriptfehler — bash: .PSVersion: Befehl nicht gefunden. WTF?
Das ist nachvollziehbar — standardmäßig verwenden die Runner (die für die Ausführung von Skriptjobs zuständig sind und von GitLab bereitgestellt werden) bash zur Ausführung von Befehlen. Das lässt sich beheben, indem man in der Jobbeschreibung explizit angibt, welche Tags der ausführende Pipeline-Runner haben sollte:
dummy job on windows:
script:
- echo ok
tags:
- windowsAusgezeichnet! Jetzt wird die Pipeline ausgeführt.
Ein aufmerksamer Leser, der die angegebenen Schritte wiederholt, wird feststellen, dass der Job in der Phase test, obwohl wir die Phase nicht angegeben haben. Wie man vermuten kann, test ist die Standardphase.
Wir setzen die Erstellung des Konfigurationsgerüsts fort, indem wir alle oben beschriebenen Jobs hinzufügen:
build job:
script:
- echo "building..."
tags:
- windows
stage: build
test and cover job:
script:
- echo "running tests and coverage analysis..."
tags:
- windows
stage: test
pack and deploy job:
script:
- echo "packing and pushing to nuget..."
tags:
- windows
stage: deploy
pages:
script:
- echo "creating docs..."
tags:
- windows
stage: deployWir haben eine nicht besonders funktionale, aber dennoch korrekte Pipeline erhalten.
Trigger-Einrichtung
Da für keine der Aufgaben Auslöserfilter angegeben sind, wird die Pipeline vollständig bei jedem Push von Commits ins Repository ausgeführt. Da dies im Allgemeinen nicht das gewünschte Verhalten ist, werden wir Auslöserfilter für die Aufgaben konfigurieren.
Filter können in zwei Formaten konfiguriert werden: und . Kurz gesagt, only/except lässt sich die Filterung anhand von Triggern konfigurieren (merge_request, zum Beispiel — konfiguriert die Aufgabe so, dass sie bei jeder Erstellung eines Merge-Requests und bei jedem Push von Commits in den Branch, der die Basis im Merge-Request ist, ausgeführt wird) und den Namen der Branches (einschließlich der Verwendung von regulären Ausdrücken); rules ermöglicht es, eine Reihe von Bedingungen festzulegen und optional die Bedingung für die Ausführung der Aufgabe basierend auf dem Erfolg vorhergehender Aufgaben zu ändern ().
Erinnern wir uns an die Anforderungen — Build und Test nur für Merge-Requests, Packen und Pushen nach Azure DevOps — für Merge-Requests und Pushes in den Master-Branch, Dokumentationserstellung — für Pushes in den Master-Branch.
Beginnen wir mit der Konfiguration des Build-Jobs, indem wir eine Regel für das Auslösen nur bei Merge-Requests hinzufügen:
build job:
# snip
only:
- merge_requestLassen Sie uns nun die Aufgabe für das Packen bei Merge-Requests und das Hinzufügen von Commits zum Master einrichten:
pack and deploy job:
# snip
only:
- merge_request
- masterWie Sie sehen, ist alles einfach und geradlinig.
Außerdem kann die Aufgabe so konfiguriert werden, dass sie nur bei Erstellung eines Merge-Requests mit einem bestimmten Ziel- oder Quellzweig ausgelöst wird:
rules:
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"In den Bedingungen können ; Regeln rules sind nicht kompatibel mit den Regeln only/except.
Einrichtung der Artefaktaufbewahrung
Während der Ausführung der Aufgabe build job werden Artefakte des Builds erstellt, die in nachfolgenden Aufgaben wiederverwendet werden können. Dazu müssen in die Aufgaben-Konfiguration die Pfade und Dateien eingefügt werden, die gespeichert und in den folgenden Aufgaben wiederverwendet werden sollen, im Schlüssel :
build job:
# snip
artifacts:
paths:
- path/to/build/artifacts
- another/path
- MyCoolLib.*/bin/Release/*Die Pfade unterstützen Wildcards, was ihre Festlegung definitiv erleichtert.
Wenn eine Aufgabe Artefakte erstellt, hat jede nachfolgende Aufgabe Zugriff auf diese Artefakte – sie werden sich an denselben Pfaden relativ zum Wurzelverzeichnis befinden, wie sie aus der ursprünglichen Aufgabe gesammelt wurden. Außerdem sind die Artefakte auf der Website zum Download verfügbar.
Jetzt, da unser (und getesteter) Konfigurationsrahmen bereit ist, können wir mit dem Schreiben der Skripte für die Aufgaben beginnen.
Skripte schreiben
Möglicherweise war es einmal vor langer Zeit, in einer weit, weit entfernten Galaxie, schmerzhaft, Projekte (einschließlich .net) über die Befehlszeile zu erstellen. Heute hingegen können wir ein Projekt mit nur drei Befehlen erstellen, testen und veröffentlichen:
dotnet build
dotnet test
dotnet packNatürlich gibt es einige Nuancen, die unsere Befehle etwas komplizierter machen.
- Wir wollen ein Release-Build und kein Debug-Build, daher fügen wir zu jedem Befehl hinzu:
-c Release - Beim Testen möchten wir Daten zur Codeabdeckung sammeln, daher müssen wir einen Coverage-Analyzer zu den Testbibliotheken hinzufügen:
- In alle Testbibliotheken sollte das Paket
coverlet.msbuild:dotnet add package coverlet.msbuildaus dem Projektordner - Zum Befehl zum Ausführen der Tests fügen wir hinzu
/p:CollectCoverage=true - Fügen wir der Testaufgaben-Konfiguration einen Schlüssel zur Erfassung der Abdeckungsresultate hinzu (siehe unten)
- In alle Testbibliotheken sollte das Paket
- Beim Packen des Codes in NuGet-Pakete legen wir das Ausgabeverzeichnis für die Pakete fest:
-o .
Sammeln von Codedeckungsdaten
Coverlet gibt nach dem Testlauf Statistiken über die Ausführung in der Konsole aus:
Berechnung des Abdeckungsresultats...
Bericht wird generiert 'C:Usersxxxsourcereposmy-projectmyProject.testscoverage.json'
+-------------+--------+--------+--------+
| Modul | Zeile | Branch | Methode |
+-------------+--------+--------+--------+
| Projekt 1 | 83,24% | 66,66% | 92,1% |
+-------------+--------+--------+--------+
| Projekt 2 | 87,5% | 50% | 100% |
+-------------+--------+--------+--------+
| Projekt 3 | 100% | 83,33% | 100% |
+-------------+--------+--------+--------+
+---------+--------+--------+--------+
| | Zeile | Branch | Methode |
+---------+--------+--------+--------+
| Gesamt | 84,27% | 65,76% | 92,94% |
+---------+--------+--------+--------+
| Durchschnitt | 90,24% | 66,66% | 97,36% |
+---------+--------+--------+--------+GitLab erlaubt die Angabe eines regulären Ausdrucks zur Erfassung von Statistiken, die dann als Badge abgerufen werden können. Der reguläre Ausdruck wird in den Einstellungen der Aufgabe mit dem Schlüssel angegeben coverage; im Ausdruck muss eine Capture-Gruppe enthalten sein, deren Wert in das Badge übertragen wird:
test and cover job:
# snippet
coverage: /|s*Totals*|s*(d+[,.]d+%)/Hier erfassen wir Statistiken aus der Zeile mit der Gesamtabdeckung der Linien.
Wir veröffentlichen Pakete und Dokumentationen
Beide Aktionen sind in unserem letzten Schritt der Pipeline geplant – da der Build und die Tests erfolgreich waren, können wir unsere Fortschritte mit der Welt teilen.
Zunächst betrachten wir die Veröffentlichung an die Paketquelle:
Falls die Projektkonfiguration keine nuget-Datei enthält (
nuget.config), erstellen wir eine neue:dotnet new nugetconfigWarum: Im Image kann der Schreibzugriff auf die globalen (Benutzer- und Maschinen-) Konfigurationen eingeschränkt sein. Um keine Fehler zu erhalten, erstellen wir einfach eine neue lokale Konfiguration und arbeiten mit dieser.
- Fügen wir der lokalen Konfiguration eine neue Paketquelle hinzu:
nuget sources add -name -source -username -password -configfile nuget.config -StorePasswordInClearTextname— lokaler Name der Quelle, nicht entscheidendurl— URL der Quelle aus dem Schritt "Konten vorbereiten", Pkt. 6organization— Name der Organisation in Azure DevOpsgitlab variable— Name der Variable mit dem Zugriffstoken, die in GitLab hinzugefügt wurde ("Konten vorbereiten", Pkt. 11). Selbstverständlich im Format$variableName-StorePasswordInClearText— ein Hack zur Umgehung des Zugriffsfehlers ()- Für den Fall von Fehlern kann es nützlich sein, hinzuzufügen
-verbosity detailed
- Wir senden das Paket an die Quelle:
nuget push -source -skipduplicate -apikey *.nupkg- Wir senden alle Pakete aus dem aktuellen Verzeichnis, daher
*.nupkg. name— aus dem vorherigen Schritt.key— jede Zeile. In Azure DevOps wird im Fenster "Connect to feed" immer eine Beispielzeile angegebenaz.-skipduplicate— beim Versuch, ein bereits vorhandenes Paket ohne diesen Schlüssel zu senden, wird die Quelle einen Fehler zurückgeben409 Konflikt; mit dem Schlüssel wird der Upload übersprungen.
- Wir senden alle Pakete aus dem aktuellen Verzeichnis, daher
Jetzt konfigurieren wir die Dokumentationserstellung:
- Zunächst initialisieren wir im Repository im Master-Branch das Projekt docfx. Dazu muss vom Stammverzeichnis aus der Befehl ausgeführt werden
docfx initund im interaktiven Modus die Schlüsselparameter für den Dokumentationsbau festgelegt werden. Eine detaillierte Beschreibung der minimalen Projekteinrichtung .- Bei der Einrichtung ist es wichtig, das Ausgabeverzeichnis anzugeben
..public— GitLab verwendet standardmäßig den Inhalt des public-Ordners im Stammverzeichnis des Repositories als Quelle für Pages. Da sich das Projekt in einem untergeordneten Ordner im Repository befinden wird, fügen wir den Pfad zum übergeordneten Verzeichnis hinzu.
- Bei der Einrichtung ist es wichtig, das Ausgabeverzeichnis anzugeben
- Wir senden die Änderungen an GitLab.
- In die Pipeline-Konfiguration fügen wir die Aufgabe hinzu
pages(reserviertes Wort für Aufgaben zur Veröffentlichung von Websites in GitLab Pages):- Skript:
nuget install docfx.console -version 2.51.0— installiert docfx; die Version ist angegeben, um die Richtigkeit der Installationspfade des Pakets zu gewährleisten..docfx.console.2.51.0toolsdocfx.exe .docfx_projectdocfx.json— wir erstellen die Dokumentation
- Knoten artifacts:
- Skript:
pages:
# snip
artifacts:
paths:
- publicLyrischer Einschub über docfx
Früher habe ich bei der Projekteinrichtung die Codequelle für die Dokumentation als Lösungsgdatei angegeben. Der Hauptnachteil ist, dass die Dokumentation auch für Testprojekte erstellt wird. Falls dies nicht gewünscht ist, kann man diesen Wert dem Knoten zuweisen. metadata.src:
{
"metadata": [
{
"src": [
{
"src": "../",
"files": [
"**/*.csproj"
],
"exclude":[
"*.tests*/**"
]
}
],
// --- snip ---
},
// --- snip ---
],
// --- snip ---
}metadata.src.src: "../"— wir gehen eine Ebene höher relativ zum Standortdocfx.json, da die Suche in den Mustern nicht im Verzeichnisbaum nach oben funktioniert.metadata.src.files: ["**/*.csproj"]— globales Muster, wir sammeln alle C#-Projekte aus allen Verzeichnissen.metadata.src.exclude: ["*.tests*/**"]— globales Muster, wir schließen alles aus den Ordnern mit.testsim Namen
Zwischenergebnis
Eine solch einfache Konfiguration lässt sich in nur einer halben Stunde und bei einer Tasse Kaffee erstellen. Damit kann bei jeder Merge-Request und dem Versand an den Master überprüft werden, ob der Code erfolgreich gebaut wird und die Tests bestehen. Zudem werden neue Pakete geschnürt, die Dokumentation aktualisiert und das Auge erfreut sich an den schönen Badges im README des Projekts.
Die endgültige .gitlab-ci.yml
image: mcr.microsoft.com/dotnet/core/sdk:3.1
before_script:
- $PSVersionTable.PSVersion
- dotnet --version
- nuget help | select-string Version
stages:
- build
- test
- deploy
build job:
stage: build
script:
- dotnet build -c Release
tags:
- windows
only:
- merge_requests
- master
artifacts:
paths:
- your/path/to/binaries
test and cover job:
stage: test
tags:
- windows
script:
- dotnet test -c Release /p:CollectCoverage=true
coverage: /|s*Totals*|s*(d+[,.]d+%) /
only:
- merge_requests
- master
pack and deploy job:
stage: deploy
tags:
- windows
script:
- dotnet pack -c Release -o .
- dotnet new nugetconfig
- nuget sources add -name feedName -source https://pkgs.dev.azure.com/your-organization/_packaging/your-feed/nuget/v3/index.json -username your-organization -password $nugetFeedToken -configfile nuget.config -StorePasswordInClearText
- nuget push -source feedName -skipduplicate -apikey az *.nupkg
only:
- master
pages:
tags:
- windows
stage: deploy
script:
- nuget install docfx.console -version 2.51.0
- $env:path = "$env:path;$($(get-location).Path)"
- .docfx.console.2.51.0toolsdocfx.exe .docfxdocfx.json
artifacts:
paths:
- public
only:
- masterÜbrigens, die Badges
Wegen ihnen wurde alles ins Leben gerufen!
Statusabzeichen für Pipelines und Codeabdeckung sind in GitLab in den CI/CD-Einstellungen unter dem Abschnitt Gtntral-Pipelines verfügbar:

Das Abzeichen mit dem Link zur Dokumentation habe ich auf der Plattform — dort ist alles recht einfach, man kann sein eigenes Abzeichen erstellen und es über eine Anfrage erhalten.

Azure DevOps Artifacts ermöglicht ebenfalls die Erstellung von Abzeichen für Pakete mit Angabe der aktuellen Version. Dazu muss man im Azure DevOps-Portal auf 'Create badge' des ausgewählten Pakets klicken und die Markdown-Markup kopieren:


Einen Hauch von Ästhetik hinzufügen
Gemeinsame Konfigurationsfragmente hervorheben
Beim Schreiben der Konfiguration und beim Suchen in der Dokumentation bin ich auf eine interessante Möglichkeit in YAML gestoßen – die Wiederverwendung von Fragmenten.
Wie aus den Aufgabeneinstellungen ersichtlich, erfordern alle einen Tag Windows am Runner, und sie werden ausgelöst, wenn in den Master gesendet wird oder eine Merge-Anfrage erstellt wird (außer für Dokumentationen). Fügen wir dies in das Fragment ein, das wir wiederverwenden möchten:
.common_tags: &common_tags
tags:
- windows
.common_only: &common_only
only:
- merge_requests
- masterUnd jetzt können wir im Beschreibungstext der Aufgabe das zuvor deklarierte Fragment einfügen:
build job:
<<: *common_tags
<<: *common_onlyFragmentnamen sollten mit einem Punkt beginnen, um nicht als Aufgabe interpretiert zu werden.
Versionsverwaltung von Paketen
Beim Erstellen eines Pakets überprüft der Compiler die Befehlszeilenparameter und, falls diese fehlen, die Projektdateien. Findet er den Knoten Version, nimmt er dessen Wert als Version des zu erstellenden Pakets. Um ein Paket mit einer neuen Version zu erstellen, muss man daher entweder diese im Projektfile aktualisieren oder sie als Befehlszeilenargument übergeben.
Fügen wir noch eine Anforderung hinzu: Die letzten beiden Zahlen der Version sollen das Jahr und das Datum des Paketbaus sein, und wir fügen Vorabversionen hinzu. Diese Daten im Projektfile zu ergänzen und vor jedem Commit zu überprüfen ist natürlich möglich — aber wir können dies auch im Pipeline-Prozess erledigen, indem wir die Version des Pakets aus dem Kontext zusammensetzen und als Befehlszeilenargument übergeben.
Lassen Sie uns vereinbaren, dass, wenn in der Commit-Nachricht eine Zeile im Format vorhanden ist release (v./ver./version) <versionsnummer> (rev./revision <revision>)?, nehmen wir die Versionsnummer aus dieser Zeile, ergänzen sie mit dem aktuellen Datum und übergeben sie als Argument an den Befehl dotnet pack. Fehlt die Zeile — werden wir das Paket einfach nicht erstellen.
Diese Aufgabe wird mit folgendem Skript gelöst:
# регулярное выражение для поиска строки с версией
$rx = "releases+(v.?|ver.?|version)s*(?<maj>d+)(?<min>.d+)?(?<rel>.d+)?s*((rev.?|revision)?s+(?<rev>[a-zA-Z0-9-_]+))?"
# ищем строку в сообщении коммита, передаваемом в одной из предопределяемых GitLab'ом переменных
$found = $env:CI_COMMIT_MESSAGE -match $rx
# совпадений нет - выходим
if (!$found) { Write-Output "no release info found, aborting"; exit }
# извлекаем мажорную и минорную версии
$maj = $matches['maj']
$min = $matches['min']
# если строка содержит номер релиза - используем его, иначе - текущий год
if ($matches.ContainsKey('rel')) { $rel = $matches['rel'] } else { $rel = ".$(get-date -format "yyyy")" }
# в качестве номера сборки - текущие месяц и день
$bld = $(get-date -format "MMdd")
# если есть данные по пререлизной версии - включаем их в версию
if ($matches.ContainsKey('rev')) { $rev = "-$($matches['rev'])" } else { $rev = '' }
# собираем единую строку версии
$version = "$maj$min$rel.$bld$rev"
# собираем пакеты
dotnet pack -c Release -o . /p:Version=$versionWir fügen das Skript zur Aufgabe hinzu Pack- und Bereitstellungsaufgabe und beobachten den Paketbuild nur, wenn die angegebene Zeile in der Commit-Nachricht vorhanden ist.
Gesamt
Nach etwa einer halben bis einer Stunde für das Schreiben der Konfiguration, das Debuggen im lokalen PowerShell und möglicherweise ein paar Fehlversuchen haben wir eine einfache Konfiguration zur Automatisierung alltäglicher Aufgaben erhalten.
Natürlich ist GitLab CI/CD viel umfassender und facettenreicher, als es nach dem Lesen dieses Leitfadens erscheinen mag — . Dort gibt es sogar , mit dem Sie
Automatisch Ihre Anwendungen erkennen, erstellen, testen, bereitstellen und überwachen
Jetzt steht die Konfiguration einer Pipeline zur Bereitstellung von Anwendungen in Azure an, unter Verwendung von Pulumi und automatischer Erkennung der Zielumgebung, was im nächsten Artikel behandelt wird.
Quelle: habr.com








