Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Мне часцяком даводзіцца будаваць пайплайн для зборкі праектаў на Java. Часам гэта апенсорс, часам не. Нядаўна я вырашыў паспрабаваць перанесці частку сваіх рэпазітароў з Travis-CI і TeamCity на GitHub Actions, і вось што з гэтага атрымалася.

Што будзем аўтаматызаваць

Для пачатку нам патрэбен праект, які мы будзем аўтаматызаваць, давайце зробім невялікае дадатак на Spring boot / Java 11 / Maven. У рамках гэтага артыкула логіка прыкладання нас цікавіць не будзе зусім, нам важная інфраструктура вакол прыкладання, так што нам хопіць просценькага REST API кантролера.

Паглядзець зыходнікі можна тут: github.com/antkorwin/github-actions усе этапы пабудовы pipeline-канвеера адлюстраваны ў пул-рэквестах гэтага праекта.

JIRA і планаванне

Варта сказаць, што мы звычайна выкарыстоўваем JIRA у якасці трэкера задач, так што давайце завядзем асобную борду пад гэты праект і накідаем туды першыя задачы:

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Крыху пазней мы яшчэ вернемся да таго, што цікавага могуць даць у звязку JIRA і GitHub.

Аўтаматызуем зборку праекта

Наш тэставы праект збіраецца праз maven, так што зборка яго дастаткова простая, усё, што нам трэба, гэта mvn clean package.

Каб зрабіць гэта пры дапамозе Github Actions, нам трэба будзе стварыць у рэпазітары файл з апісаннем нашага workflow, гэта можна зрабіць звычайным yml-файлам, не магу сказаць што мне падабаецца «праграмаванне на yml», але што парабіць - які робіцца ў дырэкторыі .github/ workflow/ файл build.yml у якім будзем апісваць дзеянні пры зборцы майстар галінкі:

name: Build

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - 'master'

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Package
        run: mvn -B clean package -DskipTests

on - гэта апісанне падзеі, па якой будзе запускацца наш скрыпт.

on: pull_request / push - кажа аб тым, што гэты workflow трэба запускаць пры кожным пушы ў майстар і стварэнні пул-рэквестаў.

Далей ідзе апісанне заданняў (працоўных месцаў) і крокі выканання (крокі) для кожнай задачы.

runs-on - тут мы можам абраць мэтавую АС, на здзіўленне можна абраць нават Mac OS, але на прыватных рэпазітарах гэта даволі дарагое задавальненне (у параўнанні з linux).

выкарыстоўвае дазваляе перавыкарыстоўваць іншыя экшэны, так напрыклад пры дапамозе экшэна actions/setup-java мы ўсталёўваем асяроддзе для Java 11.

Пры дапамозе з мы можам паказаць параметры з якімі запускаем дзеянне, па сутнасці гэта аргументы, якія будуць перадавацца ў экшэн.

Застаецца толькі запусціць мавенам зборку праекта: run: mvn -B clean package сцяг -B кажа аб тым, што нам патрэбен non-interactive mode, каб мавен раптам не захацеў нешта ў нас спытаць

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Выдатна! Цяпер пры кожным коміце ў майстар, запускаецца зборка праекта.

Аўтаматызуем запуск тэстаў

Зборка гэта добра, але ў рэальнасці праект можа шчасна збірацца, але не працаваць. Таму наступным крокам трэба заняцца аўтаматызацыяй прагону тэстаў. Да таго ж, даволі зручна глядзець вынік праходу тэстаў, калі робіш рэўю PR - ты сапраўды ведаеш, што тэсты праходзяць і ніхто не забыўся, перад тым як рабіць merge, прагнаць сваю галінку.

Які робіцца запуск тэстаў пры стварэнні пул-рэквеста і merge у майстар, а заадно дадамо пабудову справаздачы пра code-coverage.

name: Build

on:
  pull_request:
    branches:
      - '*'
  push:
    branches:
      - 'master'

jobs:
  build:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Verify
        run: mvn -B clean verify
      - name: Test Coverage
        uses: codecov/codecov-action@v1
        with:
          token: ${{ secrets.CODECOV_TOKEN }}

Для пакрыцця тэстаў я выкарыстоўваю codecov у звязку з jacoco убудовай. У codecov ёсць свой экшэн, але яму для працы з нашым pull-request-ом патрэбен токен:

${{ secrets.CODECOV_TOKEN }} - Такую канструкцыю мы будзем сустракаць яшчэ не адзін раз, secrets гэта механізм захоўвання сакрэтаў у гітхабе, мы можам там прапісаць паролі/токены/хасты/url-ы і іншыя дадзеныя, якімі не варта свяціць у кодавай базе рэпазітара.

Дадаць зменную ў secrets, можна ў наладах рэпазітара на GitHub:

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Атрымаць токен можна на codecov.io пасля аўтарызацыі праз GitHub, для дадання public праекту трэба проста прайсці па спасылцы выгляду: GitHub user name/[repo name]. Прыватны рэпазітар таксама можна дадаць, для гэтага трэба даць правы codecov з дадаткам у гітхабе.

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Дадаем jacoco убудова ў POM-файл:

<plugin>
	<groupId>org.jacoco</groupId>
	<artifactId>jacoco-maven-plugin</artifactId>
	<version>0.8.4</version>
	<executions>
		<execution>
			<goals>
				<goal>prepare-agent</goal>
			</goals>
		</execution>
		<!-- attached to Maven test phase -->
		<execution>
			<id>report</id>
			<phase>test</phase>
			<goals>
				<goal>report</goal>
			</goals>
		</execution>
	</executions>
</plugin>
<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-surefire-plugin</artifactId>
	<version>2.22.2</version>
	<configuration>
		<reportFormat>plain</reportFormat>
		<includes>
			<include>**/*Test*.java</include>
			<include>**/*IT*.java</include>
		</includes>
	</configuration>
</plugin>

Цяпер у кожны наш пул-рэквест будзе заходзіць codecov бот і дадаваць графік змены пакрыцця:

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Дадамо статычны аналізатар

У большасці сваіх oпенсорс-праектаў я выкарыстоўваю sonar cloud для статычнага аналізу кода, яго даволі лёгка падлучыць да travis-ci. Так што гэта лагічны крок пры міграцыі на GitHub Actions, зрабіць тое ж самае. Маркет экшэнаў - зэбая штука, але ў гэты раз ён трохі падвёў, таму што я па звычцы знайшоў патрэбны экшэн і прапісаў яго ў workflow. А аказалася, што sonar не падтрымлівае працу праз дзеянне для аналізу праектаў на maven ці gradle. Пра гэта вядома напісана ў дакументацыі, але хто ж яе чытае?!

Праз дзеянне нельга, таму будзем рабіць праз mvn убудова:

name: SonarCloud

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  sonarcloud:
    runs-on: ubuntu-16.04
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Analyze with SonarCloud
#       set environment variables:
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
#       run sonar maven plugin:
        run: mvn -B verify sonar:sonar -Dsonar.projectKey=antkorwin_github-actions -Dsonar.organization=antkorwin-github -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN -Dsonar.coverage.jacoco.xmlReportPaths=./target/site/jacoco/jacoco.xml

SONAR_TOKEN - Можна атрымаць у sonarcloud.io і трэба прапісаць яго ў secrets. GITHUB_TOKEN — гэта ўбудаваны токен, які генеруе гітхаб, з дапамогай яго sonarcloud[bot] зможа аўтарызавацца ў гіце, каб пакідаць нам паведамленні ў пул-рэквестах.

Dsonar.projectKey - Назва праекта ў санары, паглядзець можна ў наладах праекта.

Dsonar.organization - Назва арганізацыі з GitHub.

Які робіцца пул-рэквест і чакаем, калі sonarcloud[bot] прыйдзе ў каментары:

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

кіраванне рэлізамі

Білд настроілі, тэсты прагналі, можна і рэліз зрабіць. Давайце паглядзім, як GitHub Actions дапамагае істотна спрасціць release management.

На працы ў мяне ёсць праекты, кодавая база якіх ляжыць у bitbucket (усё як у той гісторыі "днём пішу ў бітбакет, уначы коммичу ў GitHub"). Нажаль, у bitbucket няма ўбудаваных сродкаў для кіравання рэлізамі. Гэта праблема, таму што пад кожны рэліз прыходзіцца рукамі заводзіць старонку ў confluence і скідваць туды ўсе фічы якія ўвайшлі ў рэліз, шарсціць палац розуму, цягі ў jira, коміты ў рэпазітары. Шанцаў памыліцца шмат, можна нешта забыцца ці ўпісаць тое, што ўжо рэлізавалі ў мінулы раз, часам проста не зразумела, да чаго аднесці нейкі пул-рэквест - гэта фіча ці фікс багаў, ці праўка тэстаў, ці нешта інфраструктурнае. .

Як нам можа дапамагчы GitHub actions? Ёсць выдатны экшэн - release drafter, ён дазваляе задаць шаблон файла release notes, каб наладзіць катэгорыі пул-рэквестаў і аўтаматычна групаваць іх у release notes файле:

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Прыклад шаблону для наладкі справаздачы(.github/release-drafter.yml):

name-template: 'v$NEXT_PATCH_VERSION'
tag-template: 'v$NEXT_PATCH_VERSION'
categories:
  - title: ' New Features'
    labels:
      - 'type:features'
# в эту категорию собираем все PR с меткой type:features

  - title: ' Bugs Fixes'
    labels:
      - 'type:fix'
# аналогично для метки type:fix и т.д.

  - title: ' Documentation'
    labels:
      - 'type:documentation'

  - title: ' Configuration'
    labels:
      - 'type:config'

change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
template: |
  ## Changes
  $CHANGES

Дадаем скрыпт для генерацыі чарнавіка рэлізу (.github/workflows/release-draft.yml):

name: "Create draft release"

on:
  push:
    branches:
      - master

jobs:
  update_draft_release:
    runs-on: ubuntu-18.04
    steps:
      - uses: release-drafter/release-drafter@v5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Усе пул-рэквесты з гэтага моманту будуць збірацца ў release notes аўтаматычна - magic!

Тут можа ўзнікнуць пытанне: а што калі распрацоўшчыкі забудуцца праставіць пазнакі ў PR? Тады незразумела, у якую катэгорыю яго аднесці, і зноў давядзецца разбірацца ўручную, з кожным PR-ам асобна. Каб выправіць гэтую праблему, мы можам скарыстацца яшчэ адным экшэнам – label verifier – ён правярае наяўнасць тэгаў на пул-рэквест. Калі няма ніводнага абавязковага тэга, то праверка будзе завалена і паведамленне пра гэта мы ўбачым у нашым пул-рэквесце.

name: "Verify type labels"

on:
  pull_request:
    types: [opened, labeled, unlabeled, synchronize]

jobs:
  triage:
    runs-on: ubuntu-18.04
    steps:
      - uses: zwaldowski/match-label-action@v2
        with:
          allowed: 'type:fix, type:features, type:documentation, type:tests, type:config'

Цяпер любы pull-request трэба пазначыць адным з тэгаў: type:fix, type:features, type:documentation, type:tests, type:config.

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Аўта-анатаванне пул-рэквестаў

Раз ужо мы закранулі такую ​​тэму як эфектыўная праца з пул-рэквестамі, то варта сказаць яшчэ пра такі экшэн, як labeler, ён прастаўляе пазнакі ў PR на падставе таго, якія файлы былі змененыя. Напрыклад, мы можам пазначыць як [build] любы пул-рэквест у якім ёсць змены ў каталогу .github/workflow.

Падлучыць яго даволі проста:

name: "Auto-assign themes to PR"

on:
  - pull_request

jobs:
  triage:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/labeler@v2
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}

Яшчэ нам спатрэбіцца файл з апісаннем адпаведнасці каталогаў праекту з тэматыкамі пул-рэквестаў:

theme:build:
  - ".github/**"
  - "pom.xml"
  - ".travis.yml"
  - ".gitignore"
  - "Dockerfile"

theme:code:
  - "src/main/*"

theme:tests:
  - "src/test/*"

theme:documentation:
  - "docs/**"

theme:TRASH:
  - ".idea/**"
  - "target/**"

Сябраваць дзеянне аўтаматычна якое прастаўляе пазнакі ў пул-рэквесты і дзеянне, правяральнае наяўнасць абавязковых метак, у мяне не выйшла, match-label на адрэз не жадае бачыць прастаўленыя ботам пазнакі. Падобна прасцей напісаць сваё дзеянне, якое сумяшчае абодва этапы. Але нават у такім выглядзе карыстацца даволі зручна, трэба абраць пазнаку са спісу пры стварэнні пул-рэквеста.

Час дэплоіць

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Я паспрабаваў некалькі варыянтаў дэплою праз GitHub Actions (праз ssh, праз scp, і пры дапамозе docker-hub), і магу сказаць, што, хутчэй за ўсё, вы знойдзеце спосаб заліць бінарку на сервер, якім бы ненармальным не быў ваш pipeline.

Мне спадабаўся варыянт трымаць усю інфраструктуру ў адным месцы, таму разгледзім, як зрабіць дэплой у GitHub Packages (гэта рэпазітар для бінарнага кантэнту, npm, jar, docker).

Cкпрыпт зборкі docker выявы і публікацыі яго ў GitHub Packages:

name: Deploy docker image

on:
  push:
    branches:
      - 'master'

jobs:

  build_docker_image:
    runs-on: ubuntu-18.04
    steps:

#     Build JAR:
      - uses: actions/checkout@v1
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 1.11
      - name: Maven Package
        run: mvn -B clean compile package -DskipTests

#     Set global environment variables:
      - name: set global env
        id: global_env
        run: |
          echo "::set-output name=IMAGE_NAME::${GITHUB_REPOSITORY#*/}"
          echo "::set-output name=DOCKERHUB_IMAGE_NAME::docker.pkg.github.com/${GITHUB_REPOSITORY}/${GITHUB_REPOSITORY#*/}"

#     Build Docker image:
      - name: Build and tag image
        run: |
          docker build -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:latest" -t "${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}:${GITHUB_SHA::8}" .

      - name: Docker login
        run: docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

#     Publish image to github package repository:
      - name: Publish image
        env:
          IMAGE_NAME: $GITHUB_REPOSITORY
        run: docker push "docker.pkg.github.com/$GITHUB_REPOSITORY/${{ steps.global_env.outputs.IMAGE_NAME }}"

Для пачатку нам трэба сабраць JAR-файл нашага прыкладання, пасля чаго мы вылічаем шлях да GitHub docker registry і назву нашай выявы. Тут ёсць некалькі хітрасцей, з якімі мы яшчэ не сутыкаліся:

  • канструкцыя выгляду: echo "::set-output name=NAME::VALUE" дазваляе задаць значэнне зменнай у бягучым кроку, так каб яго потым можна было прачытаць ва ўсіх астатніх кроках.
  • атрымаць значэнне зменнай усталяванай на папярэднім кроку можна праз ідэнтыфікатар гэтага кроку: ${{ steps.global_env.outputs.DOCKERHUB_IMAGE_NAME }}
  • У стандартнай зменнай GITHUB_REPOSITORY захоўваецца назоў рэпазітара і яго ўладальнік («owner/repo-name»). Для таго каб выразаць з гэтага радка ўсё акрамя назову рэпазітара, скарыстаемся bash сінтаксісам: ${GITHUB_REPOSITORY#*/}

Далей нам трэба сабраць докер-вобраз:

docker build -t "docker.pkg.github.com/antkorwin/github-actions/github-actions:latest"

Аўтарызавацца ў registry:

docker login docker.pkg.github.com -u $GITHUB_ACTOR -p ${{secrets.GITHUB_TOKEN}}

І апублікаваць выяву ў GitHub Packages Repository:

docker push "docker.pkg.github.com/antkorwin/github-actions/github-actions"

Для таго каб паказаць версію выявы, мы выкарыстаем першыя лічбы з SHA-хэша коммита - GITHUB_SHA тут таксама ёсць нюансы, калі вы будзеце рабіць такія зборкі не толькі пры merge у master, а яшчэ і па падзеі стварэння пул-рэквеста, то SHA можа не супадаць з хэшам, які мы бачым у гісторыі гіта, таму што дзеянне actions/checkout робіць свой унікальны хэш, каб пазбегнуць узаемных блакіровак дзеянняў у PR.

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Калі ўсё атрымалася шчасна, то адкрыўшы падзел packages (https://github.com/antkorwin/github-actions/packages) у рэпазітары, вы ўбачыце новы докер выява:

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Там жа можна паглядзець спіс версій докер-выявы.

Застаецца толькі настроіць наш сервер на працу з гэтым registry і запусціць перазапуск сэрвісу. Пра тое як гэта зрабіць праз systemd, я, мабыць, раскажу ў іншы раз.

Маніторынг

Давайце паглядзім нескладаны варыянт, як рабіць health check нашага прыкладання з дапамогай GitHub Actions. У нашым бутавым дадатку ёсць actuator, так што API для праверкі яго стану нават і пісаць не трэба, для лянівых ужо ўсё зрабілі. Трэба толькі тузануць хост: SERVER-URL:PORT/actuator/health

$ curl -v 127.0.0.1:8080/actuator/health

> GET /actuator/health HTTP/1.1
> Host: 127.0.0.1:8080
> User-Agent: curl/7.61.1
> Accept: */*

< HTTP/1.1 200
< Content-Type: application/vnd.spring-boot.actuator.v3+json
< Transfer-Encoding: chunked
< Date: Thu, 04 Jun 2020 12:33:37 GMT

{"status":"UP"}

Усё, што нам трэба - напісаць таск праверкі сервера па кроне, ну а калі раптам ён нам не адкажа, то будзем слаць апавяшчэнне ў тэлеграм.

Для пачатку разбяромся, як запусціць workflow па кроне:

on:
  schedule:
    - cron:  '*/5 * * * *'

Усё проста, нават не верыцца што ў гітхабе можна зрабіць такія івэнты, якія зусім не ўкладваюцца ў webhook-і. Дэталі ёсць у дакументацыі: help.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events-schedule

Праверку статуту сервера зробім рукамі праз curl:

jobs:
  ping:
    runs-on: ubuntu-18.04
    steps:

      - name: curl actuator
        id: ping
        run: |
          echo "::set-output name=status::$(curl ${{secrets.SERVER_HOST}}/api/actuator/health)"

      - name: health check
        run: |
          if [[ ${{ steps.ping.outputs.status }} != *"UP"* ]]; then
            echo "health check is failed"
            exit 1
          fi
          echo "It's OK"

Спачатку захоўваем у зменную тое, што адказаў сервер на запыт, на наступным кроку правяраем што статут UP і, калі гэта не так, то выходзім з памылкай. Калі трэба рукамі "заваліць" дзеянне, то выхад 1 - Прыдатнае зброю.

  - name: send alert in telegram
    if: ${{ failure() }}
    uses: appleboy/telegram-action@master
    with:
      to: ${{ secrets.TELEGRAM_TO }}
      token: ${{ secrets.TELEGRAM_TOKEN }}
      message: |
        Health check of the:
        ${{secrets.SERVER_HOST}}/api/actuator/health
        failed with the result:
        ${{ steps.ping.outputs.status }}

Адпраўку ў тэлеграм які робіцца, толькі калі дзеянне завалілася на папярэднім кроку. Для адпраўкі паведамлення выкарыстоўваем appleboy/telegram-action, пра тое, як атрымаць токен бота і id чата можна пачытаць у дакументацыі: github.com/appleboy/telegram-action

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Не забудзьцеся прапісаць у сакрэтах на гітхабе: URL для сервера і токены для тэлеграм робата.

Бонус трэк - JIRA для лянівых

Я абяцаў, што мы вернемся да JIRA, і мы вярнуліся. Сотні разоў назіраў на стэндапах сітуацыю, калі распрацоўшчыкі зрабілі фічу, злілі галінку, але забыліся перацягнуць задачу ў JIRA. Вядома, калі б усё гэта рабілася ў адным месцы, то было б прасцей, але фактычна мы пішам код у IDE, зліваем галінкі ў bitbucket ці GitHub, а задачы потым цягаем у Jira, для гэтага трэба адчыняць новыя вокны, часам лагініцца яшчэ раз і г.д. Калі ты выдатна памятаеш, што трэба рабіць далей, то адчыняць борду лішні раз няма сэнсу. У выніку, раніцай на стэндапе трэба марнаваць час на актуалізацыю дошкі задач.

GitHub дапаможа нам і ў гэтым руцінным занятку, для пачатку мы можам перацягваць задачы аўтаматам, у калонку code_review, калі закінулі пул-рэквест. Усё, што трэба - гэта прытрымлівацца пагаднення ў найменні галінак:

[имя проекта]-[номер таска]-название

напрыклад, калі ключ праекта "GitHub Actions" будзе GA, то GA-8-jira-bot можа быць галінкай для рэалізацыі задачы GA-8.

Інтэграцыя з JIRA працуе праз экшэны ад Atlassian, яны не ідэальныя, трэба сказаць, што некаторыя з іх у мяне наогул не зарабілі. Але мы абмяркуем толькі тыя, што дакладна працуюць і актыўна выкарыстоўваюцца.

Для пачатку трэба прайсці аўтарызацыю ў JIRA пры дапамозе дзеяння: atlassian/gajira-login

jobs:
  build:
    runs-on: ubuntu-latest
    name: Jira Workflow
    steps:
      - name: Login
        uses: atlassian/gajira-login@master
        env:
          JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }}
          JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }}
          JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}

Для гэтага трэба атрымаць токен у JIRA, як гэта зрабіць распісана тут: confluence.atlassian.com/cloud/api-tokens-938839638.html

Вылучаем ідэнтыфікатар задачы з назову галінкі:

  - name: Find Issue
    id: find_issue
    shell: bash
    run: |
      echo "::set-output name=ISSUE_ID::$(echo ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}')"
      echo brach name: $GITHUB_HEAD_REF
      echo extracted issue: ${GITHUB_HEAD_REF} | egrep -o 'GA-[0-9]{1,4}'

  - name: Check Issue
    shell: bash
    run: |
      if [[ "${{steps.find_issue.outputs.ISSUE_ID}}" == "" ]]; then
        echo "Please name your branch according to the JIRA issue: [project_key]-[task_number]-branch_name"
        exit 1
      fi
      echo succcessfully found JIRA issue: ${{steps.find_issue.outputs.ISSUE_ID}}

Калі пашукаць у GitHub marketplace, то можна знайсці дзеянне для гэтай задачы, але мне прыйшлося напісаць тое самае праз grep па назове галінкі, таму што гэтае дзеянне ад Atlassian ні ў якую не захацела працаваць на маім праекце, разбірацца, што ж там не так. даўжэй, чым зрабіць рукамі тое ж самае.

Засталося толькі перамясціць задачу ў калонку "Code review" пры стварэнні пул-рэквеста:

  - name: Transition issue
    if: ${{ success() }}
    uses: atlassian/gajira-transition@master
    with:
      issue: ${{ steps.find_issue.outputs.ISSUE_ID }}
      transition: "Code review"

Для гэтага ёсць спецыяльнае дзеянне на GitHub, усё, што яму трэба - гэта ідэнтыфікатар задачы, атрыманы на папярэднім кроку і аўтарызацыя ў JIRA, якую мы рабілі вышэй.

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Такой жа выявай можна перацягваць задачы пры merge у майстар, і іншых падзеях з GitHub workflow. Увогуле, усё залежыць ад вашай фантазіі і жаданні аўтаматызаваць руцінныя працэсы.

Высновы

Калі паглядзець на класічную дыяграму DEVOPS, то мы пакрылі ўсе этапы, хіба што акрамя operate, думаю, калі паспрабаваць, то можна знайсці які-небудзь экшэн у маркеце для інтэграцыі з help-desk сістэмай, так што будзем лічыць што pipeline атрымаўся грунтоўны і на падставе яго выкарыстання можна зрабіць вывады.

Кругі пекла з GitHub Actions (будуем CI/CD pipeline для Java-праекта)

Плюсы:

  • Marketplace з гатовымі дзеяннямі на ўсе выпадкі жыцця, гэта вельмі крута. У большасці з іх яшчэ і зыходнікі можна паглядзець, каб зразумець як вырашыць падобную задачу або запосціць feature request аўтару прама ў гітхаб рэпазітары.
  • Выбар мэтавай платформы для зборкі: Linux, mac os, windows даволі цікавая фіча.
  • Github Packages выдатная рэч, трымаць усю інфраструктуру ў адным месцы зручна, не трэба сярфіць па розных акенцах, усё ў радыусе аднаго-двух клікаў мышы і выдатна інтэгравана з GitHub Actions. Падтрымка docker registry у бясплатнай версіі - гэта таксама добрая перавага.
  • GitHub хавае сакрэты ў логах зборкі, таму карыстацца ім для захоўвання пароляў і токенаў не так ужо і страшна. За ўвесь час эксперыментаў мне не ўдалося ні разу ўбачыць сакрэт у чыстым выглядзе ў кансолі.
  • Бясплатны для Open Source праектаў

Мінусы:

  • YML, ну не люблю я яго. Пры працы з такім флоу ў мяне самы часты commit message гэта "fix yml format", то забудзешся дзесьці таб паставіць, то не на тым радку напішаш. Увогуле, сядзець перад экранам з транспарцірам і лінейкай не самы прыемны занятак.
  • DEBUG, адладжваць флоу комитами, запускам пересборкі і высновай у кансоль не заўсёды зручна, але гэта больш з разраду "вы зажэрліся", абвыклі працаваць са зручнымі IDEA, калі можна адладжваць усё, што заўгодна.
  • Свой экшэн можна напісаць на чым заўгодна калі загарнуць яго ў докер, але натыўна падтрымліваецца толькі javascript, вядома гэтая справа густу, але я б аддаў перавагу нешта іншае замест js.

Нагадаю, што рэпазітар з усімі скрыптамі тут: github.com/antkorwin/github-actions

На наступным тыдні я буду выступаць з дакладам на канферэнцыі Heisenbug 2020 Piter. Раскажу не толькі, як пазбегнуць памылак пры падрыхтоўцы тэставых дадзеных, але і падзялюся сваімі сакрэтамі працы з наборамі дадзеных у Java-прыкладаннях!

Крыніца: habr.com