Questo articolo è destinato agli sviluppatori Java che hanno bisogno di pubblicare rapidamente i propri prodotti nei repository di Sonatype e/o Maven Central utilizzando GitLab. In questo articolo parlerò della configurazione di gitlab-runner, gitlab-ci e del plugin Maven per affrontare questa esigenza.
Prerequisiti:
- Archiviazione sicura delle chiavi mvn e GPG.
- Esecuzione sicura delle attività CI pubbliche.
- Caricamento di artefatti (release/snapshot) nei repository pubblici.
- Controllo automatico delle versioni release per la pubblicazione su Maven Central.
- Soluzione generale per il caricamento degli artefatti nel repository per più progetti.
- Semplicità e facilità d'uso.
Contenuto
Informazioni generali
- Una descrizione dettagliata del meccanismo di pubblicazione degli artefatti su Maven Central tramite il Servizio di Hosting dei Repository OSS di Sonatype è già stata trattata in da parte dell'utente , quindi nei punti necessari farò riferimento a questo articolo.
- Precedentemente ci si registra in e si apre un ticket per la creazione del repository (dettagli su come fare nella sezione ). Dopo l'apertura del repository, la coppia login/password di JIRA (di seguito conto Sonatype) sarà utilizzata per caricare gli artefatti in Sonatype nexus.
- Il processo di generazione della chiave GPG è descritto in modo piuttosto asciutto. Per maggiori dettagli consultare la sezione
- Se si utilizza il terminale Linux per generare la chiave GPG (gnupg/gnupg2), è necessario installare per generare entropia. Altrimenti, la generazione della chiave potrebbe richiedere molto tempo.
- Servizi di archiviazione pubblica chiavi GPG
Configurazione del progetto di deploy in GitLab
- Per prima cosa, è necessario creare e configurare un progetto in cui verrà memorizzato il pipeline per il deploy degli artefatti. Ho chiamato il mio progetto in modo semplice e diretto —
- Dopo aver creato il repository, è necessario limitare l'accesso alla modifica del repository.
Si passa a progetto → Impostazioni → Repository → Branch protetti. Si rimuovono tutte le regole e si aggiunge una singola regola con Wildcard * con diritto di push e merge solo per gli utenti con ruolo di Maintainers. Questa regola funzionerà per tutti gli utenti sia di questo progetto che del gruppo a cui questo progetto appartiene.
- Se ci sono più manutentori, la soluzione migliore è limitare l'accesso al progetto in generale.
Andiamo su progetto -> Impostazioni -> Generali -> Visibilità, funzionalità del progetto, permessi e impostiamo la visibilità del progetto su Privato.
Il mio progetto è accessibile pubblicamente, dato che utilizzo un GitLab Runner personale e solo io ho accesso per modificare il repository. Inoltre, non mi interessa rendere pubbliche informazioni riservate nei log dei pipeline pubblici. - Inasprimento delle regole per la modifica del repository
Andiamo su progetto -> Impostazioni -> Repository -> Regole di push e attiviamo i flag Restrizione del committente, Controlla se l'autore è un utente di GitLab. Raccomando anche di configurare , e di attivare il flag Rifiuta commit non firmati. - Successivamente, è necessario configurare un trigger per avviare i task
Andiamo su progetto -> Impostazioni -> CI / CD -> Trigger dei pipeline e creiamo un nuovo token di trigger
Questo token può essere immediatamente aggiunto alla configurazione generale delle variabili per il gruppo di progetti.
Andiamo su gruppo -> Impostazioni -> CI / CD -> Variabili e aggiungiamo la variabileDEPLOY_TOKENcon il valore del token di trigger.
GitLab Runner
In questa sezione è descritta la configurazione per l'esecuzione dei task di deploy utilizzando un runner personale (Specific) e un runner pubblico (Shared).
Runner specifico
Utilizzo runner personali, poiché è innanzitutto conveniente, veloce ed economico.
Per il runner consiglio un VDS Linux con 1 CPU, 2 GB di RAM, 20 GB di HDD. Il costo è di circa 3000₽ all'anno.
Il mio runner
Per il runner ho scelto un VDS con 4 CPU, 4 GB di RAM e 50 GB di SSD. È costato circa 11000₽ e non me ne sono mai pentito.
Ho un totale di 7 macchine. 5 su Aruba e 2 su Ihor.
Quindi, abbiamo un runner. Ora lo configureremo.
Accedi alla macchina tramite SSH e installa java, git, maven, gnupg2.
Installa il gitlab runner
- Crea un nuovo gruppo
runnersudo groupadd runner - Crea una directory per la cache di maven e assegna i permessi al gruppo
runner
Questo passaggio può essere saltato se non si prevede di eseguire più runner sulla stessa macchina.mkdir -p /usr/cache/.m2/repository chown -R :runner /usr/cache chmod -R 770 /usr/cache - Creiamo un utente
gitlab-deployere aggiungilo al grupporunneruseradd -m -d /home/gitlab-deployer gitlab-deployer usermod -a -G runner gitlab-deployer - Aggiungi nel file
/etc/ssh/sshd_configla seguente rigaAllowUsers root@* gitlab-deployer@127.0.0.1 - Riavvia
Il client SSH e i programmisystemctl restart sshd - Imposta una password per l'utente
gitlab-deployer(può essere semplice, poiché c'è una restrizione per localhost)passwd gitlab-deployer - Installa GitLab Runner (Linux x86-64)
sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64 sudo chmod +x /usr/local/bin/gitlab-runner ln -s /usr/local/bin/gitlab-runner /etc/alternatives/gitlab-runner ln -s /etc/alternatives/gitlab-runner /usr/bin/gitlab-runner - Andiamo sul sito gitlab.com -> deploy-project -> Impostazioni -> CI/CD -> Runners -> Runners Specifici e copiamo il token di registrazione
Screenshot
- Registriamo il runner
gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml
Processo
Runtime platform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Esecuzione in modalità di sistema.
Inserire l'URL del coordinatore gitlab-ci (ad es. https://gitlab.com/):
https://gitlab.com/
Inserire il token gitlab-ci per questo runner:
REGISTRATION_TOKEN
Inserire la descrizione gitlab-ci per questo runner:
[ih1174328.vds.myihor.ru]: Deploy Runner
Inserire i tag gitlab-ci per questo runner (separati da virgola):
deploy
Registrazione del runner... riuscita runner=ZvKdjJhx
Inserire l'esecutore: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner registrato con successo. Sentiti libero di avviarlo, ma se è già in esecuzione, il config dovrebbe ricaricarsi automaticamente!- Verifichiamo che il runner sia registrato. Andiamo sul sito gitlab.com -> deploy-project -> Impostazioni -> CI/CD -> Runners -> Runners Specifici -> Runners attivati per questo progetto
Screenshot
- Aggiungiamo separato servizio
/etc/systemd/system/gitlab-deployer.service[Unit] Description=GitLab Deploy Runner After=syslog.target network.target ConditionFileIsExecutable=/usr/local/bin/gitlab-runner [Service] StartLimitInterval=5 StartLimitBurst=10 ExecStart=/usr/local/bin/gitlab-runner "run" "--working-directory" "/home/gitlab-deployer" "--config" "/etc/gitlab-runner/gitlab-deployer-config.toml" "--service" "gitlab-deployer" "--syslog" "--user" "gitlab-deployer" Restart=always RestartSec=120 [Install] WantedBy=multi-user.target - Avviamo il servizio.
systemctl enable gitlab-deployer.service systemctl start gitlab-deployer.service systemctl status gitlab-deployer.service - Verifichiamo che il runner sia in esecuzione.
Esempio
Generazione delle chiavi GPG
- Da questa macchina accediamo via ssh con l'utente
gitlab-deployer(Questo è importante per generare la chiave GPG)ssh gitlab-deployer@127.0.0.1 - Generiamo la chiave rispondendo alle domande. Ho usato il mio nome e la mia email.
Assicurati di specificare una password per la chiave. Questa chiave verrà utilizzata per firmare gli artefatti.gpg --gen-key - Controlliamo
gpg --list-keys -a /home/gitlab-deployer/.gnupg/pubring.gpg ---------------------------------------- pub 4096R/00000000 2019-04-19 uid Petruha Petrov sub 4096R/11111111 2019-04-19 - Carichiamo la nostra chiave pubblica sul server delle chiavi
gpg --keyserver keys.gnupg.net --send-key 00000000 gpg: invio della chiave 00000000 al server hkp keys.gnupg.net
Configurazione di Maven
- Accediamo con l'utente
gitlab-deployersu gitlab-deployer - Creiamo la directory maven repository e colliamola con la cache (non sbagliatevi)
Questo passaggio può essere saltato se non prevedi di eseguire più runner sulla stessa macchina.mkdir -p ~/.m2/repository ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository - Creiamo la chiave principale
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Creiamo il file ~/.m2/settings-security.xml
{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Cifriamo la password dell'account Sonatype
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Creiamo il file ~/.m2/settings.xml
env true GPG_SECRET_KEY_PASSPHRASE sonatype SONATYPE_USERNAME {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
dove,
GPG_SECRET_KEY_PASSPHRASE — password per la chiave GPG
SONATYPE_USERNAME — login dell'account Sonatype
A questo punto le impostazioni del runner sono complete, possiamo passare alla sezione
Runner condiviso
Generazione delle chiavi GPG
- In primo luogo, è necessario creare una chiave GPG. Per farlo, installiamo gnupg.
yum install -y gnupg - Generiamo la chiave rispondendo alle domande. Ho utilizzato il mio nome e indirizzo email. È fondamentale specificare una password per la chiave.
gpg --gen-key - Visualizziamo le informazioni sulla chiave
gpg --list-keys -a pub rsa3072 2019-04-24 [SC] [expires: 2021-04-23] 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 uid [ultimate] tttemp sub rsa3072 2019-04-24 [E] [expires: none] - Carichiamo la nostra chiave pubblica sul server delle chiavi
gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 gpg: invio della chiave 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 al server hkp keys.gnupg.net - Otteniamo la chiave privata
gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 -----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5 ... =2Wd2 -----END PGP PRIVATE KEY BLOCK----- - Andiamo alle impostazioni del progetto -> Settings -> CI / CD -> Variables e salviamo la chiave privata nella variabile
GPG_SECRET_KEY
Configurazione di Maven
- Creiamo la chiave principale
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Andiamo alle impostazioni del progetto -> Settings -> CI / CD -> Variables e salviamo nella variabile
SETTINGS_SECURITY_XMLle seguenti righe:{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Cifriamo la password dell'account Sonatype
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Andiamo alle impostazioni del progetto -> Settings -> CI / CD -> Variables e salviamo nella variabile
SETTINGS_XMLle seguenti righe:env true GPG_SECRET_KEY_PASSPHRASE sonatype sonatype_username {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
dove,
GPG_SECRET_KEY_PASSPHRASE — password per la chiave GPG
SONATYPE_USERNAME — login dell'account Sonatype
Deploy dell'immagine Docker
- Creiamo un Dockerfile abbastanza semplice per eseguire compiti di deploy con la versione appropriata di Java. Di seguito è riportato un esempio per 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/ - Compiliamo il contenitore per il tuo progetto
docker build -t registry.gitlab.com/group/deploy . - Autenticazione e caricamento del contenitore nel registro.
docker login -u USER -p PASSWORD registry.gitlab.com docker push registry.gitlab.com/group/deploy
GitLab CI
Deploy del progetto
Aggiungiamo il file .gitlab-ci.yml nella radice del progetto di deploy
Lo script presenta due attività di deploy escludenti. Specific Runner o Shared Runner rispettivamente.
.gitlab-ci.yml
stages:
- deploy
Specific Runner:
extends: .java_deploy_template
# L'attività verrà eseguita sul vostro shell-runner
tags:
- deploy
Shared Runner:
extends: .java_deploy_template
# L'attività verrà eseguita su un runner docker pubblico
tags:
- docker
# Immagine dalla sezione GitLab Runner -> Shared Runner -> Docker
image: registry.gitlab.com/group/deploy-project:latest
before_script:
# Importiamo la chiave GPG
- printf "${GPG_SECRET_KEY}" | gpg --batch --import
# Salviamo la configurazione di maven
- printf "${SETTINGS_SECURITY_XML}" > ~/ .m2/settings-security.xml
- printf "${SETTINGS_XML}" > ~/ .m2/settings.xml
.java_deploy_template:
stage: deploy
# L'attività scatta per trigger, se la variabile DEPLOY è uguale a java
only:
variables:
- $DEPLOY == "java"
variables:
# disabilitiamo il clone del progetto attuale
GIT_STRATEGY: none
script:
# Forniamo la possibilità di memorizzare la password in chiaro
- git config --global credential.helper store
# Salviamo le credenziali temporanee per l'utente gitlab-ci-token
# Il token funziona per tutti i progetti pubblici su gitlab.com e per i progetti di gruppo
- echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/ .git-credentials
# Puliamo completamente la directory corrente
- rm -rf .* *
# Cloniamo il progetto che andremo a deployare in Sonatype Nexus
- git clone ${DEPLOY_CI_REPOSITORY_URL} .
# Passiamo al commit necessario
- git checkout ${DEPLOY_CI_COMMIT_SHA} -f
# Se almeno un pom.xml contiene il parametro autoReleaseAfterClose abortiamo il build.
# Altrimenti c'è il rischio di caricare artefatti non completi nel maven central
- >
for pom in $(find . -name pom.xml); do
if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
echo "File $pom contiene un'impostazione vietata: ";
exit 1;
fi;
done
# Se il parametro DEPLOY_CI_COMMIT_TAG è vuoto, impostiamo forzatamente la versione 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
# Avviamo l'attività di build e deploy degli artefatti
- mvn clean deploy -DskipTests=trueProgetto Java
Nei progetti java che si prevede di caricare in repository pubblici è necessario aggiungere 2 passaggi per caricare le versioni Release e Snapshot.
.gitlab-ci.yml
fasi:
- build
- test
- verifica
- deploy
Rilascio:
estende: .trigger_deploy
# Eseguire il compito solo per tag.
only:
- tags
Snapshot:
estende: .trigger_deploy
# Eseguiamo il compito di pubblicazione della versione SNAPSHOT manualmente
when: manual
# Non eseguire il compito se è stato impostato un tag.
except:
- tags
.trigger_deploy:
fase: deploy
variabili:
# Disabilitiamo la clonazione del progetto attuale
GIT_STRATEGY: none
# Link al trigger del compito di deploy
URL: "https://gitlab.com/api/v4/projects//trigger/pipeline"
# Variabili del compito di 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:
# Non utilizzo cURL, poiché con i flag --fail --show-error
# non restituisce il corpo della risposta se il codice HTTP è 400 o superiore
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}In questa soluzione ho voluto andare un po' oltre e ho deciso di utilizzare un unico template CI per i progetti Java.
In dettaglio
Ho creato un progetto separato in cui ho posizionato il template CI per i progetti Java. .
common.yml
fasi:
- build
- test
- verifica
- deploy
variabili:
SONAR_ARGS: "
-Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA}
-Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}
"
.build_java_project:
fase: build
tags:
- touchbit-shell
variabili:
SKIP_TEST: "false"
script:
- mvn clean
- mvn package -DskipTests=${SKIP_TEST}
artifacts:
when: always
expire_in: 30 day
paths:
- "*\/target\/reports"
.build_sphinx_doc:
fase: build
tags:
- touchbit-shell
variabili:
DOCKERFILE: .indirect\/docs\/Dockerfile
script:
- docker build --no-cache -t ${CI_PROJECT_NAME}\/doc -f ${DOCKERFILE} .
.junit_module_test_run:
fase: test
tags:
- touchbit-shell
variabili:
MODULE: ""
script:
- cd ${MODULE}
- mvn test
artifacts:
when: always
expire_in: 30 day
paths:
- "*\/target\/reports"
.junit_test_run:
fase: test
tags:
- touchbit-shell
script:
- mvn test
artifacts:
when: always
expire_in: 30 day
paths:
- "*\/target\/reports"
.sonar_review:
fase: verifica
tags:
- touchbit-shell
dipendenze: []
script:
- >
if [ "$CI_BUILD_REF_NAME" == "master" ]; then
mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS
else
mvn compile sonar:sonar -Dsonar.login=$SONAR_LOGIN $SONAR_ARGS -Dsonar.analysis.mode=preview
fi
.trigger_deploy:
fase: deploy
tags:
- touchbit-shell
variabili:
URL: "https://gitlab.com/api/v4/projects/10345765/trigger/pipeline"
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:
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}
.trigger_release_deploy:
estende: .trigger_deploy
only:
- tags
.trigger_snapshot_deploy:
estende: .trigger_deploy
when: manual
except:
- tags
Pertanto, nei progetti java stessi, il file .gitlab-ci.yml appare piuttosto compatto e poco verboso.
.gitlab-ci.yml
include: https://gitlab.com/TouchBIT/gitlab-ci/raw/master/common.yml
Shields4J:
extends: .build_java_project
Sphinx doc:
extends: .build_sphinx_doc
variables:
DOCKERFILE: .docs/Dockerfile
Sonar review:
extends: .sonar_review
dependencies:
- Shields4J
Release:
extends: .trigger_release_deploy
Snapshot:
extends: .trigger_snapshot_deployConfigurazione di pom.xml
Questo argomento è descritto in modo molto dettagliato. in , quindi descriverò alcune sfumature nell'uso dei plugin. Descriverò anche quanto sia facile e semplice usarli. nexus-staging-maven-plugin, se non vuoi o non puoi usare org.sonatype.oss:oss-parent come genitore per il tuo progetto.
maven-install-plugin
Installa i moduli nel repository locale.
È molto utile per il controllo locale delle soluzioni in altri progetti, così come per il checksum.
org.apache.maven.plugins
maven-install-plugin
install-project
install
target/${project.artifactId}-${project.version}.jar
```target/${project.artifactId}-${project.version}-sources.jar
dependency-reduced-pom.xml
true
truemaven-javadoc-plugin
Generazione della javadoc per il progetto.
org.apache.maven.plugins
maven-javadoc-plugin
jar
prepare-package
true
true
falseSe hai un modulo che non contiene java (ad esempio solo risorse)
Oppure non vuoi in genere generare javadoc, ecco come procedere. maven-jar-plugin
org.apache.maven.plugins
maven-jar-plugin
empty-javadoc-jar
generate-resources
jar
javadoc
${basedir}/javadocmaven-gpg-plugin
org.apache.maven.plugins
maven-gpg-plugin
sign-artifacts
deploy
signnexus-staging-maven-plugin
Configurazione:
org.sonatype.plugins
nexus-staging-maven-plugin
org.sonatype.plugins
nexus-staging-maven-plugin
true
sonatype
https://oss.sonatype.org/
true
org.apache.maven.plugins
maven-deploy-plugin
true
sonatype
Repository Nexus Snapshot
https://oss.sonatype.org/content/repositories/snapshots/
sonatype
Repository Nexus Release
https://oss.sonatype.org/service/local/staging/deploy/maven2/Se hai un progetto multimodulo e non hai bisogno di caricare un certo modulo nel repository, devi aggiungere nel pom.xml di quel modulo nexus-staging-maven-plugin con il flag skipNexusStagingDeployMojo
org.sonatype.plugins
nexus-staging-maven-plugin
trueDopo il caricamento, le versioni snapshot/release sono disponibili in
SonatypeNexus
https://oss.sonatype.org/content/groups/staging/
Altri vantaggi
- Un elenco molto ampio di obiettivi per lavorare con il repository nexus (
mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin). - Controllo automatico della possibilità di caricamento su maven central
Risultato
Pubblicazione della versione SNAPSHOT
Durante la costruzione del progetto è possibile eseguire manualmente il compito di caricamento della versione SNAPSHOT nel nexus
L'esecuzione di questo compito attiva un compito corrispondente nel progetto deploy ().
Log ridotto
Esecuzione con gitlab-runner 11.10.0 (3001a600)
su Deploy runner JSKWyxUw
Utilizzando l'esecutore Shell...
Esecuzione su ih1174328.vds.myihor.ru...
Salto della configurazione del repository Git
Salto del checkout di Git
Salto della configurazione dei sottogruppi Git
$ rm -rf .* *
$ git config --global credential.helper store
$ echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
$ git clone ${DEPLOY_CI_REPOSITORY_URL} .
Clonazione in 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Nota: controllo di '850f86aa317194395c5387790da1350e437125a7'.
Sei nello stato 'detached HEAD'. Puoi esplorare, apportare modifiche sperimentali e farne commit, e puoi scartare eventuali commit che fai in questo stato senza influenzare alcun ramo eseguendo un altro checkout.
Se desideri creare un nuovo ramo per mantenere i commit che crei, puoi farlo (ora o dopo) utilizzando -b con il comando checkout di nuovo. Esempio:
git checkout -b nome_nuovo_ramo
HEAD è ora a 850f86a... salta il test di deploy test-core
$ for pom in $(find . -name pom.xml); do # comando multi-linea compresso
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # comando multi-linea compresso
[INFO] Scansione dei progetti...
[INFO] Ispezione della build con un totale di 4 moduli...
[INFO] Installazione delle funzionalità Nexus Staging:
[INFO] ... totale di 4 esecuzioni di maven-deploy-plugin sostituite con nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Ordine di Build del Reattore:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Shields4J client [jar]
[INFO] TestNG listener [jar]
[INFO]
[INFO] -----------------------------
[INFO] Costruzione di Shields4J 1.0.0 [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Ricerca della radice del aggregatore locale...
[INFO] Radice di aggregazione locale: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Elaborazione della modifica di org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Elaborazione di org.touchbit.shields4j:shields4j-parent
[INFO] Aggiornamento del progetto org.touchbit.shields4j:shields4j-parent
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO]
[INFO] Elaborazione di org.touchbit.shields4j:client
[INFO] Aggiornamento del genitore org.touchbit.shields4j:shields4j-parent
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO] Aggiornamento della dipendenza org.touchbit.shields4j:test-core
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO]
[INFO] Elaborazione di org.touchbit.shields4j:test-core
[INFO] Aggiornamento del genitore org.touchbit.shields4j:shields4j-parent
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO]
[INFO] Elaborazione di org.touchbit.shields4j:testng
[INFO] Aggiornamento del genitore org.touchbit.shields4j:shields4j-parent
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO] Aggiornamento della dipendenza org.touchbit.shields4j:client
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO] Aggiornamento della dipendenza org.touchbit.shields4j:test-core
[INFO] dalla versione 1.0.0 alla 1.0.0-SNAPSHOT
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Riepilogo del Reattore:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCCESS [ 0.992 s]
[INFO] test-core .......................................... SKIPPED
[INFO] Shields4J client ................................... SKIPPED
[INFO] TestNG listener 1.0.0 .............................. SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Tempo totale: 2.483 s
[INFO] Terminato alle: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Scansione dei progetti...
[INFO] Ispezione della build con un totale di 4 moduli...
[INFO] Installazione delle funzionalità Nexus Staging:
[INFO] ... totale di 4 esecuzioni di maven-deploy-plugin sostituite con nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Ordine di Build del Reattore:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Shields4J client [jar]
[INFO] TestNG listener [jar]
[INFO]
[INFO] -----------------------------
[INFO] Costruzione di Shields4J 1.0.0-SNAPSHOT [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
DELETTO
...
[INFO] * Il deploy in blocco degli artefatti snapshot raccolti localmente è terminato.
[INFO] Il deploy remoto è terminato con successo.
[INFO] ------------------------------------------------------------------------
[INFO] Riepilogo del Reattore:
[INFO]
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... SUCCESS [ 2.375 s]
[INFO] test-core .......................................... SUCCESS [ 3.929 s]
[INFO] Shields4J client ................................... SUCCESS [ 3.815 s]
[INFO] TestNG listener 1.0.0-SNAPSHOT ..................... SUCCESS [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Tempo totale: 47.629 s
[INFO] Terminato alle: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------Di conseguenza, è stata caricata una versione in nexus .
Tutte le versioni snapshot possono essere eliminate dal repository sul sito sotto il proprio account.
Pubblicazione della versione release
Quando si installa il tag, si attiva automaticamente il compito corrispondente nel progetto di deploy per caricare la versione di rilascio in nexus ().
La cosa migliore è che si attiva automaticamente la chiusura del rilascio in nexus.
[INFO] Esecuzione della staging remota...
[INFO]
[INFO] * Staging remoto nel profilo di staging ID "9043b43f77dcc9"
[INFO] * Creato repository di staging con ID "orgtouchbit-1037".
[INFO] * Repository di staging a https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO] * Caricamento degli artefatti localmente in staging nel profilo org.touchbit
[INFO] * Caricamento degli artefatti localmente in staging completato.
[INFO] * Chiusura del repository di staging con ID "orgtouchbit-1037".
In attesa che l'operazione venga completata...
.........
[INFO] Staged remote 1 repository, completato con successo.
[INFO] ------------------------------------------------------------------------
[INFO] Riepilogo del reattore:
[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] Tempo totale: 01:47 min
[INFO] Completato il: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------E se qualcosa è andato storto, il compito fallirà sicuramente
[INFO] Esecuzione della preparazione remota...
[INFO]
[INFO] * Preparazione remota nel profilo di preparazione ID "9043b43f77dcc9"
[INFO] * Creato repository di preparazione con ID "orgtouchbit-1038".
[INFO] * Repository di preparazione su https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO] * Caricamento degli artifact preparati localmente nel profilo org.touchbit
[INFO] * Caricamento degli artifact preparati localmente completato.
[INFO] * Chiusura del repository di preparazione con ID "orgtouchbit-1038".
Attesa del completamento dell'operazione...
.......
[ERROR] Errore di regola durante la chiusura del repository di preparazione con ID "orgtouchbit-1039".
[ERROR]
[ERROR] Rapporto di errore delle regole di preparazione Nexus
[ERROR] ==================================
[ERROR]
[ERROR] Errori nel repository "orgtouchbit-1039"
[ERROR] Errori della regola "signature-staging"
[ERROR] * Nessuna chiave pubblica: Chiave con id: (1f42b618d1cbe1b5) non è stata trovata su http://keys.gnupg.net:11371/. Carica la tua chiave pubblica e riprova l'operazione.
...
[ERROR] Pulizia della directory di preparazione locale dopo un errore di regola durante la chiusura dei repository di preparazione: [orgtouchbit-1039]
[ERROR] * Eliminazione del contesto 9043b43f77dcc9.properties
[ERROR] Pulizia dei repository di preparazione remoti dopo un errore di regola durante la chiusura dei repository di preparazione: [orgtouchbit-1039]
[ERROR] * Eliminazione del repository di preparazione fallito con ID "orgtouchbit-1039" (Errore di regola durante la chiusura dei repository di preparazione: [orgtouchbit-1039]).
[ERROR] Preparazione remota completata con un errore: Errore nelle regole di preparazione!
[INFO] ------------------------------------------------------------------------
[INFO] Riepilogo del reattore:
[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] ERRORE DI COSTRUZIONE
[INFO] ------------------------------------------------------------------------Ci resta soltanto un'unica scelta. O eliminare questa versione o pubblicarla.
Dopo il rilascio, dopo un po' gli artifact saranno in
off-topic
È stata una sorpresa per me che Maven indicizzi altri repository pubblici.
Ho dovuto aggiungere robots.txt, poiché aveva indicizzato il mio vecchio repository.
Conclusione
Cosa abbiamo
- Un progetto di deploy separato in cui è possibile implementare diverse attività CI per caricare artifact in repository pubblici per vari linguaggi di programmazione.
- Il progetto di deploy è isolato da interferenze esterne e può essere modificato solo da utenti con il ruolo di Owner e Maintainer.
- Un Runner Specifico separato con cache 'calda' per eseguire solo attività di deploy.
- Pubblicazione di versioni snapshot/release in un repository pubblico.
- Verifica automatica della versione release per la pubblicazione in Maven Central.
- Protezione contro la pubblicazione automatica di versioni 'grezze' in Maven Central.
- Costruzione e pubblicazione di versioni snapshot 'con un clic'.
- Unico repository per ottenere versioni snapshot/release.
- Pipeline generale per l'assemblaggio/test e pubblicazione di un progetto Java.
Impostare GitLab CI non è un argomento così complicato come potrebbe sembrare a prima vista. Basta configurare CI "chiavi in mano" un paio di volte e poi non sei più un dilettante in questo campo. Inoltre, la documentazione di GitLab è piuttosto abbondante. Non abbiate paura di fare il primo passo. La strada si crea sotto i passi di chi avanza (non ricordo chi lo ha detto 🙂 ).
Sarò felice di ricevere feedback.
Nell'articolo successivo parlerò di come configurare GitLab CI per l'esecuzione concorrente di task con test di integrazione (con l'avvio dei servizi testati tramite docker-compose), se hai solo un runner shell.
Fonte: habr.com
