Podešavanje GitLab CI za učitavanje java projekta na maven central

Ovaj članak je namijenjen java programerima koji trebaju brzo objaviti svoje proizvode u sonatype i/ili maven centralnim spremištima koristeći GitLab. U ovom članku ću govoriti o postavljanju gitlab-runnera, gitlab-ci i maven-plugina za rješavanje ovog problema.

Preduslovi:

  • Sigurno skladištenje mvn i GPG ključeva.
  • Sigurno izvršavanje javnih CI zadataka.
  • Učitavanje artefakata (izdanja/snimka) u javna spremišta.
  • Automatska provjera verzija izdanja za objavljivanje u maven centralu.
  • Općenito rješenje za učitavanje artefakata u spremište za više projekata.
  • Jednostavnost i lakoća korištenja.

Sadržaj

Opće informacije

  • Detaljan opis mehanizma za objavljivanje artefakata u Maven Central preko Sonatype OSS Repository Hosting usluge je već opisan u Ovaj članak korisnika Googolplex, pa ću se referirati na ovaj članak na pravim mjestima.
  • Prethodno se prijavite na Sonatype JIRA i pokrenite tiket za otvaranje spremišta (za više detalja pročitajte odjeljak Kreirajte Sonatype JIRA kartu). Nakon otvaranja spremišta, JIRA par login/password (u daljem tekstu Sonatype nalog) će se koristiti za učitavanje artefakata na Sonatype nexus.
  • Nadalje, proces generiranja GPG ključa je vrlo suhoparno opisan. Pogledajte odjeljak za više detalja. Konfiguriranje GnuPG-a za potpisivanje artefakata
  • Ako koristite Linux konzolu za generiranje GPG ključa (gnupg/gnupg2), tada morate instalirati rng-tools da generiše entropiju. U suprotnom, generiranje ključeva može potrajati jako dugo.
  • Storage Services javnosti GPG ključevi

Na sadržaj

Postavljanje projekta implementacije u GitLabu

  • Prije svega, potrebno je kreirati i konfigurirati projekt u kojem će cjevovod biti pohranjen za postavljanje artefakata. Svoj sam projekat nazvao jednostavno i nekomplikovano - rasporediti
  • Nakon kreiranja spremišta, morate ograničiti pristup da biste promijenili spremište.
    Idite na projekat -> Postavke -> Repozitorijum -> Zaštićene grane. Brišemo sva pravila i dodajemo jedno pravilo sa zamjenskim znakom * s pravom guranja i spajanja samo za korisnike s ulogom održavatelja. Ovo pravilo će raditi za sve korisnike i ovog projekta i grupe kojoj ovaj projekat pripada.
    Podešavanje GitLab CI za učitavanje java projekta na maven central
  • Ako postoji nekoliko održavatelja, onda bi najbolje rješenje bilo načelno ograničiti pristup projektu.
    Idite na projekat -> Postavke -> Općenito -> Vidljivost, karakteristike projekta, dozvole i postavite Vidljivost projekta na privatan.
    Imam projekat u javnom pristupu, pošto koristim svoj GitLab Runner i samo ja imam pristup da modifikujem spremište. Pa, zapravo, nije u mom interesu da prikazujem privatne informacije u javnim evidencijama.
  • Pooštravanje pravila za promjenu spremišta
    Idite na projekat -> Settings -> Repository -> Push Rules i postavite zastavice Committer limitation, Provjerite da li je autor GitLab korisnik. Takođe preporučujem podešavanje urezivanje potpisivanja, i postavite oznaku Odbaci nepotpisano urezivanje.
  • Zatim morate konfigurirati okidač za pokretanje zadataka
    Idite na projekt -> Postavke -> CI / CD -> Pipeline okidači i kreirajte novi okidač-token
    Ovaj token se može odmah dodati općoj konfiguraciji varijabli za grupu projekata.
    Idite na grupu -> Postavke -> CI / CD -> Varijable i dodajte varijablu DEPLOY_TOKEN sa trigger-tokenom u vrijednosti.

Na sadržaj

GitLab Runner

Ovaj odjeljak opisuje konfiguraciju za izvršavanje zadataka prilikom implementacije pomoću izvornog (specifičnog) i javnog (dijeljenog) pokretača.

Specific Runner

Koristim svoje trkače, jer su prije svega zgodne, brze, jeftine.
Za trkače preporučujem Linux VDS sa 1 CPU, 2 GB RAM-a, 20 GB HDD-om. Cijena emisije ~ 3000₽ godišnje.

Moj trkač

Za trkač sam uzeo VDS 4 CPU, 4 GB RAM-a, 50 GB SSD. Koštao je ~11000₽ i nikada nisam požalio.
Imam ukupno 7 mašina. 5 na arubi i 2 na ihoru.

Dakle, imamo trkača. Sada ćemo to postaviti.
Idemo na mašinu preko SSH-a i instaliramo java, git, maven, gnupg2.

Na sadržaj

Instalacija gitlab runnera

  • Kreirajte novu grupu runner
    sudo groupadd runner
  • Kreirajte direktorij za maven cache i dodijelite grupna prava runner
    Možete preskočiti ovaj korak ako ne planirate pokrenuti više pokretača na istoj mašini.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Kreirajte korisnika gitlab-deployer i dodati u grupu runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Dodaj u fajl /etc/ssh/sshd_config sljedeći red
    AllowUsers root@* [email protected]
  • Ponovo pokreni sshd
    systemctl restart sshd
  • Postavite lozinku za korisnika gitlab-deployer (može biti jednostavno, jer postoji ograničenje za localhost)
    passwd gitlab-deployer
  • Instalirajte 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
  • Idite na gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners i kopirajte registracijski token

Ekran

Podešavanje GitLab CI za učitavanje java projekta na maven central

  • Registracija trkača
    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!

  • Provjerite je li trkač registriran. Idite na gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners aktivirani za ovaj projekat

Ekran

Podešavanje GitLab CI za učitavanje java projekta na maven central

  • Dodaj odvojeno servis /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
  • Pokrećemo uslugu.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Provjerite da li trkač radi.

Primjer:

Podešavanje GitLab CI za učitavanje java projekta na maven central

Na sadržaj

Generisanje GPG ključeva

  • Sa iste mašine idemo preko ssh-a pod korisnikom gitlab-deployer (ovo je važno za generiranje GPG ključeva)

    ssh [email protected]

  • Odgovarajući na pitanja generišemo ključ. Koristio sam svoje ime i email.
    Obavezno navedite lozinku za ključ. Artefakti će biti potpisani ovim ključem.

    gpg --gen-key 

  • Proverite

    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

  • Učitavanje našeg javnog ključa na server ključeva

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

Na sadržaj

Maven setup

  • Idemo ispod korisnika gitlab-deployer
    su gitlab-deployer 
  • Kreirajte maven direktorij spremište i povežite se s keš memorijom (ne griješite)
    Ovaj korak se može preskočiti ako ne planirate pokrenuti nekoliko trkača na istoj mašini.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Kreirajte glavni ključ
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Kreirajte datoteku ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Šifriranje lozinke sa Sonatype naloga
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Kreirajte datoteku ~/.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>

gdje,
GPG_SECRET_KEY_PASSHRASE - Lozinka ključa GPG
SONATYPE_USERNAME - prijava na sonatype račun

Ovo završava podešavanje trkača, možete nastaviti na odjeljak GitLab CI

Na sadržaj

Shared Runner

Generisanje GPG ključeva

  • Prije svega, trebate kreirati GPG ključ. Da biste to učinili, instalirajte gnupg.

    yum install -y gnupg

  • Odgovarajući na pitanja generišemo ključ. Koristio sam svoje ime i email. Obavezno navedite lozinku za ključ.

    gpg --gen-key 

  • Dohvatite ključne informacije

    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]

  • Učitavanje našeg javnog ključa na server ključeva

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

  • Dobivanje privatnog ključa

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

  • Idite na postavke projekta -> Postavke -> CI / CD -> Varijable i spremite privatni ključ u varijablu GPG_SECRET_KEY
    Podešavanje GitLab CI za učitavanje java projekta na maven central

Na sadržaj

Maven setup

  • Kreirajte glavni ključ
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Idite na postavke projekta -> Postavke -> CI / CD -> Varijable i spremite u varijablu SETTINGS_SECURITY_XML sljedeći redovi:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Šifriranje lozinke sa Sonatype naloga
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Idite na postavke projekta -> Postavke -> CI / CD -> Varijable i spremite u varijablu SETTINGS_XML sljedeći redovi:
    <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>

gdje,
GPG_SECRET_KEY_PASSHRASE - Lozinka ključa GPG
SONATYPE_USERNAME - prijava na sonatype račun

Na sadržaj

Postavite docker sliku

  • Kreiramo prilično jednostavan Dockerfile za pokretanje zadataka prilikom implementacije sa željenom verzijom Jave. Ispod je primjer za 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/

  • Izgradnja kontejnera za vaš projekat

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

  • Mi autentifikujemo i učitavamo kontejner u registar.

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

Na sadržaj

GitLab CI

Deploy project

Dodajte datoteku .gitlab-ci.yml u korijen projekta postavljanja
Skripta predstavlja dva međusobno isključiva zadatka implementacije. Specific Runner ili Shared Runner.

.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

Na sadržaj

Java projekat

U java projektima koji bi trebali biti učitani u javna spremišta, morate dodati 2 koraka za preuzimanje verzija izdanja i snimka.

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

U ovom rješenju otišao sam malo dalje i odlučio da koristim jedan CI šablon za java projekte.

Više detalja

Napravio sam poseban projekat gitlab-ci u koji je postavio CI šablon za java projekte common.yml.

common.yml

stages:
  - build
  - test
  - verify
  - deploy

variables:
  SONAR_ARGS: "
  -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} 
  -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} 
  "

.build_java_project:
  stage: build
  tags:
    - touchbit-shell
  variables:
    SKIP_TEST: "false"
  script:
    - mvn clean
    - mvn package -DskipTests=${SKIP_TEST}
  artifacts:
    when: always
    expire_in: 30 day
    paths:
      - "*/target/reports"

.build_sphinx_doc:
  stage: build
  tags:
    - touchbit-shell
  variables:
    DOCKERFILE: .indirect/docs/Dockerfile
  script:
    - docker build --no-cache -t ${CI_PROJECT_NAME}/doc -f ${DOCKERFILE} .

.junit_module_test_run:
  stage: test
  tags:
    - touchbit-shell
  variables:
    MODULE: ""
  script:
    - cd ${MODULE}
    - mvn test
  artifacts:
    when: always
    expire_in: 30 day
    paths:
      - "*/target/reports"

.junit_test_run:
  stage: test
  tags:
    - touchbit-shell
  script:
    - mvn test
  artifacts:
    when: always
    expire_in: 30 day
    paths:
    - "*/target/reports"

.sonar_review:
  stage: verify
  tags:
    - touchbit-shell
  dependencies: []
  script:
    - >
      if [ "$CI_BUILD_REF_NAME" == "master" ]; then
        mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS
      else
        mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS -Dsonar.analysis.mode=preview
      fi

.trigger_deploy:
  stage: deploy
  tags:
    - touchbit-shell
  variables:
    URL: "https://gitlab.com/api/v4/projects/10345765/trigger/pipeline"
    POST_DATA: "
      token=${DEPLOY_TOKEN}&
      ref=master&
      variables[DEPLOY]=${DEPLOY}&
      variables[DEPLOY_CI_REPOSITORY_URL]=${CI_REPOSITORY_URL}&
      variables[DEPLOY_CI_PROJECT_NAME]=${CI_PROJECT_NAME}&
      variables[DEPLOY_CI_COMMIT_SHA]=${CI_COMMIT_SHA}&
      variables[DEPLOY_CI_COMMIT_TAG]=${CI_COMMIT_TAG}
      "
  script:
  - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

.trigger_release_deploy:
  extends: .trigger_deploy
  only:
    - tags

.trigger_snapshot_deploy:
  extends: .trigger_deploy
  when: manual
  except:
    - tags

Kao rezultat toga, u samim java projektima, .gitlab-ci.yml izgleda vrlo kompaktno i ne opširno

.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

Na sadržaj

pom.xml konfiguracija

Ova tema je vrlo detaljno opisana. Googolplex в Postavljanje mavena za automatsko potpisivanje i učitavanje artefakata u spremišta snimaka i postavljanje, pa ću opisati neke od nijansi korištenja dodataka. Također ću opisati koliko lako i prirodno možete koristiti nexus-staging-maven-pluginako ne želite ili ne možete koristiti org.sonatype.oss:oss-parent kao roditelj za svoj projekat.

maven-install-plugin

Instalira module u lokalno spremište.
Vrlo korisno za lokalnu verifikaciju rješenja u drugim projektima, kao i kontrolnu sumu.

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

Na sadržaj

maven-javadoc-plugin

Generisanje javadoc-a za projekat.

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

Ako imate modul koji ne sadrži java (na primjer samo resurse)
Ili ne želite da generišete javadoc u principu, pa da pomognete 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>

Na sadržaj

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>

Na sadržaj

nexus-staging-maven-plugin

Konfiguracija:

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

Ako imate projekat sa više modula, a ne morate da učitavate određeni modul u spremište, onda morate da dodate u pom.xml ovog modula nexus-staging-maven-plugin sa zastavom skipNexusStagingDeployMojo

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

Nakon učitavanja snimka/izdanja dostupne su verzije u postavljanje spremišta

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

Više pluseva

  • Veoma bogata lista ciljeva za rad sa nexus repozitorijumom (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatska provjera izdanja za preuzimanje u maven centralu

Na sadržaj

rezultat

Objavljivanje SNAPSHOT verzije

Prilikom izrade projekta, moguće je ručno pokrenuti zadatak za preuzimanje SNAPSHOT verzije na nexus

Podešavanje GitLab CI za učitavanje java projekta na maven central

Kada se ovaj zadatak pokrene, pokreće se odgovarajući zadatak u projektu implementacije (primer).

izrezani dnevnik

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

Kao rezultat, učitava se nexus verzija 1.0.0-SNAPSHOT.

Sve verzije snimaka mogu se ukloniti iz spremišta na stranici oss.sonatype.org pod vašim računom.

Podešavanje GitLab CI za učitavanje java projekta na maven central

Na sadržaj

Objavljivanje izdanja verzije

Kada je oznaka postavljena, automatski se pokreće odgovarajući zadatak u projektu implementacije da prenese verziju izdanja na nexus (primer).

Podešavanje GitLab CI za učitavanje java projekta na maven central

Najbolji dio je što se zatvaranje zatvaranja automatski aktivira u nexusu.

[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 ako nešto pođe po zlu, onda zadatak neće uspjeti

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

Kao rezultat toga, ostaje nam samo jedan izbor. Ili izbrišite ovu verziju ili objavite.

Podešavanje GitLab CI za učitavanje java projekta na maven central

Nakon izlaska, nakon nekog vremena, artefakti će biti unutra Podešavanje GitLab CI za učitavanje java projekta na maven central

offtopic

Za mene je bilo otkriće da maven indeksira druga javna spremišta.
Morao sam da otpremim robots.txt jer je indeksirao moje staro spremište.

Na sadržaj

zaključak

Šta imamo

  • Zaseban projekat implementacije u kojem možete implementirati nekoliko CI zadataka za učitavanje artefakata u javna spremišta za različite razvojne jezike.
  • Projekat implementacije je izoliran od vanjskih smetnji i mogu ga mijenjati samo korisnici s ulogama vlasnika i održavatelja.
  • Odvojeni Specific Runner sa "vrućom" keš memorijom za pokretanje samo zadataka implementacije.
  • Objavljivanje snimaka/izdanja verzija u javnom spremištu.
  • Automatska provjera verzije izdanja za spremnost za objavljivanje u maven centralu.
  • Zaštita od automatskog objavljivanja "sirovih" verzija u maven central.
  • Izgradite i objavite verzije snimaka „na klik“.
  • Jedno spremište za dobijanje snimaka/izdanja verzija.
  • Generalni cevovod za izgradnju / testiranje / objavljivanje java projekta.

Postavljanje GitLab CI-a nije tako komplikovana tema kao što se čini na prvi pogled. Dovoljno je nekoliko puta postaviti CI po principu ključ u ruke, a sada ste daleko od amatera u ovoj stvari. Štaviše, GitLab dokumentacija je vrlo suvišna. Nemojte se plašiti da napravite prvi korak. Put se pojavljuje ispod stepenica osobe koja hoda (ne sjećam se ko je to rekao :)

Bit će mi drago da dobijem povratnu informaciju.

U sljedećem članku ću vam pokazati kako postaviti GitLab CI za konkurentno pokretanje zadataka integracijskog testa (pokretanje testnih usluga sa docker-compose) ako imate samo jedan shell runner.

Na sadržaj

izvor: www.habr.com

Dodajte komentar