Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

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 diesem Artikel durch den Benutzer von Googolplex, daher werde ich an den entsprechenden Stellen auf diesen Artikel verweisen.
  • Vorabregistrierung in Sonatype JIRA und Ticket zur Eröffnung des Repositories anlegen (ausführlicher in dem Abschnitt lesen Ticket in Sonatype JIRA erstellen). 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 GnuPG zur Signierung von Artefakten konfigurieren
  • Wenn Sie die Linux-Konsole zur Generierung des GPG-Schlüssels (GnuPG/GnuPG2) verwenden, müssen Sie rng-tools installieren, um Entropie zu generieren. Andernfalls kann die Schlüsselerzeugung sehr lange dauern.
  • Speicherdienste öffentlicher GPG-Schlüssel

Zurück zum Inhalt

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 — deploy
  • 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.
    Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central
  • 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, die Signatur von Commits, 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 hinzu DEPLOY_TOKEN mit dem Trigger-Token als Wert.

Zurück zum Inhalt

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.

Zurück zum Inhalt

Installieren Sie den GitLab Runner.

  • Erstellen Sie eine neue Gruppe runner
    sudo 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-deployer und fügen Sie ihn zur Gruppe hinzu. runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Fügen Sie in die Datei /etc/ssh/sshd_config die folgende Zeile ein
    AllowUsers root@* gitlab-deployer@127.0.0.1
  • Starten wir neu sshd
    systemctl 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

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

  • 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

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

  • 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

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

Zurück zum Inhalt

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

Zurück zum Inhalt

Einrichtung von Maven

  • Melden Sie sich als Benutzer an gitlab-deployer
    su 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 GitLab CI

Zurück zum Inhalt

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
    Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

Zurück zum Inhalt

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

Zurück zum Inhalt

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

Zurück zum Inhalt

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

Zurück zum Inhalt

Java-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 gitlab-ci in dem ich die CI-Vorlage für Java-Projekte abgelegt habe common.yml.

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_deploy

Zurück zum Inhalt

Konfiguration der pom.xml

Dieses Thema ist sehr detailliert beschrieben. Googolplex in Die Maven-Konfiguration für die automatische Signierung und das Hochladen von Artefakten in die Snapshot- und Staging-Repositories., 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
        
        true

Zurück zum Inhalt

maven-javadoc-plugin

Generierung der javadoc für das Projekt.

org.apache.maven.plugins
  maven-javadoc-plugin
  
    
      
        jar
      
      
      prepare-package
      
        
        true
        true
        
        false

Wenn 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}/javadoc

Zurück zum Inhalt

maven-gpg-plugin

org.apache.maven.plugins
  maven-gpg-plugin
  
    
      sign-artifacts
      
      
      deploy
      
        sign

Zurück zum Inhalt

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

Nach dem Hochladen sind snapshot/release-Versionen im Staging-Repository verfügbar

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

Zurück zum Inhalt

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.

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

Beim Start dieser Aufgabe wird die entsprechende Aufgabe im Deploy-Projekt ausgelöst (Nummer 00 oder).

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 1.0.0-SNAPSHOT.

Alle Snapshot-Versionen können aus dem Repository auf der Website entfernt werden oss.sonatype.org unter Ihrem Konto.

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

Zurück zum Inhalt

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 (Nummer 00 oder).

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

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.

Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

Nach der Veröffentlichung werden die Artefakte irgendwann in Einrichten von GitLab CI für das Hochladen von Java-Projekten in Maven Central

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.

Zurück zum Inhalt

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.

Zurück zum Inhalt

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster