A GitLab CI beállítása java projekt feltöltéséhez a maven centralba
Ez a cikk azoknak a java-fejlesztőknek szól, akiknek gyorsan közzé kell tenniük termékeiket a Sonatype és/vagy a Maven központi adattáraiban a GitLab segítségével. Ebben a cikkben a gitlab-runner, a gitlab-ci és a maven-plugin beállításáról fogok beszélni a probléma megoldására.
Feltételek:
Mvn és GPG kulcsok biztonságos tárolása.
A közcélú CI-feladatok biztonságos végrehajtása.
Műtermékek (kiadás/pillanatkép) feltöltése nyilvános adattárakba.
A kiadási verziók automatikus ellenőrzése közzétételhez a maven centralban.
Általános megoldás műtermékek feltöltésére több projekt tárházába.
A Maven Centralban a Sonatype OSS Repository Hosting szolgáltatáson keresztüli közreadásának mechanizmusának részletes leírását már leírtuk ez a cikk felhasználó googolplex, ezért a megfelelő helyeken hivatkozni fogok erre a cikkre.
Előzetes regisztráció a JIRA szonátípia és nyissa meg a jegyet a tároló megnyitásához (további részletekért olvassa el a részt Hozzon létre jegyet a Sonatype JIRA-n). Az adattár megnyitása után a JIRA bejelentkezési/jelszópárját (a továbbiakban: Sonatype fiók) a rendszer a műtermékek Sonatype nexusba való feltöltésére fogja használni.
Ha a Linux konzolt használja GPG kulcs létrehozásához (gnupg/gnupg2), akkor telepítenie kell rng-eszközök entrópiát generálni. Ellenkező esetben a kulcs előállítása nagyon sokáig tarthat.
Először is létre kell hoznia és be kell állítania egy projektet, amelyben a folyamatot a műtermékek telepítéséhez tárolja. A projektemet egyszerűen és egyszerűen elneveztem - telepíteni
A tár létrehozása után korlátozni kell a hozzáférést a tár megváltoztatásához.
Lépjen a projekt -> Beállítások -> Leraktár -> Védett ágak menüpontra. Töröljük az összes szabályt, és egyetlen szabályt adunk hozzá helyettesítő karakterrel *, amely csak a fenntartói szerepkörrel rendelkező felhasználók számára jogosult a leküldésre és egyesítésre. Ez a szabály mind ennek a projektnek, mind annak a csoportnak az összes felhasználója számára működik, amelyhez a projekt tartozik.
Ha több karbantartó van, akkor a legjobb megoldás a projekthez való hozzáférés elvi korlátozása lenne.
Lépjen a projekt -> Beállítások -> Általános -> Láthatóság, projektfunkciók, engedélyek menüpontra, és állítsa be a Projekt láthatóságát értékre Magán.
Van egy nyilvánosan elérhető projektem, mivel a saját GitLab Runneremet használom, és csak nekem van hozzáférésem a tárhely módosításához. Nos, valójában nem érdekem, hogy privát információkat jelenítsek meg a nyilvános csővezeték-naplókban.
Az adattár megváltoztatására vonatkozó szabályok szigorítása
Menjen a projekthez -> Beállítások -> Repository -> Push Rules, és állítsa be a Committer korlátozást, ellenőrizze, hogy a szerző GitLab-felhasználó-e. Javaslom a beállítást is aláírást vállalni, és állítsa be az aláíratlan véglegesítések elutasítása jelzőt.
Ezután konfigurálnia kell egy triggert a feladatok elindításához
Lépjen a projekt -> Beállítások -> CI / CD -> Pipeline triggerek menüpontra, és hozzon létre egy új trigger-token
Ez a token azonnal hozzáadható egy projektcsoport változóinak általános konfigurációjához.
Lépjen a csoport -> Beállítások -> CI / CD -> Változók menüpontra, és adjon hozzá egy változót DEPLOY_TOKEN trigger-token értékkel.
Ez a szakasz a saját (specifikus) és nyilvános (Megosztott) futtató használatával futtatandó feladatok konfigurációját írja le.
Konkrét futó
Saját futókat használok, mert mindenekelőtt kényelmes, gyors és olcsó.
Futónak linuxos VDS-t ajánlok 1 CPU-val, 2 GB RAM-mal, 20 GB HDD-vel. A kibocsátási ár ~3000₽ évente.
A futóm
A futóhoz VDS 4 CPU-t, 4 GB RAM-ot, 50 GB SSD-t vettem. Ára ~11000 XNUMX₽, és soha nem bántam meg.
Összesen 7 gépem van. 5 arubán és 2 ihoron.
Szóval van egy futónk. Most konfiguráljuk.
SSH-n keresztül megyünk a géphez és telepítjük a java, git, maven, gnupg2-t.
Hozzon létre egy könyvtárat a maven gyorsítótár számára, és rendeljen hozzá csoportengedélyeket runner
Ezt a pontot kihagyhatja, ha nem tervezi több futó futtatását egy gépen.
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!
Ellenőrizzük, hogy a futó regisztrálva van-e. Nyissa meg a gitlab.com webhelyet -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners activated for this project.
Képernyő
hozzáadása különálló szolgáltatás /etc/systemd/system/gitlab-deployer.service
A kérdések megválaszolásával kulcsot generálunk. A saját nevemet és email címemet használtam.
Feltétlenül adja meg a kulcs jelszavát. A műtermékek aláírása ezzel a kulccsal történik.
gpg --gen-key
Ellenőrzés
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
Nyilvános kulcsunk feltöltése a kulcsszerverre
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Hozzon létre egy maven könyvtárat raktár és link a gyorsítótárhoz (nem tévedés)
Ezt a pontot kihagyhatja, ha nem tervezi több futó futtatását egy gépen.
Létrehozunk egy meglehetősen egyszerű Dockerfile-t a telepítési feladatok futtatásához a Java szükséges verziójával. Az alábbiakban egy példa az alpesi területre.
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/
Adja hozzá a .gitlab-ci.yml fájlt a telepítési projekt gyökeréhez
A szkript két, egymást kölcsönösen kizáró telepítési feladatot mutat be. Adott futó vagy megosztott futó.
.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
Azoknál a java projekteknél, amelyeket fel kell tölteni nyilvános adattárakba, 2 lépést kell hozzáadnia a kiadási és pillanatfelvételi verziók letöltéséhez.
.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}
Ebben a megoldásban egy kicsit tovább mentem, és úgy döntöttem, hogy egy CI-sablont használok a java projektekhez.
További részletek
Létrehoztam egy külön projektet gitlab-ci amelyben elhelyeztem egy CI-sablont a java projektekhez gyakori.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>
Ha olyan modulja van, amely nem tartalmaz Java-t (például csak erőforrásokat)
Vagy elvileg nem akarsz javadocot generálni, akkor segíts maven-jar-plugin
Ha több modulos projektje van, és nem kell egy adott modult feltöltenie a tárolóba, akkor hozzá kell adnia nexus-staging-maven-plugin zászlóval skipNexusStagingDeployMojo
A letöltés után a pillanatfelvétel/kiadás verziók elérhetők állomásozó adattárak
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Még több plusz
Nagyon gazdag célok listája a nexus adattárral való munkához (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Automatikus kiadás-ellenőrzés a maven centralba való feltöltéshez
Ha telepítve van egy címke, a telepítési projektben a megfelelő feladat automatikusan elindul a kiadási verzió letöltéséhez a nexus (példa).
A legjobb az egészben az, hogy a közeli feloldás automatikusan aktiválódik a nexusban.
[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] ------------------------------------------------------------------------
És ha valami elromlik, a feladat biztosan meghiúsul
[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] ------------------------------------------------------------------------
Ennek eredményeként csak egy választásunk marad. Vagy törölje ezt a verziót, vagy tegye közzé.
A kiadás után egy idő után a műtermékek bekerülnek
off topic
Felfedezés volt számomra, hogy a maven más nyilvános adattárakat is indexel.
Hozzá kellett adnom a robots.txt fájlt, mert indexelte a régi tárhelyemet.
Egy külön telepítési projekt, amelyben számos CI-feladatot hajthat végre a köztermékek nyilvános tárolókba való feltöltéséhez különböző fejlesztési nyelvekhez.
A Telepítési projekt el van szigetelve a külső zavaroktól, és csak a tulajdonosi és karbantartói szerepkörrel rendelkező felhasználók módosíthatják.
Egy külön speciális futtató „forró” gyorsítótárral, amely csak a telepítési feladatokat futtatja.
Pillanatkép/kiadási verziók közzététele nyilvános lerakatban.
A kiadási verzió automatikus ellenőrzése a Maven Centralban való közzétételre.
Védelem a „nyers” verziók automatikus közzététele ellen a maven centralban.
Pillanatkép-verziók létrehozása és közzététele „kattintásra”.
Egyetlen tároló a pillanatkép/kiadási verziók beszerzéséhez.
Általános folyamat Java projektek felépítéséhez/teszteléséhez/közzétételéhez.
A GitLab CI beállítása nem olyan bonyolult téma, mint amilyennek első pillantásra tűnik. Elég, ha párszor kulcsrakészen beállítod a CI-t, és most már messze nem vagy amatőr ebben a kérdésben. Ráadásul a GitLab dokumentációja nagyon redundáns. Ne félj megtenni az első lépést. Az út megjelenik a sétáló ember lépcsője alatt (már nem emlékszem, ki mondta :)
Szívesen fogadok visszajelzést.
A következő cikkben arról fogok beszélni, hogyan konfigurálhatja a GitLab CI-t úgy, hogy versenyképesen futtasson integrációs teszteket tartalmazó feladatokat (a tesztelés alatt álló szolgáltatások futtatása a docker-compose használatával), ha csak egy shell-futtatója van.