Nastavenie GitLab CI na nahranie projektu java do maven central

Tento článok je určený pre java vývojárov, ktorí potrebujú rýchlo publikovať svoje produkty do centrálnych repozitárov sonatype a/alebo maven pomocou GitLab. V tomto článku budem hovoriť o nastavení gitlab-runner, gitlab-ci a maven-plugin na vyriešenie tohto problému.

Predpoklady:

  • Bezpečné uloženie kľúčov mvn a GPG.
  • Bezpečné vykonávanie úloh verejnej CI.
  • Nahrávanie artefaktov (vydanie/snímka) do verejných úložísk.
  • Automatická kontrola verzií vydania na zverejnenie v centrále maven.
  • Všeobecné riešenie pre nahrávanie artefaktov do úložiska pre viacero projektov.
  • Jednoduchosť a jednoduchosť použitia.

Obsah

Všeobecné informácie

  • Podrobný popis mechanizmu zverejňovania artefaktov do Maven Central cez Sonatype OSS Repository Hosting Service je už popísaný v tento článok používateľ googolplex, preto budem odkazovať na tento článok na správnych miestach.
  • Predbežne sa zaregistrujte na Sonatyp JIRA a spustite lístok na otvorenie úložiska (ďalšie podrobnosti nájdete v časti Vytvorte lístok Sonatype JIRA). Po otvorení úložiska bude pár login/heslo JIRA (ďalej len Sonatype účet) použitý na nahrávanie artefaktov do Sonatype nexusu.
  • Ďalej je proces generovania GPG kľúča opísaný veľmi sucho. Ďalšie podrobnosti nájdete v sekcii. Konfigurácia GnuPG na podpisovanie artefaktov
  • Ak používate konzolu Linux na generovanie kľúča GPG (gnupg/gnupg2), musíte nainštalovať RNG-tools vytvárať entropiu. V opačnom prípade môže generovanie kľúča trvať veľmi dlho.
  • Skladovacie služby verejnosti GPG kľúče

K obsahu

Nastavenie projektu nasadenia v GitLab

  • V prvom rade je potrebné vytvoriť a nakonfigurovať projekt, v ktorom bude uložený pipeline na nasadenie artefaktov. Svoj projekt som nazval jednoducho a nekomplikovane - rozmiestniť
  • Po vytvorení úložiska musíte obmedziť prístup, aby ste mohli úložisko zmeniť.
    Prejdite do projektu -> Nastavenia -> Úložisko -> Chránené pobočky. Vymažeme všetky pravidlá a pridáme jediné pravidlo so zástupným znakom * s právom push a zlúčením len pre používateľov s rolou správcov. Toto pravidlo bude fungovať pre všetkých používateľov tohto projektu aj skupiny, do ktorej tento projekt patrí.
    Nastavenie GitLab CI na nahranie projektu java do maven central
  • Ak existuje niekoľko správcov, najlepším riešením by bolo zásadne obmedziť prístup k projektu.
    Prejdite na projekt -> Nastavenia -> Všeobecné -> Viditeľnosť, funkcie projektu, povolenia a nastavte Viditeľnosť projektu na Súkromný.
    Mám projekt vo verejnom prístupe, pretože používam svoj vlastný GitLab Runner a iba ja mám prístup k úprave úložiska. V skutočnosti nie je v mojom záujme zobrazovať súkromné ​​informácie vo verejných protokoloch.
  • Sprísnenie pravidiel pre zmenu úložiska
    Prejdite do projektu -> Nastavenia -> Úložisko -> Pravidlá push a nastavte príznaky Obmedzenie poverenia, Skontrolujte, či je autor používateľom GitLab. Odporúčam aj nastavenie odovzdať podpisa nastavte príznak Odmietnuť nepodpísané potvrdenia.
  • Ďalej musíte nakonfigurovať spúšťač na spustenie úloh
    Prejdite na projekt -> Nastavenia -> CI / CD -> Spúšťače Pipeline a vytvorte nový spúšťací token
    Tento token je možné okamžite pridať do všeobecnej konfigurácie premenných pre skupinu projektov.
    Prejdite do skupiny -> Nastavenia -> CI / CD -> Premenné a pridajte premennú DEPLOY_TOKEN so spúšťacím tokenom v hodnote.

K obsahu

GitLab Runner

Táto časť popisuje konfiguráciu spúšťania úloh pri nasadení pomocou natívneho (špecifického) a verejného (zdieľaného) spúšťača.

Špecifický bežec

Používam vlastné bežce, pretože je to v prvom rade pohodlné, rýchle, lacné.
Pre bežcov odporúčam Linux VDS s 1 CPU, 2 GB RAM, 20 GB HDD. Emisná cena ~ 3000₽ ročne.

Môj bežec

Pre bežca som vzal VDS 4 CPU, 4 GB RAM, 50 GB SSD. Stálo to ~11000 XNUMX₽ a nikdy som to neoľutoval.
Mám spolu 7 strojov. 5 na arube a 2 na ihor.

Takže máme bežca. Teraz to nastavíme.
Ideme do stroja cez SSH a nainštalujeme java, git, maven, gnupg2.

K obsahu

Inštalácia gitlab runner

  • Vytvorte novú skupinu runner
    sudo groupadd runner
  • Vytvorte adresár pre vyrovnávaciu pamäť maven a priraďte skupinové práva runner
    Tento krok môžete preskočiť, ak neplánujete behať viacerých bežcov na rovnakom stroji.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Vytvorte používateľa gitlab-deployer a pridať do skupiny runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Pridať do súboru /etc/ssh/sshd_config ďalší riadok
    AllowUsers root@* [email protected]
  • Reštartovať sshd
    systemctl restart sshd
  • Nastavte heslo pre používateľa gitlab-deployer (môže to byť jednoduché, pretože existuje obmedzenie pre localhost)
    passwd gitlab-deployer
  • Nainštalujte 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
  • Prejdite na gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners a skopírujte registračný token

Obrazovka

Nastavenie GitLab CI na nahranie projektu java do maven central

  • Registrácia bežca
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

Proces

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!

  • Skontrolujte, či je bežec zaregistrovaný. Prejdite na gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners aktivované pre tento projekt

Obrazovka

Nastavenie GitLab CI na nahranie projektu java do maven central

  • Pridať oddelene služba /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
  • Spúšťame službu.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Skontrolujeme, či bežec beží.

Príklad

Nastavenie GitLab CI na nahranie projektu java do maven central

K obsahu

generovanie kľúča GPG

  • Z toho istého stroja ideme cez ssh pod user gitlab-deployer (toto je dôležité pre generovanie kľúčov GPG)

    ssh [email protected]

  • Kľúč vygenerujeme zodpovedaním otázok. Použil som svoje meno a e-mail.
    Nezabudnite zadať heslo pre kľúč. Artefakty budú podpísané týmto kľúčom.

    gpg --gen-key 

  • check

    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

  • Nahrávanie nášho verejného kľúča na server kľúčov

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

K obsahu

Nastavenie Maven

  • Ideme pod užívateľa gitlab-deployer
    su gitlab-deployer 
  • Vytvorte maven adresár sklad a odkaz na vyrovnávaciu pamäť (nedajte sa pomýliť)
    Tento krok je možné preskočiť, ak neplánujete behať niekoľko bežcov na rovnakom stroji.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Vytvorte hlavný kľúč
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Vytvorte súbor ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Šifrovanie hesla z účtu Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Vytvorte súbor ~/.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>

kde,
GPG_SECRET_KEY_PASSPHRASE - heslo pre kľúč GPG
SONATYPE_USERNAME - prihlásenie do účtu sonatype

Tým je nastavenie bežca dokončené, môžete pokračovať do sekcie GitLab CI

K obsahu

Zdieľaný bežec

generovanie kľúča GPG

  • Najprv musíte vytvoriť kľúč GPG. Ak to chcete urobiť, nainštalujte gnupg.

    yum install -y gnupg

  • Kľúč vygenerujeme zodpovedaním otázok. Použil som svoje meno a e-mail. Nezabudnite zadať heslo pre kľúč.

    gpg --gen-key 

  • Získajte kľúčové informácie

    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]

  • Nahrávanie nášho verejného kľúča na server kľúčov

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

  • Získame súkromný kľúč

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

  • Prejdite do nastavení projektu -> Nastavenia -> CI / CD -> Premenné a uložte súkromný kľúč do premennej GPG_SECRET_KEY
    Nastavenie GitLab CI na nahranie projektu java do maven central

K obsahu

Nastavenie Maven

  • Vytvorte hlavný kľúč
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Prejdite do nastavení projektu -> Nastavenia -> CI / CD -> Premenné a uložte do premennej SETTINGS_SECURITY_XML nasledujúce riadky:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Šifrovanie hesla z účtu Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Prejdite do nastavení projektu -> Nastavenia -> CI / CD -> Premenné a uložte do premennej SETTINGS_XML nasledujúce riadky:
    <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>

kde,
GPG_SECRET_KEY_PASSPHRASE - heslo pre kľúč GPG
SONATYPE_USERNAME - prihlásenie do účtu sonatype

K obsahu

Nasadiť obrázok doku

  • Vytvárame pomerne jednoduchý súbor Dockerfile na spúšťanie úloh pri nasadení s požadovanou verziou Java. Nižšie je uvedený príklad pre alpské.

    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/

  • Vytvorenie kontajnera pre váš projekt

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

  • Overíme a načítame kontajner do registra.

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

K obsahu

GitLab CI

Nasadiť projekt

Pridajte súbor .gitlab-ci.yml do koreňového adresára projektu nasadenia
Skript predstavuje dve vzájomne sa vylučujúce úlohy nasadenia. Špecifický bežec alebo zdieľaný bežec.

.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

K obsahu

Java projekt

V projektoch java, ktoré sa majú nahrať do verejných úložísk, musíte pridať 2 kroky na stiahnutie verzií Release a Snapshot.

.gitlab-ci.yml

stages:
  - build
  - test
  - verify
  - deploy

<...>

Release:
  extends: .trigger_deploy
  # Запускать задачу только пo тегу.
  only:
    - tags

Snapshot:
  extends: .trigger_deploy
  # Запускаем задачу на публикацию SNAPSHOT версии вручную
  when: manual
  # Не запускать задачу, если проставлен тег.
  except:
    - tags

.trigger_deploy:
  stage: deploy
  variables:
    # Отключаем клонирование текущего проекта
    GIT_STRATEGY: none
    # Ссылка на триггер deploy-задачи
    URL: "https://gitlab.com/api/v4/projects/<deploy project ID>/trigger/pipeline"
    # Переменные deploy-задачи
    POST_DATA: "
      token=${DEPLOY_TOKEN}&
      ref=master&
      variables[DEPLOY]=${DEPLOY}&
      variables[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
      variables[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
      variables[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
      variables[DEPLOY_CI_COMMIT_TAG]=${CI_COMMIT_TAG}
      "
  script:
    # Не использую cURL, так как с флагами --fail --show-error
    # он не выводит тело ответа, если HTTP код 400 и более 
    - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

V tomto riešení som zašiel trochu ďalej a rozhodol som sa použiť jednu CI šablónu pre java projekty.

Viac podrobností

Vytvoril som samostatný projekt gitlab-ci do ktorej umiestnil CI šablónu pre java projekty obyčajný.yml.

obyčajný.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

Výsledkom je, že v samotných java projektoch vyzerá .gitlab-ci.yml veľmi kompaktne a nie podrobne

.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

K obsahu

konfigurácia pom.xml

Táto téma je opísaná veľmi podrobne. googolplex в Nastavenie mavenu na automatické podpisovanie a nahrávanie artefaktov do úložísk snímok a prípravy, takže popíšem niektoré nuansy používania doplnkov. Popíšem tiež, ako ľahko a prirodzene môžete používať nexus-staging-maven-pluginak nechcete alebo nemôžete použiť org.sonatype.oss:oss-parent ako rodiča pre váš projekt.

maven-install-plugin

Nainštaluje moduly do lokálneho úložiska.
Veľmi užitočné pre lokálne overenie riešení v iných projektoch, ako aj kontrolný súčet.

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

K obsahu

maven-javadoc-plugin

Generovanie javadoc pre 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>

Ak máte modul, ktorý neobsahuje java (napríklad iba zdroje)
Alebo v zásade nechcete generovať javadoc, potom pomôcť 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>

K obsahu

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>

K obsahu

nexus-staging-maven-plugin

Konfigurácia:

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

Ak máte projekt s viacerými modulmi a nepotrebujete nahrať konkrétny modul do úložiska, musíte pridať nexus-staging-maven-plugin s vlajkou skipNexusStagingDeployMojo

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

Po nahratí snímky/vydania sú dostupné verzie v odkladacie úložiská

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

Viac plusov

  • Veľmi bohatý zoznam cieľov pre prácu s úložiskom Nexus (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatická kontrola stiahnuteľnosti v centrále maven

K obsahu

Výsledok

Publikovanie verzie SNAPSHOT

Pri zostavovaní projektu je možné manuálne spustiť úlohu na stiahnutie verzie SNAPSHOT do nexusu

Nastavenie GitLab CI na nahranie projektu java do maven central

Po spustení tejto úlohy sa spustí zodpovedajúca úloha v projekte nasadenia (príklad).

orezaný denník

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

V dôsledku toho sa načíta verzia pre nexus 1.0.0-SNÍMKA.

Všetky verzie snímok je možné odstrániť z úložiska na stránke oss.sonatype.org pod vaším účtom.

Nastavenie GitLab CI na nahranie projektu java do maven central

K obsahu

Publikovanie verzie vydania

Keď je značka nastavená, zodpovedajúca úloha v projekte nasadenia sa automaticky spustí na nahranie verzie vydania do zariadenia nexus (príklad).

Nastavenie GitLab CI na nahranie projektu java do maven central

Najlepšie na tom je, že blízke uvoľnenie sa automaticky spustí v nexuse.

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

A ak sa niečo pokazilo, úloha zlyhá

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

V dôsledku toho nám zostáva len jedna možnosť. Alebo odstráňte túto verziu alebo zverejnite.

Nastavenie GitLab CI na nahranie projektu java do maven central

Po vydaní, po nejakom čase, budú artefakty in Nastavenie GitLab CI na nahranie projektu java do maven central

mimo témy

Bolo pre mňa zjavením, že maven indexuje iné verejné úložiská.
Musel som nahrať súbor robots.txt, pretože indexoval môj starý repozitár.

K obsahu

Záver

Čo máme

  • Samostatný projekt nasadenia, v ktorom môžete implementovať niekoľko úloh CI na nahrávanie artefaktov do verejných úložísk pre rôzne vývojové jazyky.
  • Projekt nasadenia je izolovaný od vonkajšieho rušenia a môžu ho upravovať iba používatelia s rolami Vlastník a Správca.
  • Samostatný špecifický bežec s „horúcou“ vyrovnávacou pamäťou na spustenie iba úloh nasadenia.
  • Zverejnenie snímok/verzií vydania vo verejnom úložisku.
  • Automatická kontrola pripravenosti verzie na publikovanie v maven centrale.
  • Ochrana pred automatickým zverejnením „surových“ verzií v centrále maven.
  • Vytvárajte a publikujte verzie snímok „na kliknutie“.
  • Jediné úložisko na získanie verzií snímok/vydaní.
  • Všeobecný kanál na vytváranie/testovanie/publikovanie java projektu.

Nastavenie GitLab CI nie je taká zložitá téma, ako sa na prvý pohľad zdá. Stačí niekoľkokrát nastaviť CI na kľúč a teraz v tejto veci nie ste ani zďaleka amatér. Dokumentácia GitLab je navyše veľmi nadbytočná. Nebojte sa urobiť prvý krok. Cesta sa objavuje pod krokmi kráčajúcej osoby (nepamätám si, kto to povedal :)

Budem rád za spätnú väzbu.

V ďalšom článku vám ukážem, ako nastaviť GitLab CI na konkurenčné spúšťanie úloh integračného testu (spustenie testovacích služieb s docker-compose), ak máte iba jeden shell runner.

K obsahu

Zdroj: hab.com

Pridať komentár