Github ActionsとCircleCIの組み合わせが最高という話【前編】

#後編はこちら
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にしてください。

![スクリーンショット 2021-01-18 3.34.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411927/a52584dd-8740-ec5d-9df0-fc641ef4d80b.png)

Activeのチェックを外してあげればOK<br><br>

# レビュワーが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を渡してあげることができ、それによってどのジョブを実行するか判断できるようになります。

https://circleci.com/docs/api/v2/#operation/triggerPipeline

### ちょっとした例
**API叩く時**

```shell
curl -X POST -H "Content-Type:application/json" -d '{"branch": "master", "parameters": {"task": "build"}}' \
https://circleci.com/api/v2/project/github/ユーザー名(Organization名)/レポジトリ名/pipeline
```

**CircleCI側**

```yaml
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最高愛してる

# 全体
といきたいところなんですが、長くなってしまうので次の記事に全体の解説を書きます。

https://qiita.com/dosukoi_android/items/f84907d60c749103bb16