#後編はこちら
https://qiita.com/dosukoi_android/items/f84907d60c749103bb16
はじめに
弊社のプロジェクトでGithub ActionsとCircleCIを組み合わせたところめちゃくちゃ最高だったという話です。
経緯
弊社のAndroidチームでは元々Github Actionsしか使っていませんでした。
ビルド、テスト、Lintチェック、Slackへの通知、自動マージ、デプロイ
全てGithub Actionsを使っていました。
ある日PMから「Github Actions使いすぎやで。料金がとんでもないことになるやで」とご忠告をいただきました。
Github Actionsは従量課金制なので使えば使うほど料金がかかります。
弊社のサーバーサイドチームは基本的にCircleCIを使っていて、最近出た従量課金のプランではなくコンテナごとに料金が決まるプランでした。
そこでAndroidテックリードと話をしたところ「早く結果が欲しいものはGithub Actions、順番待ちでいいものはCircleCI」という結論に至りました。
記事の対象
Github Actionsの構文がそれなりにわかる人
CircleCIの構文がそれなりにわかる人
Github Actionsを使っているチーム
Github Actionsの料金にちょっと不安があるチーム
CircleCIがコンテナごとに料金が決まるチーム
(いや、めっちゃ限定的やないかい)
フロー
上記にあるように、
早く結果が欲しいものはGithub Actions
順番待ちでいいものはCircleCI
となります。
弊社Androidチームでは以下のような結果になりました
ビルド、LintチェックはGithub Actions
テスト、Slackへの通知、自動マージ、デプロイはCircleCI
Github Actions
PRを作成し、pushするごとにビルド、Lintチェックを行う
CircleCI
レビュワーがapproveをしたらテストが走り、テスト結果がレッドだった場合はSlackへの通知、グリーンの場合は自動マージ
マージされたらDelpoyGateへデプロイ
という感じです
実現方法
Github Actionsの長所といえばなんと言ってもトリガーの多さです。
CircleCIはブランチにプッシュされたらぐらいのトリガーしかありませんが、Github Actionsは数え切れないくらいのトリガーがあります。
そのトリガーを生かすために、CircleCIの起動はGithub Actions側からCircleCIのAPIを叩いてあげます。
普段はWebhookを使ってCircleCIを起動するのですが、今回はAPIを叩きます。
ですので、レポジトリの設定からCircleCIのWebhookの設定をOFFにしてください。
Activeのチェックを外してあげればOK
レビュワーがapproveしたらCircleCIを起動する方法
Github Actionsはトリガーが多いと言いましたが、レビュワーがapproveしたらなんて限定的なトリガーはありません。
「じゃあだめやんけ」
そんなことは言わないでください。
トリガーの組み合わせ次第で実現できるのです
ここに詳しく書いてあります
https://qiita.com/dosukoi_android/items/a3464548b3aa293c62dd
簡単に説明すると、レビューが提出されたトリガーとgithubのwebhookで取得できるレビューのstate(状態?)がapprovedの時にCircleCIのAPIを叩いてあげればいいのです。
マージされたタイミングでCircleCIを起動する方法
これまたマージされたというトリガーはないのです。
これもまた組み合わせ次第で実現できます
詳しくは以下の記事
https://qiita.com/dosukoi_android/items/e41f5c2c2a7120685af8
簡単に説明すると、クローズされたらというトリガーとwebhookで取得できるマージされたかというフラグを組み合わせて、マージされていたらCircleCIのAPIを叩いてあげます。
課題
CircleCIを使ったことがある人はわかると思いますが、ジョブごとの起動ができません。(多分)(できたらごめんなさい)(APIを叩くときは確実にできなかったと思う)
なのでこれだけだと、レビュワーがapproveしただけでマージされた時のジョブも起動されてしまいます。
それは良くありませんね。
テストをしたいだけなのにデプロイされてしまったらひとたまりもありません。
解決方法
CircleCI v2.1から導入されたparametersを使ってあげるとこの問題が解決できます。
CircleCIのAPIを叩くときにparametersを渡してあげることができ、それによってどのジョブを実行するか判断できるようになります。
ちょっとした例
API叩く時
curl -X POST -H "Content-Type:application/json" -d '{"branch": "master", "parameters": {"task": "build"}}' \
https://circleci.com/api/v2/project/github/ユーザー名(Organization名)/レポジトリ名/pipeline
CircleCI側
version: 2.1
parameters:
task:
type: enum
enum: ["build", "test", "deploy"]
default: "build"
orbs:
android: circleci/android@0.2.1
job:
build:
executor: android/android
steps:
やりたいこと書いてく
test:
buildと一緒
deploy:
上と一緒
workflows:
version: 2.1
build:
# ここが本題
when:
equal: [ build, << pipeline.parameters.task >> ]
jobs:
- build
test:
when:
equal: [ test, << pipeline.parameters.task >> ]
jobs:
- test
deploy:
when:
equal: [ deploy, << pipeline.parameters.task >> ]
jobs:
- deploy
こんな感じでenumとしてparametersを渡してあげると、渡された値によってどのジョブを実行するかを決めることができます。
enum最高愛してる
全体
といきたいところなんですが、長くなってしまうので次の記事に全体の解説を書きます。