Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

Овај чланак је намењен Јава програмерима који имају потребу да брзо објаве своје производе у сонатипе и/или мавен централним репозиторијумима користећи ГитЛаб. У овом чланку ћу говорити о подешавању гитлаб-руннера, гитлаб-ци и мавен-плугин-а за решавање овог проблема.

Предуслови:

  • Сигурно складиштење мвн и ГПГ кључева.
  • Безбедно извршавање јавних ЦИ задатака.
  • Отпремање артефаката (издања/снимка) у јавна спремишта.
  • Аутоматска провера верзија издања за објављивање у мавен централу.
  • Опште решење за отпремање артефаката у спремиште за више пројеката.
  • Једноставност и лакоћа употребе.

Садржина

Опште информације

  • Детаљан опис механизма за објављивање артефаката у Мавен Централ преко Сонатипе ОСС Репоситори Хостинг услуге је већ описан у Овај чланак корисника Гооголплек, па ћу се позивати на овај чланак на правим местима.
  • Региструјте се унапред за Сонатипе ЈИРА и отворите тикет да отворите спремиште (прочитајте одељак за више детаља Направите карту на Сонатипе ЈИРА). Након отварања спремишта, пар пријава/лозинка из ЈИРА-е (у даљем тексту Сонатипе налог) ће се користити за отпремање артефаката у Сонатипе некус.
  • Затим, процес генерисања ГПГ кључа је описан веома суво. Погледајте одељак за више детаља Конфигурисање ГнуПГ-а за потписивање артефаката
  • Ако користите Линук конзолу за генерисање ГПГ кључа (гнупг/гнупг2), онда морате да инсталирате рнг-алати да генерише ентропију. У супротном, генерисање кључева може потрајати веома дуго.
  • Услуге складиштења јавно ГПГ кључеви

На садржај

Подешавање пројекта имплементације у ГитЛабу

  • Пре свега, потребно је да креирате и конфигуришете пројекат у коме ће цевовод бити ускладиштен за постављање артефаката. Свој пројекат сам назвао једноставно и некомпликовано - развити
  • Након креирања спремишта, потребно је да ограничите приступ да бисте променили спремиште.
    Идите на пројекат -> Подешавања -> Репозиторијум -> Заштићене гране. Бришемо сва правила и додајемо једно правило са џокер знаком * са правом гурања и спајања само за кориснике са улогом одржаваоца. Ово правило ће функционисати за све кориснике и овог пројекта и групе којој овај пројекат припада.
    Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ
  • Ако постоји неколико одржавалаца, онда би најбоље решење било да се у принципу ограничи приступ пројекту.
    Идите на пројекат -> Подешавања -> Опште -> Видљивост, карактеристике пројекта, дозволе и подесите Видљивост пројекта на Приватан.
    Имам јавно доступан пројекат, пошто користим свој ГитЛаб Руннер и само ја имам приступ да променим спремиште. Па, заправо, није у мом интересу да приказујем приватне информације у јавним евиденцијама цевовода.
  • Пооштравање правила за промену спремишта
    Идите на пројекат -> Сеттингс -> Репоситори -> Пусх Рулес и поставите ограничење Цоммиттер-а, Проверите да ли је аутор корисник ГитЛаб-а. Такође препоручујем постављање потпис за урезивање, и поставите ознаку Одбаци непотписано урезивање.
  • Затим морате да конфигуришете окидач за покретање задатака
    Идите на пројекат -> Подешавања -> ЦИ / ЦД -> Окидачи цевовода и креирајте нови окидач-токен
    Овај токен се може одмах додати општој конфигурацији варијабли за групу пројеката.
    Идите на групу -> Подешавања -> ЦИ / ЦД -> Променљиве и додајте променљиву DEPLOY_TOKEN са окидачем-токеном у вредности.

На садржај

ГитЛаб Руннер

Овај одељак описује конфигурацију за извршавање задатака при постављању помоћу сопственог (специфичног) и јавног (дељеног) покретача.

Специфиц Руннер

Користим своје тркаче јер су, пре свега, згодне, брзе и јефтине.
За тркаче, препоручујем Линук ВДС са 1 ЦПУ, 2 ГБ РАМ-а, 20 ГБ ХДД-ом. Цена емисије је ~3000₽ годишње.

Мој тркач

За тркач сам узео ВДС 4 ЦПУ, 4 ГБ РАМ-а, 50 ГБ ССД. Коштао је ~11000₽ и никада нисам пожалио.
Имам укупно 7 машина. 5 на аруби и 2 на ихору.

Дакле, имамо тркача. Сада ћемо га конфигурисати.
Идемо на машину преко ССХ-а и инсталирамо јава, гит, мавен, гнупг2.

На садржај

Инсталирање гитлаб руннера

  • Направите нову групу runner
    sudo groupadd runner
  • Креирајте директоријум за мавен кеш и доделите групне дозволе 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@* [email protected]
  • Рестарт sshd
    systemctl restart sshd
  • Постављање лозинке за корисника gitlab-deployer (може бити једноставно, пошто постоји ограничење за локални хост)
    passwd gitlab-deployer
  • Инсталирајте ГитЛаб Руннер (Линук к86-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-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!

  • Проверавамо да ли је тркач регистрован. Идите на веб локацију гитлаб.цом -> деплои-пројецт -> Сеттингс -> ЦИ/ЦД -> Руннерс -> Специфиц Руннерс -> Руннерс активирани за овај пројекат

Екран

Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

  • Додај одвојити услуга /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-deployer (ово је важно за генерисање ГПГ кључа)

    ssh [email protected]

  • Одговарајући на питања генеришемо кључ. Користио сам своје име и имејл.
    Обавезно наведите лозинку за кључ. Артефакти ће бити потписани овим кључем.

    gpg --gen-key 

  • Провера

    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

  • Отпремање нашег јавног кључа на сервер кључева

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

На садржај

Постављање Мавен-а

  • Пријавите се као корисник gitlab-deployer
    su gitlab-deployer 
  • Направите мавен директоријум Складиште и линк до кеша (не грешите)
    Можете прескочити ову тачку ако не планирате да покренете неколико тркача на једној машини.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Направите главни кључ
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Направите датотеку ~/.м2/сеттингс-сецурити.кмл
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Шифровање лозинке за Сонатипе налог
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Направите датотеку ~/.м2/сеттингс.кмл
    <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>

Где,
ГПГ_СЕЦРЕТ_КЕИ_ПАССПХРАСЕ - лозинка за ГПГ кључ
СОНАТИПЕ_УСЕРНАМЕ — пријављивање на сонатипе налог

Ово завршава подешавање тркача, можете прећи на одељак ГитЛаб ЦИ

На садржај

Схаред Руннер

Генерисање ГПГ кључева

  • Пре свега, потребно је да креирате ГПГ кључ. Да бисте то урадили, инсталирајте гнупг.

    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 <[email protected]>
    sub   rsa3072 2019-04-24 [E] [expires: none]

  • Отпремање нашег јавног кључа на сервер кључева

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

  • Добијамо приватни кључ

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

  • Идите на подешавања пројекта -> Подешавања -> ЦИ / ЦД -> Променљиве и сачувајте приватни кључ у променљивој GPG_SECRET_KEY
    Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

На садржај

Постављање Мавен-а

  • Направите главни кључ
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Идите на подешавања пројекта -> Подешавања -> ЦИ / ЦД -> Променљиве и сачувајте у променљивој SETTINGS_SECURITY_XML следеће редове:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Шифровање лозинке за Сонатипе налог
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Идите на подешавања пројекта -> Подешавања -> ЦИ / ЦД -> Променљиве и сачувајте у променљивој 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>

Где,
ГПГ_СЕЦРЕТ_КЕИ_ПАССПХРАСЕ - лозинка за ГПГ кључ
СОНАТИПЕ_УСЕРНАМЕ — пријављивање на сонатипе налог

На садржај

Примените доцкер слику

  • Креирамо прилично једноставан Доцкерфиле за покретање задатака имплементације са потребном верзијом Јаве. Испод је пример за алпски.

    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 .

  • Ми аутентификујемо и учитавамо контејнер у регистар.

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

На садржај

ГитЛаб ЦИ

Деплои пројецт

Додајте датотеку .гитлаб-ци.имл у корен пројекта постављања
Скрипта представља два међусобно искључива задатка постављања. Специфиц Руннер или Схаред Руннер.

.гитлаб-ци.имл

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

На садржај

Јава пројекат

У јава пројектима који би требало да буду отпремљени у јавна спремишта, потребно је да додате 2 корака за преузимање верзија издања и снимка.

.гитлаб-ци.имл

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}

У овом решењу отишао сам мало даље и одлучио да користим један ЦИ шаблон за јава пројекте.

Више детаља

Направио сам посебан пројекат гитлаб-ци у који сам поставио ЦИ шаблон за јава пројекте цоммон.имл.

цоммон.имл

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

Као резултат тога, у самим јава пројектима, .гитлаб-ци.имл изгледа веома компактно и није опширно

.гитлаб-ци.имл

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

На садржај

Пом.кмл конфигурација

Ова тема је описана веома детаљно. Гооголплек в Подешавање мавена за аутоматско потписивање и отпремање артефаката у спремишта снимака и постављање, па ћу описати неке од нијанси коришћења додатака. Такође ћу описати колико лако и опуштено можете да користите nexus-staging-maven-pluginако не желите или не можете да користите орг.сонатипе.осс:осс-парент као родитељ за свој пројекат.

мавен-инсталл-плугин

Инсталира модуле у локално спремиште.
Веома корисно за локалну верификацију решења у другим пројектима, као и контролну суму.

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

На садржај

мавен-јавадоц-плугин

Генерисање јавадоц-а за пројекат.

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

Ако имате модул који не садржи јава (на пример само ресурсе)
Или у принципу не желите да генеришете јавадоц, онда помозите 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>

На садржај

мавен-гпг-плугин

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

На садржај

некус-стагинг-мавен-плугин

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

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

Ако имате пројекат са више модула и не морате да отпремате одређени модул у спремиште, онда морате да додате nexus-staging-maven-plugin са заставом skipNexusStagingDeployMojo

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

Након преузимања, верзије снимка/издања су доступне у постављање спремишта

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

Више плусева

  • Веома богата листа циљева за рад са некус репозиторијумом (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Аутоматска провера отпуштања за отпремање на мавен централ

На садржај

Резултат

Објављивање СНАПСХОТ верзије

Када правите пројекат, могуће је ручно покренути задатак за преузимање СНАПСХОТ верзије на некус

Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

Када се овај задатак покрене, покреће се одговарајући задатак у пројекту имплементације (пример).

Обрезан дневник

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

Као резултат, верзија се учитава у некус 1.0.0-СНАПСХОТ.

Све верзије снимака могу се избрисати из спремишта на веб локацији осс.сонатипе.орг под вашим налогом.

Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

На садржај

Објављивање верзије издања

Када је ознака инсталирана, аутоматски се покреће одговарајући задатак у пројекту имплементације за преузимање верзије издања на некус (пример).

Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

Најбољи део је што се затварање ослобађања аутоматски покреће у некусу.

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

А ако нешто крене наопако, задатак ће сигурно пропасти

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

Као резултат тога, остаје нам само један избор. Или избришите ову верзију или је објавите.

Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

Након пуштања, након неког времена, артефакти ће бити унутра Подешавање ГитЛаб ЦИ за отпремање јава пројекта на мавен централ

оффтопиц

За мене је било откриће да Мавен индексира друга јавна спремишта.
Морао сам да додам роботс.ткт јер је индексирао моје старо спремиште.

На садржај

Закључак

Оно што имамо

  • Засебан пројекат имплементације у којем можете имплементирати неколико ЦИ задатака за отпремање артефаката у јавна спремишта за различите развојне језике.
  • Пројекат Деплои је изолован од спољних сметњи и могу га мењати само корисници са улогама власника и одржаваоца.
  • Одвојени Специфиц Руннер са „врућом“ кеш меморијом за покретање само задатака за примену.
  • Објављивање снимака/верзија издања у јавном спремишту.
  • Аутоматска провера спремности верзије издања за објављивање у мавен централу.
  • Заштита од аутоматског објављивања „сирових“ верзија у мавен централу.
  • Направите и објавите верзије снимака „на клик“.
  • Једно спремиште за добијање снимака/издања верзија.
  • Општи цевовод за прављење/тестирање/објављивање јава пројекта.

Подешавање ГитЛаб ЦИ није тако компликована тема као што изгледа на први поглед. Довољно је неколико пута поставити ЦИ по принципу „кључ у руке“, а сада сте далеко од аматера у овој ствари. Штавише, ГитЛаб документација је веома сувишна. Немојте се плашити да направите први корак. Пут се појављује испод степеница особе која хода (не сећам се ко је то рекао :)

Биће ми драго да добијем повратне информације.

У следећем чланку ћу говорити о томе како да конфигуришем ГитЛаб ЦИ да конкурентно покреће задатке са интеграцијским тестовима (покретање услуга које се тестирају помоћу доцкер-цомпосе) ако имате само један покретач љуске.

На садржај

Извор: ввв.хабр.цом

Додај коментар