Nyetél GitLab CI pikeun unggah proyék java ka maven central
Artikel ieu dimaksudkeun pikeun pamekar java anu kudu gancang nyebarkeun produk maranéhna pikeun sonatype na / atawa maven repositories sentral maké GitLab. Dina artikel ieu, kuring bakal ngobrol ngeunaan nyetel gitlab-runner, gitlab-ci jeung maven-plugin pikeun ngajawab masalah ieu.
Prasyarat:
Panyimpenan aman tina mvn sareng konci GPG.
Palaksanaan aman tina tugas CI publik.
Ngunggah artefak (release/snapshot) ka repositori umum.
Pariksa otomatis versi release pikeun publikasi dina maven sentral.
Solusi umum pikeun unggah artefak ka gudang pikeun sababaraha proyék.
Katerangan lengkep ngeunaan mékanisme pikeun nyebarkeun artefak ka Maven Central via Sonatype OSS Repository Hosting Service parantos dijelaskeun dina Artikel ieu pamaké Googolplex, janten kuring bakal ngarujuk kana tulisan ieu dina tempat anu leres.
Pra-pendaptaran di Sonatype JIRA sareng ngamimitian tikét pikeun muka gudang (pikeun langkung rinci, baca bagian éta Jieun tikét Sonatype JIRA). Saatos muka gudang, pasangan login / sandi JIRA (saterusna disebut akun Sonatype) bakal dipaké pikeun unggah artefak kana Sonatype nexus.
Upami anjeun nganggo konsol Linux pikeun ngahasilkeun konci GPG (gnupg/gnupg2), maka anjeun kedah pasang. rng-parabot pikeun ngahasilkeun éntropi. Upami teu kitu, generasi konci tiasa nyandak waktos anu pohara lila.
Anu mimiti, anjeun kedah nyiptakeun sareng ngonpigurasikeun proyék dimana pipa bakal disimpen pikeun panyebaran artefak. Kuring nyauran proyék kuring saderhana sareng teu rumit - nyebarkeun
Saatos nyiptakeun gudang, anjeun kedah ngabatesan aksés pikeun ngarobih gudang.
Pindah ka proyék -> Setélan -> Repositori -> Cabang Dilindungan. Kami ngahapus sadaya aturan sareng nambihan aturan tunggal sareng Wildcard * kalayan hak nyorong sareng ngagabung ngan pikeun pangguna anu ngagaduhan peran Maintainers. Aturan ieu bakal dianggo pikeun sadaya pangguna tina proyék ieu sareng grup dimana proyék ieu milik.
Upami aya sababaraha pangropéa, maka solusi anu pangsaéna nyaéta ngabatesan aksés kana proyék sacara prinsip.
Pindah ka proyék -> Setélan -> Umum -> Visibilitas, fitur proyék, idin tur nyetel pisibilitas Project ka wasta.
Kuring boga proyék di aksés umum, saprak kuring make sorangan GitLab runner na ngan kuring boga aksés ka ngaropéa Repository nu. Nya, saleresna sanés kapentingan kuring pikeun nunjukkeun inpormasi pribadi dina log pipa umum.
Tightening aturan pikeun ngarobah Repository nu
Pindah ka proyék -> Setélan -> Repository -> Aturan Push tur nyetel umbul larangan Committer, Pariksa naha pangarang téh pamaké GitLab. Kuring ogé nyarankeun setelan komitmen Signing, tur nyetel Bandéra commits Tolak unsigned.
Salajengna, anjeun kedah ngonpigurasikeun pemicu pikeun ngajalankeun tugas
Pindah ka proyék -> Setélan -> CI / CD -> Pipeline micu sareng jieun pemicu-token énggal
token Ieu bisa langsung ditambahkeun kana konfigurasi umum variabel pikeun grup proyék.
Pindah ka grup -> Setélan -> CI / CD -> Variabel sareng tambahkeun variabel DEPLOY_TOKEN kalawan pemicu-token dina nilai.
bagian ieu ngajelaskeun konfigurasi pikeun ngajalankeun tugas on nyebarkeun maké pribumi (spésifik) jeung umum (dibagikeun) runner.
Runner husus
Kuring make runners sorangan, sabab mimitina éta merenah, gancang, mirah.
Pikeun runner I nyarankeun Linux Ubuntu VDS kalawan 1 CPU, 2 GB RAM, 20 GB HDD. Harga ngaluarkeun ~ 3000₽ per taun.
Lumpat kuring
Pikeun runner I nyandak VDS 4 CPU, 4 GB RAM, 50 GB SSD. Éta hargana ~ 11000₽ sareng henteu kantos kuciwa.
Kuring boga total 7 mesin. 5 on aruba jeung 2 on ihor.
Janten, urang gaduh runner. Ayeuna urang bakal nyetél éta.
Urang buka mesin via SSH tur masang java, git, maven, gnupg2.
Jieun diréktori pikeun cache maven jeung napelkeun hak grup runner
Anjeun tiasa ngalangkungan léngkah ieu upami anjeun henteu ngarencanakeun ngajalankeun sababaraha pelari dina mesin anu sami.
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!
Pariksa yén runner kadaptar. Buka gitlab.com -> deploy-project -> Setélan -> CI/CD -> Runners -> Runners Spésifik -> Runners diaktipkeun pikeun proyék ieu
Urang ngahasilkeun konci ku ngajawab patarosan. Kuring nganggo nami sareng email kuring sorangan.
Pastikeun pikeun nangtukeun sandi pikeun konci. Artefak bakal ditandatanganan ku konci ieu.
gpg --gen-key
Cék
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
Unggah konci publik kami ka keyserver
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Jieun diréktori maven Repository sareng numbu sareng cache (teu salah)
Léngkah ieu tiasa dilewatan upami anjeun henteu ngarencanakeun ngajalankeun sababaraha pelari dina mesin anu sami.
Kami nyiptakeun Dockerfile anu cukup saderhana pikeun ngajalankeun tugas dina nyebarkeun sareng versi Java anu dipikahoyong. Di handap ieu conto pikeun 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/
Tambahkeun file .gitlab-ci.yml kana akar proyék nyebarkeun
Skrip nampilkeun dua tugas panyebaran anu saling ekslusif. Runner Spésifik atanapi Runner Dibagi masing-masing.
.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
Topik ieu dijelaskeun sacara rinci. Googolplex в Nyetel maven pikeun otomatis asup sareng unggah artefak kana snapshot sareng repositori pementasan, Jadi kuring bakal ngajelaskeun sababaraha nuansa ngagunakeun plugins. Kuring ogé bakal ngajelaskeun kumaha gampang sareng alami anjeun tiasa dianggo nexus-staging-maven-pluginupami anjeun henteu hoyong atanapi henteu tiasa nganggo org.sonatype.oss:oss-parent salaku indungna pikeun proyék anjeun.
maven-install-plugin
Masang modul kana gudang lokal.
Mangpaat pisan pikeun verifikasi lokal solusi dina proyék séjén, kitu ogé checksum a.
<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>
Upami anjeun gaduh modul anu henteu ngandung java (upamana ngan ukur sumber daya)
Atanapi anjeun henteu hoyong ngahasilkeun javadoc prinsipna, teras ngabantosan maven-jar-plugin
Upami anjeun gaduh proyék multi-modul, sareng anjeun henteu kedah unggah modul khusus kana gudang, teras anjeun kedah nambihan kana pom.xml modul ieu. nexus-staging-maven-plugin kalawan bandéra skipNexusStagingDeployMojo
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Langkung pluss
Daptar udagan anu beunghar pikeun damel sareng gudang nexus (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Pariksa release otomatis pikeun downloadability di maven sentral
Nalika tag disetel, tugas anu saluyu dina proyék panyebaran otomatis dipicu pikeun unggah versi pelepasan ka Nexus (conto).
Bagian anu pangsaéna nyaéta sékrési nutup sacara otomatis micu dina 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] ------------------------------------------------------------------------
Sareng upami aya anu salah, maka tugasna bakal gagal
[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] ------------------------------------------------------------------------
Hasilna, urang tinggaleun ngan hiji pilihan. Atawa pupus versi ieu atawa nyebarkeun.
Saatos dileupaskeun, saatos sababaraha waktos, artefak bakal aya
offtopic
Ieu wahyu ka abdi nu maven indexes repositories publik lianna.
Kuring kungsi unggah robots.txt sabab saestuna Repository heubeul kuring.
Proyék panyebaran anu kapisah dimana anjeun tiasa ngalaksanakeun sababaraha tugas CI pikeun unggah artefak ka repositori umum pikeun sababaraha basa pangembangan.
Proyék panyebaran diisolasi tina gangguan luar sareng ngan ukur tiasa dirobih ku pangguna anu ngagaduhan peran Pamilik sareng Pangurus.
Runner spésifik anu misah sareng cache "panas" pikeun ngajalankeun ngan ukur nyebarkeun tugas.
Publikasi vérsi snapshot/release dina gudang umum.
Pariksa otomatis versi release pikeun kesiapan pikeun publikasi dina maven sentral.
Perlindungan ngalawan publikasi otomatis tina versi "atah" dina maven sentral.
Ngawangun sareng nyebarkeun versi snapshot "dina klik".
Repositori tunggal pikeun kéngingkeun vérsi snapshot/release.
Pipa umum pikeun ngawangun / nguji / nyebarkeun proyék java.
Nyetél GitLab CI sanés pajeulit topik sapertos anu sigana di glance kahiji. Cukup pikeun nyetél CI dina dasar turnkey sababaraha kali, sareng ayeuna anjeun jauh ti amatir dina masalah ieu. Leuwih ti éta, dokuméntasi GitLab pisan kaleuleuwihan. Tong sieun nyandak léngkah munggaran. Jalan némbongan handapeun undak-usuk jalma anu leumpang (kuring henteu émut saha anu nyariosna :)
Kuring bakal bungah eupan balik.
Dina artikel salajengna, kuring bakal nunjukkeun anjeun kumaha nyetél GitLab CI pikeun ngajalankeun tugas uji integrasi sacara kompetitif (ngajalankeun jasa uji sareng docker-compose) upami anjeun ngan ukur gaduh hiji cangkang runner.