GitLab CI-Konfiguration 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. 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 diesem Artikel vom Benutzer Googolplex, daher werde ich an den benötigten Stellen auf diesen Artikel verweisen.
  • Vorab registrieren wir uns bei Sonatype JIRA und erstellen ein Ticket zur Eröffnung des Repositories (lesen Sie mehr im Abschnitt Einen Ticket bei Sonatype JIRA erstellen). 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 Konfiguration von GnuPG zur Signierung von Artefakten
  • Wenn Sie die Linux-Konsole zur Generierung des GPG-Schlüssels (gnupg/gnupg2) verwenden, müssen Sie rng-tools zur Generierung von Entropie installieren. Andernfalls kann die Schlüsselgenerierung sehr lange dauern.
  • Speicherdienste öffentlicher GPG-Schlüssel

Inhaltsverzeichnis

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

Inhaltsverzeichnis

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.

Inhaltsverzeichnis

Wir installieren den GitLab Runner

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

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

  • 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

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

  • 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

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

Inhaltsverzeichnis

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

Inhaltsverzeichnis

Maven-Konfiguration

  • Wir melden uns als Benutzer an gitlab-deployer
    su 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 GitLab CI

Inhaltsverzeichnis

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

Inhaltsverzeichnis

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

Inhaltsverzeichnis

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

Inhaltsverzeichnis

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

Inhaltsverzeichnis

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

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_deploy

Inhaltsverzeichnis

Konfiguration der pom.xml

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

Inhaltsverzeichnis

maven-javadoc-plugin

Generierung von 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 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}/javadoc

Inhaltsverzeichnis

maven-gpg-plugin

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

Inhaltsverzeichnis

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/

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
      
        true

Nach dem Hochladen sind Snapshot/Release-Versionen in Staging-Repositories

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

Inhaltsverzeichnis

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

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

Beim Start dieser Aufgabe wird die entsprechende Aufgabe im Projekt Deploy ausgelöst (Beispiel).

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

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

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

Inhaltsverzeichnis

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 (Beispiel).

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

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.

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

Nach der Veröffentlichung werden die Artefakte nach einiger Zeit in GitLab CI-Konfiguration für das Hochladen von Java-Projekten in Maven Central

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.

Inhaltsverzeichnis

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.

Inhaltsverzeichnis

Quelle: habr.com

Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server 🔥 Zuverlässiges Hosting für Websites mit DDoS-Schutz kaufen, VPS VDS Server - ProHoster