GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Dit artikel is bedoeld voor Java-ontwikkelaars die hun producten snel willen publiceren in sonatype en/of maven centrale repository's met behulp van GitLab. In dit artikel zal ik het hebben over het opzetten van gitlab-runner, gitlab-ci en maven-plugin om dit probleem op te lossen.

Vereisten:

  • Veilige opslag van mvn- en GPG-sleutels.
  • Veilige uitvoering van openbare CI-taken.
  • Artefacten (release/momentopname) uploaden naar openbare opslagplaatsen.
  • Automatische controle van releaseversies voor publicatie in Maven Central.
  • Een algemene oplossing voor het uploaden van artefacten naar een repository voor meerdere projecten.
  • Eenvoud en gebruiksgemak.

Inhoud

Algemene informatie

  • Een gedetailleerde beschrijving van het mechanisme voor het publiceren van artefacten in Maven Central via Sonatype OSS Repository Hosting Service is al beschreven in Dit artikel gebruiker googolplex, dus ik zal op de juiste plaatsen naar dit artikel verwijzen.
  • Vooraf inschrijven voor Sonatype JIRA en open een ticket om de repository te openen (lees de sectie voor meer details Maak een ticket aan op Sonatype JIRA). Na het openen van de repository wordt het login/wachtwoord-paar van JIRA (hierna het Sonatype-account genoemd) gebruikt om artefacten naar Sonatype Nexus te uploaden.
  • Vervolgens wordt het proces van het genereren van een GPG-sleutel zeer droog beschreven. Zie sectie voor meer details GnuPG configureren om artefacten te ondertekenen
  • Als u de Linux-console gebruikt om een ​​GPG-sleutel (gnupg/gnupg2) te genereren, moet u deze installeren RNG-gereedschappen entropie te genereren. Anders kan het genereren van de sleutel erg lang duren.
  • Opslagdiensten openbaar GPG-sleutels

Terug naar inhoud

Een implementatieproject opzetten in GitLab

  • Allereerst moet u een project maken en configureren waarin de pijplijn wordt opgeslagen voor het implementeren van artefacten. Ik noemde mijn project eenvoudig en ongecompliceerd: implementeren
  • Nadat u de repository hebt gemaakt, moet u de toegang beperken om de repository te wijzigen.
    Ga naar project -> Instellingen -> Repository -> Beschermde vestigingen. We verwijderen alle regels en voegen een enkele regel toe met Wildcard * met het recht om alleen te pushen en samen te voegen voor gebruikers met de rol Onderhouders. Deze regel werkt voor alle gebruikers van zowel dit project als de groep waartoe dit project behoort.
    GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden
  • Als er meerdere beheerders zijn, is het in principe de beste oplossing om de toegang tot het project te beperken.
    Ga naar project -> Instellingen -> Algemeen -> Zichtbaarheid, projectfuncties, rechten en stel Projectzichtbaarheid in op Privé.
    Ik heb een publiek toegankelijk project, aangezien ik mijn eigen GitLab Runner gebruik en alleen ik toegang heb om de repository te wijzigen. Nou ja, eigenlijk is het niet in mijn belang om privé-informatie weer te geven in openbare pijplijnlogboeken.
  • Aanscherping van de regels voor het wijzigen van de repository
    Ga naar het project -> Instellingen -> Repository -> Pushregels en stel de Committer-beperking in. Controleer of de auteur een GitLab-gebruikersvlag is. Ik raad ook aan om op te zetten handtekening vastleggenen stel de vlag Niet-ondertekende commits afwijzen in.
  • Vervolgens moet u een trigger configureren om taken te starten
    Ga naar project -> Instellingen -> CI/CD -> Pipeline-triggers en maak een nieuw trigger-token
    Dit token kan onmiddellijk worden toegevoegd aan de algemene configuratie van variabelen voor een groep projecten.
    Ga naar groep -> Instellingen -> CI/CD -> Variabelen en voeg een variabele toe DEPLOY_TOKEN met trigger-token in waarde.

Terug naar inhoud

GitLab Runner

In deze sectie wordt de configuratie beschreven voor het uitvoeren van taken bij implementatie met uw eigen (specifieke) en openbare (gedeelde) runner.

Specifieke loper

Ik gebruik mijn eigen hardlopers omdat het in de eerste plaats handig, snel en goedkoop is.
Voor een hardloper raad ik een Linux VDS aan met 1 CPU, 2 GB RAM, 20 GB HDD. De uitgifteprijs bedraagt ​​~3000₽ per jaar.

Mijn hardloper

Voor de hardloper nam ik VDS 4 CPU, 4 GB RAM, 50 GB SSD. Kostte ~11000₽ en heb er nooit spijt van gehad.
Ik heb in totaal 7 machines. 5 op Aruba en 2 op ihor.

We hebben dus een loper. Nu zullen we het configureren.
We gaan via SSH naar de machine en installeren java, git, maven, gnupg2.

Terug naar inhoud

Gitlab Runner installeren

  • Maak een nieuwe groep runner
    sudo groupadd runner
  • Maak een map voor de maven-cache en wijs groepsmachtigingen toe runner
    U kunt dit punt overslaan als u niet van plan bent meerdere hardlopers op één machine te gebruiken.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Maak een gebruiker aan gitlab-deployer en toevoegen aan de groep runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Toevoegen aan bestand /etc/ssh/sshd_config volgende regel
    AllowUsers root@* [email protected]
  • Opnieuw opstarten sshd
    systemctl restart sshd
  • Een wachtwoord instellen voor de gebruiker gitlab-deployer (kan eenvoudig zijn, omdat er een beperking is voor localhost)
    passwd gitlab-deployer
  • Installeer 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
  • Ga naar de website gitlab.com -> deploy-project -> Instellingen -> CI/CD -> Runners -> Specific Runners en kopieer het registratietoken

Scherm

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

  • Een loper registreren
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

Процесс

Runtime platform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://gitlab.com/
Please enter the gitlab-ci token for this runner:
REGISTRATION_TOKEN
Please enter the gitlab-ci description for this runner:
[ih1174328.vds.myihor.ru]: Deploy Runner
Please enter the gitlab-ci tags for this runner (comma separated):
deploy
Registering runner... succeeded                     runner=ZvKdjJhx
Please enter the executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

  • Wij controleren of de loper geregistreerd is. Ga naar de website gitlab.com -> implement-project -> Instellingen -> CI/CD -> Runners -> Specifieke Runners -> Runners geactiveerd voor dit project

Scherm

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

  • Toevoegen apart service /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
  • Laten we beginnen met de dienst.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • We controleren of de loper loopt.

Voorbeeld

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Terug naar inhoud

GPG-sleutels genereren

  • Vanaf dezelfde machine loggen we in via ssh onder de gebruiker gitlab-deployer (dit is belangrijk voor het genereren van de GPG-sleutel)

    ssh [email protected]

  • Door het beantwoorden van vragen genereren wij een sleutel. Ik heb mijn eigen naam en e-mailadres gebruikt.
    Zorg ervoor dat u het wachtwoord voor de sleutel opgeeft. Artefacten worden met deze sleutel ondertekend.

    gpg --gen-key 

  • check de

    gpg --list-keys -a
    /home/gitlab-deployer/.gnupg/pubring.gpg
    ----------------------------------------
    pub   4096R/00000000 2019-04-19
    uid                  Petruha Petrov <[email protected]>
    sub   4096R/11111111 2019-04-19

  • Het uploaden van onze publieke sleutel naar de sleutelserver

    gpg --keyserver keys.gnupg.net --send-key 00000000
    gpg: sending key 00000000 to hkp server keys.gnupg.net

Terug naar inhoud

Maven opzetten

  • Log in als gebruiker gitlab-deployer
    su gitlab-deployer 
  • Maak een maven-map bewaarplaats en link naar de cache (vergis je niet)
    U kunt dit punt overslaan als u niet van plan bent meerdere hardlopers op één machine te gebruiken.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Maak een hoofdsleutel
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Maak een bestand ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Het wachtwoord voor het Sonatype-account coderen
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Maak een bestand ~/.m2/settings.xml
    <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>

Waar,
GPG_SECRET_KEY_PASSPHRASE - wachtwoord voor de GPG-sleutel
SONATYPE_USERNAME — inloggen bij sonatype-account

Hiermee is de installatie van de runner voltooid, u kunt doorgaan naar de sectie GitLab-CI

Terug naar inhoud

Gedeelde loper

GPG-sleutels genereren

  • Allereerst moet u een GPG-sleutel maken. Om dit te doen, installeer gnupg.

    yum install -y gnupg

  • Door het beantwoorden van vragen genereren wij een sleutel. Ik heb mijn eigen naam en e-mailadres gebruikt. Zorg ervoor dat u het wachtwoord voor de sleutel opgeeft.

    gpg --gen-key 

  • Informatie over de sleutel weergeven

    gpg --list-keys -a
    pub   rsa3072 2019-04-24 [SC] [expires: 2021-04-23]
      2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    uid           [ultimate] tttemp <[email protected]>
    sub   rsa3072 2019-04-24 [E] [expires: none]

  • Het uploaden van onze publieke sleutel naar de sleutelserver

    gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    gpg: sending key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 to hkp server keys.gnupg.net

  • Wij krijgen de privésleutel

    gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    -----BEGIN PGP PRIVATE KEY BLOCK-----
    lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5
    ...
    =2Wd2
    -----END PGP PRIVATE KEY BLOCK-----

  • Ga naar projectinstellingen -> Instellingen -> CI/CD -> Variabelen en sla de privésleutel op in een variabele GPG_SECRET_KEY
    GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Terug naar inhoud

Maven opzetten

  • Maak een hoofdsleutel
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Ga naar projectinstellingen -> Instellingen -> CI/CD -> Variabelen en sla deze op in een variabele SETTINGS_SECURITY_XML de volgende regels:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Het wachtwoord voor het Sonatype-account coderen
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Ga naar projectinstellingen -> Instellingen -> CI/CD -> Variabelen en sla deze op in een variabele SETTINGS_XML de volgende regels:
    <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>

Waar,
GPG_SECRET_KEY_PASSPHRASE - wachtwoord voor de GPG-sleutel
SONATYPE_USERNAME — inloggen bij sonatype-account

Terug naar inhoud

Docker-installatiekopie implementeren

  • We maken een vrij eenvoudig Dockerbestand om implementatietaken uit te voeren met de vereiste versie van Java. Hieronder ziet u een voorbeeld voor 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/

  • Een container samenstellen voor uw project

    docker build -t registry.gitlab.com/group/deploy .

  • We authenticeren en laden de container in het register.

    docker login -u USER -p PASSWORD registry.gitlab.com
    docker push registry.gitlab.com/group/deploy

Terug naar inhoud

GitLab-CI

Project implementeren

Voeg het bestand .gitlab-ci.yml toe aan de hoofdmap van het implementatieproject
Het script presenteert twee elkaar uitsluitende implementatietaken. Specifieke Runner of Gedeelde Runner.

.gitlab-ci.yml

stages:
  - deploy

Specific Runner:
  extends: .java_deploy_template
  # Задача будет выполняться на вашем shell-раннере
  tags:
    - deploy

Shared Runner:
  extends: .java_deploy_template
  # Задача будет выполняться на публичном docker-раннере
  tags:
    - docker
  # Образ из раздела GitLab Runner -> Shared Runner -> Docker
  image: registry.gitlab.com/group/deploy-project:latest
  before_script:
    # Импортируем GPG ключ
    - printf "${GPG_SECRET_KEY}" | gpg --batch --import
    # Сохраняем maven конфигурацию
    - printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
    - printf "${SETTINGS_XML}" > ~/.m2/settings.xml

.java_deploy_template:
  stage: deploy
  # Задача сработает по триггеру, если передана переменная DEPLOY со значением java
  only:
    variables:
    - $DEPLOY == "java"
  variables:
    # отключаем клонирование текущего проекта
    GIT_STRATEGY: none
  script:
    # Предоставляем возможность хранения пароля в незашифрованном виде
    - git config --global credential.helper store
    # Сохраняем временные креды пользователя gitlab-ci-token
    # Токен работает для всех публичных проектов gitlab.com и для проектов группы
    - echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
    # Полностью чистим текущую директорию
    - rm -rf .* *
    # Клонируем проект который, будем деплоить в Sonatype Nexus
    - git clone ${DEPLOY_CI_REPOSITORY_URL} .
    # Переключаемся на нужный коммит
    - git checkout ${DEPLOY_CI_COMMIT_SHA} -f
    # Если хоть один pom.xml содержит параметр autoReleaseAfterClose валим сборку.
    # В противном случае есть риск залить сырые артефакты в maven central
    - >
      for pom in $(find . -name pom.xml); do
        if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
          echo "File $pom contains prohibited setting: <autoReleaseAfterClose>";
          exit 1;
        fi;
      done
    # Если параметр DEPLOY_CI_COMMIT_TAG пустой, то принудительно ставим SNAPSHOT-версию
    - >
      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
    # Запускаем задачу на сборку и деплой артефактов
    - mvn clean deploy -DskipTests=true

Terug naar inhoud

Java-project

In Java-projecten die naar openbare repository's moeten worden geüpload, moet u twee stappen toevoegen om de Release- en Snapshot-versies te downloaden.

.gitlab-ci.yml

stages:
  - build
  - test
  - verify
  - deploy

<...>

Release:
  extends: .trigger_deploy
  # Запускать задачу только пo тегу.
  only:
    - tags

Snapshot:
  extends: .trigger_deploy
  # Запускаем задачу на публикацию SNAPSHOT версии вручную
  when: manual
  # Не запускать задачу, если проставлен тег.
  except:
    - tags

.trigger_deploy:
  stage: deploy
  variables:
    # Отключаем клонирование текущего проекта
    GIT_STRATEGY: none
    # Ссылка на триггер deploy-задачи
    URL: "https://gitlab.com/api/v4/projects/<deploy project ID>/trigger/pipeline"
    # Переменные deploy-задачи
    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, так как с флагами --fail --show-error
    # он не выводит тело ответа, если HTTP код 400 и более 
    - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

Bij deze oplossing ging ik nog een stapje verder en besloot ik één CI-sjabloon voor Java-projecten te gebruiken.

Meer details

Ik heb een apart project gemaakt gitlab-ci waarin ik een CI-sjabloon voor Java-projecten heb geplaatst common.yml.

common.yml

stages:
  - build
  - test
  - verify
  - deploy

variables:
  SONAR_ARGS: "
  -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} 
  -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} 
  "

.build_java_project:
  stage: build
  tags:
    - touchbit-shell
  variables:
    SKIP_TEST: "false"
  script:
    - mvn clean
    - mvn package -DskipTests=${SKIP_TEST}
  artifacts:
    when: always
    expire_in: 30 day
    paths:
      - "*/target/reports"

.build_sphinx_doc:
  stage: build
  tags:
    - touchbit-shell
  variables:
    DOCKERFILE: .indirect/docs/Dockerfile
  script:
    - docker build --no-cache -t ${CI_PROJECT_NAME}/doc -f ${DOCKERFILE} .

.junit_module_test_run:
  stage: test
  tags:
    - touchbit-shell
  variables:
    MODULE: ""
  script:
    - cd ${MODULE}
    - mvn test
  artifacts:
    when: always
    expire_in: 30 day
    paths:
      - "*/target/reports"

.junit_test_run:
  stage: test
  tags:
    - touchbit-shell
  script:
    - mvn test
  artifacts:
    when: always
    expire_in: 30 day
    paths:
    - "*/target/reports"

.sonar_review:
  stage: verify
  tags:
    - touchbit-shell
  dependencies: []
  script:
    - >
      if [ "$CI_BUILD_REF_NAME" == "master" ]; then
        mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS
      else
        mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS -Dsonar.analysis.mode=preview
      fi

.trigger_deploy:
  stage: deploy
  tags:
    - touchbit-shell
  variables:
    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}
      "
  script:
  - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

.trigger_release_deploy:
  extends: .trigger_deploy
  only:
    - tags

.trigger_snapshot_deploy:
  extends: .trigger_deploy
  when: manual
  except:
    - tags

Als gevolg hiervan ziet .gitlab-ci.yml er in de Java-projecten zelf erg compact en niet uitgebreid uit

.gitlab-ci.yml

include: https://gitlab.com/TouchBIT/gitlab-ci/raw/master/common.yml

Shields4J:
  extends: .build_java_project

Sphinx doc:
  extends: .build_sphinx_doc
  variables:
    DOCKERFILE: .docs/Dockerfile

Sonar review:
  extends: .sonar_review
  dependencies:
    - Shields4J

Release:
  extends: .trigger_release_deploy

Snapshot:
  extends: .trigger_snapshot_deploy

Terug naar inhoud

Pom.xml-configuratie

Dit onderwerp wordt uitgebreid beschreven. googolplex в Maven instellen om automatisch artefacten te ondertekenen en te uploaden naar snapshot- en staging-opslagplaatsen, dus ik zal enkele nuances van het gebruik van plug-ins beschrijven. Ook zal ik beschrijven hoe gemakkelijk en ontspannen je het kunt gebruiken nexus-staging-maven-pluginals u org.sonatype.oss:oss-parent niet als ouder voor uw project wilt of kunt gebruiken.

maven-installatie-plug-in

Installeert modules in de lokale repository.
Zeer nuttig voor lokale verificatie van oplossingen in andere projecten, evenals voor een controlesom.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-install-plugin</artifactId>
  <executions>
    <execution>
      <id>install-project</id>
      <!-- Если у вас многомодульный проект с деплоем родительского помика -->
      <phase>install</phase>
      <!-- Явно указываем файлы для локальной установки -->
      <configuration>
        <file>target/${project.artifactId}-${project.version}.jar</file>
```target/${project.artifactId}-${project.version}-sources.jar</sources>
        <pomFile>dependency-reduced-pom.xml</pomFile>
        <!-- Принудительное обновление метаданных проекта -->
        <updateReleaseInfo>true</updateReleaseInfo>
        <!-- Контрольные суммы для проверки целостности -->
        <createChecksum>true</createChecksum>
      </configuration>
    </execution>
  </executions>
</plugin>

Terug naar inhoud

maven-javadoc-plug-in

Javadoc genereren voor het project.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>jar</goal>
      </goals>
      <!-- Генерация javadoc должна быть после фазы генерации ресурсов -->
      <phase>prepare-package</phase>
      <configuration>
        <!-- Очень помогает в публичных проектах -->
        <failOnError>true</failOnError>
        <failOnWarnings>true</failOnWarnings>
        <!-- Убирает ошибку поиска документации в target директории -->
        <detectOfflineLinks>false</detectOfflineLinks>
      </configuration>
    </execution>
  </executions>
</plugin>

Als u een module heeft die geen Java bevat (bijvoorbeeld alleen resources)
Of als je in principe geen Javadoc wilt genereren, help dan maven-jar-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <executions>
    <execution>
      <id>empty-javadoc-jar</id>
      <phase>generate-resources</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <classifier>javadoc</classifier>
        <classesDirectory>${basedir}/javadoc</classesDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

Terug naar inhoud

maven-gpg-plug-in

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-gpg-plugin</artifactId>
  <executions>
    <execution>
      <id>sign-artifacts</id>
      <!-- Сборка будет падать, если отсутствует GPG ключ -->
      <!-- Подписываем артефакты только на фазе deploy -->
      <phase>deploy</phase>
      <goals>
        <goal>sign</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Terug naar inhoud

nexus-staging-maven-plug-in

Configuratie:

<project>
  <!-- ... -->
  <build>
    <plugins>
      <!-- ... -->
      <plugin>
        <groupId>org.sonatype.plugins</groupId>
        <artifactId>nexus-staging-maven-plugin</artifactId>
      </plugin>
    </plugins>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.sonatype.plugins</groupId>
          <artifactId>nexus-staging-maven-plugin</artifactId>
          <extensions>true</extensions>
          <configuration>
            <serverId>sonatype</serverId>
            <nexusUrl>https://oss.sonatype.org/</nexusUrl>
            <!-- Обновляем метаданные, чтобы пометить артефакт как release -->
            <!-- Не влияет на snapshot версии -->
            <updateReleaseInfo>true</updateReleaseInfo>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-deploy-plugin</artifactId>
          <configuration>
            <!-- Отключаем плагин -->
            <skip>true</skip>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
  <distributionManagement>
    <snapshotRepository>
      <id>sonatype</id>
      <name>Nexus Snapshot Repository</name>
      <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
    </snapshotRepository>
    <repository>
      <id>sonatype</id>
      <name>Nexus Release Repository</name>
      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
  </distributionManagement>
</project>

Als u een project met meerdere modules heeft en u hoeft geen specifieke module naar de repository te uploaden, dan moet u toevoegen nexus-staging-maven-plugin met vlag skipNexusStagingDeployMojo

<build>
  <plugins>
    <plugin>
      <groupId>org.sonatype.plugins</groupId>
      <artifactId>nexus-staging-maven-plugin</artifactId>
      <configuration>
        <skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
      </configuration>
    </plugin>
  </plugins>
</build>

Na het downloaden zijn snapshot-/releaseversies beschikbaar in opslagplaatsen inrichten

<repositories>
  <repository>
    <id>SonatypeNexus</id>
    <url>https://oss.sonatype.org/content/groups/staging/</url>
    <!-- Не надо указывать флаги snapshot/release для репозитория -->
  </repository>
</repositories>

Meer pluspunten

  • Een zeer rijke lijst met doelen voor het werken met de Nexus-repository (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatische vrijgavecontrole voor uploaden naar Maven Central

Terug naar inhoud

Resultaat

SNAPSHOT-versie publiceren

Bij het bouwen van een project is het mogelijk om handmatig een taak te starten om de SNAPSHOT-versie naar Nexus te downloaden

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Wanneer deze taak wordt gestart, wordt de overeenkomstige taak in het implementatieproject geactiveerd (voorbeeld).

Bijgesneden logboek

Running with gitlab-runner 11.10.0 (3001a600)
  on Deploy runner JSKWyxUw
Using Shell executor...
Running on ih1174328.vds.myihor.ru...
Skipping Git repository setup
Skipping Git checkout
Skipping Git submodules setup
$ 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} .
Cloning into 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Note: checking out '850f86aa317194395c5387790da1350e437125a7'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
  git checkout -b new_branch_name
HEAD is now at 850f86a... skip deploy test-core
$ for pom in $(find . -name pom.xml); do # collapsed multi-line command
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # collapsed multi-line command
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 4 modules...
[INFO] Installing Nexus Staging features:
[INFO]   ... total of 4 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] Shields4J                                                          [pom]
[INFO] test-core                                                          [jar]
[INFO] Shields4J client                                                   [jar]
[INFO] TestNG listener                                                    [jar]
[INFO] 
[INFO] --------------< org.touchbit.shields4j:shields4j-parent >---------------
[INFO] Building Shields4J 1.0.0                                           [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Searching for local aggregator root...
[INFO] Local aggregation root: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Processing change of org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Processing org.touchbit.shields4j:shields4j-parent
[INFO]     Updating project org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] Processing org.touchbit.shields4j:client
[INFO]     Updating parent org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]     Updating dependency org.touchbit.shields4j:test-core
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] Processing org.touchbit.shields4j:test-core
[INFO]     Updating parent org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] Processing org.touchbit.shields4j:testng
[INFO]     Updating parent org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]     Updating dependency org.touchbit.shields4j:client
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]     Updating dependency org.touchbit.shields4j:test-core
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... SUCCESS [  0.992 s]
[INFO] test-core .......................................... SKIPPED
[INFO] Shields4J client ................................... SKIPPED
[INFO] TestNG listener 1.0.0 .............................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.483 s
[INFO] Finished at: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 4 modules...
[INFO] Installing Nexus Staging features:
[INFO]   ... total of 4 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] Shields4J                                                          [pom]
[INFO] test-core                                                          [jar]
[INFO] Shields4J client                                                   [jar]
[INFO] TestNG listener                                                    [jar]
[INFO] 
[INFO] --------------< org.touchbit.shields4j:shields4j-parent >---------------
[INFO] Building Shields4J 1.0.0-SNAPSHOT                                  [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
DELETED
...
[INFO]  * Bulk deploy of locally gathered snapshot artifacts finished.
[INFO] Remote deploy finished with success.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... SUCCESS [  2.375 s]
[INFO] test-core .......................................... SUCCESS [  3.929 s]
[INFO] Shields4J client ................................... SUCCESS [  3.815 s]
[INFO] TestNG listener 1.0.0-SNAPSHOT ..................... SUCCESS [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 47.629 s
[INFO] Finished at: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------

Als gevolg hiervan wordt de versie in Nexus geladen 1.0.0-MOMENTOPNAME.

Alle snapshotversies kunnen uit de repository op de website worden verwijderd oss.sonatype.org onder uw rekening.

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Terug naar inhoud

Een releaseversie publiceren

Wanneer een tag is geïnstalleerd, wordt de overeenkomstige taak in het implementatieproject automatisch geactiveerd om de releaseversie naar Nexus te downloaden (voorbeeld).

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Het beste is dat close release automatisch wordt geactiveerd in Nexus.

[INFO] Performing remote staging...
[INFO] 
[INFO]  * Remote staging into staging profile ID "9043b43f77dcc9"
[INFO]  * Created staging repository with ID "orgtouchbit-1037".
[INFO]  * Staging repository at https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO]  * Uploading locally staged artifacts to profile org.touchbit
[INFO]  * Upload of locally staged artifacts finished.
[INFO]  * Closing staging repository with ID "orgtouchbit-1037".
Waiting for operation to complete...
.........
[INFO] Remote staged 1 repositories, finished with success.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... SUCCESS [  9.603 s]
[INFO] test-core .......................................... SUCCESS [  3.419 s]
[INFO] Shields4J client ................................... SUCCESS [  9.793 s]
[INFO] TestNG listener 1.0.0 .............................. SUCCESS [01:23 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:47 min
[INFO] Finished at: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------

En als er iets misgaat, zal de taak zeker mislukken

[INFO] Performing remote staging...
[INFO] 
[INFO]  * Remote staging into staging profile ID "9043b43f77dcc9"
[INFO]  * Created staging repository with ID "orgtouchbit-1038".
[INFO]  * Staging repository at https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO]  * Uploading locally staged artifacts to profile org.touchbit
[INFO]  * Upload of locally staged artifacts finished.
[INFO]  * Closing staging repository with ID "orgtouchbit-1038".
Waiting for operation to complete...
.......
[ERROR] Rule failure while trying to close staging repository with ID "orgtouchbit-1039".
[ERROR] 
[ERROR] Nexus Staging Rules Failure Report
[ERROR] ==================================
[ERROR] 
[ERROR] Repository "orgtouchbit-1039" failures
[ERROR]   Rule "signature-staging" failures
[ERROR]     * No public key: Key with id: (1f42b618d1cbe1b5) was not able to be located on &lt;a href=http://keys.gnupg.net:11371/&gt;http://keys.gnupg.net:11371/&lt;/a&gt;. Upload your public key and try the operation again.
...
[ERROR] Cleaning up local stage directory after a Rule failure during close of staging repositories: [orgtouchbit-1039]
[ERROR]  * Deleting context 9043b43f77dcc9.properties
[ERROR] Cleaning up remote stage repositories after a Rule failure during close of staging repositories: [orgtouchbit-1039]
[ERROR]  * Dropping failed staging repository with ID "orgtouchbit-1039" (Rule failure during close of staging repositories: [orgtouchbit-1039]).
[ERROR] Remote staging finished with a failure: Staging rules failure!
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... SUCCESS [  4.073 s]
[INFO] test-core .......................................... SUCCESS [  2.788 s]
[INFO] Shields4J client ................................... SUCCESS [  3.962 s]
[INFO] TestNG listener 1.0.0 .............................. FAILURE [01:07 min]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

Het resultaat is dat we nog maar één keuze hebben. Verwijder deze versie of publiceer deze.

GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

Na de release zullen de artefacten na enige tijd binnen zijn GitLab CI instellen om een ​​Java-project naar Maven Central te uploaden

off topic

Het was voor mij een ontdekking dat Maven andere openbare repository's indexeert.
Ik moest robots.txt toevoegen omdat het mijn oude repository indexeerde.

Terug naar inhoud

Conclusie

Wat we hebben

  • Een afzonderlijk implementatieproject waarin u verschillende CI-taken kunt implementeren voor het uploaden van artefacten naar openbare opslagplaatsen voor verschillende ontwikkelingstalen.
  • Het Deploy-project is geïsoleerd van inmenging van buitenaf en kan alleen worden gewijzigd door gebruikers met de rollen Eigenaar en Onderhouder.
  • Een aparte Specific Runner met een ‘hot’ cache om alleen implementatietaken uit te voeren.
  • Publiceren van snapshot-/releaseversies in een openbare repository.
  • Automatische controle van de releaseversie op gereedheid voor publicatie in Maven Central.
  • Bescherming tegen automatische publicatie van “ruwe” versies in Maven Central.
  • Bouw en publiceer snapshotversies “met een klik”.
  • Eén enkele opslagplaats voor het verkrijgen van snapshot-/releaseversies.
  • Algemene pijplijn voor het bouwen/testen/publiceren van een Java-project.

Het opzetten van GitLab CI is niet zo ingewikkeld als het op het eerste gezicht lijkt. Het is voldoende om CI een paar keer turnkey op te zetten, en nu ben je verre van een amateur op dit gebied. Bovendien is GitLab-documentatie erg redundant. Wees niet bang om de eerste stap te zetten. De weg verschijnt onder de treden van de persoon die loopt (ik weet niet meer wie het zei :)

Ik ontvang graag feedback.

In het volgende artikel zal ik het hebben over hoe je GitLab CI kunt configureren om taken met integratietests competitief uit te voeren (de geteste services uitvoeren met docker-compose) als je maar één shell-runner hebt.

Terug naar inhoud

Bron: www.habr.com

Voeg een reactie