Dieser Artikel richtet sich an Java-Entwickler, die schnell ihre Produkte in den Repositories von Sonatype und/oder Maven Central mit GitLab veröffentlichen möchten. Ich werde die Einrichtung von gitlab-runner, gitlab-ci und maven-plugin zur Lösung dieser Aufgabe erläutern.
Voraussetzungen:
- Sichere Speicherung von Maven- und GPG-Schlüsseln.
- Sicheres Ausführen öffentlicher CI-Jobs.
- Hochladen von Artefakten (Release/Snapshot) in öffentliche Repositories.
- Automatische Überprüfung von Release-Versionen zur Veröffentlichung in Maven Central.
- Allgemeine Lösung zum Hochladen von Artefakten in ein Repository für mehrere Projekte.
- Einfachheit und Benutzerfreundlichkeit.
Inhalt
Allgemeine Informationen
- Eine detaillierte Beschreibung des Mechanismus zur Veröffentlichung von Artefakten in Maven Central über den Sonatype OSS Repository Hosting Service ist bereits in durch den Benutzer von , daher werde ich an den entsprechenden Stellen auf diesen Artikel verweisen.
- Vorabregistrierung in und Ticket zur Eröffnung des Repositories anlegen (ausführlicher in dem Abschnitt lesen ). Nach der Eröffnung des Repositories werden die Login-/Passwortdaten von JIRA (später Sonatype-Konto) für das Hochladen von Artefakten in Sonatype Nexus verwendet.
- Der Prozess zur Generierung des GPG-Schlüssels wird eher trocken beschrieben. Ausführlicher im Abschnitt
- Wenn Sie die Linux-Konsole zur Generierung des GPG-Schlüssels (GnuPG/GnuPG2) verwenden, müssen Sie installieren, um Entropie zu generieren. Andernfalls kann die Schlüsselerzeugung sehr lange dauern.
- Speicherdienste öffentlicher GPG-Schlüssel
Konfiguration des Deploy-Projekts in GitLab
- Zunächst müssen Sie ein Projekt erstellen und konfigurieren, in dem der Pipeline für das Deployment von Artefakten gespeichert wird. Mein Projekt habe ich einfach und schlicht genannt —
- Nach der Erstellung des Repositories müssen die Zugriffsrechte zur Änderung des Repositories eingeschränkt werden.
Gehen Sie zu Projekt -> Einstellungen -> Repository -> Geschützte Branches. Entfernen Sie alle Regeln und fügen Sie eine einzige Regel mit Wildcard * hinzu, mit Push- und Merge-Rechten nur für Benutzer mit der Rolle Maintainers. Diese Regel wird für alle Benutzer sowohl des Projekts als auch der Gruppe, zu der das Projekt gehört, funktionieren.
- Wenn es mehrere Maintainer gibt, ist es am besten, den Zugang zum Projekt grundsätzlich zu beschränken.
Gehen Sie zu Projekt -> Einstellungen -> Allgemein -> Sichtbarkeit, Projekteigenschaften, Berechtigungen und setzen Sie die Projekt-Sichtbarkeit auf den Wert Privat.
Ich habe mein Projekt öffentlich zugänglich gemacht, da ich meinen eigenen GitLab Runner nutze und nur ich Änderungszugriff auf das Repository habe. Außerdem liegt es nicht in meinem Interesse, private Informationen in öffentlichen Pipeline-Protokollen zu zeigen. - Verschärfung der Regeln zur Änderung des Repositories
Gehen Sie zu Projekt -> Einstellungen -> Repository -> Push-Regeln und aktivieren Sie die Optionen Committer-Einschränkung, Überprüfen, ob der Autor ein GitLab-Benutzer ist. Ich empfehle außerdem, , und aktivieren Sie das Feld Unsigned Commits ablehnen. - Als nächstes müssen Sie einen Trigger zum Starten von Jobs einrichten.
Gehen Sie zu Projekt -> Einstellungen -> CI / CD -> Pipeline-Trigger und erstellen Sie ein neues Trigger-Token.
Dieses Token kann sofort zur allgemeinen Konfiguration der Variablen für die Projektgruppe hinzugefügt werden.
Gehen Sie zur Gruppe -> Einstellungen -> CI / CD -> Variablen und fügen Sie die Variable hinzuDEPLOY_TOKENmit dem Trigger-Token als Wert.
GitLab Runner
In diesem Abschnitt wird die Konfiguration für das Starten von Aufgaben bei Deployments mit einem eigenen (Specific) und öffentlichen (Shared) Runner beschrieben.
Spezifischer Runner
Ich verwende eigene Runner, da es in erster Linie praktisch, schnell und kostengünstig ist.
Für den Runner empfehle ich einen Linux VDS mit 1 CPU, 2 GB RAM und 20 GB HDD. Die Kosten belaufen sich auf ca. 3000 ₽ pro Jahr.
Mein Runner
Für den Runner habe ich einen VDS mit 4 CPU, 4 GB RAM und 50 GB SSD gewählt. Kostete ca. 11000 ₽ und ich habe es nicht bereut.
Ich habe insgesamt 7 Maschinen. 5 bei Aruba und 2 bei Ihor.
Also, wir haben einen Runner. Jetzt werden wir ihn konfigurieren.
Melden Sie sich über SSH bei der Maschine an und installieren Sie Java, Git, Maven, GnuPG2.
Installieren Sie den GitLab Runner.
- Erstellen Sie eine neue Gruppe
runnersudo groupadd runner - Erstellen Sie ein Verzeichnis für den Maven-Cache und geben Sie die Gruppeneinstellungen.
runner
Dieser Punkt kann übersprungen werden, wenn Sie nicht planen, mehrere Runner auf einer Maschine auszuführen.mkdir -p /usr/cache/.m2/repository chown -R :runner /usr/cache chmod -R 770 /usr/cache - Erstellen Sie einen Benutzer
gitlab-deployerund fügen Sie ihn zur Gruppe hinzu.runneruseradd -m -d /home/gitlab-deployer gitlab-deployer usermod -a -G runner gitlab-deployer - Fügen Sie in die Datei
/etc/ssh/sshd_configdie folgende Zeile einAllowUsers root@* gitlab-deployer@127.0.0.1 - Starten wir neu
sshdsystemctl restart sshd - Legen Sie ein Passwort für den Benutzer fest
gitlab-deployer(ein einfaches Passwort ist ausreichend, da es eine Beschränkung für localhost gibt)passwd gitlab-deployer - Installieren Sie den GitLab Runner (Linux x86-64)
sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64 sudo chmod +x /usr/local/bin/gitlab-runner ln -s /usr/local/bin/gitlab-runner /etc/alternatives/gitlab-runner ln -s /etc/alternatives/gitlab-runner /usr/bin/gitlab-runner - Gehen Sie zu gitlab.com -> deploy-project -> Einstellungen -> CI/CD -> Runner -> Spezifische Runner und kopieren Sie das Registrierungs-Token
Screenshot
- Registrieren Sie den Runner
gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml
Prozess
Runtime-Plattform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Läuft im Systemmodus.
Bitte geben Sie die GitLab-CI Koordinator-URL ein (z.B. https://gitlab.com/):
https://gitlab.com/
Bitte geben Sie das GitLab-CI Token für diesen Runner ein:
REGISTRATION_TOKEN
Bitte geben Sie die Beschreibung für diesen Runner ein:
[ih1174328.vds.myihor.ru]: Deploy Runner
Bitte geben Sie die Tags für diesen Runner ein (kommagetrennt):
deploy
Registrieren des Runners... erfolgreich runner=ZvKdjJhx
Bitte geben Sie den Executor ein: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner erfolgreich registriert. Sie können ihn jetzt starten, aber wenn er bereits läuft, sollte die Konfiguration automatisch neu geladen werden!- Wir überprüfen, ob der Runner registriert ist. Gehen Sie zu gitlab.com -> deploy-project -> Einstellungen -> CI/CD -> Runner -> Spezifische Runner -> Für dieses Projekt aktivierte Runner
Screenshot
- Hinzufügen getrennt Dienst
/etc/systemd/system/gitlab-deployer.service[Unit] Description=GitLab Deploy Runner After=syslog.target network.target ConditionFileIsExecutable=/usr/local/bin/gitlab-runner [Service] StartLimitInterval=5 StartLimitBurst=10 ExecStart=/usr/local/bin/gitlab-runner "run" "--working-directory" "/home/gitlab-deployer" "--config" "/etc/gitlab-runner/gitlab-deployer-config.toml" "--service" "gitlab-deployer" "--syslog" "--user" "gitlab-deployer" Restart=always RestartSec=120 [Install] WantedBy=multi-user.target - Wir starten den Dienst.
systemctl enable gitlab-deployer.service systemctl start gitlab-deployer.service systemctl status gitlab-deployer.service - Wir überprüfen, ob der Runner läuft.
Beispiel
Generierung von GPG-Schlüsseln
- Melden Sie sich von derselben Maschine per SSH als Benutzer an
gitlab-deployer(das ist wichtig für die Generierung des GPG-Schlüssels)ssh gitlab-deployer@127.0.0.1 - Generieren Sie den Schlüssel, indem Sie die Fragen beantworten. Ich habe meinen eigenen Namen und meine E-Mail verwendet.
Stellen Sie sicher, dass Sie ein Passwort für den Schlüssel angeben. Mit diesem Schlüssel werden die Artefakte signiert.gpg --gen-key - Wir überprüfen.
gpg --list-keys -a /home/gitlab-deployer/.gnupg/pubring.gpg ---------------------------------------- pub 4096R/00000000 2019-04-19 uid Petruha Petrov sub 4096R/11111111 2019-04-19 - Laden Sie unseren öffentlichen Schlüssel auf den Schlüsselserver hoch
gpg --keyserver keys.gnupg.net --send-key 00000000 gpg: Schlüssel 00000000 wird an den hkp-Server keys.gnupg.net gesendet
Einrichtung von Maven
- Melden Sie sich als Benutzer an
gitlab-deployersu gitlab-deployer - Erstellen Sie das Verzeichnis maven repository und verlinken mit Cache (nicht verwechseln)
Dieser Punkt kann übersprungen werden, wenn Sie nicht planen, mehrere Runner auf einer Maschine zu starten.mkdir -p ~/\.m2/repository ln -s /usr/cache/\.m2/repository /home/gitlab-deployer/\.m2/repository - Master-Schlüssel erstellen
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Die Datei ~/\.m2/settings-security.xml erstellen
{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Passwort für das Sonatype-Konto verschlüsseln
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Die Datei ~/\.m2/settings.xml erstellen
env true GPG_SECRET_KEY_PASSPHRASE sonatype SONATYPE_USERNAME {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
wobei,
GPG_SECRET_KEY_PASSPHRASE — Passwort für den GPG-Schlüssel
SONATYPE_USERNAME — Benutzername des Sonatype-Kontos
Damit ist die Konfiguration des Runners abgeschlossen, wir können zum Abschnitt
Shared Runner
Generierung von GPG-Schlüsseln
- Zunächst muss ein GPG-Schlüssel erstellt werden. Dafür installieren wir gnupg.
yum install -y gnupg - Wir generieren einen Schlüssel, indem wir Fragen beantworten. Ich habe meinen eigenen Namen und E-Mail-Adresse verwendet. Achten Sie darauf, ein Passwort für den Schlüssel anzugeben.
gpg --gen-key - Wir geben die Informationen zum Schlüssel aus
gpg --list-keys -a pub rsa3072 2019-04-24 [SC] [abläuft: 2021-04-23] 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 uid [ultimativ] tttemp sub rsa3072 2019-04-24 [E] [abläuft: keine] - Laden Sie unseren öffentlichen Schlüssel auf den Schlüsselserver hoch
gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 gpg: Schlüssel 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 an hkp-Server keys.gnupg.net senden - Wir erhalten den privaten Schlüssel
gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 -----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5 ... =2Wd2 -----END PGP PRIVATE KEY BLOCK----- - Gehen Sie zu den Projekteinstellungen -> Einstellungen -> CI / CD -> Variablen und speichern Sie den privaten Schlüssel in einer Variablen
GPG_SECRET_KEY
Einrichtung von Maven
- Master-Schlüssel erstellen
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Gehen Sie zu den Projekteinstellungen -> Einstellungen -> CI / CD -> Variablen und speichern Sie in einer Variablen
SETTINGS_SECURITY_XMLfolgende Zeilen:{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Passwort für das Sonatype-Konto verschlüsseln
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Gehen Sie zu den Projekteinstellungen -> Einstellungen -> CI / CD -> Variablen und speichern Sie in einer Variablen
SETTINGS_XMLfolgende Zeilen:<settings> <profiles> <profile> <id>env</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <gpg.passphrase>GPG_SECRET_KEY_PASSPHRASE</gpg.passphrase> </properties> </profile> </profiles> <servers> <server> <id>sonatype</id> <username>sonatype_username</username> <password>{98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}</password> </server> </servers> </settings>
wobei,
GPG_SECRET_KEY_PASSPHRASE — Passwort für den GPG-Schlüssel
SONATYPE_USERNAME — Benutzername des Sonatype-Kontos
Docker-Image bereitstellen
- Wir erstellen eine einfache Dockerfile zur Ausführung von Deployment-Aufgaben mit der benötigten Java-Version. Unten finden Sie ein Beispiel für Alpine.
FROM java:8u111-jdk-alpine RUN apk add gnupg maven git --update-cache --repository http://dl-4.alpinelinux.org/alpine/edge/community/ --allow-untrusted && mkdir ~/.m2/ - Wir erstellen einen Container für Ihr Projekt.
docker build -t registry.gitlab.com/group/deploy . - Wir authentifizieren uns und laden den Container in das Registry hoch.
docker login -u USER -p PASSWORD registry.gitlab.com docker push registry.gitlab.com/group/deploy
GitLab CI
Projekt bereitstellen
Fügen Sie eine .gitlab-ci.yml-Datei in das Root-Verzeichnis des Deploy-Projekts hinzu.
Im Skript sind zwei sich gegenseitig ausschließende Deploy-Aufgaben dargestellt: ein spezifischer Runner oder ein gemeinsamer Runner.
.gitlab-ci.yml
Stufen:
- bereitstellen
Spezifischer Runner:
extends: .java_deploy_template
# Die Aufgabe wird auf Ihrem Shell-Runner ausgeführt
tags:
- bereitstellen
Geteilter Runner:
extends: .java_deploy_template
# Die Aufgabe wird auf einem öffentlichen Docker-Runner ausgeführt
tags:
- docker
# Bild aus dem Abschnitt GitLab Runner -> Geteilter Runner -> Docker
image: registry.gitlab.com/group/deploy-project:latest
before_script:
# Importiere den GPG-Schlüssel
- printf "${GPG_SECRET_KEY}" | gpg --batch --import
# Speichere die Maven-Konfiguration
- printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
- printf "${SETTINGS_XML}" > ~/.m2/settings.xml
.java_deploy_template:
stage: bereitstellen
# Die Aufgabe wird durch einen Trigger ausgelöst, wenn die Variable DEPLOY mit dem Wert java übergeben wird
only:
variables:
- $DEPLOY == "java"
variables:
# Deaktiviere das Klonen des aktuellen Projekts
GIT_STRATEGY: none
script:
# Ermöglicht die Speicherung des Passworts im unverschlüsselten Format
- git config --global credential.helper store
# Speichert temporäre Zugangsdaten für den Benutzer gitlab-ci-token
# Das Token funktioniert für alle öffentlichen Projekte auf gitlab.com und für Gruppenprojekte
- echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
# Reinige das aktuelle Verzeichnis vollständig
- rm -rf .* *
# Klone das Projekt, das wir in Sonatype Nexus bereitstellen wollen
- git clone ${DEPLOY_CI_REPOSITORY_URL} .
# Wechsle zum benötigten Commit
- git checkout ${DEPLOY_CI_COMMIT_SHA} -f
# Wenn auch nur eine pom.xml den Parameter autoReleaseAfterClose enthält, breche den Build ab.
# Andernfalls besteht die Gefahr, unverarbeitete Artefakte in Maven Central hochzuladen
- >
for pom in $(find . -name pom.xml); do
if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
echo "Die Datei $pom enthält die verbotene Einstellung: ";
exit 1;
fi;
done
# Wenn der Parameter DEPLOY_CI_COMMIT_TAG leer ist, setze die SNAPSHOT-Version zwangsweise
- >
if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then
mvn versions:set -DnewVersion=${DEPLOY_CI_COMMIT_TAG}
else
VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec)
if [[ "${VERSION}" == *-SNAPSHOT ]]; then
mvn versions:set -DnewVersion=${VERSION}
else
mvn versions:set -DnewVersion=${VERSION}-SNAPSHOT
fi
fi
# Starte die Aufgabe zum Bauen und Bereitstellen der Artefakte
- mvn clean deploy -DskipTests=trueJava-Projekt
In Java-Projekten, die für öffentliche Repositories vorgesehen sind, müssen zwei Schritte zum Hochladen von Release- und Snapshot-Versionen hinzugefügt werden.
.gitlab-ci.yml
stages:
- build
- test
- verify
- deploy
Release:
extends: .trigger_deploy
# Aufgabe nur bei Tag ausführen.
only:
- tags
Snapshot:
extends: .trigger_deploy
# Aufgabe zum Veröffentlichen der SNAPSHOT-Version manuell ausführen
when: manual
# Aufgabe nicht ausführen, wenn ein Tag gesetzt ist.
except:
- tags
.trigger_deploy:
stage: deploy
variables:
# Klonen des aktuellen Projekts deaktivieren
GIT_STRATEGY: none
# URL zum Triggern der Deploy-Aufgabe
URL: "https://gitlab.com/api/v4/projects//trigger/pipeline"
# Variablen für die Deploy-Aufgabe
POST_DATA: "
token=${DEPLOY_TOKEN}&
ref=master&
variables[DEPLOY]=${DEPLOY}&
variables[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
variables[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
variables[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
variables[DEPLOY_CI_COMMIT_TAG]=${CI_COMMIT_TAG}
"
script:
# cURL nicht verwenden, da es mit den Flags --fail --show-error
# den Antwortinhalt nicht ausgibt, wenn der HTTP-Code 400 oder höher ist
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}In dieser Lösung bin ich einen Schritt weiter gegangen und habe mich entschieden, eine CI-Vorlage für Java-Projekte zu verwenden.
Mehr Details
Ich habe ein separates Projekt erstellt in dem ich die CI-Vorlage für Java-Projekte abgelegt habe .
common.yml
Stufen:
- erstellen
- testen
- überprüfen
- bereitstellen
Variablen:
SONAR_ARGS: "
-Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA}
-Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}
"
.build_java_project:
Stufe: erstellen
Tags:
- touchbit-shell
Variablen:
SKIP_TEST: "false"
Skript:
- mvn clean
- mvn package -DskipTests=${SKIP_TEST}
Artefakte:
wenn: immer
Ablauf_in: 30 Tage
Pfade:
- "*/target/reports"
.build_sphinx_doc:
Stufe: erstellen
Tags:
- touchbit-shell
Variablen:
DOCKERFILE: .indirect/docs/Dockerfile
Skript:
- docker build --no-cache -t ${CI_PROJECT_NAME}/doc -f ${DOCKERFILE} .
.junit_module_test_run:
Stufe: testen
Tags:
- touchbit-shell
Variablen:
MODULE: ""
Skript:
- cd ${MODULE}
- mvn test
Artefakte:
wenn: immer
Ablauf_in: 30 Tage
Pfade:
- "*/target/reports"
.junit_test_run:
Stufe: testen
Tags:
- touchbit-shell
Skript:
- mvn test
Artefakte:
wenn: immer
Ablauf_in: 30 Tage
Pfade:
- "*/target/reports"
.sonar_review:
Stufe: überprüfen
Tags:
- touchbit-shell
Abhängigkeiten: []
Skript:
- >
wenn [ "$CI_BUILD_REF_NAME" == "master" ]; dann
mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS
sonst
mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS -Dsonar.analysis.mode=preview
fi
.trigger_deploy:
Stufe: bereitstellen
Tags:
- touchbit-shell
Variablen:
URL: "https://gitlab.com/api/v4/projects/10345765/trigger/pipeline"
POST_DATA: "
token=${DEPLOY_TOKEN}&
ref=master&
variables[DEPLOY]=${DEPLOY}&
variables[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
variables[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
variables[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
variables[DEPLOY_CI_COMMIT_TAG]=${CI_COMMIT_TAG}
"
Skript:
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}
.trigger_release_deploy:
erweitert: .trigger_deploy
nur:
- Tags
.trigger_snapshot_deploy:
erweitert: .trigger_deploy
wann: manuell
außer:
- Tags
In den Java-Projekten selbst sieht die .gitlab-ci.yml recht kompakt und prägnant aus.
.gitlab-ci.yml
include: https://gitlab.com/TouchBIT/gitlab-ci/raw/master/common.yml
Shields4J:
extends: .build_java_project
Sphinx-Dokumentation:
extends: .build_sphinx_doc
variables:
DOCKERFILE: .docs/Dockerfile
Sonar-Überprüfung:
extends: .sonar_review
dependencies:
- Shields4J
Release:
extends: .trigger_release_deploy
Snapshot:
extends: .trigger_snapshot_deployKonfiguration der pom.xml
Dieses Thema ist sehr detailliert beschrieben. in , daher werde ich einige Nuancen bei der Verwendung von Plugins beschreiben. Auch werde ich erläutern, wie einfach und unkompliziert man sie verwenden kann. nexus-staging-maven-plugin, falls Sie org.sonatype.oss:oss-parent nicht als übergeordnetes Element für Ihr Projekt nutzen möchten oder können.
maven-install-plugin
Installiert Module im lokalen Repository.
Ist sehr nützlich für lokale Überprüfungen von Lösungen in anderen Projekten sowie für die Checksumme.
org.apache.maven.plugins
maven-install-plugin
install-project
install
target/${project.artifactId}-${project.version}.jar
```target/${project.artifactId}-${project.version}-sources.jar
dependency-reduced-pom.xml
true
truemaven-javadoc-plugin
Generierung der javadoc für das Projekt.
org.apache.maven.plugins
maven-javadoc-plugin
jar
prepare-package
true
true
falseWenn Sie ein Modul haben, das keinen Java-Code enthält (z. B. nur Ressourcen),
oder Sie möchten grundsätzlich keine Javadoc generieren, dann hilft Ihnen maven-jar-plugin
org.apache.maven.plugins
maven-jar-plugin
empty-javadoc-jar
generate-resources
jar
javadoc
${basedir}/javadocmaven-gpg-plugin
org.apache.maven.plugins
maven-gpg-plugin
sign-artifacts
deploy
signnexus-staging-maven-plugin
Konfiguration:
org.sonatype.plugins
nexus-staging-maven-plugin
org.sonatype.plugins
nexus-staging-maven-plugin
true
sonatype
https://oss.sonatype.org/
true
org.apache.maven.plugins
maven-deploy-plugin
true
sonatype
Nexus Snapshot Repository
https://oss.sonatype.org/content/repositories/snapshots/
sonatype
Nexus Release Repository
https://oss.sonatype.org/service/local/staging/deploy/maven2/Falls Ihr Projekt mehrere Module umfasst und Sie keinen bestimmten Modul in das Repository hochladen müssen, fügen Sie bitte in die pom.xml dieses Moduls nexus-staging-maven-plugin das Flag skipNexusStagingDeployMojo
org.sonatype.plugins
nexus-staging-maven-plugin
trueNach dem Hochladen sind snapshot/release-Versionen im
SonatypeNexus
https://oss.sonatype.org/content/groups/staging/
Weitere Vorteile
- Eine sehr umfassende Liste von Zielen für die Arbeit mit dem Nexus-Repository (
mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin). - Automatische Überprüfung der Release-Bereitschaft für Maven Central
Ergebnis
Veröffentlichung der SNAPSHOT-Version
Beim Bauen des Projekts besteht die Möglichkeit, manuell die Aufgabe zum Hochladen der SNAPSHOT-Version in Nexus zu starten.
Beim Start dieser Aufgabe wird die entsprechende Aufgabe im Deploy-Projekt ausgelöst ().
Gekürztes Protokoll
Ausführung mit gitlab-runner 11.10.0 (3001a600)
auf Deployment-Runner JSKWyxUw
Verwendung des Shell-Executors...
Ausführung auf ih1174328.vds.myihor.ru...
Überspringe die Einrichtung des Git-Repositories
Überspringe den Git-Checkout
Überspringe die Einrichtung der Git-Submodule
$ rm -rf .* *
$ git config --global credential.helper store
$ echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
$ git clone ${DEPLOY_CI_REPOSITORY_URL} .
Klonen in 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Hinweis: Auschecken von '850f86aa317194395c5387790da1350e437125a7'.
Sie befinden sich im 'detached HEAD'-Zustand. Sie können sich umsehen, experimentelle
Änderungen vornehmen und diese committen; Sie können alle Commits, die Sie in diesem
Zustand vornehmen, verwerfen, ohne dass dies andere Branches beeinflusst, indem Sie einen weiteren Checkout durchführen.
Wenn Sie einen neuen Branch erstellen möchten, um die von Ihnen vorgenommenen Commits zu behalten, können Sie
dies tun (jetzt oder später) mit -b beim Checkout-Befehl. Beispiel:
git checkout -b new_branch_name
HEAD befindet sich jetzt bei 850f86a... überspringe das Deployment test-core
$ for pom in $(find . -name pom.xml); do # mehrzeilige Anweisung zusammengefasst
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # mehrzeilige Anweisung zusammengefasst
[INFO] Durchsuche nach Projekten...
[INFO] Überprüfe den Build mit insgesamt 4 Modulen...
[INFO] Installiere Nexus-Staging-Funktionen:
[INFO] ... insgesamt 4 Ausführungen des maven-deploy-plugin durch nexus-staging-maven-plugin ersetzt
[INFO] ------------------------------------------------------------------------
[INFO] Build-Reihenfolge des Reaktors:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Shields4J-Client [jar]
[INFO] TestNG-Listener [jar]
[INFO]
[INFO] -----------------------------
[INFO] Baue Shields4J 1.0.0 [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Suche nach lokalem Aggregator-Root...
[INFO] Lokaler Aggregations-Root: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Verarbeite Änderung von org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Verarbeite org.touchbit.shields4j:shields4j-parent
[INFO] Aktualisiere Projekt org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO]
[INFO] Verarbeite org.touchbit.shields4j:client
[INFO] Aktualisiere übergeordnetes org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO] Aktualisiere Abhängigkeit org.touchbit.shields4j:test-core
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO]
[INFO] Verarbeite org.touchbit.shields4j:test-core
[INFO] Aktualisiere übergeordnetes org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO]
[INFO] Verarbeite org.touchbit.shields4j:testng
[INFO] Aktualisiere übergeordnetes org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO] Aktualisiere Abhängigkeit org.touchbit.shields4j:client
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO] Aktualisiere Abhängigkeit org.touchbit.shields4j:test-core
[INFO] von Version 1.0.0 zu 1.0.0-SNAPSHOT
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Zusammenfassung des Reaktors:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ERFOLG [ 0.992 s]
[INFO] test-core .......................................... ÜBERSPRINGEN
[INFO] Shields4J-Client ................................... ÜBERSPRINGEN
[INFO] TestNG-Listener 1.0.0 .............................. ÜBERSPRINGEN
[INFO] ------------------------------------------------------------------------
[INFO] BUILD ERFOLG
[INFO] ------------------------------------------------------------------------
[INFO] Gesamte Zeit: 2.483 s
[INFO] Fertiggestellt am: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Durchsuche nach Projekten...
[INFO] Überprüfe den Build mit insgesamt 4 Modulen...
[INFO] Installiere Nexus-Staging-Funktionen:
[INFO] ... insgesamt 4 Ausführungen des maven-deploy-plugin durch nexus-staging-maven-plugin ersetzt
[INFO] ------------------------------------------------------------------------
[INFO] Build-Reihenfolge des Reaktors:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Shields4J-Client [jar]
[INFO] TestNG-Listener [jar]
[INFO]
[INFO] -----------------------------
[INFO] Baue Shields4J 1.0.0-SNAPSHOT [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
ENFERNT
...
[INFO] * Massenbereitstellung von lokal gesammelten Snapshot-Artefakten abgeschlossen.
[INFO] Remote-Bereitstellung erfolgreich abgeschlossen.
[INFO] ------------------------------------------------------------------------
[INFO] Zusammenfassung des Reaktors:
[INFO]
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... ERFOLG [ 2.375 s]
[INFO] test-core .......................................... ERFOLG [ 3.929 s]
[INFO] Shields4J-Client ................................... ERFOLG [ 3.815 s]
[INFO] TestNG-Listener 1.0.0-SNAPSHOT ..................... ERFOLG [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD ERFOLG
[INFO] ------------------------------------------------------------------------
[INFO] Gesamte Zeit: 47.629 s
[INFO] Fertiggestellt am: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------In der Folge wurde die Version in Nexus hochgeladen .
Alle Snapshot-Versionen können aus dem Repository auf der Website entfernt werden unter Ihrem Konto.
Veröffentlichung der Release-Version
Beim Setzen des Tags wird automatisch die entsprechende Aufgabe im Deploy-Projekt ausgelöst, um die Release-Version in Nexus hochzuladen ().
Das Angenehmste ist, dass automatisch der Close Release in Nexus aktiviert wird.
[INFO] Führe Remote-Staging durch...
[INFO]
[INFO] * Remote-Staging in das Staging-Profil-ID "9043b43f77dcc9"
[INFO] * 创建了ID为"orgtouchbit-1037"的Staging-Repository。
[INFO] * Staging-Repository unter https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO] * Hochladen der lokal staggerten Artefakte zum Profil org.touchbit
[INFO] * Upload lokal gestaggerter Artefakte abgeschlossen.
[INFO] * Schließe das Staging-Repository mit der ID "orgtouchbit-1037".
Warten auf den Abschluss der Operation...
.........
[INFO] Remote-gestagtes 1 Repository, erfolgreich abgeschlossen.
[INFO] ------------------------------------------------------------------------
[INFO] Zusammenfassung des Reaktors:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ERFOLG [ 9.603 s]
[INFO] test-core .......................................... ERFOLG [ 3.419 s]
[INFO] Shields4J-Client ................................... ERFOLG [ 9.793 s]
[INFO] TestNG-Listener 1.0.0 .............................. ERFOLG [01:23 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD ERFOLG
[INFO] ------------------------------------------------------------------------
[INFO] Gesamtzeit: 01:47 min
[INFO] Fertiggestellt am: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------Und falls etwas schiefgeht, wird die Aufgabe definitiv scheitern
[INFO] Remote-Staging wird durchgeführt...
[INFO]
[INFO] * Remote-Staging in Staging-Profil-ID "9043b43f77dcc9"
[INFO] * Staging-Repository mit ID "orgtouchbit-1038" erstellt.
[INFO] * Staging-Repository unter https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO] * Hochladen lokal gestagter Artefakte in Profil org.touchbit
[INFO] * Upload lokal gestagter Artefakte abgeschlossen.
[INFO] * Schließe Staging-Repository mit ID "orgtouchbit-1038".
Warten auf Abschluss der Operation...
.......
[ERROR] Regel-Fehler beim Versuch, das Staging-Repository mit ID "orgtouchbit-1039" zu schließen.
[ERROR]
[ERROR] Nexus Staging-Regeln Fehlerbericht
[ERROR] ==================================
[ERROR]
[ERROR] Repository "orgtouchbit-1039" Fehler
[ERROR] Regel "signature-staging" Fehler
[ERROR] * Kein öffentlicher Schlüssel: Schlüssel mit ID: (1f42b618d1cbe1b5) konnte auf http://keys.gnupg.net:11371/ nicht gefunden werden. Laden Sie Ihren öffentlichen Schlüssel hoch und versuchen Sie es erneut.
...
[ERROR] Bereinigen des lokalen Staging-Verzeichnisses nach einem Regel-Fehler beim Schließen der Staging-Repositories: [orgtouchbit-1039]
[ERROR] * Löschen des Kontexts 9043b43f77dcc9.properties
[ERROR] Bereinigen der Remote-Staging-Repositories nach einem Regel-Fehler beim Schließen der Staging-Repositories: [orgtouchbit-1039]
[ERROR] * Löschen des fehlgeschlagenen Staging-Repository mit ID "orgtouchbit-1039" (Regel-Fehler beim Schließen der Staging-Repositories: [orgtouchbit-1039]).
[ERROR] Remote-Staging beendet mit einem Fehler: Fehler bei den Staging-Regeln!
[INFO] ------------------------------------------------------------------------
[INFO] Zusammenfassung des Reaktors:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ERFOLG [ 4.073 s]
[INFO] test-core .......................................... ERFOLG [ 2.788 s]
[INFO] Shields4J-Client ................................... ERFOLG [ 3.962 s]
[INFO] TestNG-Listener 1.0.0 .............................. FEHLER [01:07 min]
[INFO] ------------------------------------------------------------------------
[INFO] BAUFEHLER
[INFO] ------------------------------------------------------------------------Für uns bleibt nur eine Wahl: entweder diese Version löschen oder veröffentlichen.
Nach der Veröffentlichung werden die Artefakte irgendwann in
Offtopic
Es war eine Überraschung für mich, dass Maven andere öffentliche Repositories indiziert.
Ich musste robots.txt anpassen, da es mein altes Repository indiziert hat.
Fazit
Was haben wir?
- Ein separates Deploy-Projekt, in dem mehrere CI-Aufgaben zur Bereitstellung von Artefakten in öffentliche Repositories für verschiedene Entwicklungssprachen umgesetzt werden können.
- Das Deploy-Projekt ist vor externen Eingriffen isoliert und kann nur von Benutzern mit der Rolle Owner und Maintainer geändert werden.
- Ein separater spezifischer Runner mit einem ‚heißen‘ Cache, der nur Deploy-Aufgaben ausführt.
- Veröffentlichung von Snapshot-/Release-Versionen in einem öffentlichen Repository.
- Automatische Überprüfung der Release-Version auf Veröffentlichungsbereitschaft im Maven Central.
- Schutz vor der automatischen Veröffentlichung von ‚rohen‘ Versionen im Maven Central.
- Erstellung und Veröffentlichung von Snapshot-Versionen ‚auf Klick‘.
- Ein zentrales Repository für den Erhalt von Snapshot-/Release-Versionen.
- Gemeinsame Pipeline zur Erstellung/Testung/Veröffentlichung des Java-Projekts.
Die Einrichtung von GitLab CI ist nicht so kompliziert, wie es auf den ersten Blick scheint. Wenn Sie CI "schlüsselfertig" ein paar Mal eingerichtet haben, sind Sie bereits kein Anfänger mehr. Besonders die Dokumentation von GitLab ist sehr umfangreich. Scheuen Sie sich nicht, den ersten Schritt zu tun. Der Weg entsteht im Gehen (ich weiß nicht mehr, wer das gesagt hat 🙂).
Ich freue mich über Ihr Feedback.
Im nächsten Artikel werde ich erklären, wie Sie GitLab CI für die gleichzeitige Ausführung von Aufgaben mit Integrationstests einrichten (mit der Ausführung der zu testenden Dienste über docker-compose), wenn Sie nur einen Shell-Runner haben.
Quelle: habr.com
