GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

Dit artikel is bedoeld foar Java-ûntwikkelders dy't de needsaak hawwe om har produkten fluch te publisearjen yn sonatype en / of maven sintrale repositories mei GitLab. Yn dit artikel sil ik prate oer it ynstellen fan gitlab-runner, gitlab-ci en maven-plugin om dit probleem op te lossen.

Betingsten:

  • Feilige opslach fan mvn- en GPG-kaaien.
  • Feilige útfiering fan iepenbiere CI taken.
  • Artefakten uploade (release / momintopname) nei iepenbiere repositories.
  • Automatysk kontrolearjen fan release ferzjes foar publikaasje yn maven sintraal.
  • In algemiene oplossing foar it uploaden fan artefakten nei in repository foar meardere projekten.
  • Ienfâld en gemak fan gebrûk.

Ynhâld

Algemiene ynformaasje

  • In detaillearre beskriuwing fan it meganisme foar it publisearjen fan artefakten yn Maven Central fia Sonatype OSS Repository Hosting Service is al beskreaun yn dit artikel brûker Googolplex, dus ik sil ferwize nei dit artikel op 'e goede plakken.
  • Pre-registrearje foar Sonatype JIRA en iepenje in kaartsje om it repository te iepenjen (lês de seksje foar mear details Meitsje in kaartsje op Sonatype JIRA). Nei it iepenjen fan it repository sil it oanmeld-/wachtwurdpaar fan JIRA (hjirnei oantsjutten as it Sonatype-akkount) brûkt wurde om artefakten te uploaden nei Sonatype nexus.
  • Dêrnei wurdt it proses fan it generearjen fan in GPG-kaai tige droech beskreaun. Sjoch seksje foar mear details GnuPG konfigurearje om artefakten te tekenjen
  • As jo ​​de Linux-konsole brûke om in GPG-kaai te generearjen (gnupg/gnupg2), dan moatte jo ynstallearje rng-tools om entropy te generearjen. Oars kin it generearjen fan kaaien in heul lang duorje.
  • Opslach tsjinsten iepenbier GPG toetsen

Nei de ynhâld

In ynsetprojekt ynstelle yn GitLab

  • Earst moatte jo in projekt oanmeitsje en konfigurearje wêryn de pipeline sil wurde opslein foar it ynsetten fan artefakten. Ik neamde myn projekt ienfâldich en sûnder komplisearre - deploy
  • Nei it meitsjen fan it repository moatte jo tagong beheine om it repository te feroarjen.
    Gean nei projekt -> Ynstellings -> Repository -> Beskerme tûken. Wy wiskje alle regels en foegje ien regel ta mei Wildcard * mei it rjocht om allinich te drukken en te fusearjen foar brûkers mei de rol fan 'e Maintainers. Dizze regel sil wurkje foar alle brûkers fan sawol dit projekt as de groep dêr't dit projekt ta heart.
    GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal
  • As d'r ferskate ûnderhâlders binne, dan soe de bêste oplossing wêze om yn prinsipe tagong ta it projekt te beheinen.
    Gean nei projekt -> Ynstellings -> Algemien -> Sichtberens, projektfunksjes, tagongsrjochten en set Projektsichtberens yn op private.
    Ik haw in iepenbier tagonklik projekt, om't ik myn eigen GitLab Runner brûke en allinich ik tagong haw om it repository te feroarjen. No, eins, it is net yn myn belangen om privee-ynformaasje te toanen yn iepenbiere pipeline-logs.
  • De regels foar it feroarjen fan de repository oanskerpe
    Gean nei it projekt -> Ynstellings -> Repository -> Push Rules en set de Committer-beheining yn, Kontrolearje oft de auteur in GitLab-brûkersflaggen is. Ik advisearje ek it opsetten commit hântekening, en set de flagge Reject unsigned commits yn.
  • Folgjende moatte jo in trigger konfigurearje om taken te starten
    Gean nei projekt -> Ynstellings -> CI / CD -> Pipeline-triggers en meitsje in nije trigger-token
    Dit token kin fuortendaliks tafoege wurde oan 'e algemiene konfiguraasje fan fariabelen foar in groep projekten.
    Gean nei groep -> Ynstellings -> CI / CD -> Fariabelen en foegje in fariabele ta DEPLOY_TOKEN mei trigger-token yn wearde.

Nei de ynhâld

GitLab Runner

Dizze seksje beskriuwt de konfiguraasje foar it útfieren fan taken by ynset mei jo eigen (Spesifike) en iepenbiere (Shared) runner.

Spesifike Runner

Ik brûk myn eigen rinners, om't it earst fan alles handich, rap en goedkeap is.
Foar in runner, Ik riede in Linux VDS mei 1 CPU, 2 GB RAM, 20 GB HDD. De útjeftepriis is ~3000₽ per jier.

Myn runner

Foar de runner Ik naam VDS 4 CPU, 4 GB RAM, 50 GB SSD. Kosten ~ 11000 ₽ en hie der noait spyt fan.
Ik haw yn totaal 7 masines. 5 op Aruba en 2 op ihor.

Sa hawwe wy in runner. No sille wy it konfigurearje.
Wy geane nei de masine fia SSH en ynstallearje java, git, maven, gnupg2.

Nei de ynhâld

Gitlab runner ynstallearje

  • Meitsje in nije groep runner
    sudo groupadd runner
  • Meitsje in map foar de maven-cache en jou groepsrjochten ta runner
    Jo kinne dit punt oerslaan as jo net fan plan binne ferskate runners op ien masine te rinnen.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Meitsje in brûker gitlab-deployer en tafoegje oan de groep runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Tafoegje oan triem /etc/ssh/sshd_config folgjende rigel
    AllowUsers root@* [email protected]
  • Reboot sshd
    systemctl restart sshd
  • It ynstellen fan in wachtwurd foar de brûker gitlab-deployer (kin ienfâldich wêze, om't d'r in beheining is foar localhost)
    passwd gitlab-deployer
  • GitLab Runner ynstallearje (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
  • Gean nei de webside gitlab.com -> deploy-project -> Ynstellings -> CI/CD -> Runners -> Spesifike Runners en kopiearje it registraasjetoken

Skerm

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

  • Registrearje in runner
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

proses

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!
  • Wy kontrolearje dat de rinner is registrearre. Gean nei de webside gitlab.com -> deploy-project -> Ynstellings -> CI/CD -> Runners -> Spesifike Runners -> Runners aktivearre foar dit projekt

Skerm

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

  • Add skiede tsjinst /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
  • Litte wy de tsjinst begjinne.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Wy kontrolearje dat de rinner rint.

Foarbyld:

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

Nei de ynhâld

It generearjen fan GPG-kaaien

  • Fan deselde masine loggen wy fia ssh yn ûnder de brûker gitlab-deployer (dit is wichtich foar it generearjen fan de GPG-kaai)
    ssh [email protected]
  • Wy generearje in kaai troch fragen te beantwurdzjen. Ik brûkte myn eigen namme en e-post.
    Soargje derfoar dat jo it wachtwurd foar de kaai opjaan. Artefakten sille wurde tekene mei dizze kaai.

    gpg --gen-key 
  • Kontrolearje
    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
  • It opladen fan ús iepenbiere kaai nei de kaai tsjinner
    gpg --keyserver keys.gnupg.net --send-key 00000000
    gpg: sending key 00000000 to hkp server keys.gnupg.net

Nei de ynhâld

Maven ynstelle

  • Oanmelde as brûker gitlab-deployer
    su gitlab-deployer 
  • Meitsje in maven triemtafel repository en keppelje nei de cache (meitsje gjin flater)
    Jo kinne dit punt oerslaan as jo net fan plan binne ferskate runners op ien masine te rinnen.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Meitsje in masterkaai
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Meitsje in triem ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Fersiferje it wachtwurd foar it Sonatype-akkount
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Meitsje in triem ~/.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>

wêr,
GPG_SECRET_KEY_PASSPHRASE - wachtwurd foar de GPG-kaai
SONATYPE_USERNAME - sonatype akkount oanmelde

Dit foltôget de opset fan 'e runner, jo kinne trochgean nei de seksje GitLab CI

Nei de ynhâld

Dielde Runner

It generearjen fan GPG-kaaien

  • Earst moatte jo in GPG-kaai meitsje. Om dit te dwaan, ynstallearje gnupg.
    yum install -y gnupg
  • Wy generearje in kaai troch fragen te beantwurdzjen. Ik brûkte myn eigen namme en e-post. Soargje derfoar dat jo it wachtwurd foar de kaai opjaan.
    gpg --gen-key 
  • It werjaan fan ynformaasje oer de kaai
    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]
  • It opladen fan ús iepenbiere kaai nei de kaai tsjinner
    gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    gpg: sending key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 to hkp server keys.gnupg.net
  • Wy krije de privee kaai
    gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    -----BEGIN PGP PRIVATE KEY BLOCK-----
    lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5
    ...
    =2Wd2
    -----END PGP PRIVATE KEY BLOCK-----
  • Gean nei projektynstellingen -> Ynstellings -> CI / CD -> Fariabelen en bewarje de privee kaai yn in fariabele GPG_SECRET_KEY
    GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

Nei de ynhâld

Maven ynstelle

  • Meitsje in masterkaai
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Gean nei projektynstellingen -> Ynstellings -> CI / CD -> Fariabelen en bewarje yn in fariabele SETTINGS_SECURITY_XML de folgjende rigels:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Fersiferje it wachtwurd foar it Sonatype-akkount
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Gean nei projektynstellingen -> Ynstellings -> CI / CD -> Fariabelen en bewarje yn in fariabele SETTINGS_XML de folgjende rigels:
    <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>

wêr,
GPG_SECRET_KEY_PASSPHRASE - wachtwurd foar de GPG-kaai
SONATYPE_USERNAME - sonatype akkount oanmelde

Nei de ynhâld

Dockerôfbylding ynsette

  • Wy meitsje in frij ienfâldige Dockerfile om taken út te fieren mei de fereaske ferzje fan Java. Hjirûnder is in foarbyld foar 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/
  • Sammelje in kontener foar jo projekt
    docker build -t registry.gitlab.com/group/deploy .
  • Wy ferifiearje en laden de kontener yn it register.
    docker login -u USER -p PASSWORD registry.gitlab.com
    docker push registry.gitlab.com/group/deploy

Nei de ynhâld

GitLab CI

Deploy projekt

Foegje it .gitlab-ci.yml-bestân ta oan 'e root fan it ynsetprojekt
It skript presintearret twa ûnderling eksklusive ynsettaken. Spesifike Runner of Shared Runner respektivelik.

.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

Nei de ynhâld

Java projekt

Yn java-projekten dy't nei iepenbiere repositories moatte wurde uploade, moatte jo 2 stappen tafoegje om de ferzjes fan Release en Snapshot 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}

Yn dizze oplossing gie ik in bytsje fierder en besleat ien CI-sjabloan te brûken foar java-projekten.

Yn details

Ik makke in apart projekt gitlab-ci wêryn ik pleatste in CI sjabloan foar java projekten 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

As gefolch, yn 'e java-projekten sels, sjocht .gitlab-ci.yml tige kompakt en net verbose

.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

Nei de ynhâld

Pom.xml konfiguraasje

Dit ûnderwerp wurdt beskreaun yn grutte detail. Googolplex в Maven ynstelle om artefakten automatysk te ûndertekenjen en te uploaden nei snapshot- en staging-repositories, dus ik sil guon fan 'e nuânses beskriuwe fan it brûken fan plugins. Ik sil ek beskriuwe hoe maklik en ûntspannen jo kinne brûke nexus-staging-maven-pluginas jo org.sonatype.oss:oss-parent net wolle of kinne brûke as âlder foar jo projekt.

maven-ynstallearje-plugin

Ynstallearret modules yn it lokale repository.
Hiel nuttich foar lokale ferifikaasje fan oplossingen yn oare projekten, lykas ek in kontrôlesum.

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

Nei de ynhâld

maven-javadoc-plugin

Javadoc generearje foar it projekt.

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

As jo ​​in module hawwe dy't gjin java befettet (bygelyks allinich boarnen)
Of jo wolle yn prinsipe gjin javadoc generearje, 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>

Nei de ynhâld

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>

Nei de ynhâld

nexus-staging-maven-plugin

Konfiguraasje:

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

As jo ​​in multi-module projekt hawwe en jo hoege gjin spesifike module te uploaden nei it repository, dan moatte jo tafoegje nexus-staging-maven-plugin mei flagge skipNexusStagingDeployMojo

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

Nei it ynladen binne ferzjes fan snapshot/release beskikber yn staging repositories

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

Mear pluses

  • In heul rike list mei doelen foar wurkjen mei it nexus repository (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatyske frijlittingskontrôle foar uploaden nei maven sintraal

Nei de ynhâld

resultaat

Publisearje SNAPSHOT ferzje

By it bouwen fan in projekt is it mooglik om in taak manuell te starten om de SNAPSHOT-ferzje nei nexus te downloaden

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

As dizze taak wurdt lansearre, wurdt de oerienkommende taak yn it ynsetprojekt trigger (foarbyld).

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

As gefolch, de ferzje wurdt laden yn nexus 1.0.0-SNAPSHOT.

Alle snapshotferzjes kinne wiske wurde fan it repository op 'e webside oss.sonatype.org ûnder jo akkount.

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

Nei de ynhâld

It publisearjen fan in release ferzje

As in tag is ynstalleare, wurdt de korrespondearjende taak yn it ynsetprojekt automatysk aktivearre om de releaseferzje te downloaden nei nexus (foarbyld).

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

It bêste diel is dat tichtby frijlitting automatysk yn 'e nexus aktivearre wurdt.

[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 as der wat mis giet, sil de taak definityf mislearje

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

As gefolch hawwe wy mar ien kar oer. Wiskje dizze ferzje of publisearje it.

GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

Nei frijlitting sille nei in skoft de artefakten binnen wêze GitLab CI ynstelle om in java-projekt te uploaden nei maven sintraal

offtopic

It wie in ûntdekking foar my dat Maven oare iepenbiere repositories yndeksearret.
Ik moast robots.txt tafoegje om't it myn âlde repository yndeksearre.

Nei de ynhâld

konklúzje

Wat wy hawwe

  • In apart ynsetprojekt wêryn jo ferskate CI-taken kinne ymplementearje foar it uploaden fan artefakten nei iepenbiere repositories foar ferskate ûntwikkelingstalen.
  • It Deploy-projekt is isolearre fan ynterferinsje fan bûten en kin allinich feroare wurde troch brûkers mei de rollen Eigner en Maintainer.
  • In aparte Spesifike Runner mei in "hot" cache om allinich taken út te fieren.
  • Snapshot/release ferzjes publisearje yn in iepenbier repository.
  • Automatyske kontrôle fan 'e releaseferzje foar reeheid foar publikaasje yn Maven Central.
  • Beskerming tsjin automatyske publikaasje fan "rauwe" ferzjes yn maven sintraal.
  • Bouwe en publisearje snapshotferzjes "op klik".
  • In inkele repository foar it krijen fan snapshot/release ferzjes.
  • Algemiene pipeline foar it bouwen / testen / publisearjen fan in java-projekt.

It ynstellen fan GitLab CI is net sa yngewikkeld in ûnderwerp as it liket op it earste each. It is genôch om CI in pear kear op turn-key basis yn te stellen, en no binne jo fier fan in amateur yn dizze saak. Boppedat is GitLab-dokumintaasje heul oerstallich. Wês net bang om de earste stap te nimmen. De dyk ferskynt ûnder de stappen fan 'e persoan dy't rint (ik herinner my net wa't it sei :)

Ik sil bliid wêze om feedback te ûntfangen.

Yn it folgjende artikel sil ik prate oer hoe't jo GitLab CI konfigurearje om taken mei yntegraasjetests konkurrearjend út te fieren (de tsjinsten ûnder test útfiere mei docker-compose) as jo mar ien shell-runner hawwe.

Nei de ynhâld

Boarne: www.habr.com