Este artículo está destinado a desarrolladores de Java que necesitan publicar rápidamente sus productos en los repositorios de Sonatype y/o Maven Central utilizando GitLab. En este artículo, hablaré sobre la configuración de gitlab-runner, gitlab-ci y el plugin de Maven para resolver esta tarea.
Requisitos previos:
- Almacenamiento seguro de las claves mvn y GPG.
- Ejecución segura de tareas CI públicas.
- Carga de artefactos (release/snapshot) en repositorios públicos.
- Verificación automática de versiones release para publicación en Maven Central.
- Solución general para cargar artefactos en el repositorio para múltiples proyectos.
- Sencillez y facilidad de uso.
Contenido
Información General
- Se ha descrito detalladamente el mecanismo de publicación de artefactos en Maven Central a través del servicio de alojamiento de repositorios OSS de Sonatype en por el usuario , por lo que haré referencia a este artículo en los lugares necesarios.
- Primero, regístrate en y crea un ticket para abrir el repositorio (lee más en la sección ). Después de abrir el repositorio, el par de login/contraseña de JIRA (más adelante, la cuenta de Sonatype) se utilizará para cargar artefactos en Sonatype Nexus.
- A continuación, el proceso de generación de la clave GPG se describe de manera bastante escueta. Detalles en la sección
- Si utilizas la consola de Linux para generar la clave GPG (gnupg/gnupg2), debes instalar para generar entropía. De lo contrario, la generación de la clave puede tardar mucho.
- Servicios de almacenamiento públicos de claves GPG
Configuración del proyecto de deploy en GitLab
- En primer lugar, es necesario crear y configurar un proyecto donde se almacenará el pipeline para el despliegue de artefactos. Yo llamé a mi proyecto de manera simple —
- Después de crear el repositorio, es necesario restringir el acceso a la modificación del repositorio.
Vamos al proyecto -> Configuración -> Repositorio -> Ramas protegidas. Eliminamos todas las reglas y agregamos una única regla con Wildcard * con permiso de push y merge solo para usuarios con el rol de Mantenedor. Esta regla funcionará para todos los usuarios tanto de este proyecto como del grupo al que pertenece este proyecto.
- Si hay varios mantenedores, la mejor solución será restringir el acceso al proyecto en general.
Vamos al proyecto -> Configuración -> General -> Visibilidad, características del proyecto, permisos y configuramos la Visibilidad del proyecto en el valor Privado.
Mi proyecto es de acceso público, ya que utilizo mi propio GitLab Runner y solo yo tengo acceso para modificar el repositorio. Además, no es de mi interés revelar información privada en los registros de pipeline públicos. - Endurecimiento de las reglas para modificar el repositorio
Vamos al proyecto -> Configuración -> Repositorio -> Reglas de push y establecemos las banderas Restricción de committer, Comprobar si el autor es un usuario de GitLab. También recomiendo configurar , y activar la opción Rechazar commits sin firmar. - A continuación, es necesario configurar un disparador para iniciar tareas
Vamos al proyecto -> Configuración -> CI / CD -> Disparadores de pipeline y creamos un nuevo token de disparo
Este token se puede agregar de inmediato a la configuración global de variables para el grupo de proyectos.
Vamos al grupo -> Configuración -> CI / CD -> Variables y agregamos la variableDEPLOY_TOKENcon el token de disparo en el valor.
GitLab Runner
En esta sección se describe la configuración para iniciar tareas de despliegue utilizando un runner propio (Específico) y un runner público (Compartido).
Runner específico
Uso runners propios porque, ante todo, es conveniente, rápido y económico.
Para el runner, recomiendo un VDS de Linux con 1 CPU, 2 GB de RAM, 20 GB de HDD. El costo es de aproximadamente 3000₽ al año.
Mi runner
Para el runner, elegí un VDS con 4 CPU, 4 GB de RAM, 50 GB de SSD. Costó alrededor de 11000₽ y no me he arrepentido ni una vez.
En total tengo 7 máquinas. 5 en Aruba y 2 en Ihor.
Así que tenemos un runner. Ahora vamos a configurarlo.
Ingresamos a la máquina por SSH e instalamos java, git, maven, gnupg2.
Instalamos gitlab runner
- Creamos un nuevo grupo
runnersudo groupadd runner - Creamos un directorio para el caché de maven y asignamos los derechos del grupo
runner
Este paso se puede omitir si no planeas ejecutar varios runners en una sola máquina.mkdir -p /usr/cache/.m2/repository chown -R :runner /usr/cache chmod -R 770 /usr/cache - Creamos el usuario
gitlab-deployery lo añadimos al gruporunneruseradd -m -d /home/gitlab-deployer gitlab-deployer usermod -a -G runner gitlab-deployer - Agregamos a archivo
/etc/ssh/sshd_configla siguiente líneaPermitirUsuarios root@* gitlab-deployer@127.0.0.1 - Reiniciando
sshdsystemctl restart sshd - Estableciendo contraseña para el usuario
gitlab-deployer(puede ser simple, ya que hay una restricción para localhost)passwd gitlab-deployer - Instalando 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 - Accedemos al sitio gitlab.com -> desplegar-proyecto -> Configuración -> CI/CD -> Runners -> Runners específicos y copiamos el token de registro
Captura de pantalla
- Registrando runner
gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml
El proceso
Plataforma de ejecución arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Ejecutando en modo sistema.
Por favor, introduzca la URL coordinador de gitlab-ci (por ejemplo, https://gitlab.com/):
https://gitlab.com/
Por favor, introduzca el token de gitlab-ci para este runner:
REGISTRATION_TOKEN
Por favor, introduzca la descripción de gitlab-ci para este runner:
[ih1174328.vds.myihor.ru]: Desplegar Runner
Por favor, introduzca las etiquetas de gitlab-ci para este runner (separadas por comas):
desplegar
Registrando runner... succeeded runner=ZvKdjJhx
Por favor, introduzca el executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner registrado con éxito. Siéntase libre de iniciarlo, pero si ya está en ejecución, ¡la configuración debería recargarse automáticamente!- Verificando que el runner esté registrado. Accedemos al sitio gitlab.com -> desplegar-proyecto -> Configuración -> CI/CD -> Runners -> Runners específicos -> Runners activados para este proyecto
Captura de pantalla
- Añadimos separado servicio
/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 - Iniciamos el servicio.
systemctl enable gitlab-deployer.service systemctl start gitlab-deployer.service systemctl status gitlab-deployer.service - Verificando que el runner esté en ejecución.
Ejemplo
Generación de claves GPG
- Desde esta misma máquina, accedemos por ssh con el usuario
gitlab-deployer(esto es importante para generar la clave GPG)ssh gitlab-deployer@127.0.0.1 - Generamos la clave respondiendo a las preguntas. Usé mi propio nombre y correo.
Asegúrese de especificar una contraseña para la clave. Esta clave se usará para firmar los artefactos.gpg --gen-key - Verificamos.
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 - Subimos nuestra clave pública al servidor de claves
gpg --keyserver keys.gnupg.net --send-key 00000000 gpg: enviando clave 00000000 al servidor hkp keys.gnupg.net
Configuración de Maven
- Accedemos como usuario
gitlab-deployersu gitlab-deployer - Creamos el directorio maven repositorio y lo vinculamos con la caché (no se equivoque)
Este paso se puede omitir si no planea ejecutar varios runners en la misma máquina.mkdir -p ~\/ .m2\/ repository ln -s \/ usr\/ cache\/ .m2\/ repository \/ home\/ gitlab-deployer\/ .m2\/ repository - Creando la clave maestra
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Creando el archivo ~\/ .m2\/ settings-security.xml
{hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Cifrando la contraseña de la cuenta de Sonatype
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Creando el archivo ~\/ .m2\/ settings.xml
env true GPG_SECRET_KEY_PASSPHRASE sonatype SONATYPE_USERNAME {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
donde,
GPG_SECRET_KEY_PASSPHRASE — contraseña de la clave GPG
SONATYPE_USERNAME — nombre de usuario de la cuenta de Sonatype
Con esto, la configuración del runner está completa, podemos pasar a la sección
Runner compartido
Generación de claves GPG
- Primero, necesitamos crear una clave GPG. Para ello, instalamos gnupg.
yum install -y gnupg - Generamos la clave respondiendo a las preguntas. Usé mi nombre y correo electrónico personales. Asegúrate de indicar una contraseña para la clave.
gpg --gen-key - Mostrando información sobre la clave
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] - Subimos nuestra clave pública al servidor de claves
gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 gpg: enviando la clave 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 al servidor hkp keys.gnupg.net - Obteniendo la clave privada
gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 -----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5 ... =2Wd2 -----END PGP PRIVATE KEY BLOCK----- - Vamos a la configuración del proyecto -> Configuración -> CI / CD -> Variables y guardamos la clave privada en la variable
GPG_SECRET_KEY
Configuración de Maven
- Creando la clave maestra
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Vamos a la configuración del proyecto -> Configuración -> CI / CD -> Variables y guardamos en la variable
SETTINGS_SECURITY_XMLlas siguientes líneas:{hnkle5BJ9HUHUMP+CXfGBl8dScfFci\/mpsur\/73tR2I=} - Cifrando la contraseña de la cuenta de Sonatype
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Vamos a la configuración del proyecto -> Configuración -> CI / CD -> Variables y guardamos en la variable
SETTINGS_XMLlas siguientes líneas:env true GPG_SECRET_KEY_PASSPHRASE sonatype sonatype_username {98Wv5+u+Tn0HX2z5G\/kR4R8Z0WBgcDBgi7d12S\/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
donde,
GPG_SECRET_KEY_PASSPHRASE — contraseña de la clave GPG
SONATYPE_USERNAME — nombre de usuario de la cuenta de Sonatype
Implementar la imagen de Docker
- Creamos un Dockerfile bastante simple para ejecutar tareas de implementación con la versión correcta de Java. A continuación, se muestra un ejemplo para alpine.
DE 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/ - Construimos un contenedor para su proyecto
docker build -t registry.gitlab.com/group/deploy . - Autenticamos y subimos el contenedor al registro.
docker login -u USER -p PASSWORD registry.gitlab.com docker push registry.gitlab.com/group/deploy
GitLab CI
Implementar el proyecto
Añadimos el archivo .gitlab-ci.yml a la raíz del proyecto de despliegue
El script presenta dos tareas mutuamente excluyentes para el despliegue. Specific Runner o Shared Runner, respectivamente.
.gitlab-ci.yml
stages:
- deploy
Specific Runner:
extends: .java_deploy_template
# La tarea se ejecutará en su shell-runner
tags:
- deploy
Shared Runner:
extends: .java_deploy_template
# La tarea se ejecutará en un docker-runner público
tags:
- docker
# Imagen de la sección GitLab Runner -> Shared Runner -> Docker
image: registry.gitlab.com/group/deploy-project:latest
before_script:
# Importamos la clave GPG
- printf "${GPG_SECRET_KEY}" | gpg --batch --import
# Guardamos la configuración de maven
- printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
- printf "${SETTINGS_XML}" > ~/.m2/settings.xml
.java_deploy_template:
stage: deploy
# La tarea se activará por el trigger si se pasa la variable DEPLOY con el valor java
only:
variables:
- $DEPLOY == "java"
variables:
# desactivamos la clonación del proyecto actual
GIT_STRATEGY: none
script:
# Permitimos el almacenamiento de la contraseña en texto claro
- git config --global credential.helper store
# Guardamos las credenciales temporales del usuario gitlab-ci-token
# El token funciona para todos los proyectos públicos en gitlab.com y para proyectos del grupo
- echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
# Limpiamos completamente el directorio actual
- rm -rf .* *
# Clonamos el proyecto que vamos a desplegar en Sonatype Nexus
- git clone ${DEPLOY_CI_REPOSITORY_URL} .
# Cambiamos al commit deseado
- git checkout ${DEPLOY_CI_COMMIT_SHA} -f
# Si al menos un pom.xml contiene el parámetro autoReleaseAfterClose, fallamos la construcción.
# De lo contrario, hay riesgo de subir artefactos crudos a maven central
- >
for pom in $(find . -name pom.xml); do
if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
echo "El archivo $pom contiene un ajuste prohibido: ";
exit 1;
fi;
done
# Si el parámetro DEPLOY_CI_COMMIT_TAG está vacío, forzamos una versión 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
# Ejecutamos la tarea de construcción y despliegue de artefactos
- mvn clean deploy -DskipTests=trueProyecto Java
En proyectos de Java que se van a cargar en repositorios públicos, es necesario agregar 2 pasos para cargar las versiones Release y Snapshot.
.gitlab-ci.yml
stages:
- build
- test
- verify
- deploy
Release:
extends: .trigger_deploy
# Ejecutar la tarea solo por etiqueta.
only:
- tags
Snapshot:
extends: .trigger_deploy
# Ejecutar manualmente la tarea para publicar la versión SNAPSHOT
when: manual
# No ejecutar la tarea si se ha asignado una etiqueta.
except:
- tags
.trigger_deploy:
stage: deploy
variables:
# Desactivar la clonación del proyecto actual
GIT_STRATEGY: none
# Enlace al trigger de tarea de despliegue
URL: "https://gitlab.com/api/v4/projects//trigger/pipeline"
# Variables para la tarea de despliegue
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:
# No uso cURL, ya que con los flags --fail --show-error
# no imprime el cuerpo de la respuesta si el código HTTP es 400 o más
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}En esta solución, fui un poco más allá y decidí utilizar una plantilla CI única para proyectos de Java.
Más detalles
Creé un proyecto separado en el que coloqué la plantilla CI para proyectos de Java .
common.yml
etapas:
- construcción
- prueba
- verificación
- implementación
variables:
SONAR_ARGS: "
-Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA}
-Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}
"
.build_java_project:
etapa: construcción
etiquetas:
- touchbit-shell
variables:
SKIP_TEST: "false"
script:
- mvn clean
- mvn package -DskipTests=${SKIP_TEST}
artefactos:
cuando: siempre
expirar_en: 30 días
rutas:
- "*\/target\/reports"
.build_sphinx_doc:
etapa: construcción
etiquetas:
- touchbit-shell
variables:
DOCKERFILE: .indirect\/docs\/Dockerfile
script:
- docker build --no-cache -t ${CI_PROJECT_NAME}\/doc -f ${DOCKERFILE} .
.junit_module_test_run:
etapa: prueba
etiquetas:
- touchbit-shell
variables:
MÓDULO: ""
script:
- cd ${MÓDULO}
- mvn test
artefactos:
cuando: siempre
expirar_en: 30 días
rutas:
- "*\/target\/reports"
.junit_test_run:
etapa: prueba
etiquetas:
- touchbit-shell
script:
- mvn test
artefactos:
cuando: siempre
expirar_en: 30 días
rutas:
- "*\/target\/reports"
.sonar_review:
etapa: verificación
etiquetas:
- touchbit-shell
dependencias: []
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:
etapa: implementación
etiquetas:
- touchbit-shell
variables:
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:
extiende: .trigger_deploy
solo:
- etiquetas
.trigger_snapshot_deploy:
extiende: .trigger_deploy
cuando: manual
excepto:
- etiquetas
Como resultado, el archivo .gitlab-ci.yml en los propios proyectos Java es bastante compacto y conciso.
.gitlab-ci.yml
incluir: https://gitlab.com/TouchBIT/gitlab-ci/raw/master/common.yml
Shields4J:
extiende: .build_java_project
Documentación Sphinx:
extiende: .build_sphinx_doc
variables:
DOCKERFILE: .docs/Dockerfile
Revisión de Sonar:
extiende: .sonar_review
dependencias:
- Shields4J
Liberación:
extiende: .trigger_release_deploy
Instantánea:
extiende: .trigger_snapshot_deployConfiguración de pom.xml
Este tema está descrito con mucho detalle. en , por lo tanto, describiré algunos matices del uso de complementos. También explicaré cómo se puede utilizar de manera fácil y sin complicaciones. nexus-staging-maven-plugin, si no desea o no puede usar org.sonatype.oss:oss-parent como padre para su proyecto.
maven-install-plugin
Instala módulos en el repositorio local.
Es muy útil para verificar localmente soluciones en otros proyectos, así como para el uso de sumas de verificación.
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
Generación de javadoc para el proyecto.
org.apache.maven.plugins
maven-javadoc-plugin
jar
prepare-package
true
true
falseSi tienes un módulo que no contiene java (por ejemplo, solo recursos)
O si no deseas generar javadoc en absoluto, aquí tienes ayuda 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
Configuración:
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
Repositorio de Snapshot de Nexus
https://oss.sonatype.org/content/repositories/snapshots/
sonatype
Repositorio de Release de Nexus
https://oss.sonatype.org/service/local/staging/deploy/maven2/Si tiene un proyecto multimódulo y no necesita cargar un módulo específico en el repositorio, debe agregar en el pom.xml de este módulo nexus-staging-maven-plugin con la bandera skipNexusStagingDeployMojo
org.sonatype.plugins
nexus-staging-maven-plugin
trueDespués de cargar la versión snapshot/release, estarán disponibles en
SonatypeNexus
https://oss.sonatype.org/content/groups/staging/
Más ventajas
- Una lista muy completa de objetivos para trabajar con el repositorio de nexus (
mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin). - Verificación automática de la versión release para su carga en maven central
Resultado
Publicación de la versión SNAPSHOT
Al construir el proyecto hay la posibilidad de ejecutar manualmente la tarea de cargar la versión SNAPSHOT en nexus
Al ejecutar esta tarea, se activa la tarea correspondiente en el proyecto deploy ().
Registro recortado
Ejecutando con gitlab-runner 11.10.0 (3001a600)
en el corredor de despliegue JSKWyxUw
Usando el ejecutor Shell...
Ejecutando en ih1174328.vds.myihor.ru...
Omitiendo configuración del repositorio de Git
Omitiendo verificación de Git
Omitiendo configuración de submódulos de 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} .
Clonando en 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Nota: comprobando '850f86aa317194395c5387790da1350e437125a7'.
Estás en un estado de 'HEAD desapegado'. Puedes mirar a tu alrededor, hacer cambios experimentales y confirmarlos, y puedes descartar cualquier confirmación que hagas en este estado sin afectar ninguna rama al realizar otro checkout.
Si quieres crear una nueva rama para retener los commits que creas, puedes hacerlo (ahora o después) usando -b con el comando checkout nuevamente. Ejemplo:
git checkout -b nombre_nueva_rama
El HEAD ahora está en 850f86a... omitir prueba de despliegue test-core
$ for pom in $(find . -name pom.xml); do # comando de varias líneas colapsado
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # comando de varias líneas colapsado
[INFO] Escaneando proyectos...
[INFO] Inspeccionando la construcción con un total de 4 módulos...
[INFO] Instalando características de Nexus Staging:
[INFO] ... un total de 4 ejecuciones de maven-deploy-plugin reemplazadas con nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Orden de construcción del Reactor:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Cliente Shields4J [jar]
[INFO] Listener TestNG [jar]
[INFO]
[INFO] -----------------------------
[INFO] Construyendo Shields4J 1.0.0 [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Buscando la raíz del agregador local...
[INFO] Raíz de agregación local: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Procesando el cambio de org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Procesando org.touchbit.shields4j:shields4j-parent
[INFO] Actualizando proyecto org.touchbit.shields4j:shields4j-parent
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO]
[INFO] Procesando org.touchbit.shields4j:client
[INFO] Actualizando padre org.touchbit.shields4j:shields4j-parent
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO] Actualizando dependencia org.touchbit.shields4j:test-core
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO]
[INFO] Procesando org.touchbit.shields4j:test-core
[INFO] Actualizando padre org.touchbit.shields4j:shields4j-parent
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO]
[INFO] Procesando org.touchbit.shields4j:testng
[INFO] Actualizando padre org.touchbit.shields4j:shields4j-parent
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO] Actualizando dependencia org.touchbit.shields4j:client
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO] Actualizando dependencia org.touchbit.shields4j:test-core
[INFO] de la versión 1.0.0 a 1.0.0-SNAPSHOT
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Resumen del Reactor:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ÉXITO [ 0.992 s]
[INFO] test-core .......................................... OMITIDO
[INFO] Cliente Shields4J ................................... OMITIDO
[INFO] Listener TestNG 1.0.0 .............................. OMITIDO
[INFO] ------------------------------------------------------------------------
[INFO] CONSTRUCCIÓN EXITOSA
[INFO] ------------------------------------------------------------------------
[INFO] Tiempo total: 2.483 s
[INFO] Terminado en: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Escaneando proyectos...
[INFO] Inspeccionando la construcción con un total de 4 módulos...
[INFO] Instalando características de Nexus Staging:
[INFO] ... un total de 4 ejecuciones de maven-deploy-plugin reemplazadas con nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Orden de construcción del Reactor:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Cliente Shields4J [jar]
[INFO] Listener TestNG [jar]
[INFO]
[INFO] -----------------------------
[INFO] Construyendo Shields4J 1.0.0-SNAPSHOT [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
ELIMINADO
...
[INFO] * El despliegue masivo de artefactos de instantáneas recogidos localmente finalizó.
[INFO] El despliegue remoto finalizó con éxito.
[INFO] ------------------------------------------------------------------------
[INFO] Resumen del Reactor:
[INFO]
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... ÉXITO [ 2.375 s]
[INFO] test-core .......................................... ÉXITO [ 3.929 s]
[INFO] Cliente Shields4J ................................... ÉXITO [ 3.815 s]
[INFO] Listener TestNG 1.0.0-SNAPSHOT ..................... ÉXITO [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] CONSTRUCCIÓN EXITOSA
[INFO] ------------------------------------------------------------------------
[INFO] Tiempo total: 47.629 s
[INFO] Terminado en: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------Como resultado, se ha cargado una versión en nexus .
Todas las versiones snapshot se pueden eliminar del repositorio en el sitio web con su cuenta.
Publicación de la versión release
Al instalar la etiqueta, se activa automáticamente la tarea correspondiente en el proyecto de despliegue para cargar la versión de lanzamiento en nexus ().
Lo más agradable es que se activa automáticamente el cierre del lanzamiento en nexus.
[INFO] Realizando el staging remoto...
[INFO]
[INFO] * Staging remoto en el perfil de staging ID "9043b43f77dcc9"
[INFO] * Repositorio de staging creado con ID "orgtouchbit-1037".
[INFO] * Repositorio de staging en https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO] * Subiendo artefactos localmente staged al perfil org.touchbit
[INFO] * La carga de artefactos localmente staged ha finalizado.
[INFO] * Cerrando el repositorio de staging con ID "orgtouchbit-1037".
Esperando que la operación se complete...
.........
[INFO] Se han preparado 1 repositorio de forma remota, finalizado con éxito.
[INFO] ------------------------------------------------------------------------
[INFO] Resumen del Reactor:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ÉXITO [ 9.603 s]
[INFO] test-core .......................................... ÉXITO [ 3.419 s]
[INFO] Cliente Shields4J ................................... ÉXITO [ 9.793 s]
[INFO] Listener TestNG 1.0.0 .............................. ÉXITO [01:23 min]
[INFO] ------------------------------------------------------------------------
[INFO] CONSTRUCCIÓN EXITOSA
[INFO] ------------------------------------------------------------------------
[INFO] Tiempo total: 01:47 min
[INFO] Finalizado en: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------Y si algo sale mal, la tarea definitivamente fallará
[INFO] Realizando una subida remota a staging...
[INFO]
[INFO] * Subida remota al perfil de staging ID "9043b43f77dcc9"
[INFO] * Se creó el repositorio de staging con ID "orgtouchbit-1038".
[INFO] * Repositorio de staging en https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO] * Subiendo artefactos de staging localmente al perfil org.touchbit
[INFO] * La subida de artefactos de staging localizados ha finalizado.
[INFO] * Cerrando el repositorio de staging con ID "orgtouchbit-1038".
Esperando que la operación se complete...
.......
[ERROR] Error de regla al intentar cerrar el repositorio de staging con ID "orgtouchbit-1039".
[ERROR]
[ERROR] Informe de Fallos de Reglas de Nexus Staging
[ERROR] ==================================
[ERROR]
[ERROR] Fallos en el repositorio "orgtouchbit-1039"
[ERROR] Fallos de la regla "signature-staging"
[ERROR] * No se encontró la clave pública: La clave con id: (1f42b618d1cbe1b5) no pudo ser localizada en http://keys.gnupg.net:11371/. Sube tu clave pública y vuelve a intentar la operación.
...
[ERROR] Limpiando el directorio local de staging después de un fallo de regla durante el cierre de los repositorios de staging: [orgtouchbit-1039]
[ERROR] * Eliminando el contexto 9043b43f77dcc9.properties
[ERROR] Limpiando los repositorios de staging remotos después de un fallo de regla durante el cierre de los repositorios de staging: [orgtouchbit-1039]
[ERROR] * Eliminando el repositorio de staging fallido con ID "orgtouchbit-1039" (Fallo de regla durante el cierre de los repositorios de staging: [orgtouchbit-1039]).
[ERROR] La subida remota finalizó con un fallo: ¡Fallo en las reglas de staging!
[INFO] ------------------------------------------------------------------------
[INFO] Resumen del Reactor:
[INFO]
[INFO] Shields4J 1.0.0 .................................... ÉXITO [ 4.073 s]
[INFO] test-core .......................................... ÉXITO [ 2.788 s]
[INFO] Cliente Shields4J .................................. ÉXITO [ 3.962 s]
[INFO] Listener de TestNG 1.0.0 .......................... FALLA [01:07 min]
[INFO] ------------------------------------------------------------------------
[INFO] FALLA EN LA CONSTRUCCIÓN
[INFO] ------------------------------------------------------------------------Como resultado, solo nos queda una elección. O eliminar esta versión o publicarla.
Después del lanzamiento, después de un tiempo, los artefactos estarán en
off-topic
Fue una revelación para mí que Maven indexa otros repositorios públicos.
Tuve que agregar un robots.txt, ya que había indexado mi antiguo repositorio.
Conclusión
Lo que tenemos
- Un proyecto de deploy separado donde se pueden implementar varias tareas de CI para cargar artefactos en repositorios públicos para diferentes lenguajes de desarrollo.
- El proyecto de deploy está aislado de interferencias externas y solo puede ser modificado por usuarios con rol de Owner y Maintainer.
- Un Runner específico separado con caché 'caliente' para ejecutar solo tareas de deploy.
- Publicación de versiones snapshot/release en el repositorio público.
- Comprobación automática de la versión de release para su preparación para la publicación en Maven Central.
- Protección contra la publicación automática de versiones 'crudas' en Maven Central.
- Compilación y publicación de versiones snapshot 'con un clic'.
- Un único repositorio para obtener versiones snapshot/release.
- Pipeline general para la construcción/prueba/publicación de un proyecto Java.
Configurar GitLab CI no es un tema tan complicado como parece a primera vista. Es suficiente con configurar CI "llave en mano" un par de veces y ya no serás un principiante en esta materia. Además, la documentación de GitLab es bastante extensa. No temas dar el primer paso. El camino se crea al andar (no recuerdo quién lo dijo 🙂 ).
Estaré encantado de recibir comentarios.
En el próximo artículo hablaré sobre cómo configurar GitLab CI para ejecutar tareas de manera concurrente con pruebas de integración (iniciando los servicios a probar con docker-compose), si solo dispones de un shell runner.
Fuente: habr.com
