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. In diesem Artikel werde ich die Konfiguration von gitlab-runner, gitlab-ci und dem Maven-Plugin für diese Aufgabe erläutern.
Voraussetzungen:
- Sichere Speicherung von mvn- und GPG-Schlüsseln.
- Sichere Durchführung öffentlicher CI-Aufgaben.
- 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 Veröffentlichungsmechanismus von Artefakten in Maven Central über den Sonatype OSS Repository Hosting Service wurde bereits in vom Benutzer , daher werde ich an den benötigten Stellen auf diesen Artikel verweisen.
- Vorab registrieren wir uns bei und erstellen ein Ticket zur Eröffnung des Repositories (lesen Sie mehr im Abschnitt ). Nach Eröffnung des Repositories wird ein Paar von Login/Passwort von JIRA (später Sonatype-Konto) zum Hochladen von Artefakten in Sonatype Nexus verwendet.
- Im Folgenden wird der Prozess zur Generierung des GPG-Schlüssels ziemlich knapp beschrieben. Mehr dazu im Abschnitt
- Wenn Sie die Linux-Konsole zur Generierung des GPG-Schlüssels (gnupg/gnupg2) verwenden, müssen Sie zur Generierung von Entropie installieren. Andernfalls kann die Schlüsselgenerierung 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 die Pipeline für die Bereitstellung von Artefakten gespeichert wird. Ich habe mein Projekt einfach und unkompliziert genannt —
- Nach der Erstellung des Repositories müssen Sie den Zugriff auf Änderungen des Repositories einschränken.
Wir gehen zu Projekt -> Einstellungen -> Repository -> Geschützte Branches. Wir löschen alle Regeln und fügen eine einzige Regel mit dem Platzhalter * hinzu, die das Pushen und Mergen nur für Benutzer mit der Rolle Maintainer erlaubt. Diese Regel gilt für alle Benutzer dieses Projekts sowie für die Gruppe, zu der dieses Projekt gehört.
- Wenn es mehrere Maintainer gibt, wäre es am besten, den Zugang zum Projekt grundsätzlich zu beschränken.
Wir gehen zu Projekt -> Einstellungen -> Allgemein -> Sichtbarkeit, Projektfunktionen, Berechtigungen und setzen die Projekt Sichtbarkeit auf den Wert Privat.
Mein Projekt ist öffentlich zugänglich, da ich meinen eigenen GitLab Runner verwende und nur ich das Recht habe, das Repository zu ändern. Außerdem liegt es nicht in meinem Interesse, private Informationen in öffentlichen Pipeline-Protokollen zu veröffentlichen. - Verschärfung der Regeln für die Änderung des Repositories
Wir gehen zu Projekt -> Einstellungen -> Repository -> Push-Regeln und aktivieren die Flags Committer-Einschränkung und Überprüfen, ob der Autor ein GitLab-Benutzer ist. Ich empfehle auch , und setze das Flag Unsigned Commits ablehnen. - Als Nächstes müssen wir einen Trigger für den Start von Aufgaben einrichten.
Wir gehen zu Projekt -> Einstellungen -> CI / CD -> Pipeline-Trigger und erstellen ein neues Trigger-Token.
Dieses Token kann sofort in die allgemeine Konfiguration der Variablen für die Projektgruppe aufgenommen werden.
Wir gehen zu Gruppe -> Einstellungen -> CI / CD -> Variablen und fügen die VariableDEPLOY_TOKENmit dem Trigger-Token als Wert hinzu.
GitLab Runner
In diesem Abschnitt wird die Konfiguration zum Starten von Deploy-Aufgaben mit einem eigenen (Specific) und öffentlichen (Shared) Runner beschrieben.
Spezifischer Runner
Ich benutze eigene Runner, da dies in erster Linie bequem, schnell und kostengünstig ist.
Für den Runner empfehle ich einen Linux VDS mit 1 CPU, 2 GB RAM und 20 GB HDD. Der Preis liegt bei etwa 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. Hat etwa 11000₽ gekostet und ich habe es keine Sekunde bereut.
Ich habe insgesamt 7 Maschinen. 5 bei aruba und 2 bei ihor.
So, wir haben einen Runner. Jetzt werden wir ihn einrichten.
Wir verbinden uns per SSH mit der Maschine und installieren Java, Git, Maven, GnuPG2.
Wir installieren den GitLab Runner
- Wir erstellen eine neue Gruppe
runnersudo groupadd runner - Wir erstellen ein Verzeichnis für den Maven-Cache und setzen die Gruppenberechtigungen
runner
Dieser Punkt kann übersprungen werden, wenn Sie nicht planen, mehrere Runner auf derselben Maschine auszuführen.mkdir -p /usr/cache/.m2/repository chown -R :runner /usr/cache chmod -R 770 /usr/cache - Wir erstellen einen Benutzer
gitlab-deployerund fügen ihn zur Gruppe hinzu.runneruseradd -m -d /home/gitlab-deployer gitlab-deployer usermod -a -G runner gitlab-deployer - Wir fügen in die Datei
/etc/ssh/sshd_configdie folgende Zeile ein.ErlaubenBenutzer root@* gitlab-deployer@127.0.0.1 - Wir starten neu
sshdsystemctl restart sshd - Wir setzen ein Passwort für den Benutzer
gitlab-deployer(ein einfaches ist möglich, da es Einschränkungen für localhost gibt)passwd gitlab-deployer - Wir installieren 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 - Wir gehen auf die Seite gitlab.com -> deploy-projekt -> Einstellungen -> CI/CD -> Runner -> Spezifische Runner und kopieren den Registrierungstoken
Screenshot
- Wir registrieren den Runner
gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml
Prozess
Laufzeitplattform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Ausführung 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 (durch Kommas getrennt):
deply
Registrierung des Runners... erfolgreich runner=ZvKdjJhx
Bitte wählen Sie den Executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner erfolgreich registriert. Sie können ihn gerne starten, aber wenn er bereits läuft, sollte die Konfiguration automatisch neu geladen werden!- Wir überprüfen, ob der Runner registriert ist. Wir gehen auf die Seite gitlab.com -> deploy-projekt -> Einstellungen -> CI/CD -> Runner -> Spezifische Runner -> Für dieses Projekt aktivierte Runner
Screenshot
- Hinzufügen einzelner Dienst
/etc/systemd/system/gitlab-deployer.service[Unit] Beschreibung=GitLab Deploy Runner Nach=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
- Von dieser Maschine aus melden wir uns 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 - Wir generieren den Schlüssel, indem wir die Fragen beantworten. Ich habe meinen eigenen Namen und meine E-Mail verwendet.
Vergessen Sie nicht, ein Passwort für den Schlüssel anzugeben. Mit diesem Schlüssel werden die Artefakte signiert.gpg --gen-key - Ü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 - Wir laden unseren öffentlichen Schlüssel auf den Schlüsselserver hoch
gpg --keyserver keys.gnupg.net --send-key 00000000 gpg: sende Schlüssel 00000000 an hkp-Server keys.gnupg.net
Maven-Konfiguration
- Wir melden uns als Benutzer an
gitlab-deployersu gitlab-deployer - Wir erstellen das Verzeichnis maven repository und verlinken es mit dem Cache (nicht verwechseln)
Dieser Punkt kann übersprungen werden, wenn Sie nicht planen, mehrere Runner auf einem Computer auszuführen.mkdir -p ~\/ .m2\/repository ln -s \/usr\/cache\/ .m2\/repository \/home\/gitlab-deployer\/ .m2\/repository - Erstellen des Master-Schlüssels
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Erstellen der Datei ~\/ .m2\/settings-security.xml
{hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Verschlüsseln des Passworts für das Sonatype-Konto
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Erstellen der Datei ~\/ .m2\/settings.xml
env true GPG_SECRET_KEY_PASSPHRASE sonatype SONATYPE_USERNAME {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
wo,
GPG_SECRET_KEY_PASSPHRASE — Passwort des GPG-Schlüssels
SONATYPE_USERNAME — Login für das Sonatype-Konto
Damit ist die Konfiguration des Runners abgeschlossen, wir können zum Abschnitt übergehen
Geteilter Runner
Generierung von GPG-Schlüsseln
- Zunächst ist es notwendig, einen GPG-Schlüssel zu erstellen. Dazu installieren wir gnupg.
yum install -y gnupg - Generieren Sie den Schlüssel, indem Sie die Fragen beantworten. Ich habe meinen eigenen Namen und die eigene E-Mail verwendet. Geben Sie unbedingt ein Passwort für den Schlüssel an.
gpg --gen-key - Informationen zum Schlüssel anzeigen
gpg --list-keys -a pub rsa3072 2019-04-24 [SC] [läuft ab: 2021-04-23] 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 uid [final] tttemp sub rsa3072 2019-04-24 [E] [läuft ab: niemals] - Wir laden unseren öffentlichen Schlüssel auf den Schlüsselserver hoch
gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 gpg: Sende Schlüssel 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 an hkp-Server keys.gnupg.net - Den privaten Schlüssel abrufen
gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 -----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5 ... =2Wd2 -----END PGP PRIVATE KEY BLOCK----- - Gehe zu den Projekteinstellungen -> Einstellungen -> CI / CD -> Variablen und speichere den privaten Schlüssel in einer Variablen
GPG_SECRET_KEY
Maven-Konfiguration
- Erstellen des Master-Schlüssels
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Gehe zu den Projekteinstellungen -> Einstellungen -> CI / CD -> Variablen und speichere in einer Variablen
SETTINGS_SECURITY_XMLfolgende Zeilen:{hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Verschlüsseln des Passworts für das Sonatype-Konto
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Gehe zu den Projekteinstellungen -> Einstellungen -> CI / CD -> Variablen und speichere in einer Variablen
SETTINGS_XMLfolgende Zeilen:env true GPG_SECRET_KEY_PASSPHRASE sonatype sonatype_username {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
wo,
GPG_SECRET_KEY_PASSPHRASE — Passwort des GPG-Schlüssels
SONATYPE_USERNAME — Login für das Sonatype-Konto
Bereitstellung des Docker-Images
- Wir erstellen eine ausreichend einfache Dockerdatei, um Aufgaben mit der benötigten Version von Java bereitzustellen. Im Folgenden finden Sie ein Beispiel für Alpine.
VON 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 bauen den 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 Datei .gitlab-ci.yml in das Stammverzeichnis des Deploy-Projekts ein
Das Skript enthält zwei sich gegenseitig ausschließende Aufgaben für das Deployment. Specific Runner oder Shared Runner entsprechend.
.gitlab-ci.yml
stages:
- deploy
Specific Runner:
extends: .java_deploy_template
# Die Aufgabe wird auf Ihrem Shell-Runner ausgeführt
tags:
- deploy
Shared Runner:
extends: .java_deploy_template
# Die Aufgabe wird auf einem öffentlichen Docker-Runner ausgeführt
tags:
- docker
# Image aus dem Abschnitt GitLab Runner -> Shared 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 Maven-Konfiguration
- printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
- printf "${SETTINGS_XML}" > ~/.m2/settings.xml
.java_deploy_template:
stage: deploy
# Die Aufgabe wird durch einen Trigger gestartet, wenn die Variable DEPLOY mit dem Wert java übergeben wird
only:
variables:
- $DEPLOY == "java"
variables:
# Deaktivieren des Klonens des aktuellen Projekts
GIT_STRATEGY: none
script:
# Ermöglicht das Speichern des Passworts im unverschlüsselten Format
- git config --global credential.helper store
# Speichere temporäre Kredentialien für den Benutzer gitlab-ci-token
# 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
# Reinigen des aktuellen Verzeichnisses
- rm -rf .* *
# Klone das Projekt, das wir in Sonatype Nexus bereitstellen werden
- git clone ${DEPLOY_CI_REPOSITORY_URL} .
# Wechseln Sie zu dem gewünschten Commit
- git checkout ${DEPLOY_CI_COMMIT_SHA} -f
# Wenn eine pom.xml den Parameter autoReleaseAfterClose enthält, scheitert der Build.
# Andernfalls besteht die Gefahr, rohe Artefakte in das Maven Central hochzuladen
- >
for pom in $(find . -name pom.xml); do
if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
echo "Datei $pom enthält die verbotene Einstellung: ";
exit 1;
fi;
done
# Wenn der Parameter DEPLOY_CI_COMMIT_TAG leer ist, setzen wir zwangsläufig die SNAPSHOT-Version
- >
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 Erstellen und Bereitstellen der Artefakte
- mvn clean deploy -DskipTests=trueJava-Projekt
In Java-Projekten, die in öffentliche Repositories hochgeladen werden sollen, müssen zwei Schritte für die Bereitstellung von Release- und Snapshot-Versionen hinzugefügt werden.
.gitlab-ci.yml
stages:
- build
- test
- verify
- deploy
Release:
extends: .trigger_deploy
# Auf diese Aufgabe nur nach Tag ausführen.
only:
- tags
Snapshot:
extends: .trigger_deploy
# Aufgabe für die Veröffentlichung der SNAPSHOT-Version manuell starten
when: manual
# Aufgabe nicht starten, wenn ein Tag gesetzt ist.
except:
- tags
.trigger_deploy:
stage: deploy
variables:
# Klonen des aktuellen Projekts deaktivieren
GIT_STRATEGY: none
# Link zum Trigger der Deploy-Aufgabe
URL: "https://gitlab.com/api/v4/projects//trigger/pipeline"
# Variablen der 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:
# Verwende kein cURL, da mit den Flags --fail --show-error
# der Antwortinhalt nicht angezeigt wird, 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 beschlossen, eine CI-Vorlage für Java-Projekte zu verwenden.
Genauer gesagt
Ich habe ein separates Projekt erstellt in dem ich die CI-Vorlage für Java-Projekte platziert habe .
common.yml
phasen:
- 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:
phase: erstellen
tags:
- touchbit-shell
variablen:
SKIP_TEST: "false"
skript:
- mvn clean
- mvn package -DskipTests=${SKIP_TEST}
artefakte:
wenn: immer
ablaufen_in: 30 tag
pfade:
- "*\/target\/reports"
.build_sphinx_doc:
phase: 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:
phase: testen
tags:
- touchbit-shell
variablen:
MODUL: ""
skript:
- cd ${MODUL}
- mvn test
artefakte:
wenn: immer
ablaufen_in: 30 tag
pfade:
- "*\/target\/reports"
.junit_test_run:
phase: testen
tags:
- touchbit-shell
skript:
- mvn test
artefakte:
wenn: immer
ablaufen_in: 30 tag
pfade:
- "*\/target\/reports"
.sonar_review:
phase: ü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:
phase: bereitstellen
tags:
- touchbit-shell
variablen:
URL: "https:\/\/gitlab.com\/api\/v4\/projects\/10345765\/trigger\/pipeline"
POST_DATA: "
token=${DEPLOY_TOKEN}&
ref=master&
variablen[DEPLOY]=${DEPLOY}&
variablen[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
variablen[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
variablen[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
variablen[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
wenn: manuell
außer:
- tags
In der Tat sieht die .gitlab-ci.yml in den Java-Projekten selbst recht kompakt und prägnant aus.
.gitlab-ci.yml
einfügen: https:\/\/gitlab.com\/TouchBIT\/gitlab-ci\/raw\/master\/common.yml
Shields4J:
erweitert: .build_java_project
Sphinx-Dokumentation:
erweitert: .build_sphinx_doc
variablen:
DOCKERFILE: .docs\/Dockerfile
Sonar-Überprüfung:
erweitert: .sonar_review
abhängigkeiten:
- Shields4J
Veröffentlichung:
erweitert: .trigger_release_deploy
Schnappschuss:
erweitert: .trigger_snapshot_deployKonfiguration der pom.xml
Dieses Thema wird sehr detailliert behandelt. in , deshalb werde ich einige Nuancen der Verwendung von Plugins beschreiben. Außerdem werde ich erläutern, wie einfach und unaufdringlich sie verwendet werden können. nexus-staging-maven-plugin, wenn Sie org.sonatype.oss:oss-parent nicht als Elternteil Ihres Projekts verwenden möchten oder können.
maven-install-plugin
Installiert Module im lokalen Repository.
Sehr nützlich für lokale Überprüfungen von Lösungen in anderen Projekten sowie zur Kontrolle.
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 von 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 wenn Sie im Prinzip keine javadoc generieren möchten, dann hilft 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/Wenn Sie ein Multimodul-Projekt haben und es nicht notwendig ist, ein bestimmtes Modul in das Repository hochzuladen, müssen Sie in der pom.xml dieses Moduls hinzufügen nexus-staging-maven-plugin mit dem Flag skipNexusStagingDeployMojo
org.sonatype.plugins
nexus-staging-maven-plugin
trueNach dem Hochladen sind Snapshot/Release-Versionen in
SonatypeNexus
https://oss.sonatype.org/content/groups/staging/
Weitere Vorteile
- Eine sehr umfangreiche Liste von Zielen zur Arbeit mit dem Nexus-Repository (
mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin). - Automatische Überprüfung des Releases auf die Möglichkeit, in Maven Central hochgeladen zu werden
Ergebnis
Veröffentlichung von SNAPSHOT-Versionen
Bei der Erstellung des Projekts besteht die Möglichkeit, die Aufgabe zum manuellen Hochladen der SNAPSHOT-Version in Nexus zu starten
Beim Start dieser Aufgabe wird die entsprechende Aufgabe im Projekt Deploy ausgelöst ().
Reduzierte Protokollierung
Ausführen mit gitlab-runner 11.10.0 (3001a600)
auf Deploy runner JSKWyxUw
Verwendung von Shell-Executor...
Wird auf ih1174328.vds.myihor.ru ausgeführt...
Überspringe die Einrichtung des Git-Repositorys
Ü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} .
Clone in 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Hinweis: Überprüfe '850f86aa317194395c5387790da1350e437125a7'.
Du befindest dich im Status 'detached HEAD'. Du kannst dich umsehen, experimentelle
Änderungen vornehmen und diese committen, und du kannst alle Commits, die du in diesem
Zustand machst, verwerfen, ohne dass dies Auswirkungen auf irgendwelche Branches hat, indem du einen anderen Checkout durchführst.
Wenn du einen neuen Branch erstellen möchtest, um die Commits zu behalten, die du erstellst, kannst du dies
jetzt oder später mit -b beim Checkout-Befehl erneut tun. Beispiel:
git checkout -b neuer_branch_name
HEAD ist jetzt auf 850f86a... überspringe den Deploy-Test-Kern
$ for pom in $(find . -name pom.xml); do # zusammengeklappt mehrzeiliges Kommando
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # zusammengeklappt mehrzeiliges Kommando
[INFO] Scanne nach Projekten...
[INFO] Überprüfe den Build mit insgesamt 4 Modulen...
[INFO] Installiere Nexus-Staging-Funktionen:
[INFO] ... insgesamt 4 Ausführungen des maven-deploy-plugins wurden durch nexus-staging-maven-plugin ersetzt
[INFO] ------------------------------------------------------------------------
[INFO] Reihenfolge des Reaktor-Baus:
[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-Wurzel...
[INFO] Lokale Aggregierungswurzel: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Verarbeitung der Änderung von org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Verarbeitung von org.touchbit.shields4j:shields4j-parent
[INFO] Aktueller Projekt org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO]
[INFO] Verarbeitung von org.touchbit.shields4j:client
[INFO] Aktualisiere übergeordneten org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO] Aktualisiere Abhängigkeit org.touchbit.shields4j:test-core
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO]
[INFO] Verarbeitung von org.touchbit.shields4j:test-core
[INFO] Aktualisiere übergeordneten org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO]
[INFO] Verarbeitung von org.touchbit.shields4j:testng
[INFO] Aktualisiere übergeordneten org.touchbit.shields4j:shields4j-parent
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO] Aktualisiere Abhängigkeit org.touchbit.shields4j:client
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO] Aktualisiere Abhängigkeit org.touchbit.shields4j:test-core
[INFO] von Version 1.0.0 auf 1.0.0-SNAPSHOT
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Reaktor-Zusammenfassung:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ERFOLG [ 0.992 s]
[INFO] test-core .......................................... ÜBERSPRUNGEN
[INFO] Shields4J-Client ................................... ÜBERSPRUNGEN
[INFO] TestNG-Listener 1.0.0 .............................. ÜBERSPRUNGEN
[INFO] ------------------------------------------------------------------------
[INFO] BAU-ERFOLG
[INFO] ------------------------------------------------------------------------
[INFO] Gesamtzeit: 2.483 s
[INFO] Fertig um: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Scanne nach Projekten...
[INFO] Überprüfe den Build mit insgesamt 4 Modulen...
[INFO] Installiere Nexus-Staging-Funktionen:
[INFO] ... insgesamt 4 Ausführungen des maven-deploy-plugins wurden durch nexus-staging-maven-plugin ersetzt
[INFO] ------------------------------------------------------------------------
[INFO] Reihenfolge des Reaktor-Baus:
[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 ]---------------------------------
...
LÖSCHEN
...
[INFO] * Massenbereitstellung der lokal gesammelten Snapshot-Artefakte abgeschlossen.
[INFO] Remote-Bereitstellung erfolgreich abgeschlossen.
[INFO] ------------------------------------------------------------------------
[INFO] Reaktor-Zusammenfassung:
[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] BAU-ERFOLG
[INFO] ------------------------------------------------------------------------
[INFO] Gesamtzeit: 47.629 s
[INFO] Fertig um: 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 gelöscht werden unter Ihrem Konto.
Veröffentlichung der Release-Version
Beim Setzen des Tags wird automatisch die entsprechende Aufgabe im Projekt deploy zum Hochladen der Release-Version in Nexus ausgelöst ().
Das Beste daran ist, dass das Schließen des Releases in Nexus automatisch ausgelöst wird.
[INFO] Fernveröffentlichung wird durchgeführt...
[INFO]
[INFO] * Remote-Staging in Staging-Profil-ID "9043b43f77dcc9"
[INFO] * Staging-Repository mit ID "orgtouchbit-1037" erstellt.
[INFO] * Staging-Repository unter https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO] * Hochladen lokal gestufter Artefakte in das Profil org.touchbit
[INFO] * Upload lokal gestufter Artefakte abgeschlossen.
[INFO] * Schließen des Staging-Repository mit ID "orgtouchbit-1037".
Warten auf den Abschluss der Operation...
.........
[INFO] Remote gestufte 1 Repositories, erfolgreich abgeschlossen.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor-Zusammenfassung:
[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 ERFOLGREICH
[INFO] ------------------------------------------------------------------------
[INFO] Gesamte Zeit: 01:47 min
[INFO] Fertiggestellt am: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------Und wenn etwas schiefgeht, wird die Aufgabe auf jeden Fall fehlschlagen
[INFO] Remote Staging wird durchgeführt...
[INFO]
[INFO] * Remote-Staging in das 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] * Upload von lokal gestagten Artefakten zum Profil org.touchbit
[INFO] * Upload der lokal gestagten Artefakte abgeschlossen.
[INFO] * Staging-Repository mit ID "orgtouchbit-1038" wird geschlossen.
Warten auf den Abschluss der Operation...
.......
[ERROR] Regelverstoß beim Versuch, das Staging-Repository mit ID "orgtouchbit-1039" zu schließen.
[ERROR]
[ERROR] Nexus Staging Rules 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 die Operation erneut.
...
[ERROR] Aufräumen des lokalen Stage-Verzeichnisses nach einem Regelverstoß beim Schließen der Staging-Repositories: [orgtouchbit-1039]
[ERROR] * Kontext 9043b43f77dcc9.properties wird gelöscht
[ERROR] Aufräumen der Remote-Stage-Repositories nach einem Regelverstoß beim Schließen der Staging-Repositories: [orgtouchbit-1039]
[ERROR] * Fehlerhaftes Staging-Repository mit ID "orgtouchbit-1039" wird gelöscht (Regelverstoß beim Schließen der Staging-Repositories: [orgtouchbit-1039]).
[ERROR] Remote-Staging abgeschlossen mit einem Fehler: Staging-Regelnfehler!
[INFO] ------------------------------------------------------------------------
[INFO] Reactor-Zusammenfassung:
[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] BUILD FEHLGESCHLAGEN
[INFO] ------------------------------------------------------------------------So bleibt uns nur noch die Wahl. Entweder diese Version löschen oder veröffentlichen.
Nach der Veröffentlichung werden die Artefakte nach einiger Zeit in
Offtopic
Es war für mich eine Überraschung, dass Maven andere öffentliche Repositories indiziert.
Ich musste eine robots.txt hinzufügen, da es mein altes Repository indiziert hat.
Fazit
Was haben wir?
- Ein separates Deployment-Projekt, in dem mehrere CI-Aufgaben zum Hochladen von Artefakten in öffentliche Repositories für verschiedene Programmiersprachen realisiert werden können.
- Das Deployment-Projekt ist von externen Eingriffen isoliert und kann nur von Benutzern mit den Rollen Owner und Maintainer geändert werden.
- Ein separater spezifischer Runner mit "heißen" Caches, um nur Deployment-Aufgaben auszuführen.
- Veröffentlichung von Snapshot-/Release-Versionen in einem öffentlichen Repository.
- Automatische Überprüfung der Release-Version auf die Bereitschaft zur Veröffentlichung in Maven Central.
- Schutz vor automatischer Veröffentlichung von "rohen" Versionen in Maven Central.
- Build und Veröffentlichung von Snapshot-Versionen "auf Knopfdruck".
- Einheitliches Repository zum Abrufen von Snapshot-/Release-Versionen.
- Der allgemeine Pipeline für den Aufbau/Tests/Publikation eines Java-Projekts.
Die Einrichtung von GitLab CI ist kein so kompliziertes Thema, wie es auf den ersten Blick scheint. Man muss nur ein oder zwei Mal CI „schlüsselfertig“ einrichten, und schon ist man weit entfernt von einem Anfänger in diesem Bereich. Außerdem ist die GitLab-Dokumentation sehr umfangreich. Fürchten Sie sich nicht, den ersten Schritt zu machen. Der Weg entsteht im Gehen (ich erinnere mich nicht, wer das gesagt hat 🙂 ).
Ich freue mich über Feedback.
Im nächsten Artikel werde ich darüber berichten, wie man GitLab CI für die parallele Ausführung von Aufgaben mit Integrationstests einrichtet (mit dem Start der zu testenden Dienste über docker-compose), wenn Sie nur einen Shell-Runner haben.
Quelle: habr.com
