راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

این مقاله برای توسعه دهندگان جاوا است که نیاز به انتشار سریع محصولات خود در مخازن مرکزی sonatype و/یا maven با استفاده از GitLab دارند. در این مقاله در مورد راه اندازی gitlab-runner، gitlab-ci و maven-plugin برای حل این مشکل صحبت خواهم کرد.

پیش نیازها:

  • ذخیره سازی ایمن کلیدهای mvn و GPG.
  • اجرای ایمن وظایف عمومی CI.
  • بارگذاری مصنوعات (نسخه/عکس فوری) در مخازن عمومی.
  • بررسی خودکار نسخه های انتشار برای انتشار در maven central.
  • یک راه حل کلی برای آپلود مصنوعات در یک مخزن برای چندین پروژه.
  • سادگی و سهولت استفاده.

مقدار

اطلاعات عمومی

  • شرح مفصلی از مکانیسم انتشار مصنوعات در Maven Central از طریق سرویس میزبانی مخزن Sonatype OSS قبلاً در این مقاله کاربر Googolplex، بنابراین در جاهای مناسب به این مقاله اشاره خواهم کرد.
  • پیش ثبت نام در سوناتایپ JIRA و یک بلیط برای باز کردن مخزن شروع کنید (برای جزئیات بیشتر، بخش را بخوانید یک بلیط در Sonatype JIRA ایجاد کنید). پس از باز کردن مخزن، جفت ورود/گذرواژه JIRA (از این پس به عنوان حساب Sonatype نامیده می شود) برای آپلود مصنوعات در Nexus Sonatype استفاده می شود.
  • در مرحله بعد، روند تولید یک کلید GPG بسیار خشک توضیح داده شده است. برای جزئیات بیشتر به بخش مراجعه کنید پیکربندی GnuPG برای امضای مصنوعات
  • اگر از کنسول لینوکس برای تولید یک کلید GPG (gnupg/gnupg2) استفاده می کنید، باید نصب کنید rng-tools برای ایجاد آنتروپی در غیر این صورت، تولید کلید ممکن است زمان زیادی طول بکشد.
  • خدمات ذخیره سازی عمومی کلیدهای GPG

به محتوا

راه اندازی یک پروژه استقرار در GitLab

  • اول از همه، شما باید پروژه ای را ایجاد و پیکربندی کنید که در آن خط لوله برای استقرار مصنوعات ذخیره می شود. من پروژه ام را ساده و بدون پیچیدگی نامیدم - گسترش
  • پس از ایجاد مخزن، باید دسترسی را برای تغییر مخزن محدود کنید.
    به پروژه -> Settings -> Repository -> Protected Branches بروید. ما همه قوانین را حذف می کنیم و یک قانون را با Wildcard * اضافه می کنیم که فقط برای کاربران دارای نقش Maintainers حق فشار دادن و ادغام را دارد. این قانون برای همه کاربران این پروژه و گروهی که این پروژه به آن تعلق دارد کار خواهد کرد.
    راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central
  • اگر چندین نگهدار وجود دارد، بهترین راه حل محدود کردن دسترسی به پروژه در اصل است.
    به پروژه -> تنظیمات -> عمومی -> مشاهده، ویژگی‌های پروژه، مجوزها بروید و نمایان بودن پروژه را روی خصوصی.
    من یک پروژه در دسترسی عمومی دارم، زیرا از GitLab Runner خودم استفاده می کنم و فقط من به تغییر مخزن دسترسی دارم. خوب، در واقع به نفع من نیست که اطلاعات خصوصی را در گزارش های خط لوله عمومی نشان دهم.
  • تشدید قوانین برای تغییر مخزن
    به پروژه -> Settings -> Repository -> Push Rules بروید و flags محدودیت Committer را تنظیم کنید، بررسی کنید که آیا نویسنده کاربر GitLab است یا خیر. تنظیم را هم توصیه می کنم متعهد امضا کردنو پرچم رد commits unsigned را تنظیم کنید.
  • در مرحله بعد، باید یک ماشه را برای اجرای وظایف پیکربندی کنید
    به پروژه -> Settings -> CI / CD -> Pipeline triggers بروید و یک Trigger-token جدید ایجاد کنید.
    این نشانه را می توان بلافاصله به پیکربندی کلی متغیرها برای گروهی از پروژه ها اضافه کرد.
    به گروه -> Settings -> CI / CD -> Variables بروید و یک متغیر اضافه کنید DEPLOY_TOKEN با نشانه ماشه در مقدار.

به محتوا

GitLab Runner

این بخش پیکربندی برای اجرای وظایف در هنگام استقرار با استفاده از رانر بومی (Specific) و عمومی (Shared) را توضیح می دهد.

دونده خاص

من از دونده های خودم استفاده می کنم، زیرا اول از همه راحت، سریع، ارزان است.
برای رانر لینوکس VDS را با 1 CPU، 2 گیگابایت رم، 20 گیگابایت HDD توصیه می کنم. قیمت صدور ~ 3000 ₽ در سال.

دونده من

برای رانر من VDS 4 CPU، 4GB RAM، 50GB SSD گرفتم. هزینه آن ~ 11000 ₽ بود و هرگز پشیمان نشدم.
من در کل 7 دستگاه دارم. 5 در آروبا و 2 در ihor.

بنابراین ما یک دونده داریم. حالا ما آن را پیکربندی می کنیم.
از طریق SSH به دستگاه می رویم و جاوا، git، maven، gnupg2 را نصب می کنیم.

به محتوا

نصب gitlab runner

  • یک گروه جدید ایجاد کنید runner
    sudo groupadd runner
  • یک دایرکتوری برای کش maven ایجاد کنید و مجوزهای گروه را اختصاص دهید runner
    اگر قصد ندارید چندین رانر را روی یک دستگاه اجرا کنید، می‌توانید از این مرحله بگذرید.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • یک کاربر ایجاد کنید gitlab-deployer و به گروه اضافه کنید runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • به فایل اضافه کنید /etc/ssh/sshd_config خط بعدی
    AllowUsers root@* [email protected]
  • راه اندازی مجدد sshd
    systemctl restart sshd
  • یک رمز عبور برای کاربر تعیین کنید gitlab-deployer (می تواند ساده باشد، زیرا برای لوکال هاست محدودیت وجود دارد)
    passwd gitlab-deployer
  • نصب 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
  • به وب سایت gitlab.com -> deploy-project -> تنظیمات -> CI/CD -> Runners -> Specific Runners بروید و رمز ثبت نام را کپی کنید.

صفحه نمایش

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

  • ثبت نام یک دونده
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

روند

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!

  • بررسی می کنیم که دونده ثبت نام کرده باشد. به وب سایت gitlab.com بروید -> deploy-project -> تنظیمات -> CI/CD -> Runners -> Specific Runners -> Runners فعال شده برای این پروژه

صفحه نمایش

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

  • اضافه کنید جداگانه، مجزا خدمات /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
  • بیایید سرویس را شروع کنیم.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • بررسی کنید که دونده در حال دویدن است.

مثال

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

به محتوا

تولید کلیدهای GPG

  • از همان دستگاه از طریق ssh زیر کاربر وارد می شویم gitlab-deployer (این برای تولید کلید GPG مهم است)

    ssh [email protected]

  • ما با پاسخ دادن به سوالات یک کلید تولید می کنیم. من از نام و ایمیل خودم استفاده کردم.
    حتما رمز عبور کلید را مشخص کنید. آثار با این کلید امضا خواهند شد.

    gpg --gen-key 

  • چک کردن

    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

  • در حال آپلود کلید عمومی ما در سرور کلید

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

به محتوا

راه اندازی Maven

  • زیر کاربر می رویم gitlab-deployer
    su gitlab-deployer 
  • یک دایرکتوری maven ایجاد کنید مخزن و پیوند به حافظه پنهان (اشتباه نکنید)
    اگر قصد ندارید چندین رانر را روی یک دستگاه اجرا کنید، می توانید از این نکته صرف نظر کنید.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • یک کلید اصلی ایجاد کنید
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • فایل ~/.m2/settings-security.xml ایجاد کنید
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • رمزگذاری رمز عبور برای حساب Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • یک فایل ~/.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>

جایی که،
GPG_SECRET_KEY_PASSPHRASE - رمز عبور کلید GPG
SONATYPE_USERNAME — ورود به حساب sonatype

با این کار تنظیمات runner کامل می شود، می توانید به بخش بروید GitLab CI

به محتوا

دونده مشترک

تولید کلیدهای GPG

  • اول از همه، شما باید یک کلید GPG ایجاد کنید. برای انجام این کار، gnupg را نصب کنید.

    yum install -y gnupg

  • ما با پاسخ دادن به سوالات یک کلید تولید می کنیم. من از نام و ایمیل خودم استفاده کردم. حتما رمز عبور کلید را مشخص کنید.

    gpg --gen-key 

  • بازیابی اطلاعات کلیدی

    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]

  • در حال آپلود کلید عمومی ما در سرور کلید

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

  • ما کلید خصوصی را دریافت می کنیم

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

  • به تنظیمات پروژه -> تنظیمات -> CI / CD -> متغیرها بروید و کلید خصوصی را در یک متغیر ذخیره کنید. GPG_SECRET_KEY
    راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

به محتوا

راه اندازی Maven

  • یک کلید اصلی ایجاد کنید
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • به تنظیمات پروژه -> تنظیمات -> CI / CD -> متغیرها بروید و در یک متغیر ذخیره کنید SETTINGS_SECURITY_XML خطوط زیر:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • رمزگذاری رمز عبور برای حساب Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • به تنظیمات پروژه -> تنظیمات -> CI / CD -> متغیرها بروید و در یک متغیر ذخیره کنید 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>

جایی که،
GPG_SECRET_KEY_PASSPHRASE - رمز عبور کلید GPG
SONATYPE_USERNAME — ورود به حساب sonatype

به محتوا

استقرار تصویر داکر

  • ما یک Dockerfile نسبتاً ساده برای اجرای وظایف در هنگام استقرار با نسخه مورد نظر جاوا ایجاد می کنیم. در زیر یک مثال برای آلپاین آورده شده است.

    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/

  • مونتاژ یک کانتینر برای پروژه شما

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

  • ما کانتینر را احراز هویت می کنیم و در رجیستری بارگذاری می کنیم.

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

به محتوا

GitLab CI

استقرار پروژه

فایل .gitlab-ci.yml را به ریشه پروژه deploy اضافه کنید
اسکریپت دو وظیفه استقرار منحصر به فرد متقابل را ارائه می دهد. به ترتیب Specific Runner یا Shared Runner.

.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

به محتوا

پروژه جاوا

در پروژه های جاوا که قرار است در مخازن عمومی آپلود شوند، باید 2 مرحله برای دانلود نسخه Release و 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}

در این راه حل، کمی جلوتر رفتم و تصمیم گرفتم از یک قالب CI برای پروژه های جاوا استفاده کنم.

جزئیات بیشتر

من یک پروژه جداگانه ایجاد کردم gitlab-ci که در آن یک قالب CI برای پروژه های جاوا قرار دادم 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

در نتیجه، در خود پروژه‌های جاوا، .gitlab-ci.yml بسیار فشرده به نظر می‌رسد و پرمخاطب نیست.

.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

به محتوا

پیکربندی pom.xml

این موضوع با جزئیات کامل توضیح داده شده است. Googolplex в راه اندازی maven برای امضا و آپلود خودکار مصنوعات در مخازن عکس فوری و مرحله‌بندی، بنابراین برخی از تفاوت های ظریف استفاده از افزونه ها را شرح خواهم داد. من همچنین توضیح خواهم داد که چگونه به راحتی و به طور طبیعی می توانید استفاده کنید nexus-staging-maven-pluginاگر نمی خواهید یا نمی توانید از org.sonatype.oss:oss-parent به عنوان والد برای پروژه خود استفاده کنید.

پلاگین maven-install

ماژول ها را در مخزن محلی نصب می کند.
بسیار مفید برای تایید محلی راه حل ها در پروژه های دیگر، و همچنین چک جمع.

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

به محتوا

پلاگین maven-javadoc

ایجاد javadoc برای پروژه

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

اگر ماژولی دارید که حاوی جاوا نیست (به عنوان مثال فقط منابع)
یا در اصل نمی خواهید javadoc ایجاد کنید، سپس کمک کنید 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>

به محتوا

پلاگین maven-gpg

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

به محتوا

پلاگین nexus-staging-maven

پیکربندی:

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

اگر یک پروژه چند ماژول دارید و نیازی به آپلود ماژول خاصی در مخزن ندارید، باید اضافه کنید nexus-staging-maven-plugin با پرچم skipNexusStagingDeployMojo

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

پس از دانلود، نسخه‌های فوری/نسخه‌ای در دسترس هستند مخازن مرحله بندی

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

مزیت های بیشتر

  • یک لیست بسیار غنی از اهداف برای کار با مخزن Nexus (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • بررسی انتشار خودکار برای قابلیت دانلود در maven central

به محتوا

نتیجه

انتشار نسخه SNAPSHOT

هنگام ساخت یک پروژه، می توان به صورت دستی یک کار را برای دانلود نسخه SNAPSHOT در nexus شروع کرد

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

هنگامی که این وظیفه راه اندازی می شود، وظیفه مربوطه در پروژه استقرار فعال می شود (مثال).

سیاهه بریده شده

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] ------------------------------------------------------------------------

در نتیجه، نسخه نکسوس بارگذاری می شود 1.0.0-اسنپ شات.

تمامی نسخه های اسنپ شات را می توان از مخزن موجود در سایت حذف کرد oss.sonatype.org زیر حساب شما

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

به محتوا

انتشار نسخه انتشار

هنگامی که یک برچسب نصب می شود، وظیفه مربوطه در پروژه استقرار به طور خودکار راه اندازی می شود تا نسخه انتشار در Nexus دانلود شود (مثال).

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

بهترین بخش این است که انتشار بسته به طور خودکار در 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] ------------------------------------------------------------------------

و اگر مشکلی پیش بیاید، کار شکست خواهد خورد

[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] ------------------------------------------------------------------------

در نتیجه تنها یک انتخاب برای ما باقی می ماند. یا این نسخه را حذف کنید یا منتشر کنید.

راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

پس از انتشار، پس از مدتی، مصنوعات وارد خواهند شد راه اندازی GitLab CI برای آپلود یک پروژه جاوا در maven central

خارج از موضوع

این یک کشف برای من بود که maven سایر مخازن عمومی را نمایه می کند.
مجبور شدم robots.txt را آپلود کنم زیرا مخزن قدیمی من را ایندکس می کند.

به محتوا

نتیجه

آن چه که ما داریم

  • یک پروژه استقرار جداگانه که در آن می توانید چندین وظیفه CI را برای آپلود مصنوعات در مخازن عمومی برای زبان های مختلف توسعه پیاده سازی کنید.
  • پروژه استقرار از تداخل بیرونی جدا شده است و فقط توسط کاربرانی که دارای نقش های مالک و نگهدارنده هستند قابل تغییر است.
  • یک Runner خاص جداگانه با یک کش "داغ" برای اجرای تنها وظایف استقرار.
  • انتشار نسخه های فوری/نسخه انتشار در یک مخزن عمومی.
  • بررسی خودکار نسخه انتشار برای آمادگی برای انتشار در maven central.
  • محافظت در برابر انتشار خودکار نسخه های "خام" در maven central.
  • ساخت و انتشار نسخه فوری "با کلیک".
  • مخزن واحد برای دریافت نسخه های فوری / انتشار.
  • خط لوله عمومی برای ساخت / آزمایش / انتشار یک پروژه جاوا.

راه اندازی GitLab CI آنقدرها که در نگاه اول به نظر می رسد موضوع پیچیده ای نیست. کافی است چند بار CI را به صورت کلید در دست راه اندازی کنید، و اکنون در این مورد از یک آماتور دور هستید. علاوه بر این، اسناد GitLab بسیار زائد است. از برداشتن اولین قدم نترسید. جاده زیر پله های شخصی که در حال راه رفتن است ظاهر می شود (یادم نیست کی گفته است)

من خوشحال خواهم شد به بازخورد.

در مقاله بعدی، من به شما نشان خواهم داد که چگونه GitLab CI را برای اجرای رقابتی وظایف تست یکپارچه سازی (اجرای خدمات تست با docker-compose) راه اندازی کنید، اگر فقط یک اجرا کننده پوسته دارید.

به محتوا

منبع: www.habr.com

اضافه کردن نظر