はじめに
今回は前回、前々回、前々前回の続きの話です
前回 → Github Actionsを使ってSlackに通知してみた話
前々回 → Github Actionsを使って自動テストする話
前々前回 → Github Actionsを使ってDeployGateにデプロイする話
これらを使ってGithubのフローを大体自動化してみましょう
自動化の適用範囲
テストをCIで走らせるタイミングはチームによって変わってきますが、現在僕が参加しているチームではGithub Actionsの実行時間が増えるのがあまりよろしくないので(お金がかかるから)、Approveした段階でテストを回すようにしています。
またビルドに関してもプルリクエストを出すタイミングのみCIを走らせています。
なので自動化するのは
Approveした後のテスト→Slack通知→マージ→デプロイ
ここの部分を自動化しました。
つまりレビュワーがApproveしたらあとは全て自動でやってくれます
とても便利ですね
やり方
テストの方法、Slack通知、デプロイの方法は上記のリンクから見てください
まずは全体を見ていきましょう
name: DevUnitTest
on:
pull_request_review:
types: [ submitted ]
branches: [ master ]
jobs:
test:
if: github.event.review.state == 'approved'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: UnitTest
run: ./gradlew testDebugUnitTest
- name: Unit Test Success Notification
if: ${{ success() }}
run: |
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"attachments": [{"color": "#26A745", "title": "${{ github.event.pull_request.title }}", "title_link": "${{ github.event.pull_request.html_url }}", "text": "Success Unit Test", "author_name": "${{ github.event.pull_request.user.login }}"}]}' \
${{ secrets.SLACK_WEBHOOK}}
- name: Unit Test Failure Notification
if: ${{ failure() }}
run: |
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"attachments": [{"color": "#D73A49", "title": "${{ github.event.pull_request.title }}", "title_link": "${{ github.event.pull_request.html_url }}", "text": "Failure Unit Test", "author_name": "${{ github.event.pull_request.user.login }}"}]}' \
${{ secrets.SLACK_WEBHOOK}} && exit 1
- name: Wait For Status Check
if: ${{ success() }}
run: sleep 5s
- name: Automatic Merge
if: ${{ success() }}
run: |
curl \
-X PUT \
-H "Authorization: token ${{ secrets.PERSONAL_ACCESSTOKEN }}" \
-H "Content-Type: application/json" \
-d '{"sha": "${{ github.event.pull_request.head.sha }}", "merged": "true", "message": "Pull Request successfully merged"}' \
"${{ github.event.pull_request.url }}/merge"
解説
今回はマージの部分のみ見ていきます。
- name: Wait For Status Check
if: ${{ success() }}
run: sleep 5s
- name: Automatic Merge
if: ${{ success() }}
run: |
curl \
-X PUT \
-H "Authorization: token ${{ secrets.PERSONAL_ACCESSTOKEN }}" \
-H "Content-Type: application/json" \
-d '{"sha": "${{ github.event.pull_request.head.sha }}", "merged": "true", "message": "Pull Request successfully merged"}' \
"${{ github.event.pull_request.url }}/merge"
処理を待たなきゃいけない!?
- name: Wait For Status Check
if: ${{ success() }}
run: sleep 5s
この部分を見て、「ん?なぜ5秒も待つ必要がある?」と思った方もいるかもしれません。
僕もその一人です。
これをしないと
Head branch was modified. Review and try the merge again.
と怒られてしまうのです。
正直原因はほぼわかりません
https://stackoverflow.com/questions/38796617/how-to-avoid-delaying-github-pull-request-merge-using-api
こちらが関係してそうですが、原因わかる方教えていただけたら幸いです。
マージする
あとはマージするのみ!
- name: Automatic Merge
if: ${{ success() }}
run: |
curl \
-X PUT \
-H "Authorization: token ${{ secrets.PERSONAL_ACCESSTOKEN }}" \
-H "Content-Type: application/json" \
-d '{"sha": "${{ github.event.pull_request.head.sha }}"}' \
"${{ github.event.pull_request.url }}/merge"
Githubのマージ用のAPIを叩きます
必要な情報は以下の通り
必須なのはshaのみなので、pull_request_reviewのWebhookのpayloadから持ってきます。
まとめ
以上でGithub Actionsの自動化は終わりになります。
まとめると
CIの目的は人間以外でできる作業はとことんサボること、ヒューマンエラーをなくすることです
今回のCIでそれをほとんど達成できたと思います。
個人的に心残りは大体CircleCIでやりたかったんですが、CircleCIだとGithub Actionsほどトリガーがないので(自分調べ)ここまで便利にできないということですね
P.S.
Approve何度もしてくれたテックリード、感謝申し上げます