ProHoster > BLOG > administrare > Configurarea GitLab CI pentru a încărca un proiect java în Maven Central
Configurarea GitLab CI pentru a încărca un proiect java în Maven Central
Acest articol este destinat dezvoltatorilor java care au nevoie să-și publice rapid produsele în depozitele centrale Sonatype și/sau Maven folosind GitLab. În acest articol voi vorbi despre configurarea gitlab-runner, gitlab-ci și maven-plugin pentru a rezolva această problemă.
Condiții preliminare:
Stocarea securizată a cheilor mvn și GPG.
Executarea în siguranță a sarcinilor publice CI.
Încărcarea artefactelor (lansare/instantaneu) în depozitele publice.
Verificarea automată a versiunilor de lansare pentru publicare în Maven Central.
O soluție generală pentru încărcarea artefactelor într-un depozit pentru mai multe proiecte.
O descriere detaliată a mecanismului de publicare a artefactelor în Maven Central prin Sonatype OSS Repository Hosting Service a fost deja descrisă în Acest articol utilizator Googlelplex, așa că mă voi referi la acest articol în locurile potrivite.
Pre-înregistrați pentru Sonatip JIRA și deschideți un bilet pentru a deschide depozitul (citiți secțiunea pentru mai multe detalii Creați un bilet pe Sonatype JIRA). După deschiderea depozitului, perechea de autentificare/parolă de la JIRA (denumită în continuare contul Sonatype) va fi utilizată pentru a încărca artefacte în Sonatype nexus.
Dacă utilizați consola Linux pentru a genera o cheie GPG (gnupg/gnupg2), atunci trebuie să instalați rng-instrumente pentru a genera entropie. În caz contrar, generarea cheii poate dura foarte mult.
Configurarea unui proiect de implementare în GitLab
În primul rând, trebuie să creați și să configurați un proiect în care conducta va fi stocată pentru implementarea artefactelor. Mi-am numit proiectul simplu și necomplicat - implementa
După crearea depozitului, trebuie să restricționați accesul pentru a schimba depozitul.
Accesați proiect -> Setări -> Repository -> Ramuri protejate. Ștergem toate regulile și adăugăm o singură regulă cu Wildcard * cu drept de împingere și îmbinare numai pentru utilizatorii cu rolul de întreținere. Această regulă va funcționa atât pentru toți utilizatorii acestui proiect, cât și pentru grupul căruia îi aparține acest proiect.
Dacă există mai mulți menținători, atunci cea mai bună soluție ar fi limitarea accesului la proiect în principiu.
Accesați proiect -> Setări -> General -> Vizibilitate, caracteristici ale proiectului, permisiuni și setați vizibilitatea proiectului la Privat.
Am un proiect accesibil public, deoarece folosesc propriul meu GitLab Runner și doar eu am acces pentru a schimba depozitul. Ei bine, de fapt, nu este în interesul meu să arăt informații private în jurnalele de conducte publice.
Înăsprirea regulilor de modificare a depozitului
Accesați proiect -> Setări -> Depozit -> Reguli Push și setați restricția Committer, verificați dacă autorul este un utilizator GitLab. De asemenea, recomand configurarea commit semnătură, și setați indicatorul Respingere comiterilor nesemnate.
Apoi, trebuie să configurați un declanșator pentru a lansa sarcini
Accesați proiect -> Setări -> CI / CD -> Declanșatoare pipeline și creați un nou simbol de declanșare
Acest token poate fi adăugat imediat la configurația generală a variabilelor pentru un grup de proiecte.
Mergeți la grup -> Setări -> CI / CD -> Variabile și adăugați o variabilă DEPLOY_TOKEN cu token de declanșare în valoare.
Această secțiune descrie configurația pentru rularea sarcinilor la implementare folosind propriul ruler (Specific) și public (Partajat).
Alergator specific
Folosesc propriile mele alergători pentru că, în primul rând, este convenabil, rapid și ieftin.
Pentru un alergător, recomand un Linux VDS cu 1 CPU, 2 GB RAM, 20 GB HDD. Prețul de emisiune este de ~3000₽ pe an.
Alergatorul meu
Pentru alergător am luat CPU VDS 4, 4 GB RAM, 50 GB SSD. A costat ~11000₽ și nu am regretat niciodată.
Am un total de 7 mașini. 5 pe aruba si 2 pe ihor.
Deci avem un alergător. Acum îl vom configura.
Mergem la mașină prin SSH și instalăm java, git, maven, gnupg2.
Creați un director pentru memoria cache Maven și atribuiți permisiuni de grup runner
Puteți sări peste acest punct dacă nu intenționați să rulați mai mulți alergători pe o singură mașină.
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!
Verificăm dacă alergătorul este înscris. Accesați site-ul gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners activați pentru acest proiect
Generam o cheie răspunzând la întrebări. Mi-am folosit propriul nume și e-mail.
Asigurați-vă că specificați parola pentru cheie. Artefactele vor fi semnate cu această cheie.
gpg --gen-key
Control
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
Încărcarea cheii noastre publice pe serverul de chei
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Creați un director Maven depozit și link la cache (nu faceți greșeli)
Puteți sări peste acest punct dacă nu intenționați să rulați mai mulți alergători pe o singură mașină.
Adăugați fișierul .gitlab-ci.yml la rădăcina proiectului de implementare
Scriptul prezintă două sarcini de implementare care se exclud reciproc. Alergator specific sau, respectiv, alergător partajat.
.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
Dacă aveți un proiect cu mai multe module și nu trebuie să încărcați un anumit modul în depozit, atunci trebuie să adăugați nexus-staging-maven-plugin cu steag skipNexusStagingDeployMojo
După descărcare, versiunile instantanee/de lansare sunt disponibile în depozite de staging
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Mai multe plusuri
O listă foarte bogată de obiective pentru lucrul cu depozitul nexus (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Verificare automată a eliberării pentru încărcare în Maven Central
Când este instalată o etichetă, sarcina corespunzătoare din proiectul de implementare este declanșată automat pentru a descărca versiunea de lansare pe nexus (exemplu).
Cea mai bună parte este că eliberarea apropiată este declanșată automat în nexus.
[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] ------------------------------------------------------------------------
Și dacă ceva nu merge bine, sarcina va eșua cu siguranță
[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] ------------------------------------------------------------------------
Drept urmare, ne rămâne cu o singură alegere. Fie ștergeți această versiune, fie publicați-o.
După eliberare, după ceva timp artefactele vor intra
pe langa subiect
Pentru mine a fost o descoperire că Maven indexează alte depozite publice.
A trebuit să adaug robots.txt pentru că îmi indexa vechiul depozit.
Un proiect de implementare separat în care puteți implementa mai multe sarcini CI pentru încărcarea artefactelor în depozitele publice pentru diferite limbaje de dezvoltare.
Proiectul Deploy este izolat de interferența exterioară și poate fi modificat numai de utilizatorii cu rolurile de proprietar și de întreținere.
Un Specific Runner separat cu un cache „fierbinte” pentru a rula numai sarcini de implementare.
Publicarea versiunilor instantanee/de lansare într-un depozit public.
Verificare automată a versiunii de lansare pentru pregătirea pentru publicare în Maven Central.
Protecție împotriva publicării automate a versiunilor „brute” în Maven Central.
Creați și publicați versiuni instantanee „la clic”.
Un singur depozit pentru obținerea versiunilor instantanee/de lansare.
Conductă generală pentru construirea/testarea/publicarea unui proiect java.
Configurarea GitLab CI nu este un subiect atât de complicat pe cât pare la prima vedere. Este suficient să configurați CI la cheie de câteva ori, iar acum sunteți departe de a fi un amator în această chestiune. Mai mult, documentația GitLab este foarte redundantă. Nu vă fie teamă să faceți primul pas. Drumul apare sub treptele celui care merge (nu-mi amintesc cine a spus-o :)
Voi fi bucuros să primesc feedback.
În articolul următor voi vorbi despre cum să configurați GitLab CI pentru a rula sarcini cu teste de integrare în mod competitiv (rularea serviciilor testate folosind docker-compose) dacă aveți un singur shell runner.