Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Bài viết này dành cho các nhà phát triển java, những người cần nhanh chóng xuất bản sản phẩm của họ lên kho lưu trữ trung tâm sonatype và/hoặc maven bằng GitLab. Trong bài viết này, tôi sẽ nói về việc thiết lập gitlab-runner, gitlab-ci và maven-plugin để giải quyết vấn đề này.

Điều kiện tiên quyết:

  • Lưu trữ an toàn các khóa mvn và GPG.
  • Thực hiện an toàn các nhiệm vụ CI công cộng.
  • Tải các tạo phẩm (phát hành/ảnh chụp nhanh) lên kho lưu trữ công cộng.
  • Tự động kiểm tra các phiên bản phát hành để xuất bản ở trung tâm maven.
  • Một giải pháp chung để tải các tạo phẩm lên kho lưu trữ cho nhiều dự án.
  • Đơn giản và dễ sử dụng.

nội dung

Thông tin chung

  • Mô tả chi tiết về cơ chế xuất bản các tạo phẩm lên Maven Central thông qua Dịch vụ lưu trữ kho lưu trữ Sonatype OSS đã được mô tả trong bài viết này người sử dụng Googolplex, vì vậy tôi sẽ tham khảo bài viết này ở những nơi thích hợp.
  • Đăng ký trước tại Sonatype JIRA và bắt đầu một vé để mở kho lưu trữ (để biết thêm chi tiết, hãy đọc phần Tạo vé Sonatype JIRA). Sau khi mở kho lưu trữ, cặp thông tin đăng nhập/mật khẩu JIRA (sau đây gọi là tài khoản Sonatype) sẽ được sử dụng để tải các tạo phẩm lên mối quan hệ Sonatype.
  • Hơn nữa, quá trình tạo khóa GPG được mô tả rất khô khan. Xem phần này để biết thêm chi tiết. Định cấu hình GnuPG để ký các tạo phẩm
  • Nếu bạn đang sử dụng bảng điều khiển Linux để tạo khóa GPG (gnupg/gnupg2), thì bạn cần cài đặt rng-công cụ để tạo ra entropy. Nếu không, việc tạo khóa có thể mất nhiều thời gian.
  • Dịch vụ lưu trữ công cộng Khóa GPG

Đến nội dung

Thiết lập dự án triển khai trong GitLab

  • Trước hết, bạn cần tạo và định cấu hình một dự án trong đó quy trình sẽ được lưu trữ để triển khai các tạo phẩm. Tôi gọi dự án của mình một cách đơn giản và không phức tạp - triển khai
  • Sau khi tạo kho lưu trữ, bạn cần hạn chế quyền truy cập để thay đổi kho lưu trữ.
    Chuyển đến dự án -> Cài đặt -> Kho lưu trữ -> Chi nhánh được bảo vệ. Chúng tôi xóa tất cả các quy tắc và thêm một quy tắc duy nhất với Wildcard * với quyền đẩy và hợp nhất chỉ dành cho người dùng có vai trò Người bảo trì. Quy tắc này sẽ có hiệu lực đối với tất cả người dùng của cả dự án này và nhóm mà dự án này thuộc về.
    Thiết lập GitLab CI để tải dự án java lên trung tâm maven
  • Nếu có một số người bảo trì, thì giải pháp tốt nhất về nguyên tắc là hạn chế quyền truy cập vào dự án.
    Chuyển đến dự án -> Cài đặt -> Chung -> Khả năng hiển thị, tính năng dự án, quyền và đặt Chế độ hiển thị dự án thành Riêng.
    Tôi có một dự án được truy cập công khai vì tôi sử dụng GitLab Runner của riêng mình và chỉ tôi mới có quyền truy cập để sửa đổi kho lưu trữ. Chà, thực ra tôi không có lợi khi hiển thị thông tin cá nhân trong nhật ký đường dẫn công cộng.
  • Siết chặt quy định về thay đổi kho lưu trữ
    Đi tới dự án -> Cài đặt -> Kho lưu trữ -> Quy tắc đẩy và đặt cờ Hạn chế người gửi, Kiểm tra xem tác giả có phải là người dùng GitLab hay không. Tôi cũng khuyên bạn nên thiết lập ký cam kếtvà đặt cờ Từ chối cam kết không dấu.
  • Tiếp theo, bạn cần định cấu hình trình kích hoạt để chạy tác vụ
    Đi tới dự án -> Cài đặt -> CI / CD -> Trình kích hoạt đường ống và tạo mã thông báo kích hoạt mới
    Mã thông báo này có thể được thêm ngay vào cấu hình chung của các biến cho một nhóm dự án.
    Vào nhóm -> Cài đặt -> CI/CD -> Biến và thêm biến DEPLOY_TOKEN với mã thông báo kích hoạt trong giá trị.

Đến nội dung

Người chạy GitLab

Phần này mô tả cấu hình để chạy các tác vụ khi triển khai bằng cách sử dụng trình chạy gốc (Cụ thể) và công khai (Được chia sẻ).

Người chạy cụ thể

Tôi sử dụng máy chạy bộ của riêng mình vì trước hết nó tiện, nhanh, rẻ.
Đối với người chạy, tôi khuyên dùng Linux VDS với 1 CPU, RAM 2 GB, ổ cứng 20 GB. Giá phát hành ~ 3000₽ mỗi năm.

Á hậu của tôi

Đối với người chạy, tôi lấy CPU VDS 4, RAM 4 GB, SSD 50 GB. Nó có giá ~11000₽ và không bao giờ hối hận.
Tôi có tổng cộng 7 máy. 5 trên aruba và 2 trên ihor.

Vì vậy, chúng tôi có một Á hậu. Bây giờ chúng ta sẽ thiết lập nó.
Chúng ta vào máy thông qua SSH và cài đặt java, git, maven, gnupg2.

Đến nội dung

Cài đặt trình chạy gitlab

  • Tạo một nhóm mới runner
    sudo groupadd runner
  • Tạo một thư mục cho bộ đệm maven và gán quyền nhóm runner
    Bạn có thể bỏ qua bước này nếu bạn không định chạy nhiều trình chạy trên cùng một máy.

    mkdir -p /usr/cache/.m2/repository
    chown -R :runner /usr/cache
    chmod -R 770 /usr/cache
  • Tạo người dùng gitlab-deployer và thêm vào nhóm runner
    useradd -m -d /home/gitlab-deployer gitlab-deployer
    usermod -a -G runner gitlab-deployer
  • Thêm vào tập tin /etc/ssh/sshd_config hàng tiếp theo
    AllowUsers root@* [email protected]
  • Khởi động lại sshd
    systemctl restart sshd
  • Đặt mật khẩu cho người dùng gitlab-deployer (có thể đơn giản vì có hạn chế đối với localhost)
    passwd gitlab-deployer
  • Cài đặt 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
  • Truy cập gitlab.com -> triển khai dự án -> Cài đặt -> CI/CD -> Người chạy -> Người chạy cụ thể và sao chép mã thông báo đăng ký

Màn hình

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

  • Đăng ký người chạy
    gitlab-runner register --config /etc/gitlab-runner/gitlab-deployer-config.toml

quá trình

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!

  • Kiểm tra xem người chạy đã được đăng ký chưa. Truy cập gitlab.com -> triển khai dự án -> Cài đặt -> CI/CD -> Người chạy -> Người chạy cụ thể -> Người chạy được kích hoạt cho dự án này

Màn hình

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

  • Thêm riêng biệt vụ /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
  • Chúng tôi bắt đầu dịch vụ.
    systemctl enable gitlab-deployer.service
    systemctl start gitlab-deployer.service
    systemctl status gitlab-deployer.service
  • Kiểm tra xem người chạy có đang chạy không.

Ví dụ

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Đến nội dung

Tạo khóa GPG

  • Từ cùng một máy, chúng tôi đi qua ssh dưới quyền người dùng gitlab-deployer (điều này rất quan trọng đối với việc tạo khóa GPG)

    ssh [email protected]

  • Chúng tôi tạo ra một chìa khóa bằng cách trả lời các câu hỏi. Tôi đã sử dụng tên và email của riêng tôi.
    Hãy chắc chắn chỉ định mật khẩu cho khóa. Hiện vật sẽ được ký bằng chìa khóa này.

    gpg --gen-key 

  • Kiểm tra

    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

  • Tải khóa công khai của chúng tôi lên máy chủ khóa

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

Đến nội dung

Thiết lập Maven

  • Chúng tôi đi theo người dùng gitlab-deployer
    su gitlab-deployer 
  • Tạo một thư mục maven kho và liên kết với bộ đệm (đừng nhầm lẫn)
    Có thể bỏ qua bước này nếu bạn không định chạy nhiều vòng chạy trên cùng một máy.

    mkdir -p ~/.m2/repository
    ln -s /usr/cache/.m2/repository /home/gitlab-deployer/.m2/repository
  • Tạo khóa chính
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Tạo tệp ~/.m2/settings-security.xml
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Mã hóa mật khẩu từ tài khoản Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Tạo tệp ~/.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>

ở đâu,
GPG_SECRET_KEY_PASSPHRASE - Mật khẩu khóa GPG
SONATYPE_USERNAME - đăng nhập tài khoản sonatype

Việc này hoàn tất việc thiết lập Á hậu, bạn có thể chuyển sang phần CI GitLab

Đến nội dung

Người chạy chung

Tạo khóa GPG

  • Trước hết, bạn cần tạo khóa GPG. Để thực hiện việc này, hãy cài đặt gnupg.

    yum install -y gnupg

  • Chúng tôi tạo ra một chìa khóa bằng cách trả lời các câu hỏi. Tôi đã sử dụng tên và email của riêng tôi. Hãy chắc chắn chỉ định mật khẩu cho khóa.

    gpg --gen-key 

  • Truy xuất thông tin chính

    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]

  • Tải khóa công khai của chúng tôi lên máy chủ khóa

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

  • Lấy khóa riêng

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

  • Chuyển đến cài đặt dự án -> Cài đặt -> CI / CD -> Biến và lưu khóa riêng vào một biến GPG_SECRET_KEY
    Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Đến nội dung

Thiết lập Maven

  • Tạo khóa chính
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • Chuyển đến cài đặt dự án -> Cài đặt -> CI / CD -> Biến và lưu vào một biến SETTINGS_SECURITY_XML các dòng sau:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Mã hóa mật khẩu từ tài khoản Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • Chuyển đến cài đặt dự án -> Cài đặt -> CI / CD -> Biến và lưu vào một biến SETTINGS_XML các dòng sau:
    <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>

ở đâu,
GPG_SECRET_KEY_PASSPHRASE - Mật khẩu khóa GPG
SONATYPE_USERNAME - đăng nhập tài khoản sonatype

Đến nội dung

Triển khai hình ảnh docker

  • Chúng tôi tạo một Dockerfile khá đơn giản để chạy các tác vụ khi triển khai với phiên bản Java mong muốn. Dưới đây là một ví dụ cho núi cao.

    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/

  • Xây dựng một container cho dự án của bạn

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

  • Chúng tôi xác thực và tải vùng chứa vào sổ đăng ký.

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

Đến nội dung

CI GitLab

Triển khai dự án

Thêm tệp .gitlab-ci.yml vào thư mục gốc của dự án triển khai
Kịch bản trình bày hai nhiệm vụ triển khai loại trừ lẫn nhau. Người chạy cụ thể hoặc Người chạy chung tương ứng.

.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

Đến nội dung

dự án Java

Trong các dự án java được cho là sẽ được tải lên kho công cộng, bạn cần thêm 2 bước để tải xuống phiên bản Phát hành và Ảnh chụp nhanh.

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

Trong giải pháp này, tôi đã đi xa hơn một chút và quyết định sử dụng một mẫu CI cho các dự án java.

Biết thêm chi tiết

Tôi đã tạo một dự án riêng gitlab-ci trong đó anh ấy đã đặt mẫu CI cho các dự án java chung.yml.

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

Kết quả là, trong chính các dự án java, .gitlab-ci.yml trông rất nhỏ gọn và không dài dòng

.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

Đến nội dung

cấu hình pom.xml

Chủ đề này được mô tả rất chi tiết. Googolplex в Thiết lập maven để tự động ký và tải các tạo phẩm lên kho lưu trữ ảnh chụp nhanh và dàn dựng, vì vậy tôi sẽ mô tả một số sắc thái của việc sử dụng plugin. Tôi cũng sẽ mô tả cách bạn có thể sử dụng một cách dễ dàng và tự nhiên nexus-staging-maven-pluginnếu bạn không muốn hoặc không thể sử dụng org.sonatype.oss:oss-parent làm cấp độ gốc cho dự án của mình.

maven-cài đặt-plugin

Cài đặt các mô-đun trong kho lưu trữ cục bộ.
Rất hữu ích cho việc xác minh cục bộ các giải pháp trong các dự án khác, cũng như tổng kiểm tra.

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

Đến nội dung

maven-javadoc-plugin

Tạo javadoc cho dự án.

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

Nếu bạn có một mô-đun không chứa java (ví dụ: chỉ có tài nguyên)
Hoặc về nguyên tắc bạn không muốn tạo javadoc thì hãy trợ giúp 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>

Đến nội dung

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>

Đến nội dung

nexus-staging-maven-plugin

Cấu hình:

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

Nếu bạn có một dự án nhiều mô-đun và bạn không cần tải một mô-đun cụ thể lên kho lưu trữ thì bạn cần thêm vào pom.xml của mô-đun này nexus-staging-maven-plugin với cờ skipNexusStagingDeployMojo

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

Sau khi tải lên phiên bản chụp nhanh/phát hành có sẵn trong kho dàn dựng

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

Thêm điểm cộng

  • Một danh sách rất phong phú các mục tiêu để làm việc với kho lưu trữ Nexus (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • Kiểm tra bản phát hành tự động về khả năng tải xuống ở trung tâm maven

Đến nội dung

Kết quả

Xuất bản phiên bản SNAPSHOT

Khi xây dựng dự án có thể khởi động task thủ công để tải phiên bản SNAPSHOT về nexus

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Khi tác vụ này được khởi chạy, tác vụ tương ứng trong dự án triển khai sẽ được kích hoạt (Ví dụ).

nhật ký đã cắt

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

Kết quả là phiên bản Nexus đã được tải 1.0.0-TẠP CHÍ.

Tất cả các phiên bản ảnh chụp nhanh có thể được xóa khỏi kho lưu trữ trên trang web oss.sonatype.org dưới tài khoản của bạn.

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Đến nội dung

Công bố phiên bản phát hành

Khi thẻ được đặt, tác vụ tương ứng trong dự án triển khai sẽ tự động được kích hoạt để tải phiên bản phát hành lên nexus (Ví dụ).

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Phần hay nhất là việc phát hành đóng sẽ tự động kích hoạt trong 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] ------------------------------------------------------------------------

Và nếu có sự cố xảy ra thì nhiệm vụ sẽ thất bại

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

Kết quả là chúng ta chỉ còn lại một sự lựa chọn. Hoặc xóa phiên bản này hoặc xuất bản.

Thiết lập GitLab CI để tải dự án java lên trung tâm maven

Sau khi phát hành, sau một thời gian, các hiện vật sẽ ở trạng thái Thiết lập GitLab CI để tải dự án java lên trung tâm maven

đề ra

Tôi phát hiện ra rằng maven lập chỉ mục các kho lưu trữ công khai khác.
Tôi phải tải lên robots.txt vì nó lập chỉ mục kho lưu trữ cũ của tôi.

Đến nội dung

Kết luận

Những gì chúng tôi có

  • Một dự án triển khai riêng biệt trong đó bạn có thể triển khai một số tác vụ CI để tải các tạo phẩm lên kho công khai cho các ngôn ngữ phát triển khác nhau.
  • Dự án triển khai được tách biệt khỏi sự can thiệp từ bên ngoài và chỉ người dùng có vai trò Chủ sở hữu và Người bảo trì mới có thể sửa đổi.
  • Một Trình chạy cụ thể riêng biệt có bộ nhớ đệm “nóng” để chỉ chạy các tác vụ triển khai.
  • Xuất bản các phiên bản chụp nhanh/phát hành trong kho lưu trữ công cộng.
  • Tự động kiểm tra phiên bản phát hành để sẵn sàng xuất bản ở trung tâm maven.
  • Bảo vệ chống lại việc tự động xuất bản các phiên bản "thô" trong trung tâm maven.
  • Xây dựng và xuất bản các phiên bản chụp nhanh “khi nhấp chuột”.
  • Kho lưu trữ duy nhất để nhận các phiên bản chụp nhanh/phát hành.
  • Quy trình chung để xây dựng/thử nghiệm/xuất bản một dự án java.

Thiết lập GitLab CI không phải là một chủ đề phức tạp như thoạt nhìn. Chỉ cần thiết lập CI theo hình thức chìa khóa trao tay một vài lần là đủ và bây giờ bạn không còn là người nghiệp dư trong vấn đề này nữa. Hơn nữa, tài liệu GitLab rất dư thừa. Đừng ngại thực hiện bước đầu tiên. Con đường hiện ra dưới bước chân người đi (ko nhớ ai nói :)

Tôi sẽ vui mừng phản hồi.

Trong bài viết tiếp theo, tôi sẽ hướng dẫn bạn cách thiết lập GitLab CI để chạy các tác vụ kiểm tra tích hợp một cách cạnh tranh (chạy các dịch vụ kiểm tra với docker-compose) nếu bạn chỉ có một trình chạy shell.

Đến nội dung

Nguồn: www.habr.com

Thêm một lời nhận xét