ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-maven central

ืžืืžืจ ื–ื” ืžื™ื•ืขื“ ืœืžืคืชื—ื™ ื’'ืื•ื•ื” ืฉื™ืฉ ืœื”ื ืฆื•ืจืš ืœืคืจืกื ื‘ืžื”ื™ืจื•ืช ืืช ื”ืžื•ืฆืจื™ื ืฉืœื”ื ื‘ืžืื’ืจื™ื ืžืจื›ื–ื™ื™ื ืฉืœ sonatype ื•/ืื• ืžืื‘ืŸ ื‘ืืžืฆืขื•ืช GitLab. ื‘ืžืืžืจ ื–ื” ืื“ื‘ืจ ืขืœ ื”ื’ื“ืจืช gitlab-runner, gitlab-ci ื•-maven-plugin ื›ื“ื™ ืœืคืชื•ืจ ื‘ืขื™ื” ื–ื•.

ื“ืจื™ืฉื•ืช ืžื•ืงื“ืžื•ืช:

  • ืื—ืกื•ืŸ ืžืื•ื‘ื˜ื— ืฉืœ ืžืคืชื—ื•ืช mvn ื•-GPG.
  • ื‘ื™ืฆื•ืข ืžืื•ื‘ื˜ื— ืฉืœ ืžืฉื™ืžื•ืช CI ืฆื™ื‘ื•ืจื™ื•ืช.
  • ื”ืขืœืืช ื—ืคืฆื™ื (ืฉื—ืจื•ืจ/ืชืžื•ื ืช ืžืฆื‘) ืœืžืื’ืจื™ื ืฆื™ื‘ื•ืจื™ื™ื.
  • ื‘ื“ื™ืงื” ืื•ื˜ื•ืžื˜ื™ืช ืฉืœ ื’ืจืกืื•ืช ืฉื—ืจื•ืจ ืœืคืจืกื•ื ื‘-maven central.
  • ืคืชืจื•ืŸ ื›ืœืœื™ ืœื”ืขืœืืช ื—ืคืฆื™ื ืœืžืื’ืจ ืขื‘ื•ืจ ืžืกืคืจ ืคืจื•ื™ืงื˜ื™ื.
  • ืคืฉื˜ื•ืช ื•ืงืœื•ืช ืฉื™ืžื•ืฉ.

ืชื•ื›ืŸ

ืžื™ื“ืข ื›ืœืœื™

  • ืชื™ืื•ืจ ืžืคื•ืจื˜ ืฉืœ ื”ืžื ื’ื ื•ืŸ ืœืคืจืกื•ื ื—ืคืฆื™ื ื‘-Maven Central ื‘ืืžืฆืขื•ืช Sonatype OSS Repository Hosting Service ื›ื‘ืจ ืชื•ืืจ ื‘- ื”ืžืืžืจ ื”ื–ื” ืขืœ ื™ื“ื™ ื”ืžืฉืชืžืฉ ื’ื•ื’ืœืคื•ืœืงืก, ืื– ืืชื™ื™ื—ืก ืœืžืืžืจ ื–ื” ื‘ืžืงื•ืžื•ืช ื”ื ื›ื•ื ื™ื.
  • ื”ืจืฉืžื” ืžืจืืฉ ืœ ืกื•ื ื˜ื™ืค JIRA ื•ืคืชื— ื›ืจื˜ื™ืก ืœืคืชื™ื—ืช ื”ืžืื’ืจ (ืงืจื ืืช ื”ืกืขื™ืฃ ืœืคืจื˜ื™ื ื ื•ืกืคื™ื ืฆื•ืจ ื›ืจื˜ื™ืก ื‘-Sonatype JIRA). ืœืื—ืจ ืคืชื™ื—ืช ื”ืžืื’ืจ, ืฆืžื“ ื”ื›ื ื™ืกื”/ืกื™ืกืžื” ืž-JIRA (ืœื”ืœืŸ ื›ื—ืฉื‘ื•ืŸ Sonatype) ื™ืฉืžืฉ ืœื”ืขืœืืช ื—ืคืฆื™ื ืœ-Sonatype nexus.
  • ืœืื—ืจ ืžื›ืŸ, ืชื”ืœื™ืš ื™ืฆื™ืจืช ืžืคืชื— GPG ืžืชื•ืืจ ื‘ืฆื•ืจื” ื™ื‘ืฉื” ืžืื•ื“. ืจืื” ืกืขื™ืฃ ืœืคืจื˜ื™ื ื ื•ืกืคื™ื ื”ื’ื“ืจืช GnuPG ืœื—ืชื•ื ืขืœ ื—ืคืฆื™ื
  • ืื ืืชื” ืžืฉืชืžืฉ ื‘ืงื•ื ืกื•ืœืช ืœื™ื ื•ืงืก ื›ื“ื™ ืœื™ืฆื•ืจ ืžืคืชื— GPG (gnupg/gnupg2), ืขืœื™ืš ืœื”ืชืงื™ืŸ ื›ืœื™ื rng ืœื™ืฆื•ืจ ืื ื˜ืจื•ืคื™ื”. ืื—ืจืช, ื™ืฆื™ืจืช ืžืคืชื—ื•ืช ืขืฉื•ื™ื” ืœื”ื™ืžืฉืš ื–ืžืŸ ืจื‘ ืžืื•ื“.
  • ืฉื™ืจื•ืชื™ ืื—ืกื•ืŸ ืฆื™ื‘ื•ืจื™ ืžืคืชื—ื•ืช GPG

ืœืชื•ื›ืŸ

ื”ื’ื“ืจืช ืคืจื•ื™ืงื˜ ืคืจื™ืกื” ื‘-GitLab

  • ืงื•ื“ื ื›ืœ, ืขืœื™ืš ืœื™ืฆื•ืจ ื•ืœื”ื’ื“ื™ืจ ืคืจื•ื™ืงื˜ ืฉื‘ื• ื”ืฆื™ื ื•ืจ ื™ืื•ื—ืกืŸ ืœืฆื•ืจืš ืคืจื™ืกืช ื—ืคืฆื™ื. ืงืจืืชื™ ืœืคืจื•ื™ืงื˜ ืฉืœื™ ื‘ืคืฉื˜ื•ืช ื•ื‘ืฆื•ืจื” ืœื ืžืกื•ื‘ื›ืช - ืœืคืจื•ืก
  • ืœืื—ืจ ื™ืฆื™ืจืช ื”ืžืื’ืจ, ืขืœื™ืš ืœื”ื’ื‘ื™ืœ ืืช ื”ื’ื™ืฉื” ื›ื“ื™ ืœืฉื ื•ืช ืืช ื”ืžืื’ืจ.
    ืขื‘ื•ืจ ืœืคืจื•ื™ืงื˜ -> ื”ื’ื“ืจื•ืช -> ืžืื’ืจ -> ืกื ื™ืคื™ื ืžื•ื’ื ื™ื. ืื ื• ืžื•ื—ืงื™ื ืืช ื›ืœ ื”ื›ืœืœื™ื ื•ืžื•ืกื™ืคื™ื ื›ืœืœ ื‘ื•ื“ื“ ืขื Wildcard * ืขื ื”ื–ื›ื•ืช ืœื“ื—ื•ืฃ ื•ืœืžื–ื’ ืจืง ืขื‘ื•ืจ ืžืฉืชืžืฉื™ื ื‘ืขืœื™ ืชืคืงื™ื“ Maintainers. ื›ืœืœ ื–ื” ื™ืขื‘ื•ื“ ืขื‘ื•ืจ ื›ืœ ื”ืžืฉืชืžืฉื™ื ื”ืŸ ื‘ืคืจื•ื™ืงื˜ ื”ื–ื” ื•ื”ืŸ ื‘ืงื‘ื•ืฆื” ืฉืืœื™ื” ื”ืคืจื•ื™ืงื˜ ื”ื–ื” ืฉื™ื™ืš.
    ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-maven central
  • ืื ื™ืฉ ื›ืžื” ืžืชื—ื–ืงื™ื, ืื– ื”ืคืชืจื•ืŸ ื”ื˜ื•ื‘ ื‘ื™ื•ืชืจ ื™ื”ื™ื” ืœื”ื’ื‘ื™ืœ ืืช ื”ื’ื™ืฉื” ืœืคืจื•ื™ืงื˜ ื‘ืื•ืคืŸ ืขืงืจื•ื ื™.
    ืขื‘ื•ืจ ืืœ ืคืจื•ื™ืงื˜ -> ื”ื’ื“ืจื•ืช -> ื›ืœืœื™ -> ื ืจืื•ืช, ืชื›ื•ื ื•ืช ืคืจื•ื™ืงื˜, ื”ืจืฉืื•ืช ื•ื”ื’ื“ืจ ืืช ื ืจืื•ืช ื”ืคืจื•ื™ืงื˜ ืœ ืคึผึฐืจึธื˜ึดื™.
    ื™ืฉ ืœื™ ืคืจื•ื™ืงื˜ ื ื’ื™ืฉ ืœืฆื™ื‘ื•ืจ, ืžื›ื™ื•ื•ืŸ ืฉืื ื™ ืžืฉืชืžืฉ ื‘-GitLab Runner ืžืฉืœื™ ื•ืจืง ืœื™ ื™ืฉ ื’ื™ืฉื” ืœืฉื ื•ืช ืืช ื”ืžืื’ืจ. ื•ื‘ื›ืŸ, ืœืžืขืฉื”, ื–ื” ืœื ื”ืื™ื ื˜ืจืก ืฉืœื™ ืœื”ืฆื™ื’ ืžื™ื“ืข ืคืจื˜ื™ ื‘ื™ื•ืžื ื™ ืฆื ืจืช ืฆื™ื‘ื•ืจื™ื™ื.
  • ื”ื—ืžืจืช ื”ื›ืœืœื™ื ืœืฉื™ื ื•ื™ ื”ืžืื’ืจ
    ืขื‘ื•ืจ ืืœ ื”ืคืจื•ื™ืงื˜ -> ื”ื’ื“ืจื•ืช -> ืžืื’ืจ -> Push Rules ื•ื”ื’ื“ืจ ืืช ื”ื’ื‘ืœืช Committer, ื‘ื“ื•ืง ืื ื”ืžื—ื‘ืจ ื”ื•ื ื“ื’ืœื™ื ืฉืœ ืžืฉืชืžืฉ GitLab. ืื ื™ ื’ื ืžืžืœื™ืฅ ืœื”ื’ื“ื™ืจ ืœื”ืชื—ื™ื™ื‘ ื—ืชื™ืžื”, ื•ื”ื’ื“ืจ ืืช ื”ื“ื’ืœ 'ื“ื—ื” ื”ืชื—ื™ื™ื‘ื•ื™ื•ืช ืœื ื—ืชื•ืžื•ืช'.
  • ืœืื—ืจ ืžื›ืŸ ืขืœื™ืš ืœื”ื’ื“ื™ืจ ื˜ืจื™ื’ืจ ืœื”ืคืขืœืช ืžืฉื™ืžื•ืช
    ืขื‘ื•ืจ ืœืคืจื•ื™ืงื˜ -> ื”ื’ื“ืจื•ืช -> CI / CD -> ืžืคืขื™ืœื™ ืฆื™ื ื•ืจ ื•ืฆื•ืจ ืืกื™ืžื•ืŸ ื˜ืจื™ื’ืจ ื—ื“ืฉ
    ื ื™ืชืŸ ืœื”ื•ืกื™ืฃ ืืกื™ืžื•ืŸ ื–ื” ื‘ืื•ืคืŸ ืžื™ื™ื“ื™ ืœืชืฆื•ืจื” ื”ื›ืœืœื™ืช ืฉืœ ืžืฉืชื ื™ื ืขื‘ื•ืจ ืงื‘ื•ืฆืช ืคืจื•ื™ืงื˜ื™ื.
    ืขื‘ื•ืจ ืœืงื‘ื•ืฆื” -> ื”ื’ื“ืจื•ืช -> CI / CD -> ืžืฉืชื ื™ื ื•ื”ื•ืกืฃ ืžืฉืชื ื” DEPLOY_TOKEN ืขื ื˜ืจื™ื’ืจ ื˜ื•ืงืŸ ื‘ืขืจืš.

ืœืชื•ื›ืŸ

GitLab Runner

ืกืขื™ืฃ ื–ื” ืžืชืืจ ืืช ื”ืชืฆื•ืจื” ืœื”ืคืขืœืช ืžืฉื™ืžื•ืช ื‘ืคืจื™ืกื” ื‘ืืžืฆืขื•ืช ืจืฅ ืžืฉืœืš (ืกืคืฆื™ืคื™) ื•ืฆื™ื‘ื•ืจื™ (ืžืฉื•ืชืฃ).

ืจืฅ ืกืคืฆื™ืคื™

ืื ื™ ืžืฉืชืžืฉ ื‘ืจืฆื™ื ืžืฉืœื™ ื›ื™ ืงื•ื“ื ื›ืœ ื–ื” ื ื•ื—, ืžื”ื™ืจ ื•ื–ื•ืœ.
ืขื‘ื•ืจ ืจืฅ, ืื ื™ ืžืžืœื™ืฅ ืขืœ Linux VDS ืขื 1 CPU, 2 GB RAM, 20 GB HDD. ื”ืžื—ื™ืจ ื”ืžื‘ื•ืงืฉ ื”ื•ื ~3000โ‚ฝ ืœืฉื ื”.

ื”ืจืฅ ืฉืœื™

ืขื‘ื•ืจ ื”ืจืฅ ืœืงื—ืชื™ VDS 4 CPU, 4 GB RAM, 50 GB SSD. ืขืœื” ~11000โ‚ฝ ื•ืžืขื•ืœื ืœื ื”ืชื—ืจื˜.
ื™ืฉ ืœื™ ื‘ืกืš ื”ื›ืœ 7 ืžื›ื•ื ื•ืช. 5 ืขืœ ืืจื•ื‘ื” ื•-2 ืขืœ ihor.

ืื– ื™ืฉ ืœื ื• ืจืฅ. ืขื›ืฉื™ื• ื ื’ื“ื™ืจ ืืช ื–ื”.
ืื ื—ื ื• ื”ื•ืœื›ื™ื ืœืžื›ื•ื ื” ื“ืจืš SSH ื•ืžืชืงื™ื ื™ื java, git, maven, gnupg2.

ืœืชื•ื›ืŸ

ืžืชืงื™ืŸ gitlab ืจืื ืจ

  • ืฆื•ืจ ืงื‘ื•ืฆื” ื—ื“ืฉื” 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 (ื™ื›ื•ืœ ืœื”ื™ื•ืช ืคืฉื•ื˜, ืžื›ื™ื•ื•ืŸ ืฉื™ืฉ ื”ื’ื‘ืœื” ืขื‘ื•ืจ localhost)
    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 -> ืจืฆื™ื -> ืจืฆื™ื ืกืคืฆื™ืคื™ื™ื ื•ื”ืขืชืง ืืช ืืกื™ืžื•ืŸ ื”ืจื™ืฉื•ื

ืžึธืกึธืš

ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-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 -> ืจืฆื™ื -> ืจืฆื™ื ืกืคืฆื™ืคื™ื™ื -> ืจืฆื™ื ืฉื”ื•ืคืขืœื• ืขื‘ื•ืจ ืคืจื•ื™ืงื˜ ื–ื”

ืžึธืกึธืš

ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-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 ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-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 
  • ืฆื•ืจ ืกืคืจื™ื™ืช ืžื™ื™ื‘ืŸ ืžืื’ืจ ื•ืงื™ืฉื•ืจ ืœืžื˜ืžื•ืŸ (ืืœ ืชื˜ืขื•)
    ืืชื” ื™ื›ื•ืœ ืœื“ืœื’ ืขืœ ื ืงื•ื“ื” ื–ื• ืื ืื™ื ืš ืžืชื›ื ืŸ ืœื”ืคืขื™ืœ ืžืกืคืจ ืจืฆื™ื ืขืœ ืžื›ื•ื ื” ืื—ืช.

    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

ื–ื” ืžืฉืœื™ื ืืช ื”ื”ื’ื“ืจื” ืฉืœ ื”ืจืฅ, ืืชื” ื™ื›ื•ืœ ืœื”ืžืฉื™ืš ืœืงื˜ืข 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 ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-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

ืœืชื•ื›ืŸ

ืคืจื•ืก ืชืžื•ื ืช docker

  • ืื ื• ื™ื•ืฆืจื™ื Dockerfile ืคืฉื•ื˜ ืœืžื“ื™ ืœื”ืคืขืœืช ืžืฉื™ืžื•ืช ืคืจื™ืกื” ืขื ื”ื’ืจืกื” ื”ื ื“ืจืฉืช ืฉืœ Java. ืœื”ืœืŸ ื“ื•ื’ืžื” ืœืืœืคื™ื ื™ืช.

    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 ืœืฉื•ืจืฉ ืคืจื•ื™ืงื˜ ื”ืคืจื™ืกื”
ื”ืชืกืจื™ื˜ ืžืฆื™ื’ ืฉืชื™ ืžืฉื™ืžื•ืช ืคืจื™ืกื” ื‘ืœืขื“ื™ื•ืช ื”ื“ื“ื™ืช. ืจืฅ ืกืคืฆื™ืคื™ ืื• ืจืฅ ืžืฉื•ืชืฃ ื‘ื”ืชืืžื”.

.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

ืœืชื•ื›ืŸ

ืคืจื•ื™ืงื˜ Java

ื‘ืคืจื•ื™ืงื˜ื™ื ืฉืœ java ืฉืืžื•ืจื™ื ืœื”ืขืœื•ืช ืœืžืื’ืจื™ื ืฆื™ื‘ื•ืจื™ื™ื, ืขืœื™ืš ืœื”ื•ืกื™ืฃ 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 ืื—ืช ืขื‘ื•ืจ ืคืจื•ื™ืงื˜ื™ Java.

ืคืจื˜ื™ื ื ื•ืกืคื™ื

ื™ืฆืจืชื™ ืคืจื•ื™ืงื˜ ื ืคืจื“ gitlab-ci ื‘ื” ื”ื ื—ืชื™ ืชื‘ื ื™ืช CI ืขื‘ื•ืจ ืคืจื•ื™ืงื˜ื™ Java 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

ื›ืชื•ืฆืื” ืžื›ืš, ื‘ืคืจื•ื™ืงื˜ื™ ื”-Java ืขืฆืžื, .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

ื ื•ืฉื ื–ื” ืžืชื•ืืจ ื‘ืคื™ืจื•ื˜ ืจื‘. ื’ื•ื’ืœืคื•ืœืงืก ะฒ ื”ื’ื“ืจืช 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>

ืื ื™ืฉ ืœืš ืžื•ื“ื•ืœ ืฉืื™ื ื• ืžื›ื™ืœ Java (ืœื“ื•ื’ืžื” ืจืง ืžืฉืื‘ื™ื)
ืื• ืฉืืชื” ืœื ืจื•ืฆื” ืœื™ืฆื•ืจ 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

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

ืชึฐืฆื•ึผืจึธื”:

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

ืขื•ื“ ืคืœื•ืกื™ื

  • ืจืฉื™ืžื” ืขืฉื™ืจื” ืžืื•ื“ ืฉืœ ื™ืขื“ื™ื ืœืขื‘ื•ื“ื” ืขื ืžืื’ืจ ื”ื ืงืกื•ืก (mvn help:describe -Dplugin=org.sonatype.plugins:nexus-staging-maven-plugin).
  • ื‘ื“ื™ืงืช ืฉื—ืจื•ืจ ืื•ื˜ื•ืžื˜ื™ ืœื”ืขืœืื” ืœ-maven central

ืœืชื•ื›ืŸ

ืชื•ืฆืื”

ืคืจืกื•ื ื’ืจืกืช SNAPSHOT

ื‘ืขืช ื‘ื ื™ื™ืช ืคืจื•ื™ืงื˜, ื ื™ืชืŸ ืœื”ืคืขื™ืœ ื‘ืื•ืคืŸ ื™ื“ื ื™ ืžืฉื™ืžื” ืœื”ื•ืจื“ืช ื’ืจืกืช SNAPSHOT ืœ-nexus

ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-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] ------------------------------------------------------------------------

ื›ืชื•ืฆืื” ืžื›ืš, ื”ื’ืจืกื” ื ื˜ืขื ืช ืœืชื•ืš nexus 1.0.0- ืชืžื•ื ืช ืžืฆื‘.

ื ื™ืชืŸ ืœืžื—ื•ืง ืืช ื›ืœ ื’ืจืกืื•ืช ืชืžื•ื ืช ื”ืžืฆื‘ ืžื”ืžืื’ืจ ื‘ืืชืจ oss.sonatype.org ืชื—ืช ื—ืฉื‘ื•ื ืš.

ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-maven central

ืœืชื•ื›ืŸ

ืคืจืกื•ื ื’ืจืกืช ืžื”ื“ื•ืจื”

ื›ืืฉืจ ืชื’ ืžื•ืชืงืŸ, ื”ืžืฉื™ืžื” ื”ืžืชืื™ืžื” ื‘ืคืจื•ื™ืงื˜ ื”ืคืจื™ืกื” ืžื•ืคืขืœืช ืื•ื˜ื•ืžื˜ื™ืช ื›ื“ื™ ืœื”ื•ืจื™ื“ ืืช ื’ืจืกืช ื”ื”ืคืฆื” ืœ-nexus (ื“ื•ื’ืžื”).

ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-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 ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-maven central

ืœืื—ืจ ื”ืฉื—ืจื•ืจ, ืœืื—ืจ ื–ืžืŸ ืžื” ื”ื—ืคืฆื™ื ื™ื”ื™ื• ื‘ืคื ื™ื ื”ื’ื“ืจืช GitLab CI ืœื”ืขืœืืช ืคืจื•ื™ืงื˜ Java ืœ-maven central

ืžื—ื•ืฅ ืœื ื•ืฉื

ื–ื” ื”ื™ื” ืชื’ืœื™ืช ืขื‘ื•ืจื™ ืฉืžื™ื™ื‘ืŸ ืžืื ื“ืงืก ืžืื’ืจื™ื ืฆื™ื‘ื•ืจื™ื™ื ืื—ืจื™ื.
ื ืืœืฆืชื™ ืœื”ื•ืกื™ืฃ robots.txt ืžื›ื™ื•ื•ืŸ ืฉื”ื•ื ื”ื•ืกื™ืฃ ืœืื™ื ื“ืงืก ืืช ื”ืžืื’ืจ ื”ื™ืฉืŸ ืฉืœื™.

ืœืชื•ื›ืŸ

ืžืกืงื ื”

ืžื” ื™ืฉ ืœื ื•

  • ืคืจื•ื™ืงื˜ ืคืจื™ืกื” ื ืคืจื“ ื‘ื• ื ื™ืชืŸ ืœื™ื™ืฉื ืžืกืคืจ ืžืฉื™ืžื•ืช CI ืœื”ืขืœืืช ื—ืคืฆื™ื ืœืžืื’ืจื™ื ืฆื™ื‘ื•ืจื™ื™ื ืขื‘ื•ืจ ืฉืคื•ืช ืคื™ืชื•ื— ืฉื•ื ื•ืช.
  • ืคืจื•ื™ืงื˜ ื”-Deploy ืžื‘ื•ื“ื“ ืžื”ืคืจืขื•ืช ืžื‘ื—ื•ืฅ ื•ื ื™ืชืŸ ืœืฉื ื•ืช ืื•ืชื• ืจืง ืขืœ ื™ื“ื™ ืžืฉืชืžืฉื™ื ื‘ืขืœื™ ืชืคืงื™ื“ื™ ื”ื‘ืขืœื™ื ื•ื”ืžืชื—ื–ืง.
  • ืจืฅ ืกืคืฆื™ืคื™ ื ืคืจื“ ืขื ืžื˜ืžื•ืŸ "ื—ื" ืœื”ืคืขืœืช ืžืฉื™ืžื•ืช ืคืจื™ืกื” ื‘ืœื‘ื“.
  • ืคืจืกื•ื ื’ืจืกืื•ืช ืชืžื•ื ืช ืžืฆื‘/ื”ืคืฆื” ื‘ืžืื’ืจ ืฆื™ื‘ื•ืจื™.
  • ื‘ื“ื™ืงื” ืื•ื˜ื•ืžื˜ื™ืช ืฉืœ ื’ืจืกืช ื”ืฉื—ืจื•ืจ ืœืžื•ื›ื ื•ืช ืœืคืจืกื•ื ื‘-maven central.
  • ื”ื’ื ื” ืžืคื ื™ ืคืจืกื•ื ืื•ื˜ื•ืžื˜ื™ ืฉืœ ื’ืจืกืื•ืช "ื’ื•ืœืžื™ื•ืช" ื‘-maven central.
  • ื‘ื ื” ื•ืคืจืกื ื’ืจืกืื•ืช ืชืžื•ื ืช ืžืฆื‘ "ื‘ืœื—ื™ืฆื”".
  • ืžืื’ืจ ื™ื—ื™ื“ ืœื”ืฉื’ืช ื’ืจืกืื•ืช ืชืžื•ื ืช ืžืฆื‘/ืฉื—ืจื•ืจ.
  • ืฆื ืจืช ื›ืœืœื™ืช ืœื‘ื ื™ื™ืช/ื‘ื“ื™ืงื”/ืคืจืกื•ื ืคืจื•ื™ืงื˜ java.

ื”ื’ื“ืจืช GitLab CI ืื™ื ื” ื ื•ืฉื ืžืกื•ื‘ืš ื›ืคื™ ืฉื”ื•ื ื ืจืื” ื‘ืžื‘ื˜ ืจืืฉื•ืŸ. ืžืกืคื™ืง ืœื”ื’ื“ื™ืจ ืืช CI ืขืœ ื‘ืกื™ืก ืกื•ื”ืจ ื›ืžื” ืคืขืžื™ื, ื•ืขื›ืฉื™ื• ืืชื” ืจื—ื•ืง ืžืœื”ื™ื•ืช ื—ื•ื‘ื‘ืŸ ื‘ืขื ื™ื™ืŸ ื”ื–ื”. ื™ืชืจื” ืžื›ืš, ืชื™ืขื•ื“ GitLab ืžื™ื•ืชืจ ืžืื•ื“. ืืœ ืชืคื—ื“ ืœืขืฉื•ืช ืืช ื”ืฆืขื“ ื”ืจืืฉื•ืŸ. ื”ื“ืจืš ืžื•ืคื™ืขื” ืžืชื—ืช ืœืžื“ืจื’ื•ืช ืฉืœ ื”ื”ื•ืœื›ืช (ืื ื™ ืœื ื–ื•ื›ืจืช ืžื™ ืืžืจ ืืช ื–ื” :)

ืืฉืžื— ืœืงื‘ืœ ืžืฉื•ื‘.

ื‘ืžืืžืจ ื”ื‘ื ืื“ื‘ืจ ืขืœ ืื™ืš ืœื”ื’ื“ื™ืจ ืืช GitLab CI ืœื”ืจื™ืฅ ืžืฉื™ืžื•ืช ืขื ืžื‘ื—ื ื™ ืื™ื ื˜ื’ืจืฆื™ื” ื‘ืื•ืคืŸ ืชื—ืจื•ืชื™ (ื”ืคืขืœืช ื”ืฉื™ืจื•ืชื™ื ื”ื ื‘ื“ืงื™ื ื‘ืืžืฆืขื•ืช docker-compose) ืื ื™ืฉ ืœืš ืจืง ืจืฅ ืžืขื˜ืคืช ืื—ื“.

ืœืชื•ื›ืŸ

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”