Настройка на GitLab CI за качване на java проект в maven central

Тази статия е предназначена за Java разработчици, които имат нужда бързо да публикуват своите продукти в хранилищата на Sonatype и/или Maven Central, използвайки GitLab. В тази статия ще опиша настройката на gitlab-runner, gitlab-ci и maven-plugin за решаване на тази задача.

Предпосилки:

  • Сигурно съхранение на mvn и GPG ключове.
  • Сигурно изпълнение на публични CI задачи.
  • Качване на артефакти (release/snapshot) в публични хранилища.
  • Автоматична проверка на release версии за публикуване в Maven Central.
  • Общо решение за качване на артефакти в хранилище за няколко проекта.
  • Лесно и удобно използване.

Съдържание

Обща информация

  • Подробно описание на механизма за публикация на артефакти в Maven Central чрез Sonatype OSS Repository Hosting Service вече е описано в тази статия от потребителя Googolplex, затова в нужните места ще посочвам тази статия.
  • Преди всичко, регистрираме се в Sonatype JIRA и създаваме тикет за отваряне на хранилище (по-подробно вижте раздел Създаваме тикет в Sonatype JIRA). След откриването на хранилището, двойката логин/парола от JIRA (по-нататък účetна запись Sonatype) ще се използва за качване на артефакти в Sonatype nexus.
  • Следващият процес на генериране на GPG ключа е описан много подробно. По-подробно разгледайте раздела Настройка на GnuPG за подписване на артефакти
  • Ако използвате консолата на Linux за генериране на GPG ключ (gnupg/gnupg2), трябва да инсталирате rng-tools за генериране на ентропия. В противен случай генерирането на ключа може да отнеме много време.
  • Услуги за съхранение публични GPG ключове

К съдържанието

Настройка на deploy проекта в GitLab

  • Първо е необходимо да създадете и настроите проект, в който ще се съхранява pipeline за деплой на артефакти. Свой проект нарекох просто и ясно — deploy
  • След създаването на хранилището, е необходимо да ограничите достъпа до промени в хранилището.
    Преминаваме в проекта -> Настройки -> Хранилище -> Защитени клонове. Изтриваме всички правила и добавяме единствено правило с Wildcard * с право на push и merge само за потребители с роля Maintainers. Това правило ще важи за всички потребители както от този проект, така и от групата, в която този проект влиз.
    Настройка на GitLab CI за качване на java проект в maven central
  • Ако има няколко поддържачи, най-доброто решение е изцяло да се ограничи достъпът до проекта.
    Преминаваме в проекта -> Настройки -> Основни -> Видимост, функции на проекта, разрешения и задаваме видимостта на проекта на Private.
    Проектът ми е публичен, тъй като използвам собствен GitLab Runner и само аз имам достъп за промяна на репозитория. Освен това, не е в моите интереси да разкривам частна информация в публични pipeline логове.
  • Усилване на правилата за промяна на репозитория
    Преминаваме в проекта -> Настройки -> Репозитория -> Правила за натискане и задаваме флаговете Ограничение на комитери, Проверка дали авторът е потребител на GitLab. Също така препоръчвам да настроите подписването на комити, и да зададете флага Отхвърлине на неподписани комити.
  • След това трябва да настроите тригер за стартиране на задачите
    Преминаваме в проекта -> Настройки -> CI/CD -> Тригери на pipeline и създаваме нов trigger-token
    Този токен може веднага да бъде добавен в общата конфигурация на променливите за групата проекти.
    Преминаваме в групата -> Настройки -> CI/CD -> Променливи и добавяме променливата DEPLOY_TOKEN с trigger-token в стойността.

К съдържанието

GitLab Runner

В този раздел е описана конфигурацията за стартиране на задачи за деплой с използване на собствен (Specific) и публичен (Shared) runner.

Specific Runner

Използвам собствени ранери, тъй като това е удобно, бързо и икономично.
Препоръчвам линуксов VDS с 1 CPU, 2 GB RAM, 20 GB HDD за ранера. Цената е около 3000₽ на година.

Моят ранер

За ранера избрах VDS с 4 CPU, 4 GB RAM, 50 GB SSD. Цената беше около 11000₽ и нито веднъж не съжалих.
Общо имам 7 машини. 5 на aruba и 2 на ihor.

И така, имаме ранер. Сега ще го настроим.
Влизаме на машината по SSH и инсталираме java, git, maven, gnupg2.

К съдържанието

Инсталираме gitlab runner

  • Създаваме нова група runner
    sudo groupadd runner
  • Създаваме директория за maven кеша и задаваме права на групата runner
    Тази стъпка може да се пропусне, ако не планирате да стартирате няколко ранери на едно устройство.
    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Създаваме потребител gitlab-deployer и добавяме в групата runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Добавяме следния ред в файла /etc/ssh/sshd_config AllowUsers root@* gitlab-deployer@127.0.0.1
    Презареждаме
  • systemctl restart sshd sshd.
    Настройваме парола за потребителя
  • (може да бъде проста, тъй като важи ограничението за localhost) gitlab-deployer passwd gitlab-deployer
    Инсталираме GitLab Runner (Linux x86-64)
  • Инсталираме 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
  • Отидете на сайта gitlab.com -> deploy-project -> Настройки -> CI/CD -> Рендери -> Специфични рендери и копирайте регистрационния токен

Скрийн

Настройка на GitLab CI за качване на java проект в maven central

  • Регистрираме рендер
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

Процес

Платформа на времето arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Работи в системен режим.
Моля, въведете URL адреса на координатора gitlab-ci (например https://gitlab.com/):
https://gitlab.com/
Моля, въведете токена на gitlab-ci за този рендер:
REGISTRATION_TOKEN
Моля, въведете описанието на gitlab-ci за този рендер:
[ih1174328.vds.myihor.ru]: Deploy Runner
Моля, въведете етикетите на gitlab-ci за този рендер (разделени с запетая):
deploy
Регистриране на рендера... успешно                     runner=ZvKdjJhx
Моля, въведете изпълнителя: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Рендерът е успешно регистриран. Можете да го стартирате, но ако вече работи, конфигурацията трябва да се презареди автоматично!
  • Проверяваме дали рендерът е регистриран. Отидете на сайта gitlab.com -> deploy-project -> Настройки -> CI/CD -> Рендери -> Специфични рендери -> Рендери активирани за този проект

Скрийн

Настройка на GitLab CI за качване на java проект в maven central

  • Добавяме отделен сервис /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
  • Стартираме услугата.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Проверяваме дали рендерът е стартирал.

Пример

Настройка на GitLab CI за качване на java проект в maven central

К съдържанието

Генериране на GPG ключове

  • От тази същата машина влизаме по ssh като потребител gitlab-deployer (това е важно за генериране на GPG ключа)
    ssh gitlab-deployer@127.0.0.1
  • Генерираме ключ, отговаряйки на въпросите. Използвах собствено име и имейл.
    Общо задължително е да посочите парола за ключа. С този ключ ще бъдат подписвани артефактите.
    gpg --gen-key 
  • Проверяваме.
    gpg --list-keys -a
    /home/gitlab-deployer/.gnupg/pubring.gpg
    ----------------------------------------
    pub   4096R/00000000 2019-04-19
    uid                  Petruha Petrov 
    sub   4096R/11111111 2019-04-19
  • Качваме нашия публичен ключ на сървъра за ключове
    gpg --keyserver keys.gnupg.net --send-key 00000000
    gpg: sending key 00000000 to hkp server keys.gnupg.net

К съдържанието

Настройка на Maven

  • Влизаме като потребител gitlab-deployer
    su gitlab-deployer 
  • Създаваме директория maven repository и я свързваме с кеша (не се бъркайте)
    Тази стъпка може да се пропусне, ако не планирате да стартирате няколко рендера на една машина.
    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Създаваме майсторски ключ
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Създаваме файл ~/.m2/settings-security.xml
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Шифрираме паролата за акаунта Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Създаваме файл ~/.m2/settings.xml
    env
            
                true
            
            
                GPG_SECRET_KEY_PASSPHRASE
            
        
    
    
        
            sonatype
            SONATYPE_USERNAME
            {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}

където,
GPG_SECRET_KEY_PASSPHRASE — паролата за GPG ключа
SONATYPE_USERNAME — логин на акаунта sonatype

Тук настройката на раннера е завършена, може да преминем към раздела GitLab CI

К съдържанието

Споделен Runner

Генериране на GPG ключове

  • На първо място, е необходимо да създадете GPG ключ. За целта инсталираме gnupg.
    yum install -y gnupg
  • Генерираме ключ, отговаряйки на въпросите. Използвах собственото си име и имейл. Важно е да посочите паролата за ключа.
    gpg --gen-key 
  • Извеждаме информация за ключа
    gpg --list-keys -a
    pub   rsa3072 2019-04-24 [SC] [expires: 2021-04-23]
      2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    uid           [ultimate] tttemp 
    sub   rsa3072 2019-04-24 [E] [expires: none]
  • Качваме нашия публичен ключ на сървъра за ключове
    gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    gpg: изпраща ключ 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 до hkp сървъра keys.gnupg.net
  • Получаваме личния ключ
    gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    -----BEGIN PGP PRIVATE KEY BLOCK-----
    lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5
    ...
    =2Wd2
    -----END PGP PRIVATE KEY BLOCK-----
  • Преминаваме към настройките на проекта -> Settings -> CI / CD -> Variables и запазваме личния ключ в променлива GPG_SECRET_KEY
    Настройка на GitLab CI за качване на java проект в maven central

К съдържанието

Настройка на Maven

  • Създаваме майсторски ключ
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Преминаваме към настройките на проекта -> Settings -> CI / CD -> Variables и запазваме в променлива SETTINGS_SECURITY_XML следните редове:
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Шифрираме паролата за акаунта Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Преминаваме към настройките на проекта -> Settings -> CI / CD -> Variables и запазваме в променлива SETTINGS_XML следните редове:
    env
            
                true
            
            
                GPG_SECRET_KEY_PASSPHRASE
            
        
    
    
        
            sonatype
            sonatype_username
            {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}

където,
GPG_SECRET_KEY_PASSPHRASE — паролата за GPG ключа
SONATYPE_USERNAME — логин на акаунта sonatype

К съдържанието

Качване на Docker изображение

  • Създаваме достатъчно прост Dockerfile за стартиране на задачи по разгръщане с необходимата версия на Java. По-долу е представен пример за 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/
  • Сглобяваме контейнер за вашия проект
    docker build -t registry.gitlab.com/group/deploy .
  • Аутентифицираме се и качваме контейнера в registry.
    docker login -u USER -p PASSWORD registry.gitlab.com
    docker push registry.gitlab.com/group/deploy

К съдържанието

GitLab CI

Деплой на проект

Добавяме файл .gitlab-ci.yml в корена на проекта за деплой.
Скрипт съдържа две взаимоизключващи се задачи за деплой. Specific Runner или Shared Runner съответно.

.gitlab-ci.yml

stages:
  - deploy

Specific Runner:
  extends: .java_deploy_template
  # Задачата ще се изпълнява на вашия shell runner
  tags:
    - deploy

Shared Runner:
  extends: .java_deploy_template
  # Задачата ще се изпълнява на публичен docker runner
  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 "Файл $pom съдържа забранена настройка: ";
          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

К съдържанието

Java проект

В java проектите, които се предвижда да бъдат качвани в публични репозитории, е необходимо да се добавят 2 стъпки за качване на Release и Snapshot версии.

.gitlab-ci.yml

етапи:
  - изграждане
  - тестване
  - проверка
  - внедряване



Издание:
  разширена: .trigger_deploy
  # Стартирайте задачата само при таг.
  само:
    - тагове

Снимка:
  разширена: .trigger_deploy
  # Стартиране на задача за публикуване на SNAPSHOT версия ръчно
  когато: ръчно
  # Не стартирайте задачата, ако е зададен таг.
  освен:
    - тагове

.trigger_deploy:
  етап: внедряване
  променливи:
    # Отключване на клонирането на текущия проект
    GIT_STRATEGY: none
    # Линк към тригера на deploy задачата
    URL: "https://gitlab.com/api/v4/projects//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}
      "
  скрипт:
    # Не използвам cURL, тъй като с флаговете --fail --show-error
    # не извежда тялото на отговора, ако HTTP код 400 и повече 
    - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

В това решение отидох по-далеч и реших да използвам един CI шаблон за java проекти.

Повече подробности

Създадох отделен проект gitlab-ci в който поставих CI шаблона за java проекти common.yml.

common.yml

етапи:
  - изграждане
  - тестване
  - проверка
  - внедряване

променливи:
  SONAR_ARGS: "
  -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} 
  -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} 
  "

.build_java_project:
  етап: изграждане
  етикети:
    - touchbit-shell
  променливи:
    SKIP_TEST: "false"
  скрипт:
    - mvn clean
    - mvn package -DskipTests=${SKIP_TEST}
  артефакти:
    когато: винаги
    изтича след: 30 дни
    пътища:
      - "*/target/reports"

.build_sphinx_doc:
  етап: изграждане
  етикети:
    - touchbit-shell
  променливи:
    DOCKERFILE: .indirect/docs/Dockerfile
  скрипт:
    - docker build --no-cache -t ${CI_PROJECT_NAME}/doc -f ${DOCKERFILE} .

.junit_module_test_run:
  етап: тестване
  етикети:
    - touchbit-shell
  променливи:
    MODULE: ""
  скрипт:
    - cd ${MODULE}
    - mvn test
  артефакти:
    когато: винаги
    изтича след: 30 дни
    пътища:
      - "*/target/reports"

.junit_test_run:
  етап: тестване
  етикети:
    - touchbit-shell
  скрипт:
    - mvn test
  артефакти:
    когато: винаги
    изтича след: 30 дни
    пътища:
    - "*/target/reports"

.sonar_review:
  етап: проверка
  етикети:
    - touchbit-shell
  зависимости: []
  скрипт:
    - >
      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:
  етап: внедряване
  етикети:
    - touchbit-shell
  променливи:
    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}
      "
  скрипт:
  - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

.trigger_release_deploy:
  разширена: .trigger_deploy
  само:
    - тагове

.trigger_snapshot_deploy:
  разширена: .trigger_deploy
  когато: ръчно
  освен:
    - тагове

В резултат на това самите java проекти .gitlab-ci.yml изглеждат доста компактно и не много многословно

.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

К съдържанието

Конфигурация на pom.xml

Темата е много подробно описана Googolplex в Настройване на Maven за автоматично подписване и качване на артефакти в snapshot и staging репозитории, затова ще опиша някои специфики при използване на плъгини. Ще опиша и как лесно и удобно може да се използва nexus-staging-maven-plugin, ако не желаете или не можете да използвате org.sonatype.oss:oss-parent като родител за вашия проект.

maven-install-plugin

Инсталира модулите в локалния репозиторий.
Много полезен е за локална проверка на решения в други проекти, както и за контролна сума.

org.apache.maven.plugins
  maven-install-plugin
  
    
      install-project
      
      install
      
      
        target/${project.artifactId}-${project.version}.jar
```target/${project.artifactId}-${project.version}-sources.jar
        dependency-reduced-pom.xml
        
        true
        
        true

К съдържанието

maven-javadoc-plugin

Генерация на javadoc за проекта.

org.apache.maven.plugins
  maven-javadoc-plugin
  
    
      
        jar
      
      
      prepare-package
      
        
        true
        true
        
        false

Ако имате модул, който не съдържа java (например само ресурси)
Или не желаете изобщо да генерирате javadoc, това би помогнало maven-jar-plugin

org.apache.maven.plugins
  maven-jar-plugin
  
    
      empty-javadoc-jar
      generate-resources
      
        jar
      
      
        javadoc
        ${basedir}/javadoc

К съдържанието

maven-gpg-plugin

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

К съдържанието

nexus-staging-maven-plugin

Конфигурация:


  
    
      
      
        org.sonatype.plugins
        nexus-staging-maven-plugin
      
    
    
      
        
          org.sonatype.plugins
          nexus-staging-maven-plugin
          true
          
            sonatype
            https://oss.sonatype.org/
            
            
            true
          
        
        
          org.apache.maven.plugins
          maven-deploy-plugin
          
            
            true
          
        
      
    
  
  
    
      sonatype
      Nexus Snapshot Repository
      https://oss.sonatype.org/content/repositories/snapshots/
    
    
      sonatype
      Nexus Release Repository
      https://oss.sonatype.org/service/local/staging/deploy/maven2/

Ако имате многомодулен проект и не е необходимо да качвате определен модул в хранилището, добавете в pom.xml на този модул nexus-staging-maven-plugin с флаг skipNexusStagingDeployMojo

org.sonatype.plugins
      nexus-staging-maven-plugin
      
        true

След качването, snapshot/release версиите са достъпни в стадийни репозитории

SonatypeNexus
    https://oss.sonatype.org/content/groups/staging/
    

Още предимства

  • Много богато приложение на цели за работа с nexus репозитория (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Автоматична проверка на релиза за възможност за качване в maven central

К съдържанието

Резултат

Публикация на SNAPSHOT версия

При сборката на проекта има възможност за ръчно стартиране на задачата за качване на SNAPSHOT версия в nexus

Настройка на GitLab CI за качване на java проект в maven central

При стартиране на тази задача се задейства съответната задача в проекта deploy (пример).

Ограничен лог

Стартиране с gitlab-runner 11.10.0 (3001a600)
  на Deploy runner JSKWyxUw
Използване на Shell executor...
Стартиране на ih1174328.vds.myihor.ru...
Пропускане на настройката на Git хранилище
Пропускане на Git checkout
Пропускане на настройката на Git подмодули
$ 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} .
Клониране в 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Забележка: проверка на '850f86aa317194395c5387790da1350e437125a7'.
Вие сте в състояние 'отделена HEAD'. Можете да се разходите, да направите експериментални
промени и да ги комитирате, и можете да отмените всякакви комити, които направите в това
състояние, без да повлияете на каквито и да е клонове, като извършите нов checkout.
Ако искате да създадете нов клон, за да запазите комити, които създавате, можете
да го направите (сега или по-късно) с -b с командата checkout отново. Пример:
  git checkout -b new_branch_name
HEAD сега е на 850f86a... пропускане на deploy test-core
$ for pom in $(find . -name pom.xml); do # свита многофункционална команда
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # свита многофункционална команда
[ИНФО] Скенер проекти...
[ИНФО] Инспектиране на билд с общо 4 модула...
[ИНФО] Инсталиране на функции Nexus Staging:
[ИНФО]   ... общо 4 изпълнения на maven-deploy-plugin заменени с nexus-staging-maven-plugin
[ИНФО] ------------------------------------------------------------------------
[ИНФО] Ред на изграждане на реактора:
[ИНФО] 
[ИНФО] Shields4J                                                          [pom]
[ИНФО] test-core                                                          [jar]
[ИНФО] Shields4J клиент                                                   [jar]
[ИНФО] TestNG слушател                                                    [jar]
[ИНФО] 
[ИНФО] -----------------------------
[ИНФО] Изграждане на Shields4J 1.0.0                                           [1/4]
[ИНФО] --------------------------------[ pom ]---------------------------------
[ИНФО] 
[ИНФО] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[ИНФО] Търсене на локален корен на агрегатора...
[ИНФО] Локален корен на агрегацията: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[ИНФО] Обработка на промяната на org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[ИНФО] Обработка на org.touchbit.shields4j:shields4j-parent
[ИНФО]     Актуализиране на проекта org.touchbit.shields4j:shields4j-parent
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО] 
[ИНФО] Обработка на org.touchbit.shields4j:client
[ИНФО]     Актуализиране на родителя org.touchbit.shields4j:shields4j-parent
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО]     Актуализиране на зависимост org.touchbit.shields4j:test-core
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО] 
[ИНФО] Обработка на org.touchbit.shields4j:test-core
[ИНФО]     Актуализиране на родителя org.touchbit.shields4j:shields4j-parent
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО] 
[ИНФО] Обработка на org.touchbit.shields4j:testng
[ИНФО]     Актуализиране на родителя org.touchbit.shields4j:shields4j-parent
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО]     Актуализиране на зависимост org.touchbit.shields4j:client
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО]     Актуализиране на зависимост org.touchbit.shields4j:test-core
[ИНФО]         от версия 1.0.0 до 1.0.0-SNAPSHOT
[ИНФО] 
[ИНФО] ------------------------------------------------------------------------
[ИНФО] Резюме на реактора:
[ИНФО] 
[ИНФО] Shields4J 1.0.0 .................................... УСПЕШНО [  0.992 s]
[ИНФО] test-core .......................................... ПРОПУСНАТО
[ИНФО] Shields4J клиент ................................... ПРОПУСНАТО
[ИНФО] TestNG слушател 1.0.0 .............................. ПРОПУСНАТО
[ИНФО] ------------------------------------------------------------------------
[ИНФО] ИЗГРАЖДАНЕ УСПЕШНО
[ИНФО] ------------------------------------------------------------------------
[ИНФО] Общо време: 2.483 s
[ИНФО] Завършено в: 2019-04-21T02:40:42+03:00
[ИНФО] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[ИНФО] Скенер проекти...
[ИНФО] Инспектиране на билд с общо 4 модула...
[ИНФО] Инсталиране на функции Nexus Staging:
[ИНФО]   ... общо 4 изпълнения на maven-deploy-plugin заменени с nexus-staging-maven-plugin
[ИНФО] ------------------------------------------------------------------------
[ИНФО] Ред на изграждане на реактора:
[ИНФО] 
[ИНФО] Shields4J                                                          [pom]
[ИНФО] test-core                                                          [jar]
[ИНФО] Shields4J клиент                                                   [jar]
[ИНФО] TestNG слушател                                                    [jar]
[ИНФО] 
[ИНФО] -----------------------------
[ИНФО] Изграждане на Shields4J 1.0.0-SNAPSHOT                                  [1/4]
[ИНФО] --------------------------------[ pom ]---------------------------------
...
ИЗТРИТО
...
[ИНФО]  * Масово разполагане на локално събрани артефакти за снимка приключи.
[ИНФО] Дистанционно разполагане приключи успешно.
[ИНФО] ------------------------------------------------------------------------
[ИНФО] Резюме на реактора:
[ИНФО] 
[ИНФО] Shields4J 1.0.0-SNAPSHOT ........................... УСПЕШНО [  2.375 s]
[ИНФО] test-core .......................................... УСПЕШНО [  3.929 s]
[ИНФО] Shields4J клиент ................................... УСПЕШНО [  3.815 s]
[ИНФО] TestNG слушател 1.0.0-SNAPSHOT ..................... УСПЕШНО [ 36.134 s]
[ИНФО] ------------------------------------------------------------------------
[ИНФО] ИЗГРАЖДАНЕ УСПЕШНО
[ИНФО] ------------------------------------------------------------------------
[ИНФО] Общо време: 47.629 s
[ИНФО] Завършено в: 2019-04-21T02:41:32+03:00
[ИНФО] ------------------------------------------------------------------------

В резултат в nexus е качена версия 1.0.0-SNAPSHOT.

Всички snapshot версии могат да бъдат изтрити от репозитория на сайта oss.sonatype.org със своята учетна запис.

Настройка на GitLab CI за качване на java проект в maven central

К съдържанието

Публикация на release версия

При инсталирането на тага, автоматично се задейства съответната задача в проекта deploy за качване на релизната версия в nexus (пример).

Настройка на GitLab CI за качване на java проект в maven central

Най-приятното е, че автоматично се задейства close release в nexus.

[INFO] Извършване на отдалечено stage...
[INFO] 
[INFO]  * Отдалечено stage в профил ID "9043b43f77dcc9"
[INFO]  * Създаден staging репозиторий с ID "orgtouchbit-1037".
[INFO]  * Staging репозиторий на https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO]  * Качване на локално staged артефакти в профила org.touchbit
[INFO]  * Качването на локално staged артефакти е завършено.
[INFO]  * Затваряне на staging репозиторий с ID "orgtouchbit-1037".
Очакване на операцията да завърши...
.........
[INFO] Отдалечено staged 1 репозитории, завършено с успех.
[INFO] ------------------------------------------------------------------------
[INFO] Резюме на реактора:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... УСПЕХ [  9.603 с]
[INFO] test-core .......................................... УСПЕХ [  3.419 с]
[INFO] Shields4J клиент .................................. УСПЕХ [  9.793 с]
[INFO] TestNG listener 1.0.0 ............................ УСПЕХ [01:23 мин]
[INFO] ------------------------------------------------------------------------
[INFO] ИЗГРАЖДАНЕ УСПЕШНО
[INFO] ------------------------------------------------------------------------
[INFO] Общо време: 01:47 мин
[INFO] Завършено на: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------

И ако нещо се е объркало, задачата ще се провали

[INFO] Извършване на отдалечено тестване...
[INFO] 
[INFO]  * Отдалечено тестване в профила за тестване с ID "9043b43f77dcc9"
[INFO]  * Създадено е хранилище за тестване с ID "orgtouchbit-1038".
[INFO]  * Хранилището за тестване на адрес https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO]  * Качване на локално тествани артефакти в профила org.touchbit
[INFO]  * Качването на локално тестваните артефакти приключи.
[INFO]  * Затваряне на хранилището за тестване с ID "orgtouchbit-1038".
Изчакване за завършване на операцията...
.......
[ERROR] Провал на правилото при опит за затваряне на хранилището за тестване с ID "orgtouchbit-1039".
[ERROR] 
[ERROR] Доклад за провал на правилата на Nexus Staging
[ERROR] ==================================
[ERROR] 
[ERROR] Провали на хранилище "orgtouchbit-1039"
[ERROR]   Провали на правило "signature-staging"
[ERROR]     * Няма публичен ключ: Ключ с ID: (1f42b618d1cbe1b5) не може да бъде намерен на <a href=http://keys.gnupg.net:11371/>http://keys.gnupg.net:11371/</a>. Качете вашия публичен ключ и опитайте операцията отново.
...
[ERROR] Почистване на локалната директория за тестване след провал на правило по време на затваряне на хранилищата за тестване: [orgtouchbit-1039]
[ERROR]  * Изтриване на контекста 9043b43f77dcc9.properties
[ERROR] Почистване на отдалечените хранилища за тестване след провал на правило по време на затваряне на хранилищата за тестване: [orgtouchbit-1039]
[ERROR]  * Премахване на провалилото се хранилище за тестване с ID "orgtouchbit-1039" (Провал на правило по време на затваряне на хранилищата за тестване: [orgtouchbit-1039]).
[ERROR] Отдалеченото тестване приключи с провал: Провал на правилата за тестване!
[INFO] ------------------------------------------------------------------------
[INFO] Обобщение на реактора:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... УСПЕХ [  4.073 с]
[INFO] test-core .......................................... УСПЕХ [  2.788 с]
[INFO] Клиент на Shields4J ................................... УСПЕХ [  3.962 с]
[INFO] Слушател на TestNG 1.0.0 .............................. провал [01:07 мин]
[INFO] ------------------------------------------------------------------------
[INFO] ПРОВАЛ НА СТРОЕЖ
[INFO] ------------------------------------------------------------------------

В резултат остават само два избора. Или да изтрием тази версия, или да я публикуваме.

Настройка на GitLab CI за качване на java проект в maven central

След публикуването, след известно време артефактите ще се окажат в Настройка на GitLab CI за качване на java проект в maven central

офтор

За мен беше откритие, че maven индексира и други публични репозитории.
Пришло се наложи да добавя robots.txt, тъй като индексира моето старо хранилище.

К съдържанието

Заключение

Какво имаме

  • Отделен проект за внедряване, в който могат да бъдат реализирани няколко CI задачи за качване на артефакти в публични репозитории за различни езици за програмиране.
  • Проектът за внедряване е изолиран от външна намеса и може да бъде променян само от потребители с роля Owner и Maintainer.
  • Отделен Специфичен Изпълнител с "горещ" кеш за изпълнение само на задачи за внедряване.
  • Публикация на snapshot/release версии в публично хранилище.
  • Автоматична проверка на release версията за готовност за публикуване в maven central.
  • Защита от автоматична публикация на "сурови" версии в maven central.
  • Сглобяване и публикуване на snapshot версии "по клик".
  • Едно хранилище за получаване на snapshot/release версии.
  • Общият пайплайн за изграждане/тестиране/публикуване на Java проект.

Настройката на GitLab CI не е толкова сложна тема, колкото изглежда на пръв поглед. Достатъчно е да настроите CI "под ключ" няколко пъти и вече няма да сте дилетант в това. Особено, тъй като документацията на GitLab е доста обширна. Не се страхувайте да направите първата крачка. Пътят се появява под краката на вървящия (не помня кой го каза 🙂 ).

Ще се радвам на обратна връзка.

В следващата статия ще разкажа как да настроите GitLab CI за конкурентно стартиране на задачи с интеграционни тестове (с пускане на тестваните услуги чрез docker-compose), ако имате само един shell рънър.

К съдържанието

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster