GitLab CI opzestellen fir e Java-Projet op Maven Central eropzelueden
Dësen Artikel ass geduecht fir Java Entwéckler déi hir Produkter séier op Sonatype an / oder Maven zentrale Repositories mat GitLab verëffentleche mussen. An dësem Artikel schwätze ech iwwer Gitlab-runner, gitlab-ci a maven-Plugin opzestellen fir dëse Problem ze léisen.
Viraussetzungen:
Séchert Späichere vu mvn a GPG Schlësselen.
Sécher Ausféierung vun ëffentlechen CI Aufgaben.
Eroplueden vun Artefakte (Verëffentlechung / Snapshot) op ëffentlech Repositories.
Automatesch Kontroll vun Verëffentlechungsversioune fir Verëffentlechung am Maven Central.
Eng allgemeng Léisung fir Artefakte op e Repository fir verschidde Projeten eropzelueden.
Eng detailléiert Beschreiwung vum Mechanismus fir d'Verëffentlechung vun Artefakte op Maven Central iwwer de Sonatype OSS Repository Hosting Service ass scho beschriwwen an dësen Artikel Benotzer Googolplex, Also ech wäert dësen Artikel op de richtege Plazen verweisen.
Pre-Umeldung um Sonatyp JIRA a start en Ticket fir de Repository opzemaachen (fir méi Detailer, liest d'Sektioun Erstellt e Sonatype JIRA Ticket). Nodeems Dir de Repository opgemaach huet, gëtt de JIRA Login/Passwuert Pair (nodréiglech de Sonatype Kont bezeechent) benotzt fir Artefakte op de Sonatype Nexus eropzelueden.
Wann Dir d'Linux Konsole benotzt fir e GPG Schlëssel ze generéieren (gnupg / gnupg2), da musst Dir installéieren rng-Tools Entropie ze generéieren. Soss kann Schlëssel Generatioun ganz laang daueren.
Als éischt musst Dir e Projet erstellen an konfiguréieren an deem d'Pipeline fir d'Deployment vun Artefakte gespäichert gëtt. Ech hunn mäi Projet einfach an onkomplizéiert genannt - setzen
Nodeems Dir de Repository erstallt hutt, musst Dir den Zougang beschränken fir de Repository z'änneren.
Gitt op de Projet -> Astellungen -> Repository -> Geschützt Branches. Mir läschen all Reegelen a fügen eng eenzeg Regel mat Wildcard * mat dem Recht op ze drécken a fusionéieren nëmme fir Benotzer mat der Maintainer Roll. Dës Regel funktionnéiert souwuel fir all Benotzer vun dësem Projet wéi och fir de Grupp zu deem dëse Projet gehéiert.
Wann et e puer Ënnerhalter gëtt, da wier déi bescht Léisung den Zougang zum Projet am Prinzip ze beschränken.
Gitt op de Projet -> Astellungen -> Allgemeng -> Visibilitéit, Projetsfeatures, Permissiounen a setzt Project Visibilitéit op private.
Ech hunn e Projet am ëffentlechen Zougang, well ech meng eegen GitLab Runner benotzen an nëmmen ech hunn Zougang fir de Repository z'änneren. Gutt, tatsächlech ass et net a mengem Interesse privat Informatioun an ëffentleche Pipeline Logbicher ze weisen.
Stäerkt d'Regele fir de Repository z'änneren
Gitt op de Projet -> Astellungen -> Repository -> Push Regelen a setzt d'Fändelen Committer Restriktioun, Kontrolléiert ob den Auteur e GitLab Benotzer ass. Ech recommandéieren och Kader ënnerschreiwen engagéieren, a setzt de Reject unsigned commits Fändel.
Als nächst musst Dir en Ausléiser konfiguréieren fir Aufgaben ze lafen
Gitt op Projet -> Astellungen -> CI / CD -> Pipeline Trigger a erstellt en neien Trigger-Token
Dësen Token kann direkt an d'allgemeng Konfiguratioun vu Variablen fir eng Grupp vu Projete bäigefüügt ginn.
Gitt an d'Grupp -> Astellungen -> CI / CD -> Variablen a füügt eng Variabel derbäi DEPLOY_TOKEN mat Trigger-Token am Wäert.
Dës Sektioun beschreift d'Konfiguratioun fir d'Ausféierung vun Aufgaben mat Ärem eegenen (Spezifizesche) an ëffentlechen (Shared) Leefer.
Spezifesch Runner
Ech benotze meng eegen Leefer, well et ass als éischt praktesch, séier, bëlleg.
Fir Leefer ech recommandéieren Linux VDS mat 1 CPU, 2 GB RAM, 20 GB HDD. Ausgabepräis ~ 3000 ₽ pro Joer.
Mäi Leefer
Fir de Leefer hunn ech VDS 4 CPU, 4 GB RAM, 50 GB SSD. Kascht ~ 11000₽ an huet et ni bedauert.
Ech hunn am Ganzen 7 Maschinnen. 5 op Aruba an 2 op ihor.
Also, mir hunn e Leefer. Elo wäerte mir et opsetzen.
Mir ginn op d'Maschinn iwwer SSH an installéieren Java, Git, Maven, gnupg2.
Erstellt e Verzeechnes fir de Maven Cache a gitt Grupprechter zou runner
Dir kënnt dëse Schrëtt iwwersprangen wann Dir net plangt méi Leefer op der selwechter Maschinn ze lafen.
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!
Kontrolléiert datt de Leefer registréiert ass. Gitt op gitlab.com -> deploy-project -> Astellungen -> CI/CD -> Leefer -> Spezifesch Leefer -> Leefer aktivéiert fir dëse Projet
Mir generéieren e Schlëssel andeems mir Froen beäntweren. Ech hunn mäin eegenen Numm an E-Mail benotzt.
Gitt sécher d'Passwuert fir de Schlëssel ze spezifizéieren. Artefakte ginn mat dësem Schlëssel ënnerschriwwen.
gpg --gen-key
Iwwerpréiwen
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
Eroplueden eisen ëffentleche Schlëssel op de Schlësselserver
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Erstellt e Maven Verzeichnis Repository a Link mam Cache (maacht kee Feeler)
Dëse Schrëtt kann iwwersprangen ginn wann Dir net plangt e puer Leefer op der selwechter Maschinn ze lafen.
Als éischt musst Dir e GPG Schlëssel erstellen. Fir dëst ze maachen, installéiert gnupg.
yum install -y gnupg
Mir generéieren e Schlëssel andeems mir Froen beäntweren. Ech hunn mäin eegenen Numm an E-Mail benotzt. Gitt sécher d'Passwuert fir de Schlëssel ze spezifizéieren.
Mir kreéieren eng zimlech einfach Dockerfile fir Aufgaben op Deploy mat der gewënschter Versioun vu Java auszeféieren. Drënner ass e Beispill fir 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/
Füügt d'Datei .gitlab-ci.yml un der Wuerzel vum Deployprojet
De Skript stellt zwee géigesäiteg exklusiv Deployment Aufgaben vir. Spezifesch Runner oder Shared Runner respektiv.
.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
An Java Projeten déi sollen op ëffentlech Repositories eropgeluede ginn, musst Dir 2 Schrëtt derbäi fir d'Verëffentlechung a Snapshot Versiounen erofzelueden.
.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}
An dëser Léisung sinn ech e bësse méi wäit gaang an hunn decidéiert eng CI Schabloun fir Java Projeten ze benotzen.
Méi Detailer
Ech hunn e separate Projet erstallt gitlab-ci an deem ech eng CI Schabloun fir Java Projeten gesat hunn gemeinsam.yml.
<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>
Wann Dir e Modul hutt deen net Java enthält (zum Beispill nëmmen Ressourcen)
Oder Dir wëllt net Javadoc am Prinzip generéieren, dann ze hëllefen maven-jar-plugin
Wann Dir e Multi-Modul-Projet hutt, an Dir braucht kee spezifesche Modul an de Repository eropzelueden, da musst Dir op de pom.xml vun dësem Modul addéieren nexus-staging-maven-plugin mat Fändel skipNexusStagingDeployMojo
Nom Eroplueden Snapshot / Verëffentlechung Versioune sinn verfügbar an Staging Repositories
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Méi pluses
Eng ganz räich Lëscht vun Ziler fir mam Nexus Repository ze schaffen (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Automatesch Verëffentlechungscheck fir Downloadbarkeet am Maven Central
Verëffentlechung vun der Verëffentlechung Versioun
Wann de Tag gesat ass, gëtt déi entspriechend Aufgab am Deployprojet automatesch ausgeléist fir d'Verëffentlechungsversioun op Nexus eropzelueden (Beispill).
Dee beschten Deel ass datt enk Verëffentlechung automatesch am Nexus ausléist.
[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 wann eppes falsch gaang ass, da wäert d'Aufgab versoen
[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 <a href=http://keys.gnupg.net:11371/>http://keys.gnupg.net:11371/</a>. 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] ------------------------------------------------------------------------
Als Resultat hu mir nëmmen eng Wiel. Oder dës Versioun läschen oder publizéieren.
No der Verëffentlechung, no enger Zäit, wäerten d'Artefakte erakommen
offtopic
Et war eng Offenbarung fir mech datt Maven aner ëffentlech Repositories indexéiert.
Ech hu misse robots.txt eropluede well et meng al Repository indexéiert huet.
En separaten Deployprojet an deem Dir verschidde CI Aufgaben implementéiere kënnt fir Artefakte op ëffentlech Repositories fir verschidden Entwécklungssproochen eropzelueden.
Den Deploymentprojet ass vun externen Interferenz isoléiert a kann nëmme vu Benotzer mat de Besëtzer a Maintainer Rollen geännert ginn.
Отдельный Specific Runner с "горячим" кэшем для запуска только deploy задач.
Verëffentlechung vun Snapshot / Verëffentlechung Versiounen an engem ëffentleche Repository.
Automatesch Kontroll vun der Verëffentlechung Versioun fir Bereetschaft fir Publikatioun an Maven Central.
Защита от автоматической публикации "сырых" версий в maven central.
Сборка и публикация snapshot версий "по клику".
Een eenzege Repository fir Snapshot / Release Versiounen ze kréien.
Allgemeng Pipeline fir ze bauen / Testen / Verëffentlechung vun engem Java Projet.
Настройка GitLab CI не такая сложная тема как кажется на первый взгляд. Достаточно пару раз настроить CI "под ключ" и вот, ты уже далеко не дилетант в этом деле. Тем более GitLab документация весьма избыточна. Не бойтесь делать первый шаг. Дорога возникает под шагами идущего (не помню кто сказал 🙂 ).
Ech wäert frou Feedback.
Am nächsten Artikel weisen ech Iech wéi Dir GitLab CI opstellt fir Integratiounstestaufgaben kompetitiv ze lafen (Testservicer mat Docker-compose lafen) wann Dir nëmmen ee Shell Runner hutt.