ProHoster > blog > administratie > GitLab CI instellen om een Java-project naar Maven Central te uploaden
GitLab CI instellen om een Java-project naar Maven Central te uploaden
Dit artikel is bedoeld voor Java-ontwikkelaars die hun producten snel willen publiceren in sonatype en/of maven centrale repository's met behulp van GitLab. In dit artikel zal ik het hebben over het opzetten van gitlab-runner, gitlab-ci en maven-plugin om dit probleem op te lossen.
Vereisten:
Veilige opslag van mvn- en GPG-sleutels.
Veilige uitvoering van openbare CI-taken.
Artefacten (release/momentopname) uploaden naar openbare opslagplaatsen.
Automatische controle van releaseversies voor publicatie in Maven Central.
Een algemene oplossing voor het uploaden van artefacten naar een repository voor meerdere projecten.
Een gedetailleerde beschrijving van het mechanisme voor het publiceren van artefacten in Maven Central via Sonatype OSS Repository Hosting Service is al beschreven in Dit artikel gebruiker googolplex, dus ik zal op de juiste plaatsen naar dit artikel verwijzen.
Vooraf inschrijven voor Sonatype JIRA en open een ticket om de repository te openen (lees de sectie voor meer details Maak een ticket aan op Sonatype JIRA). Na het openen van de repository wordt het login/wachtwoord-paar van JIRA (hierna het Sonatype-account genoemd) gebruikt om artefacten naar Sonatype Nexus te uploaden.
Als u de Linux-console gebruikt om een GPG-sleutel (gnupg/gnupg2) te genereren, moet u deze installeren RNG-gereedschappen entropie te genereren. Anders kan het genereren van de sleutel erg lang duren.
Allereerst moet u een project maken en configureren waarin de pijplijn wordt opgeslagen voor het implementeren van artefacten. Ik noemde mijn project eenvoudig en ongecompliceerd: implementeren
Nadat u de repository hebt gemaakt, moet u de toegang beperken om de repository te wijzigen.
Ga naar project -> Instellingen -> Repository -> Beschermde vestigingen. We verwijderen alle regels en voegen een enkele regel toe met Wildcard * met het recht om alleen te pushen en samen te voegen voor gebruikers met de rol Onderhouders. Deze regel werkt voor alle gebruikers van zowel dit project als de groep waartoe dit project behoort.
Als er meerdere beheerders zijn, is het in principe de beste oplossing om de toegang tot het project te beperken.
Ga naar project -> Instellingen -> Algemeen -> Zichtbaarheid, projectfuncties, rechten en stel Projectzichtbaarheid in op Privé.
Ik heb een publiek toegankelijk project, aangezien ik mijn eigen GitLab Runner gebruik en alleen ik toegang heb om de repository te wijzigen. Nou ja, eigenlijk is het niet in mijn belang om privé-informatie weer te geven in openbare pijplijnlogboeken.
Aanscherping van de regels voor het wijzigen van de repository
Ga naar het project -> Instellingen -> Repository -> Pushregels en stel de Committer-beperking in. Controleer of de auteur een GitLab-gebruikersvlag is. Ik raad ook aan om op te zetten handtekening vastleggenen stel de vlag Niet-ondertekende commits afwijzen in.
Vervolgens moet u een trigger configureren om taken te starten
Ga naar project -> Instellingen -> CI/CD -> Pipeline-triggers en maak een nieuw trigger-token
Dit token kan onmiddellijk worden toegevoegd aan de algemene configuratie van variabelen voor een groep projecten.
Ga naar groep -> Instellingen -> CI/CD -> Variabelen en voeg een variabele toe DEPLOY_TOKEN met trigger-token in waarde.
In deze sectie wordt de configuratie beschreven voor het uitvoeren van taken bij implementatie met uw eigen (specifieke) en openbare (gedeelde) runner.
Specifieke loper
Ik gebruik mijn eigen hardlopers omdat het in de eerste plaats handig, snel en goedkoop is.
Voor een hardloper raad ik een Linux VDS aan met 1 CPU, 2 GB RAM, 20 GB HDD. De uitgifteprijs bedraagt ~3000₽ per jaar.
Mijn hardloper
Voor de hardloper nam ik VDS 4 CPU, 4 GB RAM, 50 GB SSD. Kostte ~11000₽ en heb er nooit spijt van gehad.
Ik heb in totaal 7 machines. 5 op Aruba en 2 op ihor.
We hebben dus een loper. Nu zullen we het configureren.
We gaan via SSH naar de machine en installeren java, git, maven, gnupg2.
Maak een map voor de maven-cache en wijs groepsmachtigingen toe runner
U kunt dit punt overslaan als u niet van plan bent meerdere hardlopers op één machine te gebruiken.
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!
Wij controleren of de loper geregistreerd is. Ga naar de website gitlab.com -> implement-project -> Instellingen -> CI/CD -> Runners -> Specifieke Runners -> Runners geactiveerd voor dit project
Scherm
Toevoegen apart service /etc/systemd/system/gitlab-deployer.service
Door het beantwoorden van vragen genereren wij een sleutel. Ik heb mijn eigen naam en e-mailadres gebruikt.
Zorg ervoor dat u het wachtwoord voor de sleutel opgeeft. Artefacten worden met deze sleutel ondertekend.
gpg --gen-key
check de
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
Het uploaden van onze publieke sleutel naar de sleutelserver
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Maak een maven-map bewaarplaats en link naar de cache (vergis je niet)
U kunt dit punt overslaan als u niet van plan bent meerdere hardlopers op één machine te gebruiken.
Allereerst moet u een GPG-sleutel maken. Om dit te doen, installeer gnupg.
yum install -y gnupg
Door het beantwoorden van vragen genereren wij een sleutel. Ik heb mijn eigen naam en e-mailadres gebruikt. Zorg ervoor dat u het wachtwoord voor de sleutel opgeeft.
We maken een vrij eenvoudig Dockerbestand om implementatietaken uit te voeren met de vereiste versie van Java. Hieronder ziet u een voorbeeld voor 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/
Voeg het bestand .gitlab-ci.yml toe aan de hoofdmap van het implementatieproject
Het script presenteert twee elkaar uitsluitende implementatietaken. Specifieke Runner of Gedeelde 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
In Java-projecten die naar openbare repository's moeten worden geüpload, moet u twee stappen toevoegen om de Release- en Snapshot-versies te downloaden.
.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}
Bij deze oplossing ging ik nog een stapje verder en besloot ik één CI-sjabloon voor Java-projecten te gebruiken.
Meer details
Ik heb een apart project gemaakt gitlab-ci waarin ik een CI-sjabloon voor Java-projecten heb geplaatst common.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>
Als u een module heeft die geen Java bevat (bijvoorbeeld alleen resources)
Of als je in principe geen Javadoc wilt genereren, help dan maven-jar-plugin
Als u een project met meerdere modules heeft en u hoeft geen specifieke module naar de repository te uploaden, dan moet u toevoegen nexus-staging-maven-plugin met vlag skipNexusStagingDeployMojo
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Meer pluspunten
Een zeer rijke lijst met doelen voor het werken met de Nexus-repository (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Automatische vrijgavecontrole voor uploaden naar Maven Central
Wanneer een tag is geïnstalleerd, wordt de overeenkomstige taak in het implementatieproject automatisch geactiveerd om de releaseversie naar Nexus te downloaden (voorbeeld).
Het beste is dat close release automatisch wordt geactiveerd in 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] ------------------------------------------------------------------------
En als er iets misgaat, zal de taak zeker mislukken
[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] ------------------------------------------------------------------------
Het resultaat is dat we nog maar één keuze hebben. Verwijder deze versie of publiceer deze.
Na de release zullen de artefacten na enige tijd binnen zijn
off topic
Het was voor mij een ontdekking dat Maven andere openbare repository's indexeert.
Ik moest robots.txt toevoegen omdat het mijn oude repository indexeerde.
Een afzonderlijk implementatieproject waarin u verschillende CI-taken kunt implementeren voor het uploaden van artefacten naar openbare opslagplaatsen voor verschillende ontwikkelingstalen.
Het Deploy-project is geïsoleerd van inmenging van buitenaf en kan alleen worden gewijzigd door gebruikers met de rollen Eigenaar en Onderhouder.
Een aparte Specific Runner met een ‘hot’ cache om alleen implementatietaken uit te voeren.
Publiceren van snapshot-/releaseversies in een openbare repository.
Automatische controle van de releaseversie op gereedheid voor publicatie in Maven Central.
Bescherming tegen automatische publicatie van “ruwe” versies in Maven Central.
Bouw en publiceer snapshotversies “met een klik”.
Eén enkele opslagplaats voor het verkrijgen van snapshot-/releaseversies.
Algemene pijplijn voor het bouwen/testen/publiceren van een Java-project.
Het opzetten van GitLab CI is niet zo ingewikkeld als het op het eerste gezicht lijkt. Het is voldoende om CI een paar keer turnkey op te zetten, en nu ben je verre van een amateur op dit gebied. Bovendien is GitLab-documentatie erg redundant. Wees niet bang om de eerste stap te zetten. De weg verschijnt onder de treden van de persoon die loopt (ik weet niet meer wie het zei :)
Ik ontvang graag feedback.
In het volgende artikel zal ik het hebben over hoe je GitLab CI kunt configureren om taken met integratietests competitief uit te voeren (de geteste services uitvoeren met docker-compose) als je maar één shell-runner hebt.