Este artigo é destinado a desenvolvedores Java que precisam publicar rapidamente seus produtos em repositórios Sonatype e/ou Maven Central usando o GitLab. Neste artigo, falarei sobre a configuração do gitlab-runner, gitlab-ci e maven-plugin para resolver essa tarefa.
Pré-requisitos:
- Armazenamento seguro das chaves mvn e GPG.
- Execução segura de tarefas públicas de CI.
- Carregamento de artefatos (release/snapshot) em repositórios públicos.
- Verificação automática de versões de release para publicação no Maven Central.
- Solução geral para o carregamento de artefatos em um repositório para vários projetos.
- Simples e fácil de usar.
Conteúdo
Informações Gerais
- Uma descrição detalhada do mecanismo de publicação de artefatos no Maven Central através do Serviço de Hospedagem de Repositórios OSS da Sonatype já foi descrita em pelo usuário , portanto, em locais necessários, farei referência a este artigo.
- Primeiro, registre-se em e crie um ticket para abrir o repositório (leia mais na seção ). Após abrir o repositório, um par de login/senha do JIRA (daqui em diante, conta Sonatype) será utilizado para carregar artefatos no Sonatype Nexus.
- A seguir, o processo de geração da chave GPG é descrito de forma bem direta. Para mais detalhes, veja a seção
- Se você estiver usando o console Linux para gerar a chave GPG (gnupg/gnupg2), é necessário instalar para gerar entropia. Caso contrário, a geração da chave pode demorar muito.
- Serviços de armazenamento públicos chaves GPG
Configuração do projeto de deploy no GitLab
- Em primeiro lugar, é necessário criar e configurar um projeto onde o pipeline será armazenado para o deploy dos artefatos. O meu projeto eu nomeei de forma simples —
- Depois de criar o repositório, é necessário restrigir o acesso à edição do repositório.
Vamos para o projeto -> Configurações -> Repositório -> Ramos Protegidos. Remove todas as regras e adiciona uma única regra com Wildcard * com permissão para push e merge apenas para usuários com o papel de Maintainers. Esta regra irá funcionar para todos os usuários tanto deste projeto quanto do grupo ao qual este projeto pertence.
- Se houver mais de um mantenedor, a melhor solução será restringir o acesso ao projeto em princípio.
Vamos para o projeto -> Configurações -> Geral -> Visibilidade, recursos do projeto, permissões e definimos a Visibilidade do projeto como Privado.
Meu projeto está disponível publicamente, pois estou usando meu próprio GitLab Runner e apenas eu tenho acesso para modificar o repositório. Além disso, não é do meu interesse expor informações privadas nos logs públicos do pipeline. - Aperto das regras para modificação do repositório
Vamos para o projeto -> Configurações -> Repositório -> Regras de Push e ativamos as opções Restrição do Commit, Verificar se o autor é um usuário GitLab. Também recomendo configurar , e ativar a opção Rejeitar commits não assinados. - Em seguida, precisamos configurar um gatilho para executar tarefas
Vamos para o projeto -> Configurações -> CI / CD -> Gatilhos de pipeline e criamos um novo token de gatilho
Esse token pode ser adicionado imediatamente à configuração geral de variáveis para o grupo de projetos.
Vamos para o grupo -> Configurações -> CI / CD -> Variáveis e adicionamos a variávelDEPLOY_TOKENcom o token do gatilho como valor.
GitLab Runner
Nesta seção está descrita a configuração para executar tarefas de deploy usando runner próprio (Específico) e público (Compartilhado).
Runner Específico
Eu uso runners próprios, pois em primeiro lugar é conveniente, rápido e barato.
Para o runner, recomendo um VDS Linux com 1 CPU, 2 GB de RAM, 20 GB de HDD. O custo é cerca de 3000₽ por ano.
Meu runner
Para o runner, eu escolhi um VDS com 4 CPUs, 4 GB de RAM, 50 GB de SSD. Custou cerca de 11000₽ e nunca me arrependi.
No total, tenho 7 máquinas. 5 na Aruba e 2 na Ihor.
Então, temos um runner. Agora vamos configurá-lo.
Entramos na máquina via SSH e instalamos java, git, maven, gnupg2.
Instalamos o gitlab runner
- Criamos um novo grupo
runnersudo groupadd runner - Criamos um diretório para o cache do maven e configuramos as permissões do grupo
runner
Este passo pode ser pulado se você não planeja executar vários runners em uma única máquina.mkdir -p /usr/cache/.m2/repository chown -R :runner /usr/cache chmod -R 770 /usr/cache - Criamos o usuário
gitlab-deployere o adicionamos ao gruporunneruseradd -m -d /home/gitlab-deployer gitlab-deployer usermod -a -G runner gitlab-deployer - Adicionamos ao arquivo
/etc/ssh/sshd_configa seguinte linhaPermitir Usuários root@* gitlab-deployer@127.0.0.1 - Reiniciando
sshd.systemctl restart sshd - Definindo a senha para o usuário
gitlab-deployer(pode ser simples, pois há uma limitação para localhost)passwd gitlab-deployer - Instalando o 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 - Acessar o site gitlab.com -> deploy-project -> Configurações -> CI/CD -> Runners -> Runners Específicos e copiar o token de registro
Captura de tela
- Registrando o runner
gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml
Processo
Plataforma de execução arch=amd64 os=linux pid=17594 revisão=3001a600 versão=11.10.0
Executando em modo de sistema.
Por favor, insira a URL do coordenador gitlab-ci (ex: https://gitlab.com/):
https://gitlab.com/
Por favor, insira o token gitlab-ci para este runner:
REGISTRATION_TOKEN
Por favor, insira a descrição gitlab-ci para este runner:
[ih1174328.vds.myihor.ru]: Deploy Runner
Por favor, insira as tags gitlab-ci para este runner (separadas por vírgula):
deploy
Registrando runner... bem-sucedido runner=ZvKdjJhx
Por favor, insira o executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner registrado com sucesso. Sinta-se à vontade para iniciá-lo, mas se já estiver em execução, a configuração deverá ser recarregada automaticamente!- Verificando se o runner está registrado. Acessar o site gitlab.com -> deploy-project -> Configurações -> CI/CD -> Runners -> Runners Específicos -> Runners ativados para este projeto
Captura de tela
- Adicionamos separado serviço
/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 - Iniciando o serviço.
systemctl enable gitlab-deployer.service systemctl start gitlab-deployer.service systemctl status gitlab-deployer.service - Verificando se o runner está em execução.
Exemplo
Geração de chaves GPG
- Acessando a máquina via ssh como usuário
gitlab-deployer(isso é importante para gerar a chave GPG)ssh gitlab-deployer@127.0.0.1 - Gerando a chave respondendo às perguntas. Eu usei meu próprio nome e e-mail.
Certifique-se de especificar uma senha para a chave. Esta chave será usada para assinar artefatos.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 - Carregando nossa chave pública no servidor de chaves
gpg --keyserver keys.gnupg.net --send-key 00000000 gpg: sending key 00000000 to hkp server keys.gnupg.net
Configuração do Maven
- Acessando como usuário
gitlab-deployersu gitlab-deployer - Criando diretório maven repository e vinculando com o cache (não erre)
Este item pode ser ignorado se você não planeja executar vários runners na mesma máquina.mkdir -p ~/.m2/repository ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository - Criando a chave mestre
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Criando o arquivo ~/.m2/settings-security.xml
{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Criptografando a senha da conta Sonatype
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Criando o arquivo ~/.m2/settings.xml
env true GPG_SECRET_KEY_PASSPHRASE sonatype SONATYPE_USERNAME {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
onde,
GPG_SECRET_KEY_PASSPHRASE — a senha da chave GPG
SONATYPE_USERNAME — login da conta sonatype
Aqui a configuração do runner está concluída, podemos passar para a seção
Runner Compartilhado
Geração de chaves GPG
- Primeiro, é necessário criar uma chave GPG. Para isso, instalamos o gnupg.
yum install -y gnupg - Geramos a chave respondendo às perguntas. Eu usei meu próprio nome e e-mail. É obrigatório indicar uma senha para a chave.
gpg --gen-key - Exibimos informações sobre a chave
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] - Carregando nossa chave pública no servidor de chaves
gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 gpg: sending key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 to hkp server keys.gnupg.net - Obtendo a chave privada
gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 -----BEGIN PGP PRIVATE KEY BLOCK----- lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5 ... =2Wd2 -----END PGP PRIVATE KEY BLOCK----- - Acesse as configurações do projeto -> Configurações -> CI / CD -> Variáveis e salve a chave privada na variável
GPG_SECRET_KEY
Configuração do Maven
- Criando a chave mestre
mvn --encrypt-master-password password {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Acesse as configurações do projeto -> Configurações -> CI / CD -> Variáveis e salve na variável
SETTINGS_SECURITY_XMLas seguintes linhas:{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=} - Criptografando a senha da conta Sonatype
mvn --encrypt-password SONATYPE_PASSWORD {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J} - Acesse as configurações do projeto -> Configurações -> CI / CD -> Variáveis e salve na variável
SETTINGS_XMLas seguintes linhas:env true GPG_SECRET_KEY_PASSPHRASE sonatype sonatype_username {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
onde,
GPG_SECRET_KEY_PASSPHRASE — a senha da chave GPG
SONATYPE_USERNAME — login da conta sonatype
Deploy da imagem Docker
- Criamos um Dockerfile bem simples para executar tarefas de deploy com a versão necessária do Java. Abaixo está um exemplo para 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/ - Construindo o contêiner para o seu projeto
docker build -t registry.gitlab.com/group/deploy . - Autenticamo-nos e fazemos o upload do contêiner no registry.
docker login -u USER -p PASSWORD registry.gitlab.com docker push registry.gitlab.com/group/deploy
GitLab CI
Deploy do projeto
Adicionamos o arquivo .gitlab-ci.yml na raiz do projeto de implantação
O script contém duas tarefas mutuamente exclusivas para a implantação. Specific Runner ou Shared Runner, respectivamente.
.gitlab-ci.yml
stages:
- deploy
Specific Runner:
extends: .java_deploy_template
# A tarefa será executada no seu shell-runner
tags:
- deploy
Shared Runner:
extends: .java_deploy_template
# A tarefa será executada no docker-runner público
tags:
- docker
# Imagem da seção GitLab Runner -> Shared Runner -> Docker
image: registry.gitlab.com/group/deploy-project:latest
before_script:
# Importamos a chave GPG
- printf "${GPG_SECRET_KEY}" | gpg --batch --import
# Salvamos a configuração do maven
- printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
- printf "${SETTINGS_XML}" > ~/.m2/settings.xml
.java_deploy_template:
stage: deploy
# A tarefa será acionada por um trigger, se a variável DEPLOY tiver o valor java
only:
variables:
- $DEPLOY == "java"
variables:
# desativamos a clonagem do projeto atual
GIT_STRATEGY: none
script:
# Permitimos o armazenamento da senha em texto não criptografado
- git config --global credential.helper store
# Salvamos as credenciais temporárias do usuário gitlab-ci-token
# O token funciona para todos os projetos públicos gitlab.com e para projetos de grupo
- echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
# Limpamos completamente o diretório atual
- rm -rf .* *
# Clonamos o projeto que vamos implantar no Sonatype Nexus
- git clone ${DEPLOY_CI_REPOSITORY_URL} .
# Mudamos para o commit desejado
- git checkout ${DEPLOY_CI_COMMIT_SHA} -f
# Se algum pom.xml contiver o parâmetro autoReleaseAfterClose, cancelamos a construção.
# Caso contrário, há o risco de enviar artefatos não finalizados para o maven central
- >
for pom in $(find . -name pom.xml); do
if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
echo "Arquivo $pom contém a configuração proibida: ";
exit 1;
fi;
done
# Se o parâmetro DEPLOY_CI_COMMIT_TAG estiver vazio, definimos forçadamente a versão 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
# Executamos a tarefa de construção e implantação dos artefatos
- mvn clean deploy -DskipTests=trueProjeto Java
Em projetos Java que se pretende carregar em repositórios públicos, é necessário adicionar 2 etapas para carregar as versões Release e Snapshot.
.gitlab-ci.yml
stages:
- build
- test
- verify
- deploy
Release:
extends: .trigger_deploy
# Executar a tarefa apenas por tag.
only:
- tags
Snapshot:
extends: .trigger_deploy
# Executamos a tarefa para publicar a versão SNAPSHOT manualmente
when: manual
# Não executar a tarefa se uma tag estiver definida.
except:
- tags
.trigger_deploy:
stage: deploy
variables:
# Desativamos a clonagem do projeto atual
GIT_STRATEGY: none
# Link para o gatilho da tarefa de deploy
URL: "https://gitlab.com/api/v4/projects//trigger/pipeline"
# Variáveis da tarefa de 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:
# Não uso cURL, pois com as flags --fail --show-error
# ele não exibe o corpo da resposta se o código HTTP for 400 ou mais
- wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}Nesta solução, fui um pouco mais longe e decidi usar um único template CI para projetos Java.
Mais detalhes
Criei um projeto separado onde coloquei o template CI para projetos Java .
common.yml
estágios:
- construir
- testar
- verificar
- implantar
variáveis:
SONAR_ARGS: "
-Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA}
-Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME}
"
.build_java_project:
estágio: construir
tags:
- touchbit-shell
variáveis:
SKIP_TEST: "false"
script:
- mvn clean
- mvn package -DskipTests=${SKIP_TEST}
artefatos:
quando: sempre
expirar_em: 30 dias
caminhos:
- "*\/target\/reports"
.build_sphinx_doc:
estágio: construir
tags:
- touchbit-shell
variáveis:
DOCKERFILE: .indirect\/docs\/Dockerfile
script:
- docker build --no-cache -t ${CI_PROJECT_NAME}\/doc -f ${DOCKERFILE} .
.junit_module_test_run:
estágio: testar
tags:
- touchbit-shell
variáveis:
MÓDULO: ""
script:
- cd ${MÓDULO}
- mvn test
artefatos:
quando: sempre
expirar_em: 30 dias
caminhos:
- "*\/target\/reports"
.junit_test_run:
estágio: testar
tags:
- touchbit-shell
script:
- mvn test
artefatos:
quando: sempre
expirar_em: 30 dias
caminhos:
- "*\/target\/reports"
.sonar_review:
estágio: verificar
tags:
- touchbit-shell
dependências: []
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:
estágio: implantar
tags:
- touchbit-shell
variáveis:
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
apenas:
- tags
.trigger_snapshot_deploy:
estende: .trigger_deploy
quando: manual
exceto:
- tags
Como resultado, os próprios projetos Java .gitlab-ci.yml aparecem bastante compactos e sucintos.
.gitlab-ci.yml
incluir: https:\/\/gitlab.com\/TouchBIT\/gitlab-ci\/raw\/master\/common.yml
Shields4J:
estende: .build_java_project
Sphinx doc:
estende: .build_sphinx_doc
variáveis:
DOCKERFILE: .docs\/Dockerfile
Sonar review:
estende: .sonar_review
dependências:
- Shields4J
Release:
estende: .trigger_release_deploy
Snapshot:
estende: .trigger_snapshot_deployConfiguração do pom.xml
Esta questão é descrita em detalhes. em , portanto, vou descrever algumas nuances do uso de plugins. Também descreverei como é fácil e natural usá-los. nexus-staging-maven-plugin, caso você não queira ou não possa usar org.sonatype.oss:oss-parent como pai do seu projeto.
maven-install-plugin
Instala os módulos no repositório local.
Muito útil para verificar soluções em outros projetos, assim como para verificação de somas de controle.
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
Geração de javadoc para o projeto.
org.apache.maven.plugins
maven-javadoc-plugin
jar
prepare-package
true
true
falseSe você tem um módulo que não contém java (por exemplo, apenas recursos)
Ou se você não deseja gerar javadoc de forma alguma, isso pode ajudar 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
Configuração:
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
Repositório Nexus Snapshot
https://oss.sonatype.org/content/repositories/snapshots/
sonatype
Repositório Nexus Release
https://oss.sonatype.org/service/local/staging/deploy/maven2/Se você tem um projeto multimódulo e não precisa enviar um módulo específico para o repositório, então no pom.xml desse módulo é necessário adicionar nexus-staging-maven-plugin com a flag skipNexusStagingDeployMojo
org.sonatype.plugins
nexus-staging-maven-plugin
trueApós o upload, as versões snapshot/release estarão disponíveis em
SonatypeNexus
https://oss.sonatype.org/content/groups/staging/
Mais benefícios
- Uma lista muito rica de metas para trabalhar com o repositório nexus (
mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin). - Verificação automática de release para upload no maven central
Resultado
Publicação da versão SNAPSHOT
Ao compilar o projeto, há a possibilidade de iniciar manualmente a tarefa de upload da versão SNAPSHOT para o nexus
Ao executar esta tarefa, uma tarefa correspondente no projeto de deploy é acionada ().
Log reduzido
Executando com gitlab-runner 11.10.0 (3001a600)
no Deploy runner JSKWyxUw
Usando executor Shell...
Executando em ih1174328.vds.myihor.ru...
Ignorando configuração do repositório Git
Ignorando checkout do Git
Ignorando configuração dos submódulos do 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 para 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Nota: checando '850f86aa317194395c5387790da1350e437125a7'.
Você está em estado 'HEAD destacado'. Você pode olhar ao redor, fazer alterações experimentais e confirmá-las, e pode descartar quaisquer confirmações que você fizer neste estado sem impactar quaisquer branches ao realizar outro checkout.
Se você quiser criar um novo branch para reter as confirmações que você criou, pode fazê-lo (agora ou depois) usando -b com o comando checkout novamente. Exemplo:
git checkout -b new_branch_name
HEAD agora está em 850f86a... pular teste de deploy test-core
$ for pom in $(find . -name pom.xml); do # comando de várias linhas colapsado
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; então # comando de várias linhas colapsado
[INFO] Escaneando por projetos...
[INFO] Inspecionando build com um total de 4 módulos...
[INFO] Instalando recursos de Staging do Nexus:
[INFO] ... total de 4 execuções do maven-deploy-plugin substituídas pelo nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Ordem de Build do Reactor:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Cliente Shields4J [jar]
[INFO] Ouvinte TestNG [jar]
[INFO]
[INFO] -----------------------------
[INFO] Construindo Shields4J 1.0.0 [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Buscando raiz do agregador local...
[INFO] Raiz de agregação local: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Processando mudança de org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Processando org.touchbit.shields4j:shields4j-parent
[INFO] Atualizando projeto org.touchbit.shields4j:shields4j-parent
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO]
[INFO] Processando org.touchbit.shields4j:client
[INFO] Atualizando pai org.touchbit.shields4j:shields4j-parent
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO] Atualizando dependência org.touchbit.shields4j:test-core
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO]
[INFO] Processando org.touchbit.shields4j:test-core
[INFO] Atualizando pai org.touchbit.shields4j:shields4j-parent
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO]
[INFO] Processando org.touchbit.shields4j:testng
[INFO] Atualizando pai org.touchbit.shields4j:shields4j-parent
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO] Atualizando dependência org.touchbit.shields4j:client
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO] Atualizando dependência org.touchbit.shields4j:test-core
[INFO] de versão 1.0.0 para 1.0.0-SNAPSHOT
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Resumo do Reactor:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCESSO [ 0.992 s]
[INFO] test-core .......................................... IGNORADO
[INFO] Cliente Shields4J ................................... IGNORADO
[INFO] Ouvinte TestNG 1.0.0 .............................. IGNORADO
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCESSO
[INFO] ------------------------------------------------------------------------
[INFO] Tempo total: 2.483 s
[INFO] Terminado em: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Escaneando por projetos...
[INFO] Inspecionando build com um total de 4 módulos...
[INFO] Instalando recursos de Staging do Nexus:
[INFO] ... total de 4 execuções do maven-deploy-plugin substituídas pelo nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Ordem de Build do Reactor:
[INFO]
[INFO] Shields4J [pom]
[INFO] test-core [jar]
[INFO] Cliente Shields4J [jar]
[INFO] Ouvinte TestNG [jar]
[INFO]
[INFO] -----------------------------
[INFO] Construindo Shields4J 1.0.0-SNAPSHOT [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
DELETADO
...
[INFO] * Depósito em massa de artefatos de snapshot reunidos localmente finalizado.
[INFO] Implantação remota finalizada com sucesso.
[INFO] ------------------------------------------------------------------------
[INFO] Resumo do Reactor:
[INFO]
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... SUCESSO [ 2.375 s]
[INFO] test-core .......................................... SUCESSO [ 3.929 s]
[INFO] Cliente Shields4J ................................... SUCESSO [ 3.815 s]
[INFO] Ouvinte TestNG 1.0.0-SNAPSHOT ..................... SUCESSO [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCESSO
[INFO] ------------------------------------------------------------------------
[INFO] Tempo total: 47.629 s
[INFO] Terminado em: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------Como resultado, a versão foi carregada no nexus .
Todas as versões snapshot podem ser removidas do repositório no site com sua conta.
Publicação da versão release
Ao instalar a tag, a tarefa correspondente no projeto de deploy para carregar a versão final no nexus é acionada automaticamente ().
O mais interessante é que o fechamento do release no nexus é acionado automaticamente.
[INFO] Realizando staging remoto...
[INFO]
[INFO] * Staging remoto no perfil de staging ID "9043b43f77dcc9"
[INFO] * Repositório de staging criado com ID "orgtouchbit-1037".
[INFO] * Repositório de staging em https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO] * Carregando artefatos localmente staged para o perfil org.touchbit
[INFO] * Upload dos artefatos localmente staged concluído.
[INFO] * Fechando o repositório de staging com ID "orgtouchbit-1037".
Aguardando a conclusão da operação...
.........
[INFO] Repositórios remotamente staged 1, finalizado com sucesso.
[INFO] ------------------------------------------------------------------------
[INFO] Resumo do Reator:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCESSO [ 9.603 s]
[INFO] test-core .......................................... SUCESSO [ 3.419 s]
[INFO] Cliente Shields4J ................................... SUCESSO [ 9.793 s]
[INFO] Ouvinte TestNG 1.0.0 .............................. SUCESSO [01:23 min]
[INFO] ------------------------------------------------------------------------
[INFO] CONSTRUÇÃO COM SUCESSO
[INFO] ------------------------------------------------------------------------
[INFO] Tempo total: 01:47 min
[INFO] Finalizado em: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------E se algo der errado, a tarefa certamente falhará
[INFO] Realizando staging remoto...
[INFO]
[INFO] * Staging remoto no perfil de staging ID "9043b43f77dcc9"
[INFO] * Repositório de staging criado com ID "orgtouchbit-1038".
[INFO] * Repositório de staging em https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO] * Enviando artefatos localmente staged para o perfil org.touchbit
[INFO] * Upload de artefatos localmente staged concluído.
[INFO] * Fechando repositório de staging com ID "orgtouchbit-1038".
Aguardando a conclusão da operação...
.......
[ERROR] Falha na regra ao tentar fechar o repositório de staging com ID "orgtouchbit-1039".
[ERROR]
[ERROR] Relatório de Falhas das Regras de Staging do Nexus
[ERROR] ==================================
[ERROR]
[ERROR] Falhas no repositório "orgtouchbit-1039"
[ERROR] Falhas na regra "signature-staging"
[ERROR] * Nenhuma chave pública: A chave com id: (1f42b618d1cbe1b5) não pôde ser localizada em http://keys.gnupg.net:11371/. Faça o upload de sua chave pública e tente a operação novamente.
...
[ERROR] Limpando o diretório local de staging após uma falha de regra durante o fechamento dos repositórios de staging: [orgtouchbit-1039]
[ERROR] * Deletando contexto 9043b43f77dcc9.properties
[ERROR] Limpando os repositórios remotos de staging após uma falha de regra durante o fechamento dos repositórios de staging: [orgtouchbit-1039]
[ERROR] * Excluindo repositório de staging com falha ID "orgtouchbit-1039" (Falha de regra durante o fechamento dos repositórios de staging: [orgtouchbit-1039]).
[ERROR] Staging remoto finalizado com falha: Falha nas regras de staging!
[INFO] ------------------------------------------------------------------------
[INFO] Resumo do Reator:
[INFO]
[INFO] Shields4J 1.0.0 .................................... SUCESSO [ 4.073 s]
[INFO] test-core .......................................... SUCESSO [ 2.788 s]
[INFO] Cliente Shields4J .................................. SUCESSO [ 3.962 s]
[INFO] TestNG listener 1.0.0 .............................. FALHA [01:07 min]
[INFO] ------------------------------------------------------------------------
[INFO] FALHA NA COMPILAÇÃO
[INFO] ------------------------------------------------------------------------Resulta que nos resta apenas uma escolha. Ou excluir esta versão ou publicá-la.
Após o lançamento, após algum tempo, os artefatos estarão em
fora do tópico
Para mim, foi uma surpresa que o Maven indexa outros repositórios públicos.
Tive que adicionar um robots.txt, pois ele indexou meu repositório antigo.
Conclusão
O que temos
- Um projeto de deploy separado no qual várias tarefas de CI podem ser realizadas para carregar artefatos em repositórios públicos para diferentes linguagens de desenvolvimento.
- O projeto de deploy está isolado de interferências externas e pode ser alterado apenas por usuários com o papel de Owner e Maintainer.
- Um Runner específico separado com cache 'quente' para executar apenas tarefas de deploy.
- Publicação de versões snapshot/release em repositórios públicos.
- Verificação automática da versão release para pronta publicação no Maven Central.
- Proteção contra a publicação automática de versões 'cruas' no Maven Central.
- Compilação e publicação de versões snapshot 'com um clique'.
- Um repositório único para obter versões snapshot/release.
- Pipeline geral para construção/teste/publicação de projetos Java.
Configurar o GitLab CI não é tão complicado quanto parece à primeira vista. Basta configurar o CI 'pronto para uso' algumas vezes e você já não é mais um iniciante na área. Além disso, a documentação do GitLab é bastante abrangente. Não tenha medo de dar o primeiro passo. O caminho se forma sob os passos de quem avança (não me lembro quem disse isso 🙂 ).
Ficarei feliz em receber feedback.
No próximo artigo, vou explicar como configurar o GitLab CI para a execução concorrente de tarefas com testes de integração (iniciando serviços testados usando docker-compose), caso você tenha apenas um shell runner.
Fonte: habr.com
