Настройка GitLab CI для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² maven central

Данная ΡΡ‚Π°Ρ‚ΡŒΡ рассчитана Π½Π° java Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ², Ρƒ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Π²ΠΎΠ·Π½ΠΈΠΊΠ»Π° ΠΏΠΎΡ‚Ρ€Π΅Π±Π½ΠΎΡΡ‚ΡŒ быстро ΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Ρ‚ΡŒ свои ΠΏΡ€ΠΎΠ΄ΡƒΠΊΡ‚Ρ‹ Π² рСпозиториях sonatype ΠΈ/ΠΈΠ»ΠΈ maven central с использованиСм GitLab. Π’ Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ я расскаТу ΠΏΡ€ΠΎ настройку gitlab-runner, gitlab-ci ΠΈ maven-plugin для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π΄Π°Π½Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ.

ΠŸΡ€Π΅Π΄ΠΏΠΎΡΡ‹Π»ΠΊΠΈ:

  • БСзопасноС Ρ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ mvn ΠΈ GPG ΠΊΠ»ΡŽΡ‡Π΅ΠΉ.
  • БСзопасноС Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… CI Π·Π°Π΄Π°Ρ‡.
  • Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² (release/snapshot) Π² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.
  • АвтоматичСская ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° release-вСрсий для ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² maven central.
  • ΠžΠ±Ρ‰Π΅Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ².
  • ΠŸΡ€ΠΎΡΡ‚ΠΎΡ‚Π° ΠΈ удобство использования.

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅

ΠžΠ±Ρ‰Π°Ρ информация

  • ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎΠ΅ описаниС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ° ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² Π² Maven Central Ρ‡Π΅Ρ€Π΅Π· Sonatype OSS Repository Hosting Service ΡƒΠΆΠ΅ описано Π² Π΄Π°Π½Π½ΠΎΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΌ Googolplex, поэтому Π² Π½ΡƒΠΆΠ½Ρ‹Ρ… мСстах Π±ΡƒΠ΄Ρƒ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° Π΄Π°Π½Π½ΡƒΡŽ ΡΡ‚Π°Ρ‚ΡŒΡŽ.
  • ΠŸΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ рСгистрируСмся Π² Sonatype JIRA ΠΈ Π·Π°Π²ΠΎΠ΄ΠΈΠΌ Ρ‚ΠΈΠΊΠ΅Ρ‚ Π½Π° ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ рСпозитория (Π±ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π» Π‘ΠΎΠ·Π΄Π°Ρ‘ΠΌ Ρ‚ΠΈΠΊΠ΅Ρ‚ Π½Π° Sonatype JIRA). ПослС открытия рСпозитория ΠΏΠ°Ρ€Π° Π»ΠΎΠ³ΠΈΠ½/ΠΏΠ°Ρ€ΠΎΠ»ΡŒ ΠΎΡ‚ JIRA (Π΄Π°Π»Π΅Π΅ учСтная запись Sonatype) Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² Π² Sonatype nexus.
  • Π”Π°Π»Π΅Π΅ процСсс Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ GPG ΠΊΠ»ΡŽΡ‡Π° описан вСсьма сухо. Π‘ΠΎΠ»Π΅Π΅ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ€Π°Π·Π΄Π΅Π» Настройка GnuPG для подписи Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ²
  • Если Π²Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚Π΅ Linux консоль для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ GPG ΠΊΠ»ΡŽΡ‡Π° (gnupg/gnupg2), Ρ‚ΠΎ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ rng-tools для Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ энтропии. Π’ ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС гСнСрация ΠΊΠ»ΡŽΡ‡Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΎΡ…ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ Π΄ΠΎΠ»Π³ΠΎ.
  • БСрвисы хранСния ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… GPG ΠΊΠ»ΡŽΡ‡Π΅ΠΉ

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Настройка deploy-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² GitLab

  • Π’ ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ ΠΈ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ Π±ΡƒΠ΄Π΅Ρ‚ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒΡΡ pipeline, для дСплоя Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ². Π‘Π²ΠΎΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ я Π½Π°Π·Π²Π°Π» просто ΠΈ нСзамысловато β€” deploy
  • ПослС создания рСпозитория, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ доступ Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ рСпозитория.
    ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ -> Settings -> Repository -> Protected Branches. УдаляСм всС ΠΏΡ€Π°Π²ΠΈΠ»Π° ΠΈ добавляСм СдинствСнноС ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ с Wildcard * с ΠΏΡ€Π°Π²ΠΎΠΌ Π½Π° push ΠΈ merge Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ с Ρ€ΠΎΠ»ΡŒΡŽ Maintainers. Π”Π°Π½Π½ΠΎΠ΅ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ для всСх ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΊΠ°ΠΊ Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°, Ρ‚Π°ΠΊ ΠΈ Π³Ρ€ΡƒΠΏΠΏΡ‹ Π² ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π²Ρ…ΠΎΠ΄ΠΈΡ‚.
    Настройка GitLab CI для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² maven central
  • Если ΠΌΠ΅ΠΉΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² нСсколько, Ρ‚ΠΎ Π»ΡƒΡ‡ΡˆΠΈΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΡ‚ΡŒ доступ ΠΊ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Ρƒ Π² ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ΅.
    ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ -> Settings -> General -> Visibility, project features, permissions ΠΈ выставляСм Project visibility Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Private.
    Π£ мСня ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠΌ доступС, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ я ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ собствСнный GitLab Runner ΠΈ доступ Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ рСпозитория Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρƒ мСня. Ну ΠΈ собствСнно Π½Π΅ Π² ΠΌΠΎΠΈΡ… интСрСсах ΡΠ²Π΅Ρ‚ΠΈΡ‚ΡŒ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΡƒΡŽ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΡŽ Π² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… pipeline-Π»ΠΎΠ³Π°Ρ….
  • УТСсточСниС ΠΏΡ€Π°Π²ΠΈΠ» Π½Π° ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ рСпозитория
    ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ -> Settings -> Repository -> Push Rules ΠΈ устанавливаСм Ρ„Π»Π°Π³ΠΈ Committer restriction, Check whether author is a GitLab user. Π’Π°ΠΊ ΠΆΠ΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ подпись ΠΊΠΎΠΌΠΌΠΈΡ‚ΠΎΠ², ΠΈ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ„Π»Π°Π³ Reject unsigned commits.
  • Π”Π°Π»Π΅Π΅ трСбуСтся Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ Ρ‚Ρ€ΠΈΠ³Π³Π΅Ρ€ для запуска Π·Π°Π΄Π°Ρ‡
    ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ -> Settings -> CI / CD -> Pipeline triggers ΠΈ создаСм Π½ΠΎΠ²Ρ‹ΠΉ trigger-token
    Π”Π°Π½Π½Ρ‹ΠΉ Ρ‚ΠΎΠΊΠ΅Π½ ΠΌΠΎΠΆΠ½ΠΎ сразу Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² ΠΎΠ±Ρ‰ΡƒΡŽ ΠΊΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… для Π³Ρ€ΡƒΠΏΠΏΡ‹ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ².
    ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ Π² Π³Ρ€ΡƒΠΏΠΏΡƒ -> Settings -> CI / CD -> Variables ΠΈ добавляСм ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ DEPLOY_TOKEN с trigger-token Π² Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΈ.

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

GitLab Runner

Π’ Π΄Π°Π½Π½ΠΎΠΌ Ρ€Π°Π·Π΄Π΅Π»Π΅ описана конфигурация для запуска Π·Π°Π΄Π°Ρ‡ Π½Π° deploy с использованиСм собствСнного (Specific) ΠΈ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠ³ΠΎ (Shared) Ρ€Π°Π½Π½Π΅Ρ€Π°.

Specific Runner

Π― ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ собствСнныС Ρ€Π°Π½Π½Π΅Ρ€Ρ‹, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ это ΡƒΠ΄ΠΎΠ±Π½ΠΎ, быстро, дСшСво.
Для Ρ€Π°Π½Π½Π΅Ρ€Π° Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΡŽ Π»ΠΈΠ½ΡƒΠΊΡΠΎΠ²ΡƒΡŽ VDS с 1 CPU, 2 GB RAM, 20 GB HDD. Π¦Π΅Π½Π° вопроса ~3000β‚½ Π² Π³ΠΎΠ΄.

Мой Ρ€Π°Π½Π½Π΅Ρ€

Для Ρ€Π°Π½Π½Π΅Ρ€Π° я взял VDS 4 CPU, 4 GB RAM, 50 GB SSD. Обошлась ~11000β‚½ ΠΈ Π½ΠΈ Ρ€Π°Π·Ρƒ Π½Π΅ ΠΏΠΎΠΆΠ°Π»Π΅Π».
Π£ мСня Π² ΠΎΠ±Ρ‰Π΅ΠΉ слоТности 7 машинок. 5 Π½Π° aruba ΠΈ 2 Π½Π° ihor.

Π˜Ρ‚Π°ΠΊ, Ρƒ нас Π΅ΡΡ‚ΡŒ Ρ€Π°Π½Π½Π΅Ρ€. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΡ‹ Π΅Π³ΠΎ Π±ΡƒΠ΄Π΅ΠΌ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ.
Π—Π°Ρ…ΠΎΠ΄ΠΈΠΌ Π½Π° ΠΌΠ°ΡˆΠΈΠ½ΠΊΡƒ ΠΏΠΎ SSH ΠΈ устанавливаСм java, 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 (ΠΌΠΎΠΆΠ½ΠΎ простой, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ дСйствуСт ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½ΠΈΠ΅ для 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 -> Settings -> CI/CD -> Runners -> Specific Runners ΠΈ ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ registration token

Π‘ΠΊΡ€ΠΈΠ½

Настройка 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 -> Settings -> CI/CD -> Runners -> Specific Runners -> Runners activated for this project

Π‘ΠΊΡ€ΠΈΠ½

Настройка 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 
  • Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Π΄ΠΈΡ€Π΅Ρ‚ΠΎΡ€ΠΈΡŽ maven repository ΠΈ Π»ΠΈΠ½ΠΊΡƒΠ΅ΠΌ с кэшСм (Π½Π΅ ΠΎΡˆΠΈΠ±ΠΈΡ‚Π΅ΡΡŒ)
    Π­Ρ‚ΠΎΡ‚ ΠΏΡƒΠ½ΠΊΡ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ, Ссли Π²Ρ‹ Π½Π΅ ΠΏΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚Π΅ запуска нСсколько Ρ€Π°Π½Π½Π΅Ρ€ΠΎΠ² Π½Π° ΠΎΠ΄Π½ΠΎΠΉ машинС.

    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

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Shared Runner

ГСнСрация 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-----

  • ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ настройки ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -> Settings -> CI / CD -> Variables ΠΈ сохраняСм ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡ Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ GPG_SECRET_KEY
    Настройка GitLab CI для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² maven central

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Настройка Maven

  • Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ мастСр ΠΊΠ»ΡŽΡ‡
    mvn --encrypt-master-password password
    {hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}
  • ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ настройки ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -> Settings -> CI / CD -> Variables ΠΈ сохраняСм Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ SETTINGS_SECURITY_XML ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ строки:
    <settingsSecurity>
    <master>{hnkle5BJ9HUHUMP+CXfGBl8dScfFci/mpsur/73tR2I=}</master>
    </settingsSecurity>
  • Π¨ΠΈΡ„Ρ€ΡƒΠ΅ΠΌ ΠΏΠ°Ρ€ΠΎΠ»ΡŒ ΠΎΡ‚ ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записи Sonatype
    mvn --encrypt-password SONATYPE_PASSWORD
    {98Wv5+u+Tn0HX2z5G/kR4R8Z0WBgcDBgi7d12S/un+SCU7uxzaZGGmJ8Cu9pAZ2J}
  • ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΠΌ настройки ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° -> Settings -> CI / CD -> Variables ΠΈ сохраняСм Π² ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ 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

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Deploy docker image

  • Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ достаточно простой Dockerfile для запуска Π·Π°Π΄Π°Ρ‡ Π½Π° deploy с Π½ΡƒΠΆΠ½ΠΎΠΉ вСрсиСй Java. НиТС прСдставлСн ΠΏΡ€ΠΈΠΌΠ΅Ρ€ для alpine.

    FROM java:8u111-jdk-alpine
    RUN apk add gnupg maven git --update-cache 
    --repository http://dl-4.alpinelinux.org/alpine/edge/community/ --allow-untrusted && 
    mkdir ~/.m2/

  • Π‘ΠΎΠ±ΠΈΡ€Π°Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ для вашСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

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

  • АутСнтифицируСмся ΠΈ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Π² registry.

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

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

GitLab CI

Deploy project

ДобавляСм Π² ΠΊΠΎΡ€Π΅Π½ΡŒ deploy-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Ρ„Π°ΠΉΠ» .gitlab-ci.yml
Π’ скриптС прСдставлСно Π΄Π²Π΅ Π²Π·Π°ΠΈΠΌΠΎΠΈΡΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡ΠΈ Π½Π° Π΄Π΅ΠΏΠ»ΠΎΠΉ. 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

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Java project

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

ΠžΡ‡Π΅Π½ΡŒ Π΄Π΅Ρ‚Π°Π»ΡŒΠ½ΠΎ данная Ρ‚Π΅ΠΌΠ° описана Googolplex Π² Настройка ΠΌΠ°Π²Π΅Π½Π° для автоматичСской подписи ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² Π² snapshot- ΠΈ staging-Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ, поэтому я ΠΎΠΏΠΈΡˆΡƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΡŽΠ°Π½ΡΡ‹ использования ΠΏΠ»Π°Π³ΠΈΠ½ΠΎΠ². Π’Π°ΠΊ ΠΆΠ΅ я ΠΎΠΏΠΈΡˆΡƒ ΠΊΠ°ΠΊ Π»Π΅Π³ΠΊΠΎ ΠΈ Π½Π΅ΠΏΡ€ΠΈΠ½ΡƒΠΆΠ΄Π΅Π½Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ nexus-staging-maven-plugin, Ссли Π²Ρ‹ Π½Π΅ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ ΠΈΠ»ΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ org.sonatype.oss:oss-parent Π² качСствС родитСля для своСго ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

maven-install-plugin

УстанавливаСт ΠΌΠΎΠ΄ΡƒΠ»ΠΈ Π² Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ.
Π’Π΅ΡΡŒΠΌΠ° ΠΏΠΎΠ»Π΅Π·Π΅Π½ для локальной ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΉ Π² Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ…, Π° Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠΉ суммой.

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

ГСнСрация 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>

Если Ρƒ вас ΠΌΠ½ΠΎΠ³ΠΎΠΌΠΎΠ΄ΡƒΠ»ΡŒΠ½Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, ΠΈ Π²Π°ΠΌ Π½Π΅Ρ‚ нСобходимости Π·Π°Π³Ρ€ΡƒΠΆΠ°Ρ‚ΡŒ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½Ρ‹ΠΉ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ, Ρ‚ΠΎ Π² pom.xml Π΄Π°Π½Π½ΠΎΠ³ΠΎ модуля Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ 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>

ПослС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ snapshot/release вСрсии доступны Π² staging Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ

<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 для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² maven central

ΠŸΡ€ΠΈ запускС Π΄Π°Π½Π½ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ триггСрится ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ Π·Π°Π΄Π°Ρ‡Π° Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ deploy (ΠΏΡ€ΠΈΠΌΠ΅Ρ€).

ΠŸΠΎΠ΄Ρ€Π΅Π·Π°Π½Π½Ρ‹ΠΉ Π»ΠΎΠ³

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

ВсС snapshot вСрсси ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ ΠΈΠ· рСпозитория Π½Π° сайтС oss.sonatype.org ΠΏΠΎΠ΄ своСй ΡƒΡ‡Π΅Ρ‚Π½ΠΎΠΉ записью.

Настройка GitLab CI для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² maven central

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

ΠŸΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΡ release вСрсии

ΠŸΡ€ΠΈ установкС Ρ‚Π΅Π³Π°, автоматичСски триггСрится ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π°Ρ Π·Π°Π΄Π°Ρ‡Π° Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ deploy Π½Π° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Ρ€Π΅Π»ΠΈΠ·Π½ΠΎΠΉ вСрсии Π² nexus (ΠΏΡ€ΠΈΠΌΠ΅Ρ€).

Настройка GitLab CI для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° Π² maven central

Π‘Π°ΠΌΠΎΠ΅ приятноС, Ρ‡Ρ‚ΠΎ автоматичСски срабатываСт close release Π² 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

ΠΎΡ„Ρ‚ΠΎΠΏ

Для мСня Π±Ρ‹Π»ΠΎ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ΠΌ, Ρ‡Ρ‚ΠΎ maven индСксируСт Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.
ΠŸΡ€ΠΈΡˆΠ»ΠΎΡΡŒ ΠΏΠΎΠ΄ΠΊΠΈΠ½ΡƒΡ‚ΡŒ robots.txt, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ проиндСксировал ΠΌΠΎΠΉ старый Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ.

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π§Ρ‚ΠΎ ΠΌΡ‹ ΠΈΠΌΠ΅Π΅ΠΌ

  • ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ deploy-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ нСсколько CI Π·Π°Π΄Π°Ρ‡ Π½Π° Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π°Ρ€Ρ‚Π΅Ρ„Π°ΠΊΡ‚ΠΎΠ² Π² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… языков Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.
  • Deploy-ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ ΠΈΠ·ΠΎΠ»ΠΈΡ€ΠΎΠ²Π°Π½ ΠΎΡ‚ постороннСго Π²ΠΌΠ΅ΡˆΠ°Ρ‚Π΅Π»ΡŒΡΡ‚Π²Π° ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ с Ρ€ΠΎΠ»ΡŒΡŽ Owner ΠΈ Maintainer.
  • ΠžΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ Specific Runner с "горячим" кэшСм для запуска Ρ‚ΠΎΠ»ΡŒΠΊΠΎ deploy Π·Π°Π΄Π°Ρ‡.
  • ΠŸΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΡ snapshot/release вСрсий Π² ΠΏΡƒΠ±Π»ΠΈΡ‡Π½ΠΎΠΌ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ.
  • АвтоматичСская ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° release вСрсии Π½Π° Π³ΠΎΡ‚ΠΎΠ²Π½ΠΎΡΡ‚ΡŒ ΠΊ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ Π² maven central.
  • Π—Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ автоматичСской ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ "сырых" вСрсий Π² maven central.
  • Π‘Π±ΠΎΡ€ΠΊΠ° ΠΈ публикация snapshot вСрсий "ΠΏΠΎ ΠΊΠ»ΠΈΠΊΡƒ".
  • Π•Π΄ΠΈΠ½Ρ‹ΠΉ Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ для получСния snapshot/release вСрсий.
  • ΠžΠ±Ρ‰ΠΈΠΉ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½ Π½Π° сборку/тСстированиС/ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΡŽ java ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

Настройка GitLab CI Π½Π΅ такая слоТная Ρ‚Π΅ΠΌΠ° ΠΊΠ°ΠΊ каТСтся Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ взгляд. Достаточно ΠΏΠ°Ρ€Ρƒ Ρ€Π°Π· Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ CI "ΠΏΠΎΠ΄ ΠΊΠ»ΡŽΡ‡" ΠΈ Π²ΠΎΡ‚, Ρ‚Ρ‹ ΡƒΠΆΠ΅ Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ Π΄ΠΈΠ»Π΅Ρ‚Π°Π½Ρ‚ Π² этом Π΄Π΅Π»Π΅. Π’Π΅ΠΌ Π±ΠΎΠ»Π΅Π΅ GitLab докумСнтация вСсьма ΠΈΠ·Π±Ρ‹Ρ‚ΠΎΡ‡Π½Π°. НС Π±ΠΎΠΉΡ‚Π΅ΡΡŒ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ шаг. Π”ΠΎΡ€ΠΎΠ³Π° Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΏΠΎΠ΄ шагами ΠΈΠ΄ΡƒΡ‰Π΅Π³ΠΎ (Π½Π΅ помню ΠΊΡ‚ΠΎ сказал πŸ™‚ ).

Π‘ΡƒΠ΄Ρƒ Ρ€Π°Π΄ фидбэку.

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ расскаТу ΠΎ Ρ‚ΠΎΠΌ, ΠΊΠ°ΠΊ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ GitLab CI для ΠΊΠΎΠ½ΠΊΡƒΡ€Π΅Π½Ρ‚Π½ΠΎΠ³ΠΎ запуска Π·Π°Π΄Π°Ρ‡ с ΠΈΠ½Ρ‚Π΅Π³Ρ€Π°Ρ†ΠΈΠΎΠ½Π½Ρ‹ΠΌΠΈ тСстами (с запуском тСстируСмых сСрвисов ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ docker-compose), Ссли Ρƒ вас Π΅ΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ shell Ρ€Π°Π½Π½Π΅Ρ€.

К ΡΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΡŽ

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com