Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

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 questo articolo da parte dell'utente Googolplex, quindi nei punti necessari farò riferimento a questo articolo.
  • Precedentemente ci si registra in Sonatype JIRA e si apre un ticket per la creazione del repository (dettagli su come fare nella sezione Creazione di un ticket su Sonatype JIRA). 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 Impostazione di GnuPG per la firma degli artefatti
  • Se si utilizza il terminale Linux per generare la chiave GPG (gnupg/gnupg2), è necessario installare rng-tools per generare entropia. Altrimenti, la generazione della chiave potrebbe richiedere molto tempo.
  • Servizi di archiviazione pubblica chiavi GPG

Contenuto

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 — deploy
  • 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.
    Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central
  • 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 la firma dei commit, 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 variabile DEPLOY_TOKEN con il valore del token di trigger.

Contenuto

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.

Contenuto

Installa il gitlab runner

  • Crea un nuovo gruppo runner
    sudo 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-deployer e aggiungilo al gruppo runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Aggiungi nel file /etc/ssh/sshd_config la seguente riga
    AllowUsers root@* gitlab-deployer@127.0.0.1
  • Riavvia Il client SSH e i programmi
    systemctl 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

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

  • 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

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

  • 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

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

Contenuto

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

Contenuto

Configurazione di Maven

  • Accediamo con l'utente gitlab-deployer
    su 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 GitLab CI

Contenuto

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 GitLab CI per il caricamento di un progetto Java su Maven Central

Contenuto

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_XML le 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_XML le 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

Contenuto

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

Contenuto

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=true

Contenuto

Progetto 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 gitlab-ci in cui ho posizionato il template CI per i progetti Java. common.yml.

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_deploy

Contenuto

Configurazione di pom.xml

Questo argomento è descritto in modo molto dettagliato. Googolplex in Configurazione di Maven per la firma automatica e il caricamento degli artefatti nei repository snapshot e staging., 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
        
        true

Contenuto

maven-javadoc-plugin

Generazione della javadoc per il progetto.

org.apache.maven.plugins
  maven-javadoc-plugin
  
    
      
        jar
      
      
      prepare-package
      
        
        true
        true
        
        false

Se 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}/javadoc

Contenuto

maven-gpg-plugin

org.apache.maven.plugins
  maven-gpg-plugin
  
    
      sign-artifacts
      
      
      deploy
      
        sign

Contenuto

nexus-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
      
        true

Dopo il caricamento, le versioni snapshot/release sono disponibili in repository di staging

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

Contenuto

Risultato

Pubblicazione della versione SNAPSHOT

Durante la costruzione del progetto è possibile eseguire manualmente il compito di caricamento della versione SNAPSHOT nel nexus

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

L'esecuzione di questo compito attiva un compito corrispondente nel progetto deploy (un esempio).

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 1.0.0-SNAPSHOT.

Tutte le versioni snapshot possono essere eliminate dal repository sul sito oss.sonatype.org sotto il proprio account.

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

Contenuto

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 (un esempio).

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

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.

Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

Dopo il rilascio, dopo un po' gli artifact saranno in Configurazione di GitLab CI per il caricamento di un progetto Java su Maven Central

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.

Contenuto

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.

Contenuto

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster