Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

Den här artikeln är avsedd för java-utvecklare som snabbt behöver publicera sina produkter till sonatype och/eller maven centrala repositories med GitLab. I den här artikeln kommer jag att prata om att ställa in gitlab-runner, gitlab-ci och maven-plugin för att lösa detta problem.

Förkunskaper:

  • Säker förvaring av mvn- och GPG-nycklar.
  • Säkert utförande av offentliga CI-uppgifter.
  • Ladda upp artefakter (release/snapshot) till offentliga arkiv.
  • Automatisk kontroll av releaseversioner för publicering i maven central.
  • En generell lösning för att ladda upp artefakter till ett arkiv för flera projekt.
  • Enkelhet och användarvänlighet.

Innehåll

Allmän information

  • En detaljerad beskrivning av mekanismen för att publicera artefakter till Maven Central via Sonatype OSS Repository Hosting Service beskrivs redan i Denna artikel användare googolplex, så jag kommer att hänvisa till den här artikeln på rätt ställen.
  • Föranmälan kl Sonatyp JIRA och starta en biljett för att öppna förvaret (för mer information, läs avsnittet Skapa en Sonatype JIRA-biljett). Efter att ha öppnat förvaret kommer JIRA-inloggning/lösenordsparet (hädanefter kallat Sonatype-kontot) att användas för att ladda upp artefakter till Sonatype-nexusen.
  • Vidare beskrivs processen att generera en GPG-nyckel mycket torrt. Se avsnittet för mer information. Konfigurera GnuPG för att signera artefakter
  • Om du använder Linux-konsolen för att generera en GPG-nyckel (gnupg/gnupg2), måste du installera rng-tools för att generera entropi. Annars kan nyckelgenerering ta mycket lång tid.
  • Lagringstjänster offentlig GPG-nycklar

Tillbaka till innehållet

Konfigurera ett distributionsprojekt i GitLab

  • Först och främst måste du skapa och konfigurera ett projekt där pipelinen kommer att lagras för distribution av artefakter. Jag kallade mitt projekt enkelt och okomplicerat - distribuera
  • Efter att ha skapat arkivet måste du begränsa åtkomsten för att ändra arkivet.
    Gå till projektet -> Inställningar -> Förvar -> Skyddade grenar. Vi tar bort alla regler och lägger till en enda regel med Wildcard * med rätt att pusha och slå samman endast för användare med rollen Maintainers. Den här regeln kommer att fungera för alla användare av både detta projekt och gruppen som det här projektet tillhör.
    Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central
  • Om det finns flera underhållare skulle den bästa lösningen vara att begränsa tillgången till projektet i princip.
    Gå till projektet -> Inställningar -> Allmänt -> Synlighet, projektfunktioner, behörigheter och ställ in Projektsynlighet till Privat.
    Jag har ett projekt i offentlig tillgång, eftersom jag använder min egen GitLab Runner och bara jag har tillgång till att modifiera arkivet. Tja, faktiskt ligger det inte i mitt intresse att visa privat information i offentliga pipelineloggar.
  • Skärpning av reglerna för ändring av förvaret
    Gå till projektet -> Inställningar -> Repository -> Push-regler och ställ in flaggorna Committer-begränsning, Kontrollera om författaren är en GitLab-användare. Jag rekommenderar också inställning begå undertecknande, och ställ in flaggan Reject unsigned commits.
  • Därefter måste du konfigurera en utlösare för att köra uppgifter
    Gå till projekt -> Inställningar -> CI / CD -> Pipeline triggers och skapa en ny trigger-token
    Denna token kan omedelbart läggas till den allmänna konfigurationen av variabler för en grupp av projekt.
    Gå till gruppen -> Inställningar -> CI / CD -> Variabler och lägg till en variabel DEPLOY_TOKEN med trigger-token i värdet.

Tillbaka till innehållet

GitLab Runner

Det här avsnittet beskriver konfigurationen för att köra uppgifter vid distribution med den inbyggda (specifika) och offentliga (Delade) löparen.

Specifik löpare

Jag använder mina egna löpare, eftersom det först och främst är bekvämt, snabbt, billigt.
För löpare rekommenderar jag Linux VDS med 1 CPU, 2 GB RAM, 20 GB hårddisk. Emissionspris ~ 3000 ₽ per år.

Min löpare

För löparen tog jag VDS 4 CPU, 4 GB RAM, 50 GB SSD. Det kostade ~11000₽ och ångrade det aldrig.
Jag har totalt 7 maskiner. 5 på aruba och 2 på ihor.

Så vi har en löpare. Nu ska vi ställa in det.
Vi går till maskinen via SSH och installerar java, git, maven, gnupg2.

Tillbaka till innehållet

Installerar gitlab runner

  • Skapa en ny grupp runner
    sudo groupadd runner
  • Skapa en katalog för maven-cachen och tilldela grupprättigheter runner
    Du kan hoppa över det här steget om du inte planerar att köra flera löpare på samma maskin.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Skapa en användare gitlab-deployer och lägg till i gruppen runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Lägg till i fil /etc/ssh/sshd_config nästa rad
    AllowUsers root@* [email protected]
  • Starta om sshd
    systemctl restart sshd
  • Ange ett lösenord för användaren gitlab-deployer (det kan vara enkelt, eftersom det finns en begränsning för localhost)
    passwd gitlab-deployer
  • Installera 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
  • Gå till gitlab.com -> deploy-project -> Inställningar -> CI/CD -> Löpare -> Specifika löpare och kopiera registreringstoken

Skärm

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

  • Registrerar löparen
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

process

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!

  • Kontrollera att löparen är registrerad. Gå till gitlab.com -> deploy-project -> Inställningar -> CI/CD -> Löpare -> Specifika löpare -> Löpare aktiverade för detta projekt

Skärm

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

  • Lägger till separat tjänsten /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
  • Vi startar tjänsten.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Kontrollera att löparen är igång.

Exempel

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

Tillbaka till innehållet

GPG-nyckelgenerering

  • Från samma maskin går vi via ssh under användaren gitlab-deployer (detta är viktigt för GPG-nyckelgenerering)

    ssh [email protected]

  • Vi skapar en nyckel genom att svara på frågor. Jag använde mitt eget namn och e-postadress.
    Var noga med att ange lösenordet för nyckeln. Artefakter kommer att signeras med denna nyckel.

    gpg --gen-key 

  • Kontroll

    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

  • Laddar upp vår publika nyckel till nyckelservern

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

Tillbaka till innehållet

Maven-inställning

  • Vi går under användaren gitlab-deployer
    su gitlab-deployer 
  • Skapa en Maven-katalog Repository och länka till cachen (gör inga misstag)
    Detta steg kan hoppas över om du inte planerar att köra flera löpare på samma maskin.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Skapa en huvudnyckel
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Skapa filen ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Kryptera lösenordet från Sonatype-kontot
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Skapa filen ~/.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>

var,
GPG_SECRET_KEY_PASSPHRASE - GPG-nyckellösenord
SONATYPE_USERNAME - sonatype-kontoinloggning

Detta slutför löparinställningen, du kan fortsätta till avsnittet GitLab CI

Tillbaka till innehållet

Delad löpare

GPG-nyckelgenerering

  • Först och främst måste du skapa en GPG-nyckel. För att göra detta, installera gnupg.

    yum install -y gnupg

  • Vi skapar en nyckel genom att svara på frågor. Jag använde mitt eget namn och e-postadress. Var noga med att ange lösenordet för nyckeln.

    gpg --gen-key 

  • Hämta nyckelinformation

    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]

  • Laddar upp vår publika nyckel till nyckelservern

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

  • Få en privat nyckel

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

  • Gå till projektinställningar -> Inställningar -> CI / CD -> Variabler och spara den privata nyckeln i en variabel GPG_SECRET_KEY
    Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

Tillbaka till innehållet

Maven-inställning

  • Skapa en huvudnyckel
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Gå till projektinställningar -> Inställningar -> CI / CD -> Variabler och spara i en variabel SETTINGS_SECURITY_XML följande rader:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Kryptera lösenordet från Sonatype-kontot
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Gå till projektinställningar -> Inställningar -> CI / CD -> Variabler och spara i en variabel SETTINGS_XML följande rader:
    <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>

var,
GPG_SECRET_KEY_PASSPHRASE - GPG-nyckellösenord
SONATYPE_USERNAME - sonatype-kontoinloggning

Tillbaka till innehållet

Distribuera docker-bild

  • Vi skapar en ganska enkel Dockerfil för att köra uppgifter vid driftsättning med den önskade versionen av Java. Nedan är ett exempel för alpint.

    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/

  • Bygga en container för ditt projekt

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

  • Vi autentiserar och laddar behållaren i registret.

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

Tillbaka till innehållet

GitLab CI

Implementera projekt

Lägg till filen .gitlab-ci.yml till roten av distributionsprojektet
Skriptet presenterar två ömsesidigt uteslutande distributionsuppgifter. Specifik löpare respektive delad löpare.

.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

Tillbaka till innehållet

Java-projekt

I java-projekt som är tänkta att laddas upp till offentliga arkiv måste du lägga till 2 steg för att ladda ner versionerna Release och Snapshot.

.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}

I den här lösningen gick jag lite längre och bestämde mig för att använda en CI-mall för java-projekt.

Mer detaljer

Jag skapade ett separat projekt gitlab-ci där han placerade CI-mallen för java-projekt vanligt.yml.

vanligt.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

Som ett resultat, i själva java-projekten, ser .gitlab-ci.yml väldigt kompakt ut och inte mångsidigt

.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

Tillbaka till innehållet

pom.xml-konfiguration

Detta ämne beskrivs i detalj. googolplex в Konfigurera Maven för att automatiskt signera och ladda upp artefakter till ögonblicksbilder och iscensättningsförråd, så jag kommer att beskriva några av nyanserna av att använda plugins. Jag kommer också att beskriva hur enkelt och naturligt du kan använda nexus-staging-maven-pluginom du inte vill eller kan använda org.sonatype.oss:oss-parent som förälder för ditt projekt.

maven-install-plugin

Installerar moduler i det lokala arkivet.
Mycket användbar för lokal verifiering av lösningar i andra projekt, samt en kontrollsumma.

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

Tillbaka till innehållet

maven-javadoc-plugin

Genererar javadoc för projektet.

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

Om du har en modul som inte innehåller java (till exempel bara resurser)
Eller så vill du inte generera javadoc i princip, då för att hjälpa till 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>

Tillbaka till innehållet

maven-gpg-plugin

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

Tillbaka till innehållet

nexus-staging-maven-plugin

Konfiguration:

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

Om du har ett flermodulsprojekt och du inte behöver ladda upp en specifik modul till förvaret, måste du lägga till i pom.xml för denna modul nexus-staging-maven-plugin med flagga skipNexusStagingDeployMojo

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

Efter uppladdning av ögonblicksbild/släpp versioner är tillgängliga i iscensättande förråd

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

Fler plus

  • En mycket rik lista med mål för att arbeta med nexus-förvaret (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatisk releasekontroll för nedladdningsbarhet i maven central

Tillbaka till innehållet

Resultat

Publicera en SNAPSHOT-version

När du bygger ett projekt är det möjligt att manuellt starta en uppgift för att ladda ner SNAPSHOT-versionen till nexus

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

När den här uppgiften startas utlöses motsvarande uppgift i distributionsprojektet (exempel).

beskuren stock

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] ------------------------------------------------------------------------

Som ett resultat laddas nexusversionen 1.0.0-SNAPSHOT.

Alla snapshotversioner kan tas bort från arkivet på webbplatsen oss.sonatype.org under ditt konto.

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

Tillbaka till innehållet

Publicering av releaseversionen

När taggen är inställd utlöses motsvarande uppgift i distributionsprojektet automatiskt för att ladda upp releaseversionen till nexus (exempel).

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

Det bästa är att close release automatiskt utlöses i 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] ------------------------------------------------------------------------

Och om något gick fel, kommer uppgiften att misslyckas

[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] ------------------------------------------------------------------------

Som ett resultat har vi bara ett val. Eller ta bort den här versionen eller publicera.

Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

Efter utgivningen, efter en tid, kommer artefakterna att vara in Konfigurera GitLab CI för att ladda upp ett java-projekt till maven central

orelevant

Det var en uppenbarelse för mig att Maven indexerar andra offentliga arkiv.
Jag var tvungen att ladda upp robots.txt eftersom det indexerade mitt gamla arkiv.

Tillbaka till innehållet

Slutsats

Det vi har

  • Ett separat distributionsprojekt där du kan implementera flera CI-uppgifter för att ladda upp artefakter till offentliga arkiv för olika utvecklingsspråk.
  • Implementeringsprojektet är isolerat från yttre störningar och kan endast ändras av användare med rollerna Ägare och Underhållare.
  • En separat Specifik Runner med en "het" cache för att endast köra distributionsuppgifter.
  • Publicering av ögonblicksbild/releaseversioner i ett offentligt arkiv.
  • Automatisk kontroll av releaseversionen för beredskap för publicering i maven central.
  • Skydd mot automatisk publicering av "rå" versioner i maven central.
  • Bygg och publicera ögonblicksbildversioner "vid klick".
  • Enstaka förråd för att få ögonblicksbild/releaseversioner.
  • Allmän pipeline för att bygga / testa / publicera ett java-projekt.

Att ställa in GitLab CI är inte ett så komplicerat ämne som det verkar vid första anblicken. Det räcker med att ställa in CI på nyckelfärdig basis ett par gånger, och nu är du långt ifrån en amatör i den här frågan. Dessutom är GitLab-dokumentationen mycket överflödig. Var inte rädd för att ta första steget. Vägen dyker upp under trappan på den som går (jag kommer inte ihåg vem som sa det :)

Jag kommer gärna med feedback.

I nästa artikel kommer jag att visa dig hur du ställer in GitLab CI för att köra integrationstestuppgifter konkurrenskraftigt (kör testtjänster med docker-compose) om du bara har en skallöpare.

Tillbaka till innehållet

Källa: will.com

Lägg en kommentar