GitLab CI-ի կարգավորում՝ java նախագիծ maven central-ում վերբեռնելու համար
Այս հոդվածը նախատեսված է Java ծրագրավորողների համար, ովքեր պետք է արագ հրապարակեն իրենց արտադրանքը sonatype և/կամ maven կենտրոնական պահեստներում՝ օգտագործելով GitLab: Այս հոդվածում ես կխոսեմ այս խնդիրը լուծելու համար gitlab-runner, gitlab-ci և maven-plugin ստեղծման մասին:
Նախադրյալներ.
mvn և GPG ստեղների անվտանգ պահպանում:
Հանրային CI-ի առաջադրանքների անվտանգ կատարում:
Արտեֆակտների վերբեռնում (թողարկում/պատկերված նկար) հանրային պահեստներ:
Maven Central-ում հրապարակման համար թողարկման տարբերակների ավտոմատ ստուգում:
Ընդհանուր լուծում մի քանի նախագծերի համար արտեֆակտներ պահեստարան վերբեռնելու համար:
Sonatype OSS Repository Hosting ծառայության միջոցով Maven Central-ում արտեֆակտների հրապարակման մեխանիզմի մանրամասն նկարագրությունը արդեն նկարագրված է. այս հոդվածը օգտվող Գուգոլպլեքս, ուստի այս հոդվածին կանդրադառնամ ճիշտ տեղերում։
Նախապես գրանցվել՝ հասցեով Sonatype JIRA և սկսեք տոմս բացել պահեստը (ավելի մանրամասն, կարդացեք բաժինը Ստեղծեք Sonatype JIRA տոմս) Պահեստը բացելուց հետո JIRA մուտքի/գաղտնաբառի զույգը (այսուհետ՝ Sonatype հաշիվ) կօգտագործվի արտեֆակտները Sonatype nexus-ում վերբեռնելու համար:
Եթե դուք օգտագործում եք Linux կոնսոլը GPG ստեղն ստեղծելու համար (gnupg/gnupg2), ապա պետք է տեղադրել rng գործիքներ էնտրոպիա առաջացնել։ Հակառակ դեպքում, բանալիների ստեղծումը կարող է շատ երկար տևել:
Առաջին հերթին, դուք պետք է ստեղծեք և կազմաձևեք մի նախագիծ, որում խողովակաշարը կպահվի արտեֆակտների տեղակայման համար: Ես իմ նախագիծն անվանեցի պարզ և ոչ բարդ, տեղակայել
Պահեստը ստեղծելուց հետո անհրաժեշտ է սահմանափակել մուտքը՝ պահեստը փոխելու համար:
Գնացեք նախագիծ -> Պարամետրեր -> Պահեստ -> Պաշտպանված մասնաճյուղեր: Մենք ջնջում ենք բոլոր կանոնները և ավելացնում ենք մեկ կանոն Wildcard *-ի միջոցով՝ սեղմելու և միաձուլելու իրավունքով միայն Maintainers դեր ունեցող օգտատերերի համար: Այս կանոնը կգործի ինչպես այս նախագծի, այնպես էլ այն խմբի համար, որին պատկանում է այս նախագիծը:
Եթե կան մի քանի սպասարկողներ, ապա լավագույն լուծումը կլինի սկզբունքորեն սահմանափակել մուտքը նախագծին:
Գնացեք նախագիծ -> Կարգավորումներ -> Ընդհանուր -> Տեսանելիություն, ծրագրի առանձնահատկություններ, թույլտվություններ և դրեք Ծրագրի տեսանելիությունը: Անձնական.
Ես հանրային հասանելիության նախագիծ ունեմ, քանի որ ես օգտագործում եմ իմ սեփական GitLab Runner-ը և միայն ինձ հասանելի է պահոցը փոփոխելու համար: Դե, իրականում իմ շահերից չի բխում մասնավոր տեղեկությունները ցուցադրել հանրային խողովակաշարերի տեղեկամատյաններում:
Պահեստը փոխելու կանոնների խստացում
Գնացեք նախագիծ -> Settings -> Repository -> Push Rules և սահմանեք դրոշները Committer-ի սահմանափակում, Ստուգեք, արդյոք հեղինակը GitLab-ի օգտվող է: Ես նաև խորհուրդ եմ տալիս կարգավորել պարտավորվում է ստորագրել, և սահմանեք Մերժել անստորագիր պարտավորությունների դրոշակը:
Հաջորդը, դուք պետք է կարգավորեք ձգան առաջադրանքները գործարկելու համար
Գնացեք նախագիծ -> Կարգավորումներ -> CI / CD -> Խողովակաշարի գործարկիչներ և ստեղծեք նոր գործարկիչ նշան:
Այս նշանը կարող է անմիջապես ավելացվել մի խումբ նախագծերի փոփոխականների ընդհանուր կազմաձևում:
Գնացեք խումբ -> Պարամետրեր -> CI / CD -> Փոփոխականներ և ավելացրեք փոփոխական DEPLOY_TOKEN արժեքի մեջ ձգանման նշանով:
Այս բաժինը նկարագրում է տեղակայման ժամանակ առաջադրանքների կատարման կոնֆիգուրացիան՝ օգտագործելով բնիկ (Հատուկ) և հանրային (Համօգտագործվող) վազող:
Հատուկ վազորդ
Ես օգտագործում եմ իմ սեփական վազորդները, քանի որ դա առաջին հերթին հարմար է, արագ, էժան։
Runer-ի համար ես առաջարկում եմ Linux VDS 1 պրոցեսորով, 2 ԳԲ օպերատիվ հիշողությամբ, 20 ԳԲ HDD-ով: Թողարկման գինը տարեկան ~ 3000₽:
Իմ վազորդը
Վազողի համար վերցրեցի VDS 4 պրոցեսոր, 4 ԳԲ օպերատիվ հիշողություն, 50 ԳԲ SSD: Այն արժեր ~ 11000₽ և երբեք չփոշմանեցի դրա համար:
Ընդհանուր 7 մեքենա ունեմ։ 5-ը արուբայի վրա և 2-ը՝ ihor-ի վրա:
Այսպիսով, մենք ունենք վազորդ: Այժմ մենք այն կտեղադրենք:
Մենք գնում ենք մեքենա SSH-ի միջոցով և տեղադրում java, git, maven, gnupg2:
Ստեղծեք գրացուցակ maven cache-ի համար և նշանակեք խմբի իրավունքները runner
Դուք կարող եք բաց թողնել այս քայլը, եթե չեք ծրագրում մի քանի վազորդներ գործարկել նույն մեքենայի վրա:
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!
Ստուգեք, որ վազորդը գրանցված է: Գնացեք gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners ակտիվացված այս նախագծի համար:
Մենք ստեղծում ենք բանալին՝ պատասխանելով հարցերին: Ես օգտագործել եմ իմ սեփական անունը և էլ.
Համոզվեք, որ նշեք բանալին բանալին: Արտեֆակտները կստորագրվեն այս բանալիով:
gpg --gen-key
Ստուգեք
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
Մեր հանրային բանալին բեռնում է բանալիների սերվեր
gpg --keyserver keys.gnupg.net --send-key 00000000
gpg: sending key 00000000 to hkp server keys.gnupg.net
Ստեղծեք maven գրացուցակ շտեմարան և կապել քեշի հետ (մի սխալվեք)
Այս քայլը կարելի է բաց թողնել, եթե դուք չեք նախատեսում մի քանի վազորդներ գործարկել նույն մեքենայի վրա:
Ավելացրեք .gitlab-ci.yml ֆայլը տեղակայման նախագծի արմատին
Սցենարը ներկայացնում է երկու միմյանց բացառող տեղակայման առաջադրանքներ: Specific Runner կամ Shared 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
Java նախագծերում, որոնք ենթադրաբար պետք է վերբեռնվեն հանրային պահեստներ, դուք պետք է ավելացնեք 2 քայլ՝ Release և 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}
Այս լուծման մեջ ես մի փոքր առաջ գնացի և որոշեցի օգտագործել մեկ CI ձևանմուշ java նախագծերի համար:
Մանրամասները
Ստեղծեցի առանձին նախագիծ gitlab-ci որում նա տեղադրեց CI կաղապարը java նախագծերի համար ընդհանուր.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>
Եթե ունեք մոդուլ, որը չի պարունակում java (օրինակ՝ միայն ռեսուրսներ)
Կամ դուք չեք ուզում սկզբունքորեն javadoc գեներացնել, հետո օգնել maven-jar-plugin
Եթե դուք ունեք բազմամոդուլային նախագիծ, և ձեզ հարկավոր չէ հատուկ մոդուլ վերբեռնել պահեստարան, ապա պետք է ավելացնեք այս մոդուլի pom.xml-ին: nexus-staging-maven-plugin դրոշով skipNexusStagingDeployMojo
Պատկերի/թողարկման տարբերակները բեռնելուց հետո հասանելի են բեմադրող պահոցներ
<repositories>
<repository>
<id>SonatypeNexus</id>
<url>https://oss.sonatype.org/content/groups/staging/</url>
<!-- Не надо указывать флаги snapshot/release для репозитория -->
</repository>
</repositories>
Ավելի շատ առավելություններ
Nexus պահեստի հետ աշխատելու թիրախների շատ հարուստ ցանկ (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
Ավտոմատ թողարկման ստուգում maven Central-ում ներբեռնման համար
Երբ պիտակը սահմանվում է, տեղակայման նախագծի համապատասխան առաջադրանքը ավտոմատ կերպով գործարկվում է թողարկման տարբերակը ներբեռնելու համար nexus (օրինակ).
Լավագույնն այն է, որ փակ թողարկումը ավտոմատ կերպով գործարկվում է 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] ------------------------------------------------------------------------
Եվ եթե ինչ-որ բան սխալ է տեղի ունեցել, ապա խնդիրը չի հաջողվի
[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] ------------------------------------------------------------------------
Արդյունքում մեզ մնում է միայն մեկ ընտրություն. Կամ ջնջեք այս տարբերակը կամ հրապարակեք:
Թողարկումից հետո որոշ ժամանակ անց արտեֆակտները կլինեն
թեմայից դուրս
Ինձ համար բացահայտում էր, որ maven-ը ինդեքսավորում է այլ հանրային պահեստներ:
Ես ստիպված էի վերբեռնել robots.txt-ը, քանի որ այն ինդեքսավորեց իմ հին պահեստը:
Առանձին տեղակայման նախագիծ, որում դուք կարող եք իրականացնել մի քանի CI առաջադրանքներ՝ արտեֆակտները ներբեռնելու տարբեր մշակման լեզուների հանրային պահեստներ:
Տեղակայման նախագիծը մեկուսացված է արտաքին միջամտությունից և կարող է փոփոխվել միայն սեփականատեր և սպասարկող դերերով օգտվողների կողմից:
Առանձին Specific Runner՝ «թեժ» քեշով՝ միայն առաջադրանքների տեղակայման համար:
Պատկերի/թողարկման տարբերակների հրապարակում հանրային պահոցում:
Թողարկման տարբերակի ավտոմատ ստուգում Maven Central-ում հրապարակման պատրաստ լինելու համար:
Կառուցեք և հրապարակեք ակնթարթային տարբերակները «սեղմումով»:
Մեկ պահոց՝ լուսապատկերների/թողարկման տարբերակներ ստանալու համար:
Ընդհանուր խողովակաշար java նախագծի կառուցման / փորձարկման / հրապարակման համար:
GitLab CI-ի կարգավորումն այնքան էլ բարդ թեմա չէ, որքան թվում է առաջին հայացքից: Բավական է մի քանի անգամ CI-ն կարգավորել բանտապահով, և այժմ դուք հեռու եք այս հարցում սիրողական լինելուց: Ավելին, GitLab-ի փաստաթղթերը շատ ավելորդ են: Մի վախեցեք առաջին քայլն անել. Ճանապարհը հայտնվում է քայլող մարդու քայլերի տակ (չեմ հիշում, թե ով է ասել :)
Ես ուրախ կլինեմ արձագանքել:
Հաջորդ հոդվածում ես ձեզ ցույց կտամ, թե ինչպես կարգավորել GitLab CI-ն, որպեսզի մրցակցային կերպով կատարի ինտեգրման թեստային առաջադրանքները (փորձարկման ծառայություններ docker-compose-ով), եթե ունեք միայն մեկ shell runner: