Opsætning af GitLab CI til at uploade et java-projekt til maven central

Denne artikel er beregnet til java-udviklere, der hurtigt har brug for at udgive deres produkter til sonatype og/eller maven centrale repositories ved hjælp af GitLab. I denne artikel vil jeg tale om opsætning af gitlab-runner, gitlab-ci og maven-plugin for at løse dette problem.

Forudsætninger:

  • Sikker opbevaring af mvn og GPG nøgler.
  • Sikker udførelse af offentlige CI-opgaver.
  • Upload af artefakter (frigivelse/snapshot) til offentlige arkiver.
  • Automatisk kontrol af udgivelsesversioner til offentliggørelse i maven central.
  • En generel løsning til upload af artefakter til et lager for flere projekter.
  • Enkelhed og brugervenlighed.

Indhold

Generel information

  • En detaljeret beskrivelse af mekanismen til udgivelse af artefakter til Maven Central via Sonatype OSS Repository Hosting Service er allerede beskrevet i denne artikel bruger googolplex, så jeg vil henvise til denne artikel de rigtige steder.
  • Forhåndstilmelding kl Sonatype JIRA og start en billet for at åbne lageret (læs afsnittet for flere detaljer Opret en Sonatype JIRA-billet). Efter åbning af lageret vil JIRA login/adgangskodeparret (herefter kaldet Sonatype-kontoen) blive brugt til at uploade artefakter til Sonatype-forbindelsen.
  • Yderligere er processen med at generere en GPG-nøgle beskrevet meget tørt. Se afsnittet for flere detaljer. Konfiguration af GnuPG til at signere artefakter
  • Hvis du bruger Linux-konsollen til at generere en GPG-nøgle (gnupg/gnupg2), skal du installere RNG-værktøjer at generere entropi. Ellers kan nøglegenerering tage meget lang tid.
  • Opbevaringstjenester offentlig GPG nøgler

Tilbage til indholdet

Opsætning af et implementeringsprojekt i GitLab

  • Først og fremmest skal du oprette og konfigurere et projekt, hvor pipelinen vil blive gemt til udrulning af artefakter. Jeg kaldte mit projekt enkelt og ukompliceret - indsætte
  • Efter at have oprettet depotet, skal du begrænse adgangen for at ændre depotet.
    Gå til projektet -> Indstillinger -> Depot -> Beskyttede grene. Vi sletter alle regler og tilføjer en enkelt regel med Wildcard * med ret til at push og flette kun for brugere med rollen Maintainers. Denne regel vil fungere for alle brugere af både dette projekt og gruppen, som dette projekt tilhører.
    Opsætning af GitLab CI til at uploade et java-projekt til maven central
  • Hvis der er flere vedligeholdere, så vil den bedste løsning være at begrænse adgangen til projektet i princippet.
    Gå til projektet -> Indstillinger -> Generelt -> Synlighed, projektfunktioner, tilladelser og indstil Projektsynlighed til Privat.
    Jeg har et projekt i offentlig adgang, da jeg bruger min egen GitLab Runner og kun jeg har adgang til at ændre depotet. Nå, faktisk er det ikke i min interesse at vise private oplysninger i offentlige pipeline logs.
  • Skærpelse af reglerne for ændring af depotet
    Gå til projektet -> Indstillinger -> Repository -> Push Rules og indstil flagene Committer-begrænsning, Tjek om forfatteren er en GitLab-bruger. Jeg anbefaler også indstilling forpligte sig til at underskrive, og indstil flaget Reject unsigned commits.
  • Dernæst skal du konfigurere en trigger for at køre opgaver
    Gå til projekt -> Indstillinger -> CI / CD -> Pipeline-udløsere og opret et nyt trigger-token
    Dette token kan straks føjes til den generelle konfiguration af variabler for en gruppe af projekter.
    Gå til gruppen -> Indstillinger -> CI / CD -> Variabler og tilføj en variabel DEPLOY_TOKEN med trigger-token i værdien.

Tilbage til indholdet

GitLab Runner

Dette afsnit beskriver konfigurationen for at køre opgaver ved implementering ved hjælp af den oprindelige (specifikke) og offentlige (delte) runner.

Specifik løber

Jeg bruger mine egne løbere, fordi det først og fremmest er praktisk, hurtigt, billigt.
For runner anbefaler jeg Linux VDS med 1 CPU, 2 GB RAM, 20 GB HDD. Udstedelsespris ~ 3000 ₽ om året.

Min løber

Til løberen tog jeg VDS 4 CPU, 4 GB RAM, 50 GB SSD. Det kostede ~11000₽ og har aldrig fortrudt det.
Jeg har i alt 7 maskiner. 5 på aruba og 2 på ihor.

Så vi har en løber. Nu sætter vi det op.
Vi går til maskinen via SSH og installerer java, git, maven, gnupg2.

Tilbage til indholdet

Installerer gitlab runner

  • Opret en ny gruppe runner
    sudo groupadd runner
  • Opret en mappe til maven-cachen og tildel grupperettigheder runner
    Du kan springe dette trin over, hvis du ikke planlægger at køre flere løbere på samme maskine.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Opret en bruger gitlab-deployer og tilføje til gruppen runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Tilføj til fil /etc/ssh/sshd_config næste linje
    AllowUsers root@* [email protected]
  • Genstart sshd
    systemctl restart sshd
  • Indstil en adgangskode til brugeren gitlab-deployer (det kan være enkelt, da der er en begrænsning for localhost)
    passwd gitlab-deployer
  • Installer 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å til gitlab.com -> deploy-project -> Indstillinger -> CI/CD -> Runners -> Specifikke løbere og kopier registreringstokenet

Skærm

Opsætning af GitLab CI til at uploade et java-projekt til maven central

  • Registrering af løberen
    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!

  • Tjek at løberen er tilmeldt. Gå til gitlab.com -> deploy-project -> Indstillinger -> CI/CD -> Løbere -> Specifikke løbere -> Løbere aktiveret for dette projekt

Skærm

Opsætning af GitLab CI til at uploade et java-projekt til maven central

  • Tilføjelse adskille 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
  • Vi starter tjenesten.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Tjek at løberen kører.

Eksempel

Opsætning af GitLab CI til at uploade et java-projekt til maven central

Tilbage til indholdet

Generering af GPG-nøgler

  • Fra samme maskine går vi via ssh under brugeren gitlab-deployer (dette er vigtigt for generering af GPG-nøgler)

    ssh [email protected]

  • Vi genererer en nøgle ved at besvare spørgsmål. Jeg brugte mit eget navn og e-mail.
    Sørg for at angive adgangskoden til nøglen. Artefakter vil blive signeret med denne nøgle.

    gpg --gen-key 

  • Kontrol

    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

  • Uploader vores offentlige nøgle til nøgleserveren

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

Tilbage til indholdet

Maven opsætning

  • Vi går under brugeren gitlab-deployer
    su gitlab-deployer 
  • Opret en maven-mappe Repository og link til cachen (tag ikke fejl)
    Dette trin kan springes over, hvis du ikke planlægger at køre flere løbere på samme maskine.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Opret en hovednøgle
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Opret filen ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Kryptering af adgangskoden fra Sonatype-kontoen
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Opret fil ~/.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>

hvor,
GPG_SECRET_KEY_PASSPHRASE - GPG-nøgleadgangskode
SONATYPE_USERNAME - login på sonatype-konto

Dette afslutter løberopsætningen, du kan fortsætte til afsnittet GitLab CI

Tilbage til indholdet

Delt løber

Generering af GPG-nøgler

  • Først og fremmest skal du oprette en GPG-nøgle. For at gøre dette skal du installere gnupg.

    yum install -y gnupg

  • Vi genererer en nøgle ved at besvare spørgsmål. Jeg brugte mit eget navn og e-mail. Sørg for at angive adgangskoden til nøglen.

    gpg --gen-key 

  • Hent nøgleoplysninger

    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]

  • Uploader vores offentlige nøgle til nøgleserveren

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

  • Få en privat nøgle

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

  • Gå til projektindstillinger -> Indstillinger -> CI / CD -> Variabler og gem den private nøgle i en variabel GPG_SECRET_KEY
    Opsætning af GitLab CI til at uploade et java-projekt til maven central

Tilbage til indholdet

Maven opsætning

  • Opret en hovednøgle
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Gå til projektindstillinger -> Indstillinger -> CI / CD -> Variabler og gem i en variabel SETTINGS_SECURITY_XML følgende linjer:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Kryptering af adgangskoden fra Sonatype-kontoen
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Gå til projektindstillinger -> Indstillinger -> CI / CD -> Variabler og gem i en variabel SETTINGS_XML følgende linjer:
    <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>

hvor,
GPG_SECRET_KEY_PASSPHRASE - GPG-nøgleadgangskode
SONATYPE_USERNAME - login på sonatype-konto

Tilbage til indholdet

Implementer docker-billede

  • Vi opretter en ret simpel Dockerfile til at køre opgaver på implementering med den ønskede version af Java. Nedenfor er et eksempel for 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/

  • Byg en container til dit projekt

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

  • Vi godkender og indlæser containeren i registreringsdatabasen.

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

Tilbage til indholdet

GitLab CI

Implementer projekt

Tilføj filen .gitlab-ci.yml til roden af ​​implementeringsprojektet
Scriptet præsenterer to gensidigt udelukkende implementeringsopgaver. Henholdsvis specifik løber eller delt løber.

.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

Tilbage til indholdet

Java projekt

I java-projekter, der formodes at blive uploadet til offentlige arkiver, skal du tilføje 2 trin for at downloade Release- og Snapshot-versionerne.

.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 denne løsning gik jeg lidt længere og besluttede at bruge en CI-skabelon til java-projekter.

Flere detaljer

Jeg lavede et separat projekt gitlab-ci hvori han placerede CI-skabelonen til java-projekter almindelig.yml.

almindelig.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 et resultat, i selve java-projekterne, ser .gitlab-ci.yml meget kompakt ud og ikke udførligt

.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

Tilbage til indholdet

pom.xml-konfiguration

Dette emne er beskrevet meget detaljeret. googolplex в Opsætning af maven til automatisk at signere og uploade artefakter til snapshot- og iscenesættelsesarkiver, så jeg vil beskrive nogle af nuancerne ved at bruge plugins. Jeg vil også beskrive, hvor nemt og naturligt du kan bruge nexus-staging-maven-pluginhvis du ikke vil eller kan bruge org.sonatype.oss:oss-parent som forælder for dit projekt.

maven-install-plugin

Installerer moduler i det lokale lager.
Meget nyttig til lokal verifikation af løsninger i andre projekter, samt en kontrolsum.

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

Tilbage til indholdet

maven-javadoc-plugin

Generering af javadoc til 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>

Hvis du har et modul, der ikke indeholder java (f.eks. kun ressourcer)
Eller du ønsker ikke at generere javadoc i princippet, så for at hjælpe 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>

Tilbage til indholdet

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>

Tilbage til indholdet

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>

Hvis du har et multi-modul projekt, og du ikke behøver at uploade et specifikt modul til repository, så skal du tilføje til pom.xml af dette modul nexus-staging-maven-plugin med flag skipNexusStagingDeployMojo

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

Efter upload af snapshot/frigivelse er versioner tilgængelige i iscenesættelse af depoter

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

Flere plusser

  • En meget rig liste over mål for at arbejde med nexus-lageret (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatisk udgivelsestjek for downloadbarhed i maven central

Tilbage til indholdet

Outcome

Udgivelse af en SNAPSHOT-version

Når du bygger et projekt, er det muligt manuelt at starte en opgave for at downloade SNAPSHOT-versionen til nexus

Opsætning af GitLab CI til at uploade et java-projekt til maven central

Når denne opgave startes, udløses den tilsvarende opgave i implementeringsprojektet (eksempel).

beskåret log

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 følge heraf er nexus-versionen indlæst 1.0.0-SNAPSHOT.

Alle snapshot-versioner kan fjernes fra lageret på webstedet oss.sonatype.org under din konto.

Opsætning af GitLab CI til at uploade et java-projekt til maven central

Tilbage til indholdet

Offentliggørelse af udgivelsesversionen

Når tagget er indstillet, udløses den tilsvarende opgave i implementeringsprojektet automatisk for at uploade udgivelsesversionen til nexus (eksempel).

Opsætning af GitLab CI til at uploade et java-projekt til maven central

Det bedste er, at close release automatisk udlø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] ------------------------------------------------------------------------

Og hvis noget gik galt, så mislykkes opgaven

[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 et resultat står vi kun tilbage med ét valg. Eller slet denne version eller udgiv.

Opsætning af GitLab CI til at uploade et java-projekt til maven central

Efter udgivelsen, efter nogen tid, vil artefakterne være inde Opsætning af GitLab CI til at uploade et java-projekt til maven central

udenfor emne

Det var en åbenbaring for mig, at Maven indekserer andre offentlige arkiver.
Jeg var nødt til at uploade robots.txt, fordi det indekserede mit gamle depot.

Tilbage til indholdet

Konklusion

hvad vi har

  • Et separat implementeringsprojekt, hvor du kan implementere adskillige CI-opgaver til upload af artefakter til offentlige arkiver til forskellige udviklingssprog.
  • Implementeringsprojektet er isoleret fra ekstern interferens og kan kun ændres af brugere med rollerne Ejer og Vedligeholder.
  • En separat Specifik Runner med en "hot" cache til kun at køre implementeringsopgaver.
  • Offentliggørelse af snapshot-/frigivelsesversioner i et offentligt lager.
  • Automatisk kontrol af udgivelsesversionen for klarhed til offentliggørelse i maven central.
  • Beskyttelse mod automatisk udgivelse af "rå" versioner i maven central.
  • Byg og udgiv snapshotversioner "ved klik".
  • Enkelt lager til at få snapshot/udgivelsesversioner.
  • Generel pipeline til opbygning / test / publicering af et java-projekt.

Opsætning af GitLab CI er ikke et så kompliceret emne, som det ser ud til ved første øjekast. Det er nok at sætte CI op på nøglefærdig basis et par gange, og nu er du langt fra en amatør i denne sag. Desuden er GitLab-dokumentation meget overflødig. Vær ikke bange for at tage det første skridt. Vejen vises under trinene på den, der går (jeg kan ikke huske, hvem der sagde det :)

Jeg vil være glad for feedback.

I den næste artikel vil jeg vise dig, hvordan du konfigurerer GitLab CI til at køre integrationstestopgaver konkurrencedygtigt (kører testtjenester med docker-compose), hvis du kun har én shell-løber.

Tilbage til indholdet

Kilde: www.habr.com

Tilføj en kommentar