ProHoster > Blog > administracja > Konfigurowanie GitLab CI do przesyłania projektu java do maven central
Konfigurowanie GitLab CI do przesyłania projektu java do maven central
Ten artykuł jest przeznaczony dla programistów Java, którzy muszą szybko opublikować swoje produkty w centralnych repozytoriach sonatype i/lub maven przy użyciu GitLab. W tym artykule omówię konfigurację gitlab-runner, gitlab-ci i maven-plugin, aby rozwiązać ten problem.
Wymagania wstępne:
Bezpieczne przechowywanie kluczy mvn i GPG.
Bezpieczne wykonywanie publicznych zadań CI.
Przesyłanie artefaktów (wersja/migawka) do repozytoriów publicznych.
Automatyczne sprawdzanie wersji wydań pod kątem publikacji w centrali maven.
Ogólne rozwiązanie umożliwiające przesyłanie artefaktów do repozytorium dla wielu projektów.
Szczegółowy opis mechanizmu publikowania artefaktów do Maven Central za pośrednictwem usługi hostingowej repozytorium Sonatype OSS opisano już w Ten artykuł użytkownik Googolplex, dlatego odniosę się do tego artykułu w odpowiednich miejscach.
Zarejestruj się wcześniej pod adresem Sonatyp JIRA i otwórz bilet, aby otworzyć repozytorium (przeczytaj sekcję, aby uzyskać więcej informacji Utwórz zgłoszenie w Sonatype JIRA). Po otwarciu repozytorium para login/hasło z JIRA (zwana dalej kontem Sonatype) zostanie użyta do przesłania artefaktów do Sonatype nexus.
Jeśli używasz konsoli Linux do generowania klucza GPG (gnupg/gnupg2), musisz zainstalować rng-tools do generowania entropii. W przeciwnym razie generowanie klucza może zająć bardzo dużo czasu.
Przede wszystkim musisz utworzyć i skonfigurować projekt, w którym będzie przechowywany potok na potrzeby wdrażania artefaktów. Nazwałem swój projekt prosto i nieskomplikowanie - rozwijać
Po utworzeniu repozytorium musisz ograniczyć dostęp, aby móc zmieniać repozytorium.
Przejdź do projektu -> Ustawienia -> Repozytorium -> Chronione gałęzie. Usuwamy wszystkie reguły i dodajemy pojedynczą regułę z symbolem wieloznacznym * z prawem do wypychania i łączenia tylko dla użytkowników z rolą Opiekunowie. Ta reguła będzie działać dla wszystkich użytkowników zarówno tego projektu, jak i grupy, do której ten projekt należy.
Jeżeli opiekunów jest kilku, to najlepszym rozwiązaniem byłoby w zasadzie ograniczenie dostępu do projektu.
Przejdź do projektu -> Ustawienia -> Ogólne -> Widoczność, funkcje projektu, uprawnienia i ustaw Widoczność projektu na Sprawy Prywatne.
Mam projekt dostępny publicznie, ponieważ korzystam z własnego GitLab Runnera i tylko ja mam dostęp do zmiany repozytorium. Cóż, właściwie nie leży w moim interesie pokazywanie prywatnych informacji w publicznych dziennikach potoków.
Zaostrzenie zasad zmiany repozytorium
Przejdź do projektu -> Ustawienia -> Repozytorium -> Reguły Push i ustaw flagi Ograniczenie Committer, Sprawdź, czy autor jest użytkownikiem GitLab. Polecam również ustawienie zobowiązać się do podpisaniai ustaw flagę Odrzuć niepodpisane zatwierdzenia.
Następnie musisz skonfigurować wyzwalacz do uruchamiania zadań
Przejdź do projektu -> Ustawienia -> CI / CD -> Wyzwalacze potokowe i utwórz nowy token wyzwalacza
Token ten można od razu dodać do ogólnej konfiguracji zmiennych dla grupy projektów.
Przejdź do grupy -> Ustawienia -> CI/CD -> Zmienne i dodaj zmienną DEPLOY_TOKEN z tokenem wyzwalacza w wartości.
W tej sekcji opisano konfigurację uruchamiania zadań podczas wdrażania przy użyciu własnego (określonego) i publicznego (współdzielonego) modułu uruchamiającego.
Konkretny biegacz
Korzystam z własnych biegaczy, bo przede wszystkim jest wygodnie, szybko, tanio.
Dla biegaczy polecam Linux VDS z 1 procesorem, 2 GB RAM, 20 GB HDD. Cena emisyjna ~3000₽ rocznie.
Mój biegacz
Na biegacza wziąłem procesor VDS 4, 4 GB RAM, 50 GB SSD. Kosztowało ~ 11000 ₽ i nigdy tego nie żałowałem.
Mam w sumie 7 maszyn. 5 na Arubie i 2 na ihor.
Mamy więc biegacza. Teraz to skonfigurujemy.
Wchodzimy na maszynę przez SSH i instalujemy Java, git, maven, gnupg2.
Utwórz katalog dla pamięci podręcznej maven i przypisz uprawnienia grupy runner
Możesz pominąć ten punkt, jeśli nie planujesz uruchamiania kilku programów uruchamiających na jednej maszynie.
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!
Sprawdzamy, czy biegacz jest zarejestrowany. Przejdź do strony gitlab.com -> Deploy-project -> Ustawienia -> CI/CD -> Runners -> Określeni Runnerzy -> Runnerzy aktywowani dla tego projektu
Generujemy klucz odpowiadając na pytania. Użyłem własnego imienia i nazwiska oraz adresu e-mail.
Pamiętaj o podaniu hasła dla klucza. Artefakty będą podpisane tym kluczem.
gpg --gen-key
Kontrola
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
Przesyłanie naszego klucza publicznego na serwer kluczy
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Utwórz katalog maven składnica i link do pamięci podręcznej (nie popełnij błędu)
Ten krok można pominąć, jeśli nie planujesz uruchamiania kilku programów uruchamiających na tej samej maszynie.
Dodaj plik .gitlab-ci.yml do katalogu głównego projektu wdrażania
Skrypt przedstawia dwa wzajemnie wykluczające się zadania wdrażania. Odpowiednio konkretny biegacz lub wspólny biegacz.
.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
Jeśli masz projekt wielomodułowy i nie musisz wgrywać konkretnego modułu do repozytorium, to musisz dodać nexus-staging-maven-plugin z flagą skipNexusStagingDeployMojo
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Więcej plusów
Bardzo bogata lista celów do pracy z repozytorium nexusa (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Automatyczne sprawdzanie wersji pod kątem możliwości pobrania w Maven Central
Po ustawieniu tagu automatycznie uruchamiane jest odpowiednie zadanie w projekcie wdrażania w celu przesłania wersji wydania do nexusa (przykład).
Najlepsze jest to, że bliskie zwolnienie automatycznie uruchamia się w Nexusie.
[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 jeśli coś pójdzie nie tak, zadanie na pewno się nie powiedzie
[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] ------------------------------------------------------------------------
W rezultacie pozostaje nam tylko jeden wybór. Usuń tę wersję lub opublikuj ją.
Po wydaniu, po pewnym czasie, artefakty będą dostępne
poza tematem
To było dla mnie odkrycie, że Maven indeksuje inne publiczne repozytoria.
Musiałem przesłać plik robots.txt, ponieważ zaindeksował on moje stare repozytorium.
Oddzielny projekt wdrożenia, w którym można zaimplementować kilka zadań CI w celu przesyłania artefaktów do publicznych repozytoriów dla różnych języków programowania.
Projekt Deploy jest odizolowany od ingerencji z zewnątrz i może być zmieniany wyłącznie przez użytkowników z rolami właściciela i opiekuna.
Oddzielny konkretny moduł uruchamiający z „gorącą” pamięcią podręczną do uruchamiania tylko zadań wdrażania.
Publikowanie wersji migawek/wydań w publicznym repozytorium.
Automatyczne sprawdzenie wersji wydania pod kątem gotowości do publikacji w centrali maven.
Ochrona przed automatyczną publikacją wersji „surowych” w maven central.
Twórz i publikuj wersje migawek „po kliknięciu”.
Pojedyncze repozytorium do uzyskiwania wersji migawek/wydań.
Ogólny potok budowania/testowania/publikowania projektu Java.
Konfiguracja GitLab CI nie jest tak skomplikowanym tematem jak się wydaje na pierwszy rzut oka. Wystarczy kilka razy skonfigurować CI pod klucz i teraz nie jesteś w tej kwestii amatorem. Co więcej, dokumentacja GitLaba jest bardzo zbędna. Nie bój się zrobić pierwszego kroku. Droga pojawia się pod schodami idącej osoby (nie pamiętam kto to powiedział :)
Z przyjemnością przekażę informację zwrotną.
W następnym artykule opowiem o tym, jak skonfigurować GitLab CI, aby konkurencyjnie uruchamiał zadania z testami integracyjnymi (uruchamiając testowane usługi za pomocą docker-compose), jeśli masz tylko jednego Shell Runnera.