ProHoster > Blog > Pangangasiwa > Pagse-set up ng GitLab CI para mag-upload ng java project sa maven central
Pagse-set up ng GitLab CI para mag-upload ng java project sa maven central
Ang artikulong ito ay inilaan para sa mga developer ng java na kailangang mabilis na mag-publish ng kanilang mga produkto sa sonatype at/o maven central repository gamit ang GitLab. Sa artikulong ito, magsasalita ako tungkol sa pag-set up ng gitlab-runner, gitlab-ci at maven-plugin upang malutas ang problemang ito.
Mga Pangangailangan:
Ligtas na imbakan ng mvn at GPG key.
Secure na pagpapatupad ng mga pampublikong gawain sa CI.
Pag-upload ng mga artifact (release/snapshot) sa mga pampublikong repository.
Awtomatikong pagsusuri ng mga bersyon ng release para sa publikasyon sa maven central.
Isang pangkalahatang solusyon para sa pag-upload ng mga artifact sa isang repository para sa maraming proyekto.
Ang isang detalyadong paglalarawan ng mekanismo para sa pag-publish ng mga artifact sa Maven Central sa pamamagitan ng Sonatype OSS Repository Hosting Service ay inilarawan na sa Ang artikulong ito gumagamit Googolplex, kaya sasangguni ako sa artikulong ito sa mga tamang lugar.
Pre-register sa Sonatype JIRA at magsimula ng tiket para buksan ang repositoryo (para sa higit pang mga detalye, basahin ang seksyon Gumawa ng Sonatype JIRA ticket). Pagkatapos buksan ang repository, ang pares ng login/password ng JIRA (mula rito ay tinutukoy bilang ang Sonatype account) ay gagamitin upang mag-upload ng mga artifact sa Sonatype nexus.
Kung gumagamit ka ng Linux console para bumuo ng GPG key (gnupg/gnupg2), kailangan mong mag-install rng-tool upang makabuo ng entropy. Kung hindi man, maaaring tumagal ng napakatagal na panahon ang pagbuo ng key.
Una sa lahat, kailangan mong lumikha at mag-configure ng isang proyekto kung saan maiimbak ang pipeline para sa pag-deploy ng mga artifact. Tinawag ko ang aking proyekto nang simple at hindi kumplikado - lumawak
Pagkatapos gumawa ng repositoryo, kailangan mong paghigpitan ang pag-access para baguhin ang repositoryo.
Pumunta sa proyekto -> Mga Setting -> Imbakan -> Mga Protektadong Sangay. Tinatanggal namin ang lahat ng panuntunan at nagdaragdag kami ng iisang panuntunan gamit ang Wildcard * na may karapatang itulak at pagsamahin lang para sa mga user na may tungkuling Mga Tagapag-maintain. Gagana ang panuntunang ito para sa lahat ng user ng proyektong ito at sa pangkat kung saan kabilang ang proyektong ito.
Kung mayroong ilang mga tagapangasiwa, kung gayon ang pinakamahusay na solusyon ay ang paghigpitan ang pag-access sa proyekto sa prinsipyo.
Pumunta sa proyekto -> Mga Setting -> Pangkalahatan -> Visibility, mga tampok ng proyekto, mga pahintulot at itakda ang visibility ng Project sa pribado.
Mayroon akong proyekto sa pampublikong pag-access, dahil ginagamit ko ang aking sariling GitLab Runner at ako lang ang may access upang baguhin ang repositoryo. Sa totoo lang, wala sa aking interes na magpakita ng pribadong impormasyon sa mga pampublikong pipeline log.
Paghigpit sa mga patakaran para sa pagbabago ng imbakan
Pumunta sa project -> Settings -> Repository -> Push Rules at itakda ang mga flag Restriction ng Committer, Suriin kung user ng GitLab ang may-akda. Inirerekomenda ko rin ang setting gumawa ng pagpirma, at itakda ang flag na Tanggihan ang mga hindi napirmahang commit.
Susunod, kailangan mong i-configure ang isang trigger upang magpatakbo ng mga gawain
Pumunta sa project -> Settings -> CI / CD -> Pipeline triggers at gumawa ng bagong trigger-token
Ang token na ito ay maaaring idagdag kaagad sa pangkalahatang configuration ng mga variable para sa isang pangkat ng mga proyekto.
Pumunta sa grupo -> Mga Setting -> CI / CD -> Mga Variable at magdagdag ng variable DEPLOY_TOKEN na may trigger-token sa halaga.
Inilalarawan ng seksyong ito ang configuration para sa pagpapatakbo ng mga gawain sa pag-deploy gamit ang native (Specific) at public (Shared) runner.
Tiyak na Runner
Gumagamit ako ng sarili kong mga runner, dahil una sa lahat ito ay maginhawa, mabilis, mura.
Para sa runner, inirerekomenda ko ang Linux VDS na may 1 CPU, 2 GB RAM, 20 GB HDD. Presyo ng isyu ~ 3000₽ bawat taon.
Ang runner ko
Para sa runner kinuha ko ang VDS 4 CPU, 4 GB RAM, 50 GB SSD. Nagkakahalaga ito ng ~11000₽ at hinding-hindi ito pinagsisihan.
Mayroon akong kabuuang 7 makina. 5 sa aruba at 2 sa ihor.
Kaya, mayroon kaming isang runner. Ngayon ay ise-set up natin ito.
Pumunta kami sa makina sa pamamagitan ng SSH at i-install ang java, git, maven, gnupg2.
Gumawa ng direktoryo para sa maven cache at magtalaga ng mga karapatan ng grupo runner
Maaari mong laktawan ang hakbang na ito kung hindi mo planong magpatakbo ng maraming runner sa parehong makina.
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!
Suriin na ang runner ay nakarehistro. Pumunta sa gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners activated para sa proyektong ito
Bumubuo kami ng isang susi sa pamamagitan ng pagsagot sa mga tanong. Ginamit ko ang sarili kong pangalan at email.
Tiyaking tukuyin ang password para sa susi. Ang mga artifact ay pipirmahan gamit ang key na ito.
gpg --gen-key
Suriin
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
Pag-upload ng aming pampublikong susi sa keyserver
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Pumunta kami sa ilalim ng gumagamit gitlab-deployer
su gitlab-deployer
Lumikha ng isang direktoryo ng maven repositoryo at mag-link sa cache (huwag magkamali)
Maaaring laktawan ang hakbang na ito kung hindi mo planong magpatakbo ng ilang runner sa parehong makina.
Una sa lahat, kailangan mong lumikha ng GPG key. Upang gawin ito, i-install ang gnupg.
yum install -y gnupg
Bumubuo kami ng isang susi sa pamamagitan ng pagsagot sa mga tanong. Ginamit ko ang sarili kong pangalan at email. Tiyaking tukuyin ang password para sa susi.
Pumunta sa mga setting ng proyekto -> Mga Setting -> CI / CD -> Mga Variable at i-save sa isang variable SETTINGS_SECURITY_XML ang mga sumusunod na linya:
Gumagawa kami ng medyo simpleng Dockerfile para magpatakbo ng mga gawain sa pag-deploy gamit ang gustong bersyon ng Java. Nasa ibaba ang isang halimbawa para sa 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/
Idagdag ang .gitlab-ci.yml file sa root ng deploy project
Ang script ay nagpapakita ng dalawang eksklusibong gawain sa pag-deploy. Tukoy na Runner o Shared Runner ayon sa pagkakabanggit.
.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
Sa mga proyektong java na dapat i-upload sa mga pampublikong repositoryo, kailangan mong magdagdag ng 2 hakbang upang i-download ang mga bersyon ng Release at Snapshot.
.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}
Sa solusyon na ito, lumayo pa ako nang kaunti at nagpasyang gumamit ng isang template ng CI para sa mga proyektong java.
Higit pang mga detalye
Gumawa ako ng isang hiwalay na proyekto gitlab-ci kung saan inilagay niya ang template ng CI para sa mga proyekto ng java karaniwan.yml.
Nag-i-install ng mga module sa lokal na imbakan.
Napaka-kapaki-pakinabang para sa lokal na pag-verify ng mga solusyon sa iba pang mga proyekto, pati na rin ang checksum.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-project</id>
<!-- Если у вас многомодульный проект с деплоем родительского помика -->
<phase>install</phase>
<!-- Явно указываем файлы для локальной установки -->
<configuration>
<file>target/${project.artifactId}-${project.version}.jar</file>
```target/${project.artifactId}-${project.version}-sources.jar</sources>
<pomFile>dependency-reduced-pom.xml</pomFile>
<!-- Принудительное обновление метаданных проекта -->
<updateReleaseInfo>true</updateReleaseInfo>
<!-- Контрольные суммы для проверки целостности -->
<createChecksum>true</createChecksum>
</configuration>
</execution>
</executions>
</plugin>
<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>
Kung mayroon kang isang module na hindi naglalaman ng java (halimbawa, mga mapagkukunan lamang)
O hindi mo nais na bumuo ng javadoc sa prinsipyo, pagkatapos ay tumulong maven-jar-plugin
Kung mayroon kang multi-module na proyekto, at hindi mo kailangang mag-upload ng isang partikular na module sa repositoryo, kailangan mong magdagdag sa pom.xml ng module na ito nexus-staging-maven-plugin may bandila skipNexusStagingDeployMojo
Pagkatapos mag-upload ng snapshot/release na mga bersyon ay available sa mga pagtatanghal ng dula
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Higit pang mga plus
Isang napakaraming listahan ng mga target para sa pagtatrabaho sa nexus repository (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Awtomatikong release check para sa downloadability sa maven central
Kapag naitakda ang tag, awtomatikong ma-trigger ang kaukulang gawain sa proyekto sa pag-deploy upang i-upload ang bersyon ng release sa nexus (halimbawa).
Ang pinakamagandang bahagi ay ang malapit na release ay awtomatikong nagti-trigger sa 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] ------------------------------------------------------------------------
At kung may nangyaring mali, mabibigo ang gawain
[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] ------------------------------------------------------------------------
Bilang isang resulta, tayo ay naiwan na may isang pagpipilian lamang. O tanggalin ang bersyon na ito o i-publish.
Pagkatapos ng paglabas, pagkaraan ng ilang oras, ilalagay ang mga artifact
wala sa pinaguusapan
Ito ay isang paghahayag sa akin na ang maven ay nag-index ng iba pang mga pampublikong repositoryo.
Kinailangan kong mag-upload ng robots.txt dahil na-index nito ang aking lumang repository.
Isang hiwalay na proyekto sa pag-deploy kung saan maaari kang magpatupad ng ilang mga gawain sa CI para sa pag-upload ng mga artifact sa mga pampublikong repositoryo para sa iba't ibang wika ng pag-unlad.
Ang proyekto sa pag-deploy ay nakahiwalay mula sa panghihimasok sa labas at maaari lamang baguhin ng mga user na may mga tungkuling May-ari at Tagapamahala.
Isang hiwalay na Specific Runner na may "mainit" na cache upang patakbuhin lamang ang mga gawain sa pag-deploy.
Paglalathala ng mga bersyon ng snapshot/release sa isang pampublikong repositoryo.
Awtomatikong suriin ang bersyon ng release para sa kahandaan para sa publikasyon sa maven central.
Proteksyon laban sa awtomatikong paglalathala ng "raw" na mga bersyon sa maven central.
Bumuo at mag-publish ng mga bersyon ng snapshot "sa pag-click".
Isang imbakan para sa pagkuha ng mga bersyon ng snapshot/release.
Pangkalahatang pipeline para sa pagbuo / pagsubok / pag-publish ng isang java project.
Ang pag-set up ng GitLab CI ay hindi kasing kumplikado ng isang paksa na tila sa unang tingin. Ito ay sapat na upang i-set up ang CI sa isang turnkey na batayan ng ilang beses, at ngayon ay malayo ka sa isang baguhan sa bagay na ito. Bukod dito, ang dokumentasyon ng GitLab ay napakalabis. Huwag matakot na gawin ang unang hakbang. Lumilitaw ang kalsada sa ilalim ng mga hakbang ng taong naglalakad (hindi ko matandaan kung sino ang nagsabi nito :)
Ako ay magiging masaya sa feedback.
Sa susunod na artikulo, ipapakita ko sa iyo kung paano i-set up ang GitLab CI upang patakbuhin ang mga gawain sa pagsubok sa pagsasama nang mapagkumpitensya (pagpapatakbo ng mga serbisyo ng pagsubok na may docker-compose) kung mayroon ka lamang isang shell runner.