Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

Kuhi ʻia kēia ʻatikala no nā mea hoʻomohala java e pono e hoʻolaha koke i kā lākou huahana ma sonatype a / a i ʻole maven kikowaena kikowaena me GitLab. Ma kēia ʻatikala e kamaʻilio wau e pili ana i ka hoʻonohonoho ʻana i ka gitlab-runner, gitlab-ci a me ka maven-plugin e hoʻoponopono i kēia pilikia.

Nā Pono:

  • Mālama palekana i nā kī mvn a me GPG.
  • Hoʻokō palekana i nā hana CI lehulehu.
  • Ka hoʻouka ʻana i nā mea kiʻi (hoʻokuʻu/paʻi kiʻi) i nā waihona lehulehu.
  • Nānā 'akomi o nā mana hoʻokuʻu no ka hoʻolaha ʻana ma ke kikowaena maven.
  • He hopena maʻamau no ka hoʻouka ʻana i nā mea kiʻi i kahi waihona no nā papahana he nui.
  • ʻO ka maʻalahi a me ka maʻalahi o ka hoʻohana.

Nā mea

Nāʻike nui

  • Ua wehewehe mua ʻia kahi wehewehe kikoʻī o ka mīkini no ka hoʻopuka ʻana i nā mea kiʻi ma Maven Central ma o Sonatype OSS Repository Hosting Service. keia 'atikala mea hoʻohana Googolplex, no laila e kuhikuhi wau i kēia ʻatikala ma nā wahi kūpono.
  • Kakau mua ma Sonatype JIRA a hoʻomaka i kahi tiketi e wehe i ka waihona (no nā kikoʻī hou aku, heluhelu i ka ʻāpana E hana i kahi tiketi Sonatype JIRA). Ma hope o ka wehe ʻana i ka waihona, e hoʻohana ʻia ka JIRA login / password pair (ma hope i kapa ʻia ʻo ka Sonatype account) e hoʻouka i nā kiʻi i ka Sonatype nexus.
  • Eia kekahi, wehewehe maloʻo loa ke kaʻina hana o ka hana ʻana i kahi kī GPG. E ʻike i ka ʻāpana no nā kikoʻī hou aku. Ka hoʻonohonoho ʻana iā GnuPG e kau inoa i nā mea hana
  • Inā hoʻohana ʻoe i ka console Linux e hana i kahi kī GPG (gnupg/gnupg2), a laila pono ʻoe e hoʻokomo. rng-mea hana e hoopuka i ka entropy. A i ʻole, hiki i ka hana kī ke lawe i kahi manawa lōʻihi loa.
  • Nā lawelawe mālama lehulehu Nā kī GPG

I ka maʻiʻo

Hoʻonohonoho i kahi papahana hoʻolālā ma GitLab

  • ʻO ka mea mua, pono ʻoe e hana a hoʻonohonoho i kahi papahana kahi e mālama ʻia ai ka pipeline i mea e kau ai i nā artifacts. Ua kāhea wau i kaʻu papahana maʻalahi a paʻakikī - hoʻolālā
  • Ma hope o ka hana ʻana i ka waihona, pono ʻoe e kaupalena i ke komo ʻana e hoʻololi i ka waihona.
    E hele i ka papahana -> Settings -> Repository -> Nā lālā pale. Holoi mākou i nā lula āpau a hoʻohui i hoʻokahi lula me Wildcard * me ke kuleana e paʻi a hoʻohui wale no nā mea hoʻohana me ke kuleana Maintainers. E hoʻohana ʻia kēia lula no nā mea hoʻohana a pau o kēia papahana a me ka hui nona kēia papahana.
    Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena
  • Inā he nui nā mea mālama, a laila ʻo ka hopena maikaʻi loa ʻo ka hoʻopaʻa ʻana i ke komo ʻana i ka papahana ma ke kumu.
    E hele i ka papahana -> Nā hoʻonohonoho -> Nui -> ʻIke, nā hiʻohiʻona papahana, nā ʻae a hoʻonohonoho i ka ʻike Project uku.
    Loaʻa iaʻu kahi papahana i ka lehulehu, ʻoiai ke hoʻohana nei au i kaʻu GitLab Runner a ʻo wau wale nō ka mea hiki ke hoʻololi i ka waihona. ʻAe, ʻaʻole pono iaʻu e hōʻike i ka ʻike pilikino i nā lāʻau pipeline lehulehu.
  • Hoʻopaʻa i nā lula no ka hoʻololi ʻana i ka waihona
    E hele i ka papahana -> Settings -> Repository -> Push Rules a hoʻonoho i nā hae Committer palena, E nānā inā he mea hoʻohana GitLab ka mea kākau. Paipai au i ka hoʻonohonoho ʻana hoʻopaʻa inoa, a hoʻonoho i ka hae hoʻopaʻa inoa ʻole.
  • A laila, pono ʻoe e hoʻonohonoho i kahi trigger e holo i nā hana
    E hele i ka papahana -> Settings -> CI / CD -> Pipeline triggers a hana i kahi hōʻailona hōʻailona hou
    Hiki ke hoʻohui koke ʻia kēia hōʻailona i ka hoʻonohonoho maʻamau o nā mea hoʻololi no kahi hui o nā papahana.
    E hele i ka hui -> Nā hoʻonohonoho -> CI / CD -> Nā mea hoʻololi a hoʻohui i kahi loli DEPLOY_TOKEN me ka trigger-token i ka waiwai.

I ka maʻiʻo

Ka holo ʻana o GitLab

Hōʻike kēia ʻāpana i ka hoʻonohonoho no ka holo ʻana i nā hana ma ka hoʻohana ʻana i kāu mea holo (Specific) a me ka lehulehu (Shared).

Holokino kikoʻī

Hoʻohana wau i kaʻu mau mea holo ponoʻī, no ka mea ʻo ka mea mua he maʻalahi, wikiwiki, maʻalahi.
No ka mea holo, paipai wau iā Linux VDS me 1 CPU, 2 GB RAM, 20 GB HDD. Kumu kūʻai hoʻopuka ~ 3000₽ i kēlā me kēia makahiki.

Ko'u kukini

No ka mea holo, ua lawe au i ka VDS 4 CPU, 4 GB RAM, 50 GB SSD. Ua kūʻai ʻia ʻo ~11000₽ a ʻaʻole mihi.
Loaʻa iaʻu he 7 mau mīkini. 5 ma aruba a me 2 ma ihor.

No laila he kukini kā mākou. I kēia manawa e hoʻonohonoho mākou.
Hele mākou i ka mīkini ma o SSH a hoʻokomo i ka java, git, maven, gnupg2.

I ka maʻiʻo

Ke hoʻouka nei i ka gitlab runner

  • E hana i hui hou runner
    sudo groupadd runner
  • E hana i kahi papa kuhikuhi no ka maven cache a hāʻawi i nā kuleana hui runner
    Hiki iā ʻoe ke hoʻokuʻu i kēia ʻanuʻu inā ʻaʻole ʻoe e hoʻolālā e holo i nā kukini he nui ma ka mīkini hoʻokahi.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Hana i mea hoʻohana gitlab-deployer a hoʻohui i ka hui runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Hoʻohui i ka faila /etc/ssh/sshd_config laina aʻe
    AllowUsers root@* [email protected]
  • Hoʻomaka hou sshd
    systemctl restart sshd
  • E hoʻonoho i ka ʻōlelo huna no ka mea hoʻohana gitlab-deployer (hiki ke maʻalahi, no ka mea aia kahi palena no localhost)
    passwd gitlab-deployer
  • E hoʻouka iā 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
  • E hele i gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners a kope i ka hōʻailona inoa.

Palena

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

  • Kakau inoa i ka mea kukini
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

kaʻina

Runtime platform arch=amd64 os=linux pid=17594 revision=3001a600 version=11.10.0
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://gitlab.com/
Please enter the gitlab-ci token for this runner:
REGISTRATION_TOKEN
Please enter the gitlab-ci description for this runner:
[ih1174328.vds.myihor.ru]: Deploy Runner
Please enter the gitlab-ci tags for this runner (comma separated):
deploy
Registering runner... succeeded                     runner=ZvKdjJhx
Please enter the executor: docker-ssh, parallels, virtualbox, docker-ssh+machine, kubernetes, docker, ssh, docker+machine, shell:
shell
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

  • E hōʻoia ua kākau inoa ʻia ka mea holo. E hele i gitlab.com -> deploy-project -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners activated for this project

Palena

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

  • Hoʻohui hoʻokaʻawale lawelawe /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
  • E hoʻomaka kākou i ka lawelawe.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • E nānā i ka holo ʻana o ka mea kukini.

Pākuhi:

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

I ka maʻiʻo

Hanana kī GPG

  • Mai ka mīkini like mākou e hele ai ma ssh ma lalo o ka mea hoʻohana gitlab-deployer (He mea nui kēia no ka hana kī GPG)

    ssh [email protected]

  • Hoʻokumu mākou i kahi kī ma ka pane ʻana i nā nīnau. Ua hoʻohana au i koʻu inoa ponoʻī a me ka leka uila.
    E hōʻoia i ka ʻōlelo huna no ke kī. E pūlima ʻia nā mea hana me kēia kī.

    gpg --gen-key 

  • Haki aku

    gpg --list-keys -a
    /home/gitlab-deployer/.gnupg/pubring.gpg
    ----------------------------------------
    pub   4096R/00000000 2019-04-19
    uid                  Petruha Petrov <[email protected]>
    sub   4096R/11111111 2019-04-19

  • Ke hoʻouka ʻana i kā mākou kī ākea i ke kikowaena kī

    gpg --keyserver keys.gnupg.net --send-key 00000000
    gpg: sending key 00000000 to hkp server keys.gnupg.net

I ka maʻiʻo

Hoʻonohonoho maven

  • E komo ma ke ano he mea hoohana gitlab-deployer
    su gitlab-deployer 
  • E hana i kahi papa kuhikuhi maven hale waihona a loulou me ka huna huna (mai kuhi hewa)
    Hiki iā ʻoe ke lele i kēia wahi inā ʻaʻole ʻoe e hoʻolālā e holo i kekahi mau mea holo ma ka mīkini hoʻokahi.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • E hana i kahi kī nui
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • E hana i ka faila ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Hoʻopili i ka ʻōlelo huna mai ka moʻokāki Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • E hana i kahi faila ~/.m2/settings.xml
    <settings>  
    <profiles>
        <profile>
            <id>env</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <gpg.passphrase>GPG_SECRET_KEY_PASSPHRASE</gpg.passphrase>
            </properties>
        </profile>
    </profiles>
    <servers>
        <server>
            <id>sonatype</id>
            <username>SONATYPE_USERNAME</username>
            <password>{98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}</password>
        </server>
    </servers>
    </settings>

ma hea,
GPG_SECRET_KEY_PASSPHRASE - ʻōlelo huna kī GPG
SONATYPE_USERNAME - ke komo mooolelo sonatype

Hoʻopau kēia i ka hoʻonohonoho holo, hiki iā ʻoe ke hele i ka ʻāpana GitLab CI

I ka maʻiʻo

Kaʻana like

Hanana kī GPG

  • ʻO ka mea mua, pono ʻoe e hana i kahi kī GPG. No ka hana ʻana i kēia, hoʻokomo i ka gnupg.

    yum install -y gnupg

  • Hoʻokumu mākou i kahi kī ma ka pane ʻana i nā nīnau. Ua hoʻohana au i koʻu inoa ponoʻī a me ka leka uila. E hōʻoia i ka ʻōlelo huna no ke kī.

    gpg --gen-key 

  • E kiʻi i ka ʻike nui

    gpg --list-keys -a
    pub   rsa3072 2019-04-24 [SC] [expires: 2021-04-23]
      2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    uid           [ultimate] tttemp <[email protected]>
    sub   rsa3072 2019-04-24 [E] [expires: none]

  • Ke hoʻouka ʻana i kā mākou kī ākea i ke kikowaena kī

    gpg --keyserver keys.gnupg.net --send-key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    gpg: sending key 2D0D1706366FC4AEF79669E24D09C55BBA3FD728 to hkp server keys.gnupg.net

  • Loaʻa i kahi kī pilikino

    gpg --export-secret-keys --armor 2D0D1706366FC4AEF79669E24D09C55BBA3FD728
    -----BEGIN PGP PRIVATE KEY BLOCK-----
    lQWGBFzAqp8BDADN41CPwJ/gQwiKEbyA902DKw/WSB1AvZQvV/ZFV77xGeG4K7k5
    ...
    =2Wd2
    -----END PGP PRIVATE KEY BLOCK-----

  • E hele i nā hoʻonohonoho papahana -> Nā hoʻonohonoho -> CI / CD -> Nā mea hoʻololi a mālama i ke kī pilikino i kahi loli GPG_SECRET_KEY
    Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

I ka maʻiʻo

Hoʻonohonoho maven

  • E hana i kahi kī nui
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • E hele i nā hoʻonohonoho papahana -> Nā hoʻonohonoho -> CI / CD -> Nā mea hoʻololi a mālama i kahi loli SETTINGS_SECURITY_XML keia mau laina:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Hoʻopili i ka ʻōlelo huna mai ka moʻokāki Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • E hele i nā hoʻonohonoho papahana -> Nā hoʻonohonoho -> CI / CD -> Nā mea hoʻololi a mālama i kahi loli SETTINGS_XML keia mau laina:
    <settings>  
    <profiles>
        <profile>
            <id>env</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <gpg.passphrase>GPG_SECRET_KEY_PASSPHRASE</gpg.passphrase>
            </properties>
        </profile>
    </profiles>
    <servers>
        <server>
            <id>sonatype</id>
            <username>sonatype_username</username>
            <password>{98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}</password>
        </server>
    </servers>
    </settings>

ma hea,
GPG_SECRET_KEY_PASSPHRASE - ʻōlelo huna kī GPG
SONATYPE_USERNAME - ke komo mooolelo sonatype

I ka maʻiʻo

E hoʻouka i ke kiʻi docker

  • Hoʻokumu mākou i kahi Dockerfile maʻalahi e holo i nā hana ma ka waiho ʻana me ka mana makemake o Java. Aia ma lalo kahi laʻana no ka 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/

  • Ke kūkulu nei i ipu no kāu papahana

    docker build -t registry.gitlab.com/group/deploy .

  • Hoʻopaʻa mākou a hoʻouka i ka pahu i loko o ka papa inoa.

    docker login -u USER -p PASSWORD registry.gitlab.com
    docker push registry.gitlab.com/group/deploy

I ka maʻiʻo

GitLab CI

Hoʻolaha i ka papahana

Hoʻohui i ka faila .gitlab-ci.yml i ke kumu o ka papahana hoʻolālā
Hōʻike ka ʻatikala i ʻelua mau hana hoʻolaha kūʻokoʻa. Runner kiko'ī a i ʻole ka mea holo kaʻa like.

.gitlab-ci.yml

stages:
  - deploy

Specific Runner:
  extends: .java_deploy_template
  # Задача будет выполняться на вашем shell-раннере
  tags:
    - deploy

Shared Runner:
  extends: .java_deploy_template
  # Задача будет выполняться на публичном docker-раннере
  tags:
    - docker
  # Образ из раздела GitLab Runner -> Shared Runner -> Docker
  image: registry.gitlab.com/group/deploy-project:latest
  before_script:
    # Импортируем GPG ключ
    - printf "${GPG_SECRET_KEY}" | gpg --batch --import
    # Сохраняем maven конфигурацию
    - printf "${SETTINGS_SECURITY_XML}" > ~/.m2/settings-security.xml
    - printf "${SETTINGS_XML}" > ~/.m2/settings.xml

.java_deploy_template:
  stage: deploy
  # Задача сработает по триггеру, если передана переменная DEPLOY со значением java
  only:
    variables:
    - $DEPLOY == "java"
  variables:
    # отключаем клонирование текущего проекта
    GIT_STRATEGY: none
  script:
    # Предоставляем возможность хранения пароля в незашифрованном виде
    - git config --global credential.helper store
    # Сохраняем временные креды пользователя gitlab-ci-token
    # Токен работает для всех публичных проектов gitlab.com и для проектов группы
    - echo "https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com" >> ~/.git-credentials
    # Полностью чистим текущую директорию
    - rm -rf .* *
    # Клонируем проект который, будем деплоить в Sonatype Nexus
    - git clone ${DEPLOY_CI_REPOSITORY_URL} .
    # Переключаемся на нужный коммит
    - git checkout ${DEPLOY_CI_COMMIT_SHA} -f
    # Если хоть один pom.xml содержит параметр autoReleaseAfterClose валим сборку.
    # В противном случае есть риск залить сырые артефакты в maven central
    - >
      for pom in $(find . -name pom.xml); do
        if [[ $(grep -q autoReleaseAfterClose "$pom" && echo $?) == 0 ]]; then
          echo "File $pom contains prohibited setting: <autoReleaseAfterClose>";
          exit 1;
        fi;
      done
    # Если параметр DEPLOY_CI_COMMIT_TAG пустой, то принудительно ставим 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
    # Запускаем задачу на сборку и деплой артефактов
    - mvn clean deploy -DskipTests=true

I ka maʻiʻo

papahana Java

Ma nā papahana java i manaʻo ʻia e hoʻouka ʻia i nā waihona waihona lehulehu, pono ʻoe e hoʻohui i nā ʻanuʻu 2 e hoʻoiho i nā mana Hoʻokuʻu a me Snapshot.

.gitlab-ci.yml

stages:
  - build
  - test
  - verify
  - deploy

<...>

Release:
  extends: .trigger_deploy
  # Запускать задачу только пo тегу.
  only:
    - tags

Snapshot:
  extends: .trigger_deploy
  # Запускаем задачу на публикацию SNAPSHOT версии вручную
  when: manual
  # Не запускать задачу, если проставлен тег.
  except:
    - tags

.trigger_deploy:
  stage: deploy
  variables:
    # Отключаем клонирование текущего проекта
    GIT_STRATEGY: none
    # Ссылка на триггер deploy-задачи
    URL: "https://gitlab.com/api/v4/projects/<deploy project ID>/trigger/pipeline"
    # Переменные 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:
    # Не использую cURL, так как с флагами --fail --show-error
    # он не выводит тело ответа, если HTTP код 400 и более 
    - wget --content-on-error -qO- ${URL} --post-data ${POST_DATA}

Ma kēia hoʻonā, ua hele iki au a hoʻoholo e hoʻohana i hoʻokahi template CI no nā papahana java.

Nāʻike hou

Ua hana au i papahana kaawale gitlab-ci kahi i waiho ai ʻo ia i ka template CI no nā papahana java maʻamau.yml.

maʻamau.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

ʻO ka hopena, ma nā papahana java iā lākou iho, ʻike ʻia ka .gitlab-ci.yml i mea paʻa loa a ʻaʻole verbose.

.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

I ka maʻiʻo

Pom.xml hoʻonohonoho

Ua wehewehe nui ʻia kēia kumuhana. Googolplex в Hoʻonohonoho i ka maven e hoʻopaʻa inoa a hoʻouka i nā kiʻi kiʻi i ka snapshot a me ka hoʻonohonoho ʻana i nā waihona, no laila e wehewehe wau i kekahi o nā nuances o ka hoʻohana ʻana i nā plugins. E wehewehe pū wau i ka maʻalahi a me ke kūlohelohe hiki iā ʻoe ke hoʻohana nexus-staging-maven-plugininā ʻaʻole ʻoe makemake a ʻaʻole hiki iā ʻoe ke hoʻohana i ka org.sonatype.oss:oss-parent ma ke ʻano he makua no kāu papahana.

maven-install-plugin

Hoʻokomo i nā modula i loko o ka waihona kūloko.
He mea maikaʻi loa no ka hōʻoia ʻana i nā hoʻonā i nā papahana ʻē aʻe, a me kahi checksum.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-install-plugin</artifactId>
  <executions>
    <execution>
      <id>install-project</id>
      <!-- Если у вас многомодульный проект с деплоем родительского помика -->
      <phase>install</phase>
      <!-- Явно указываем файлы для локальной установки -->
      <configuration>
        <file>target/${project.artifactId}-${project.version}.jar</file>
```target/${project.artifactId}-${project.version}-sources.jar</sources>
        <pomFile>dependency-reduced-pom.xml</pomFile>
        <!-- Принудительное обновление метаданных проекта -->
        <updateReleaseInfo>true</updateReleaseInfo>
        <!-- Контрольные суммы для проверки целостности -->
        <createChecksum>true</createChecksum>
      </configuration>
    </execution>
  </executions>
</plugin>

I ka maʻiʻo

maven-javadoc-plugin

Ke hana nei i javadoc no ka papahana.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <executions>
    <execution>
      <goals>
        <goal>jar</goal>
      </goals>
      <!-- Генерация javadoc должна быть после фазы генерации ресурсов -->
      <phase>prepare-package</phase>
      <configuration>
        <!-- Очень помогает в публичных проектах -->
        <failOnError>true</failOnError>
        <failOnWarnings>true</failOnWarnings>
        <!-- Убирает ошибку поиска документации в target директории -->
        <detectOfflineLinks>false</detectOfflineLinks>
      </configuration>
    </execution>
  </executions>
</plugin>

Inā loaʻa iā ʻoe kahi module ʻaʻohe java (no ka laʻana wale nō nā kumuwaiwai)
A i ʻole makemake ʻoe e hoʻohua i ka javadoc ma ke kumu, a laila e kōkua maven-jar-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <executions>
    <execution>
      <id>empty-javadoc-jar</id>
      <phase>generate-resources</phase>
      <goals>
        <goal>jar</goal>
      </goals>
      <configuration>
        <classifier>javadoc</classifier>
        <classesDirectory>${basedir}/javadoc</classesDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

I ka maʻiʻo

maven-gpg-plugin

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-gpg-plugin</artifactId>
  <executions>
    <execution>
      <id>sign-artifacts</id>
      <!-- Сборка будет падать, если отсутствует GPG ключ -->
      <!-- Подписываем артефакты только на фазе deploy -->
      <phase>deploy</phase>
      <goals>
        <goal>sign</goal>
      </goals>
    </execution>
  </executions>
</plugin>

I ka maʻiʻo

nexus-staging-maven-plugin

Hoʻonohonoho:

<project>
  <!-- ... -->
  <build>
    <plugins>
      <!-- ... -->
      <plugin>
        <groupId>org.sonatype.plugins</groupId>
        <artifactId>nexus-staging-maven-plugin</artifactId>
      </plugin>
    </plugins>
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.sonatype.plugins</groupId>
          <artifactId>nexus-staging-maven-plugin</artifactId>
          <extensions>true</extensions>
          <configuration>
            <serverId>sonatype</serverId>
            <nexusUrl>https://oss.sonatype.org/</nexusUrl>
            <!-- Обновляем метаданные, чтобы пометить артефакт как release -->
            <!-- Не влияет на snapshot версии -->
            <updateReleaseInfo>true</updateReleaseInfo>
          </configuration>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-deploy-plugin</artifactId>
          <configuration>
            <!-- Отключаем плагин -->
            <skip>true</skip>
          </configuration>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
  <distributionManagement>
    <snapshotRepository>
      <id>sonatype</id>
      <name>Nexus Snapshot Repository</name>
      <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
    </snapshotRepository>
    <repository>
      <id>sonatype</id>
      <name>Nexus Release Repository</name>
      <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
  </distributionManagement>
</project>

Inā loaʻa iā ʻoe kahi papahana multi-module, a ʻaʻole pono ʻoe e hoʻouka i kahi module kikoʻī i ka waihona, a laila pono ʻoe e hoʻohui i ka pom.xml o kēia module nexus-staging-maven-plugin me ka hae skipNexusStagingDeployMojo

<build>
  <plugins>
    <plugin>
      <groupId>org.sonatype.plugins</groupId>
      <artifactId>nexus-staging-maven-plugin</artifactId>
      <configuration>
        <skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
      </configuration>
    </plugin>
  </plugins>
</build>

Ma hope o ka hoʻouka ʻana i ka snapshot/release versions i loaʻa i loko nā hale waihona puke

<repositories>
  <repository>
    <id>SonatypeNexus</id>
    <url>https://oss.sonatype.org/content/groups/staging/</url>
    <!-- Не надо указывать флаги snapshot/release для репозитория -->
  </repository>
</repositories>

Hoʻonui hou aku

  • He papa inoa waiwai nui o nā pahuhopu no ka hana ʻana me ka waihona nexus (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Nānā hoʻokuʻu ʻakomi no ka hiki ke hoʻoiho ma ke kikowaena maven

I ka maʻiʻo

hopena

Ke paʻi ʻana i kahi mana SNAPSHOT

Ke kūkulu ʻana i kahi papahana, hiki ke hoʻomaka lima i kahi hana e hoʻoiho i ka mana SNAPSHOT i nexus

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

Ke hoʻomaka ʻia kēia hana, hoʻomaka ka hana e pili ana i ka papahana deploy (hiʻohiʻona).

lāʻau i ʻoki ʻia

Running with gitlab-runner 11.10.0 (3001a600)
  on Deploy runner JSKWyxUw
Using Shell executor...
Running on ih1174328.vds.myihor.ru...
Skipping Git repository setup
Skipping Git checkout
Skipping Git submodules setup
$ 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} .
Cloning into 'shields4j'...
$ git checkout ${DEPLOY_CI_COMMIT_SHA}
Note: checking out '850f86aa317194395c5387790da1350e437125a7'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
  git checkout -b new_branch_name
HEAD is now at 850f86a... skip deploy test-core
$ for pom in $(find . -name pom.xml); do # collapsed multi-line command
$ if [[ "${DEPLOY_CI_COMMIT_TAG}" != "" ]]; then # collapsed multi-line command
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 4 modules...
[INFO] Installing Nexus Staging features:
[INFO]   ... total of 4 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] Shields4J                                                          [pom]
[INFO] test-core                                                          [jar]
[INFO] Shields4J client                                                   [jar]
[INFO] TestNG listener                                                    [jar]
[INFO] 
[INFO] --------------< org.touchbit.shields4j:shields4j-parent >---------------
[INFO] Building Shields4J 1.0.0                                           [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
[INFO] 
[INFO] --- versions-maven-plugin:2.5:set (default-cli) @ shields4j-parent ---
[INFO] Searching for local aggregator root...
[INFO] Local aggregation root: /home/gitlab-deployer/JSKWyxUw/0/TouchBIT/deploy/shields4j
[INFO] Processing change of org.touchbit.shields4j:shields4j-parent:1.0.0 -> 1.0.0-SNAPSHOT
[INFO] Processing org.touchbit.shields4j:shields4j-parent
[INFO]     Updating project org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] Processing org.touchbit.shields4j:client
[INFO]     Updating parent org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]     Updating dependency org.touchbit.shields4j:test-core
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] Processing org.touchbit.shields4j:test-core
[INFO]     Updating parent org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] Processing org.touchbit.shields4j:testng
[INFO]     Updating parent org.touchbit.shields4j:shields4j-parent
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]     Updating dependency org.touchbit.shields4j:client
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO]     Updating dependency org.touchbit.shields4j:test-core
[INFO]         from version 1.0.0 to 1.0.0-SNAPSHOT
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[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] Total time: 2.483 s
[INFO] Finished at: 2019-04-21T02:40:42+03:00
[INFO] ------------------------------------------------------------------------
$ mvn clean deploy -DskipTests=${SKIP_TESTS}
[INFO] Scanning for projects...
[INFO] Inspecting build with total of 4 modules...
[INFO] Installing Nexus Staging features:
[INFO]   ... total of 4 executions of maven-deploy-plugin replaced with nexus-staging-maven-plugin
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Build Order:
[INFO] 
[INFO] Shields4J                                                          [pom]
[INFO] test-core                                                          [jar]
[INFO] Shields4J client                                                   [jar]
[INFO] TestNG listener                                                    [jar]
[INFO] 
[INFO] --------------< org.touchbit.shields4j:shields4j-parent >---------------
[INFO] Building Shields4J 1.0.0-SNAPSHOT                                  [1/4]
[INFO] --------------------------------[ pom ]---------------------------------
...
DELETED
...
[INFO]  * Bulk deploy of locally gathered snapshot artifacts finished.
[INFO] Remote deploy finished with success.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[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] Total time: 47.629 s
[INFO] Finished at: 2019-04-21T02:41:32+03:00
[INFO] ------------------------------------------------------------------------

ʻO ka hopena, hoʻouka ʻia ka mana nexus 1.0.0-KIKI.

Hiki ke hoʻoneʻe ʻia nā mana snapshot a pau mai ka waihona ma ka pūnaewele oss.sonatype.org ma lalo o kāu moʻokāki.

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

I ka maʻiʻo

Ke hoʻopuka nei i kahi mana hoʻokuʻu

Ke hoʻonoho ʻia ka hōʻailona, ​​​​hoʻomaka koke ʻia ka hana e pili ana i ka papahana deploy e hoʻouka i ka mana hoʻokuʻu i nexus (hiʻohiʻona).

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

ʻO ka hapa maikaʻi loa, ʻo ia ka hoʻokuʻu ʻana i ka nexus.

[INFO] Performing remote staging...
[INFO] 
[INFO]  * Remote staging into staging profile ID "9043b43f77dcc9"
[INFO]  * Created staging repository with ID "orgtouchbit-1037".
[INFO]  * Staging repository at https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1037
[INFO]  * Uploading locally staged artifacts to profile org.touchbit
[INFO]  * Upload of locally staged artifacts finished.
[INFO]  * Closing staging repository with ID "orgtouchbit-1037".
Waiting for operation to complete...
.........
[INFO] Remote staged 1 repositories, finished with success.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[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] Total time: 01:47 min
[INFO] Finished at: 2019-04-21T04:05:46+03:00
[INFO] ------------------------------------------------------------------------

A inā hewa kekahi mea, pau ka hana

[INFO] Performing remote staging...
[INFO] 
[INFO]  * Remote staging into staging profile ID "9043b43f77dcc9"
[INFO]  * Created staging repository with ID "orgtouchbit-1038".
[INFO]  * Staging repository at https://oss.sonatype.org:443/service/local/staging/deployByRepositoryId/orgtouchbit-1038
[INFO]  * Uploading locally staged artifacts to profile org.touchbit
[INFO]  * Upload of locally staged artifacts finished.
[INFO]  * Closing staging repository with ID "orgtouchbit-1038".
Waiting for operation to complete...
.......
[ERROR] Rule failure while trying to close staging repository with ID "orgtouchbit-1039".
[ERROR] 
[ERROR] Nexus Staging Rules Failure Report
[ERROR] ==================================
[ERROR] 
[ERROR] Repository "orgtouchbit-1039" failures
[ERROR]   Rule "signature-staging" failures
[ERROR]     * No public key: Key with id: (1f42b618d1cbe1b5) was not able to be located on &lt;a href=http://keys.gnupg.net:11371/&gt;http://keys.gnupg.net:11371/&lt;/a&gt;. Upload your public key and try the operation again.
...
[ERROR] Cleaning up local stage directory after a Rule failure during close of staging repositories: [orgtouchbit-1039]
[ERROR]  * Deleting context 9043b43f77dcc9.properties
[ERROR] Cleaning up remote stage repositories after a Rule failure during close of staging repositories: [orgtouchbit-1039]
[ERROR]  * Dropping failed staging repository with ID "orgtouchbit-1039" (Rule failure during close of staging repositories: [orgtouchbit-1039]).
[ERROR] Remote staging finished with a failure: Staging rules failure!
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[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] BUILD FAILURE
[INFO] ------------------------------------------------------------------------

ʻO ka hopena, hoʻokahi wale nō koho i koe. A i ʻole e holoi i kēia mana a hoʻolaha paha.

Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

Ma hope o ka hoʻokuʻu ʻana, ma hope o kekahi manawa, e komo nā mea waiwai Hoʻonohonoho i ka GitLab CI e hoʻouka i kahi papahana java i ka maven kikowaena

ma waho

He hōʻike ia iaʻu e kuhikuhi ana ʻo Maven i nā waihona waihona lehulehu.
Pono wau e hoʻouka i robots.txt no ka mea ua kuhikuhi ʻo ia i kaʻu waihona kahiko.

I ka maʻiʻo

hopena

He aha kā mākou

  • He papahana hoʻokaʻawale kahi e hiki ai iā ʻoe ke hoʻokō i kekahi mau hana CI no ka hoʻouka ʻana i nā mea kiʻi i nā waihona lehulehu no nā ʻōlelo hoʻomohala like ʻole.
  • Hoʻokaʻawale ʻia ka papahana hoʻolaha mai ka hoʻopilikia ʻana i waho a hiki ke hoʻololi wale ʻia e nā mea hoʻohana me nā kuleana Owner a Maintainer.
  • ʻO kahi Runner Kūikawā ʻokoʻa me kahi huna huna "wela" e holo wale i nā hana.
  • Paʻi ʻia o nā mana paʻi kiʻi/hoʻokuʻu i loko o kahi waihona lehulehu.
  • E nānā ʻakomi i ka mana hoʻokuʻu no ka mākaukau no ka hoʻolaha ʻana ma ke kikowaena maven.
  • Ka pale ʻana i ka paʻi ʻakomi ʻana o nā mana "raw" ma ke kikowaena maven.
  • E kūkulu a hoʻolaha i nā mana snapshot "ma ke kaomi".
  • Hoʻokahi waihona no ka loaʻa ʻana o nā mana snapshot/hoʻokuʻu.
  • ʻO ka pipeline maʻamau no ke kūkulu ʻana / hoʻāʻo / paʻi ʻana i kahi papahana java.

ʻO ka hoʻonohonoho ʻana iā GitLab CI ʻaʻole ia he kumuhana paʻakikī e like me ka mea i ʻike mua ʻia. Ua lawa ka hoʻonohonoho ʻana iā CI ma ke kumu turnkey i ʻelua mau manawa, a i kēia manawa ua mamao ʻoe mai kahi amateur i kēia mea. Eia kekahi, ʻoi aku ka nui o nā palapala GitLab. Mai makaʻu i ka hana mua. Aia ke ala ma lalo o nā ʻanuʻu o ke kanaka e hele ana (ʻaʻole wau e hoʻomanaʻo i ka mea nāna i ʻōlelo :)

E hauʻoli wau i ka manaʻo.

Ma ka ʻatikala aʻe, e hōʻike wau iā ʻoe pehea e hoʻonohonoho ai iā GitLab CI e holo i nā hana hoʻāʻo hoʻohui me ka hoʻokūkū (holo i nā lawelawe hoʻāʻo me ka docker-compose) inā he hoʻokahi wale nō mea hoʻokūkū shell.

I ka maʻiʻo

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka