Nastavení GitLab CI pro nahrání java projektu do maven central.

Tento článek je určen pro vývojáře v jazyce Java, kteří potřebují rychle publikovat své produkty v repozitářích Sonatype a/nebo Maven Central pomocí GitLabu. V tomto článku popíšu nastavení gitlab-runner, gitlab-ci a maven-plugin pro řešení tohoto úkolu.

Předpoklady:

  • Bezpečné ukládání klíčů mvn a GPG.
  • Bezpečné provádění veřejných úloh CI.
  • Nahrávání artefaktů (release/snapshot) do veřejných repozitářů.
  • Automatická kontrola release verzí pro publikaci v Maven Central.
  • Obecné řešení pro nahrávání artefaktů do repozitáře pro několik projektů.
  • Jednoduchost a pohodlí použití.

Obsah

Obecné informace

  • Podrobný popis mechanismu publikace artefaktů v Maven Central přes Sonatype OSS Repository Hosting Service byl již popsán v tomto článku uživatelem Googolplex, proto budu v potřebných místech odkazovat na tento článek.
  • Nejprve se zaregistrujeme na Sonatype JIRA a založíme ticket pro otevření repozitáře (podrobnosti najdete v sekci Vytváříme ticket na Sonatype JIRA). Po otevření repozitáře bude pár přihlašovacích údajů/hesel z JIRA (dále účet Sonatype) použito k nahrávání artefaktů do Sonatype nexus.
  • Následuje proces generování GPG klíče je popsán velmi stručně. Podrobněji viz sekce Nastavení GnuPG pro podepisování artefaktů
  • Pokud používáte Linux konzoli pro generování GPG klíče (gnupg/gnupg2), je nutné nainstalovat rng-tools pro generování entropie. Jinak může generování klíče trvat velmi dlouho.
  • Služby ukládání veřejných GPG klíčů

K obsahu

Nastavení deploy projektu v GitLab

  • Nejprve je nutné vytvořit a nastavit projekt, ve kterém bude ukládán pipeline pro nasazení artefaktů. Svůj projekt jsem pojmenoval jednoduše a bez složitostí — deploy
  • Po vytvoření repozitáře je nutné omezit přístup k úpravám repozitáře.
    Přejděte na projekt -> Nastavení -> Repozitář -> Ochráněné branche. Odstraňte všechna pravidla a přidejte jediné pravidlo s Wildcard * s oprávněním na push a merge pouze pro uživatele s rolí Maintainers. Toto pravidlo bude platit pro všechny uživatele jak tohoto projektu, tak i skupiny, do které tento projekt patří.
    Nastavení GitLab CI pro nahrání java projektu do maven central.
  • Pokud je více správců, nejlepší řešení bude omezit přístup k projektu celkově.
    Přejdeme do projektu -> Nastavení -> Obecné -> Viditelnost, funkce projektu, oprávnění a nastavíme Viditelnost projektu na hodnotu Private.
    Můj projekt je veřejně přístupný, protože používám vlastní GitLab Runner a přístup k úpravám repozitáře mám pouze já. A samozřejmě, není v mém zájmu zveřejňovat soukromé informace v veřejných pipeline logách.
  • Zpřísnění pravidel pro úpravy repozitáře
    Přejdeme do projektu -> Nastavení -> Repozitář -> Pravidla pro push a nastavíme přepínače Omezení committerů, Zkontrolovat, zda je autor uživatelským účtem GitLab. Také doporučuji nastavit podpis commitů, a nastavit přepínač Odmítnout nepodepsané commity.
  • Dále je potřeba nastavit spouštěč pro spuštění úloh
    Přejdeme do projektu -> Nastavení -> CI / CD -> Spouštěče pipeline a vytvoříme nový trigger-token
    Tento token můžeme ihned přidat do společné konfigurace proměnných pro skupinu projektů.
    Přejdeme do skupiny -> Nastavení -> CI / CD -> Proměnné a přidáme proměnnou DEPLOY_TOKEN s trigger-token v hodnotě.

K obsahu

GitLab Runner

V této části je popsána konfigurace pro spuštění úloh na deploy pomocí vlastního (Specific) a veřejného (Shared) runneru.

Specifický runner

Používám vlastní runnery, protože to je především pohodlné, rychlé a levné.
Pro runner doporučuji linuxový VDS s 1 CPU, 2 GB RAM, 20 GB HDD. Cena je přibližně 3000₽ ročně.

Můj runner

Pro runner jsem si vzal VDS 4 CPU, 4 GB RAM, 50 GB SSD. Stál přibližně 11000₽ a nikdy jsem nelitoval.
Mám celkem 7 strojů. 5 na aruba a 2 na ihor.

Takže máme runner. Teď ho budeme nastavovat.
Přihlásíme se na stroj přes SSH a nainstalujeme java, git, maven, gnupg2.

K obsahu

Instalujeme GitLab Runner

  • Vytvoříme novou skupinu runner
    sudo groupadd runner
  • Vytvoříme adresář pro maven cache a nastavíme práva skupiny runner
    Tento krok lze přeskočit, pokud neplánujete spouštět více runnerů na jednom stroji.
    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Vytváříme uživatele gitlab-deployer a přidáme do skupiny runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Přidáme do souboru /etc/ssh/sshd_config další řádek
    AllowUsers root@* gitlab-deployer@127.0.0.1
  • Restartujeme sshd.
    systemctl restart sshd
  • Nastavíme heslo pro uživatele gitlab-deployer (může být jednoduché, protože platí omezení pro localhost)
    passwd gitlab-deployer
  • Instalujeme 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
  • Přejdeme na web gitlab.com -> deploy-project -> Nastavení -> CI/CD -> Runners -> Specifické spouštěče a zkopírujeme registrační token

Screenshot

Nastavení GitLab CI pro nahrání java projektu do maven central.

  • Registrujeme spouštěč
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

Proces

Runtime platform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Běží v systémovém režimu.
Zadejte URL gitlab-ci koordinátora (např. https://gitlab.com/):
https://gitlab.com/
Zadejte gitlab-ci token pro tento spouštěč:
REGISTRATION_TOKEN
Zadejte gitlab-ci popis pro tento spouštěč:
[ih1174328.vds.myihor.ru]: Deploy Runner
Zadejte gitlab-ci tagy pro tento spouštěč (oddělené čárkami):
deply
Registrace spouštěče... úspěšná                     spouštěč=ZvKdjJhx
Zadejte executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Spouštěč registrován úspěšně. Můžete ho spustit, ale pokud již běží, konfigurace by se měla automaticky znovu načíst!
  • Ověřujeme, že spouštěč je registrován. Přejdeme na web gitlab.com -> deploy-project -> Nastavení -> CI/CD -> Runners -> Specifické spouštěče -> Spouštěče aktivované pro tento projekt

Screenshot

Nastavení GitLab CI pro nahrání java projektu do maven central.

  • Přidat samostatný servis /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
  • Spouštíme službu.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Ověřujeme, že spouštěč je spuštěn.

Příklad

Nastavení GitLab CI pro nahrání java projektu do maven central.

K obsahu

Generování GPG klíčů

  • Z této stejné mašiny se přihlásíme přes ssh jako uživatel gitlab-deployer (to je důležité pro generování GPG klíče)
    ssh gitlab-deployer@127.0.0.1
  • Generujeme klíč odpovídáním na otázky. Použil jsem své vlastní jméno a e-mail.
    Určitě uveďte heslo pro klíč. Tímto klíčem budou podepisovány artefakty.
    gpg --gen-key 
  • Kontrolujeme
    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
  • Na server klíčů nahráváme náš veřejný klíč
    gpg --keyserver keys.gnupg.net --send-key 00000000
    gpg: sending key 00000000 to hkp server keys.gnupg.net

K obsahu

Nastavení Maven

  • Přihlašujeme se jako uživatel gitlab-deployer
    su gitlab-deployer 
  • Vytváříme adresář maven repository a propojujeme s cache (nezaměňte)
    Tento krok můžete přeskočit, pokud neplánujete spouštět více spouštěčů na jedné mašině.
    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Vytváříme master klíč
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Vytváříme soubor ~/.m2/settings-security.xml
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Šifrujeme heslo k účtu Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Vytvoříme soubor ~/.m2/settings.xml
    env
            
                true
            
            
                GPG_SECRET_KEY_PASSPHRASE
            
        
    
    
        
            sonatype
            SONATYPE_USERNAME
            {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}

kde,
GPG_SECRET_KEY_PASSPHRASE — heslo k GPG klíči
SONATYPE_USERNAME — přihlašovací jméno účtu sonatype

Tímto je nastavení runneru dokončeno, můžeme pokračovat k části GitLab CI

K obsahu

Sdílený runner

Generování GPG klíčů

  • Nejprve je třeba vytvořit GPG klíč. K tomu nainstalujeme gnupg.
    yum install -y gnupg
  • Generujeme klíč a odpovídáme na otázky. Použil jsem své jméno a e-mail. Určitě zadejte heslo pro klíč.
    gpg --gen-key 
  • Zobrazíme informace o klíči
    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]
  • Na server klíčů nahráváme náš veřejný klíč
    gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    gpg: sending key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 to hkp server keys.gnupg.net
  • Získáváme soukromý klíč
    gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    -----BEGIN PGP PRIVATE KEY BLOCK-----
    lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5
    ...
    =2Wd2
    -----END PGP PRIVATE KEY BLOCK-----
  • Přejdeme do nastavení projektu -> Nastavení -> CI / CD -> Proměnné a uložíme soukromý klíč do proměnné GPG_SECRET_KEY
    Nastavení GitLab CI pro nahrání java projektu do maven central.

K obsahu

Nastavení Maven

  • Vytváříme master klíč
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Přejdeme do nastavení projektu -> Nastavení -> CI / CD -> Proměnné a uložíme do proměnné SETTINGS_SECURITY_XML následující řádky:
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Šifrujeme heslo k účtu Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Přejdeme do nastavení projektu -> Nastavení -> CI / CD -> Proměnné a uložíme do proměnné SETTINGS_XML následující řádky:
    env
            
                true
            
            
                GPG_SECRET_KEY_PASSPHRASE
            
        
    
    
        
            sonatype
            sonatype_username
            {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}

kde,
GPG_SECRET_KEY_PASSPHRASE — heslo k GPG klíči
SONATYPE_USERNAME — přihlašovací jméno účtu sonatype

K obsahu

Nasazení docker image

  • Vytvoříme dostatečně jednoduchý Dockerfile pro spuštění úkolů na deploy s požadovanou verzí Javy. Níže je uveden příklad pro 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/
  • Sestavujeme kontejner pro váš projekt
    docker build -t registry.gitlab.com/group/deploy .
  • Autentizujeme se a nahráváme kontejner do registry.
    docker login -u USER -p PASSWORD registry.gitlab.com
    docker push registry.gitlab.com/group/deploy

K obsahu

GitLab CI

Nasazení projektu

Přidáváme do kořene deploy-projektu soubor .gitlab-ci.yml
Ve skriptu jsou uvedeny dvě vzájemně se vylučující úlohy nasazení. Specific Runner nebo Shared Runner podle toho.

.gitlab-ci.yml

stages:
  - deploy

Specific Runner:
  extends: .java_deploy_template
  # Úloha bude provedena na vašem shell-runneru
  tags:
    - deploy

Shared Runner:
  extends: .java_deploy_template
  # Úloha bude provedena na veřejném docker-runneru
  tags:
    - docker
  # Obraz z oddílu GitLab Runner -> Shared Runner -> Docker
  image: registry.gitlab.com/group/deploy-project:latest
  before_script:
    # Importujeme GPG klíč
    - printf "${GPG_SECRET_KEY}" | gpg --batch --import
    # Ukládáme maven konfiguraci
    - printf "${SETTINGS_SECURITY_XML}" > ~/{.m2}/settings-security.xml
    - printf "${SETTINGS_XML}" > ~/{.m2}/settings.xml

.java_deploy_template:
  stage: deploy
  # Úloha bude aktivována, pokud je předána proměnná DEPLOY s hodnotou java
  only:
    variables:
    - $DEPLOY == "java"
  variables:
    # zakážeme klonování aktuálního projektu
    GIT_STRATEGY: none
  script:
    # Umožňujeme ukládat heslo v nezašifrované podobě
    - git config --global credential.helper store
    # Ukládáme dočasné přihlašovací údaje pro uživatele gitlab-ci-token
    # Token funguje pro všechny veřejné projekty gitlab.com a pro projekty skupiny
    - echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/{.git-credentials}
    # Úplně vyčistíme aktuální adresář
    - rm -rf .* *
    # Klonujeme projekt, který budeme nasazovat do Sonatype Nexus
    - git clone ${DEPLOY_CI_REPOSITORY_URL} .
    # Přepínáme se na požadovaný commit
    - git checkout ${DEPLOY_CI_COMMIT_SHA} -f
    # Pokud jakýkoli pom.xml obsahuje parametr autoReleaseAfterClose, tak zrušíme sestavení.
    # Jinak hrozí, že nahrajeme syrové artefakty do maven central
    - >
      for pom in $(find . -name pom.xml); do
        if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
          echo "Soubor $pom obsahuje zakázané nastavení: <autoReleaseAfterClose>";
          exit 1;
        fi;
      done
    # Pokud je parametr DEPLOY_CI_COMMIT_TAG prázdný, pak nutně nastavíme SNAPSHOT-verzi
    - >
      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
    # Spouštíme úlohu na sestavení a nasazení artefaktů
    - mvn clean deploy -DskipTests=true

K obsahu

Java projekt

V java projektech, které mají být nahrány do veřejných repozitářů, je nutné přidat 2 kroky pro nahrání Release a Snapshot verzí.

.gitlab-ci.yml

stages:
  - build
  - test
  - verify
  - deploy



Release:
  extends: .trigger_deploy
  # Spouštět úlohu pouze podle tagu.
  only:
    - tags

Snapshot:
  extends: .trigger_deploy
  # Spouštíme úlohu pro publikaci SNAPSHOT verze ručně
  when: manual
  # Nespouštět úlohu, pokud je nastaven tag.
  except:
    - tags

.trigger_deploy:
  stage: deploy
  variables:
    # Vypínáme klonování aktuálního projektu
    GIT_STRATEGY: none
    # Odkaz na trigger deploy-úlohy
    URL: "https://gitlab.com/api/v4/projects//trigger/pipeline"
    # Proměnné deploy-úlohy
    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:
    # Nepoužívám cURL, protože s flagy --fail --show-error
    # nevytiskne obsah odpovědi, pokud HTTP kód je 400 a vyšší 
    - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

V tomto řešení jsem šel o něco dál a rozhodl se použít jeden CI šablonu pro java projekty.

Podrobnější informace

Vytvořil jsem samostatný projekt gitlab-ci ve kterém jsem umístil šablonu CI pro java projekty common.yml.

common.yml

stages:
  - build
  - test
  - verify
  - deploy

variables:
  SONAR_ARGS: "
  -Dsonar.gitlab.commit_sha=${CI_COMMIT_SHA} 
  -Dsonar.gitlab.ref_name=${CI_COMMIT_REF_NAME} 
  "

.build_java_project:
  stage: build
  tags:
    - touchbit-shell
  variables:
    SKIP_TEST: "false"
  script:
    - mvn clean
    - mvn package -DskipTests=${SKIP_TEST}
  artifacts:
    when: always
    expire_in: 30 day
    paths:
      - "*/target/reports"

.build_sphinx_doc:
  stage: build
  tags:
    - touchbit-shell
  variables:
    DOCKERFILE: .indirect/docs/Dockerfile
  script:
    - docker build --no-cache -t ${CI_PROJECT_NAME}/doc -f ${DOCKERFILE} .

.junit_module_test_run:
  stage: test
  tags:
    - touchbit-shell
  variables:
    MODULE: ""
  script:
    - cd ${MODULE}
    - mvn test
  artifacts:
    when: always
    expire_in: 30 day
    paths:
      - "*/target/reports"

.junit_test_run:
  stage: test
  tags:
    - touchbit-shell
  script:
    - mvn test
  artifacts:
    when: always
    expire_in: 30 day
    paths:
    - "*/target/reports"

.sonar_review:
  stage: verify
  tags:
    - touchbit-shell
  dependencies: []
  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:
  stage: deploy
  tags:
    - 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:
  extends: .trigger_deploy
  only:
    - tags

.trigger_snapshot_deploy:
  extends: .trigger_deploy
  when: manual
  except:
    - tags

Výsledkem je, že samotné java projekty .gitlab-ci.yml vypadají velmi kompaktně a nejsou příliš rozvláčné.

.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

K obsahu

Konfigurace pom.xml

Toto téma je podrobně popsáno. Googolplex v Nastavení Maven pro automatické podepisování a nahrávání artefaktů do snapshot a staging repozitářů., proto popíšu některé nuancy použití pluginů. Také popíšu, jak snadno a přirozeně je možné je používat. nexus-staging-maven-plugin, pokud nechcete, nebo nemůžete použít org.sonatype.oss:oss-parent jako rodiče pro svůj projekt.

maven-install-plugin

Instaluje moduly do lokálního repozitáře.
Velmi užitečné pro lokální ověření řešení v jiných projektech a také kontrolní sumou.

org.apache.maven.plugins
  maven-install-plugin
  
    
      install-project
      
      install
      
      
        target/${project.artifactId}-${project.version}.jar
        
        dependency-reduced-pom.xml
        
        true
        
        true

K obsahu

maven-javadoc-plugin

Generování javadoc pro projekt.

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

Pokud máte modul, který neobsahuje java (například pouze zdroje).
Nebo pokud nechcete obecně generovat javadoc, pak je tu pomoc. maven-jar-plugin

org.apache.maven.plugins
  maven-jar-plugin
  
    
      empty-javadoc-jar
      generate-resources
      
        jar
      
      
        javadoc
        ${basedir}/javadoc

K obsahu

maven-gpg-plugin

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

K obsahu

nexus-staging-maven-plugin

Konfigurace:


  
    
      
      
        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
      Nexus Snapshot Repository
      https://oss.sonatype.org/content/repositories/snapshots/
    
    
      sonatype
      Nexus Release Repository
      https://oss.sonatype.org/service/local/staging/deploy/maven2/

Pokud máte multimodulový projekt a není nutné nahrávat konkrétní modul do repozitáře, je třeba do pom.xml tohoto modulu přidat nexus-staging-maven-plugin s příznakem skipNexusStagingDeployMojo

org.sonatype.plugins
      nexus-staging-maven-plugin
      
        true

Po nahrání jsou verze snapshot/release k dispozici v staging repozitáře

SonatypeNexus
    https://oss.sonatype.org/content/groups/staging/

Další výhody

  • Velmi bohatý seznam cílů pro práci s nexus repozitářem (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Automatická kontrola vydání na možnost nahrání do maven central

K obsahu

Výsledek

Publikace SNAPSHOT verze

Při sestavení projektu je k dispozici možnost ručního spuštění úkolu pro nahrání SNAPSHOT verze do nexus

Nastavení GitLab CI pro nahrání java projektu do maven central.

Při spuštění tohoto úkolu se spouští odpovídající úkol v projektu deploy (příklad).

Oříznutý log

Spuštění s gitlab-runner 11.10.0 (3001a600)
  na nasazovacím runneru JSKWyxUw
Použití shell executor...
Běžící na ih1174328.vds.myihor.ru...
Přeskočená konfigurace repozitáře Git
Přeskočený checkout Git
Přeskočená konfigurace submodulů 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} .
Klonování do 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Poznámka: kontrola '850f86aa317194395c5387790da1350e437125a7'.
Nacházíte se ve stavu 'detached HEAD'. Můžete se podívat okolo, provádět experimentální
změny a commitovat je, a můžete zrušit jakékoli commity, které provedete v této
poloze, aniž byste ovlivnili jakékoli větve provedením dalšího checkoutu.
Pokud chcete vytvořit novou větev, abyste si uchovali commity, které vytváříte, můžete
to udělat (nyní nebo později) pomocí -b s příkazem checkout znovu. Příklad:
  git checkout -b new_branch_name
HEAD je nyní na 850f86a... přeskočit deploy test-core
$ for pom in $(find . -name pom.xml); do # zkrácený víceřádkový příkaz
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # zkrácený víceřádkový příkaz
[INFO] Skanning projektů...
[INFO] Kontrola buildu se součtem 4 modulů...
[INFO] Instalace funkcí Nexus Staging:
[INFO]   ... celkem 4 provedení maven-deploy-plugin nahrazeno nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Pořadí sestavení Reactoru:
[INFO] 
[INFO] Shields4J                                                          [pom]
[INFO] test-core                                                          [jar]
[INFO] Shields4J client                                                   [jar]
[INFO] TestNG listener                                                    [jar]
[INFO] 
[INFO] -----------------------------
[INFO] Sestavení Shields4J 1.0.0                                           [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Hledání kořene místního agregátoru...
[INFO] Místní agregace kořen: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Zpracování změny org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Zpracování org.touchbit.shields4j:shields4j-parent
[INFO]     Aktualizace projektu org.touchbit.shields4j:shields4j-parent
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO] 
[INFO] Zpracování org.touchbit.shields4j:client
[INFO]     Aktualizace rodiče org.touchbit.shields4j:shields4j-parent
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO]     Aktualizace závislosti org.touchbit.shields4j:test-core
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO] 
[INFO] Zpracování org.touchbit.shields4j:test-core
[INFO]     Aktualizace rodiče org.touchbit.shields4j:shields4j-parent
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO] 
[INFO] Zpracování org.touchbit.shields4j:testng
[INFO]     Aktualizace rodiče org.touchbit.shields4j:shields4j-parent
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO]     Aktualizace závislosti org.touchbit.shields4j:client
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO]     Aktualizace závislosti org.touchbit.shields4j:test-core
[INFO]         z verze 1.0.0 na 1.0.0-SNAPSHOT
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Shrnutí Reactoru:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... ÚSPĚCH [  0.992 s]
[INFO] test-core .......................................... PŘESKOČENO
[INFO] Shields4J client ................................... PŘESKOČENO
[INFO] TestNG listener 1.0.0 .............................. PŘESKOČENO
[INFO] ------------------------------------------------------------------------
[INFO] VÝBAVA ÚSPĚCHU
[INFO] ------------------------------------------------------------------------
[INFO] Celkový čas: 2.483 s
[INFO] Dokončeno: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Skanning projektů...
[INFO] Kontrola buildu se součtem 4 modulů...
[INFO] Instalace funkcí Nexus Staging:
[INFO]   ... celkem 4 provedení maven-deploy-plugin nahrazeno nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Pořadí sestavení Reactoru:
[INFO] 
[INFO] Shields4J                                                          [pom]
[INFO] test-core                                                          [jar]
[INFO] Shields4J client                                                   [jar]
[INFO] TestNG listener                                                    [jar]
[INFO] 
[INFO] -----------------------------
[INFO] Sestavení Shields4J 1.0.0-SNAPSHOT                                  [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
SMAZÁNO
...
[INFO]  * Hromadné nasazení místně shromážděných artefaktů snapshot skončeno.
[INFO] Vzdálené nasazení dokončeno úspěšně.
[INFO] ------------------------------------------------------------------------
[INFO] Shrnutí Reactoru:
[INFO] 
[INFO] Shields4J 1.0.0-SNAPSHOT ........................... ÚSPĚCH [  2.375 s]
[INFO] test-core .......................................... ÚSPĚCH [  3.929 s]
[INFO] Shields4J client ................................... ÚSPĚCH [  3.815 s]
[INFO] TestNG listener 1.0.0-SNAPSHOT ..................... ÚSPĚCH [ 36.134 s]
[INFO] ------------------------------------------------------------------------
[INFO] VÝBAVA ÚSPĚCHU
[INFO] ------------------------------------------------------------------------
[INFO] Celkový čas: 47.629 s
[INFO] Dokončeno: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------

V důsledku toho byla do nexus nahrána verze 1.0.0-SNAPSHOT.

Všechny snapshot verze lze odstranit z repozitáře na webu oss.sonatype.org pod svým uživatelským účtem.

Nastavení GitLab CI pro nahrání java projektu do maven central.

K obsahu

Publikace release verze

Při instalaci tagu se automaticky spustí odpovídající úloha v projektu deploy k nahrání stabilní verze do nexus (příklad).

Nastavení GitLab CI pro nahrání java projektu do maven central.

Nejlepší na tom je, že se automaticky spustí close release v nexus.

[INFO] Provádím vzdálené staging...
[INFO] 
[INFO]  * Vzdálené staging do staging profilu ID "9043b43f77dcc9"
[INFO]  * Vytvořen staging repozitář s ID "orgtouchbit-1037".
[INFO]  * Staging repozitář na https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO]  * Nahrávání místně stagingovaných artefaktů do profilu org.touchbit
[INFO]  * Nahrání místně stagingovaných artefaktů dokončeno.
[INFO]  * Uzavření staging repozitáře s ID "orgtouchbit-1037".
Čekání na dokončení operace...
.........
[INFO] Vzdáleně stagingováno 1 repozitář, úspěšně dokončeno.
[INFO] ------------------------------------------------------------------------
[INFO] Shrnutí reaktoru:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... ÚSPĚCH [  9.603 s]
[INFO] test-core .......................................... ÚSPĚCH [  3.419 s]
[INFO] Shields4J klient ................................... ÚSPĚCH [  9.793 s]
[INFO] TestNG listener 1.0.0 .............................. ÚSPĚCH [01:23 min]
[INFO] ------------------------------------------------------------------------
[INFO] VÝSTAVBA ÚSPĚŠNÁ
[INFO] ------------------------------------------------------------------------
[INFO] Celkový čas: 01:47 min
[INFO] Dokončeno: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------

A pokud něco nevyšlo, úloha se určitě nezdaří.

[INFO] Provádění vzdáleného stagingu...
[INFO] 
[INFO]  * Vzdálený staging do profilu staging ID "9043b43f77dcc9"
[INFO]  * Vytvořen stagingový repozitář s ID "orgtouchbit-1038".
[INFO]  * Stagingový repozitář na https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO]  * Nahrávání lokálně staged artefaktů do profilu org.touchbit
[INFO]  * Nahrávání lokálně staged artefaktů dokončeno.
[INFO]  * Uzavření stagingového repozitáře s ID "orgtouchbit-1038".
Čekání na dokončení operace...
.......
[ERROR] Chyba pravidla při pokusu o uzavření stagingového repozitáře s ID "orgtouchbit-1039".
[ERROR] 
[ERROR] Zpráva o selhání pravidel Nexus Staging
[ERROR] ==================================
[ERROR] 
[ERROR] Selhání repozitáře "orgtouchbit-1039"
[ERROR]   Selhání pravidla "signature-staging"
[ERROR]     * Žádný veřejný klíč: Klíč s id: (1f42b618d1cbe1b5) nebyl nalezen na http://keys.gnupg.net:11371/. Nahrajte svůj veřejný klíč a zkuste operaci znovu.
...
[ERROR] Úklid lokálního stagingového adresáře po selhání pravidla během uzavření stagingových repozitářů: [orgtouchbit-1039]
[ERROR]  * Mazání kontextu 9043b43f77dcc9.properties
[ERROR] Úklid vzdálených stagingových repozitářů po selhání pravidla během uzavření stagingových repozitářů: [orgtouchbit-1039]
[ERROR]  * Odstranění selhávajícího stagingového repozitáře s ID "orgtouchbit-1039" (Chyba pravidla během uzavření stagingových repozitářů: [orgtouchbit-1039]).
[ERROR] Vzdálený staging skončil s chybou: Selhání pravidel pro staging!
[INFO] ------------------------------------------------------------------------
[INFO] Shrnutí reaktoru:
[INFO] 
[INFO] Shields4J 1.0.0 .................................... ÚSPĚCH [  4.073 s]
[INFO] test-core .......................................... ÚSPĚCH [  2.788 s]
[INFO] Shields4J client ................................... ÚSPĚCH [  3.962 s]
[INFO] TestNG listener 1.0.0 .............................. SELHÁNÍ [01:07 min]
[INFO] ------------------------------------------------------------------------
[INFO] SELHÁNÍ VÝSTAVBY
[INFO] ------------------------------------------------------------------------

Zůstává nám pouze jedna volba. Buď odstranit tuto verzi, nebo ji publikovat.

Nastavení GitLab CI pro nahrání java projektu do maven central.

Po vydání se artefakty za chvíli objeví v Nastavení GitLab CI pro nahrání java projektu do maven central.

of topic

Bylo pro mě překvapením, že maven indexuje jiné veřejné repozitáře.
Musel jsem přidat robots.txt, protože indexoval můj starý repozitář.

K obsahu

Závěr

Co máme

  • Samostatný deploy projekt, ve kterém lze realizovat několik CI úloh pro nahrávání artefaktů do veřejných repozitářů pro různé vývojové jazyky.
  • Deploy projekt je izolován od vnějšího zásahu a může být změněn pouze uživateli s rolí Owner a Maintainer.
  • Samostatný Specific Runner s „horkou“ cache pro spuštění pouze deploy úloh.
  • Publikace snapshot/release verzí do veřejného repozitáře.
  • Automatická kontrola release verze na připravenost k publikaci v maven central.
  • Ochrana před automatickou publikací „syrových“ verzí v maven central.
  • Sestavení a publikace snapshot verzí „jedním kliknutím“.
  • Jednotný repozitář pro získání snapshot/release verzí.
  • Obecný pipeline pro sestavení/testování/publikaci java projektu.

Nastavení GitLab CI není tak složité, jak se na první pohled zdá. Stačí několikrát nastavit CI „na klíč“ a už jsi daleko od nováčka v této oblasti. O to víc, že dokumentace GitLab je velmi podrobná. Nebojte se udělat první krok. Cesta vzniká pod kroky jdoucho (nevzpomínám si, kdo to řekl 🙂 ).

Budu rád za zpětnou vazbu.

V dalším článku se podělím o to, jak nastavit GitLab CI pro paralelní spuštění úloh s integračními testy (spuštění testovaných služeb pomocí docker-compose), pokud máte pouze jednoho shell runnera.

K obsahu

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster