Github ActionsでDeployGateにデプロイする話

# はじめに
今回はGithub Actionsを使ってDeployGateに自動デプロイする方法を紹介していきます。

CI/CDってなんかかっこいいですよね(小並感)

Androidの方法なのでiOSの方には参考にならないかもしれませんmm

# 準備
まずは準備していきましょう

まずはDeployGateを開きます。

そしたら右上のアイコンのところからアカウント設定を選び、下の方にあるAPI Keyを確認します。（後で使うのでメモっといてください）

次にGithubのレポジトリにsecretsを追加していきましょう。
レポジトリのタブバーからSettingを選択
![スクリーンショット 2020-11-16 22.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411927/da9d620c-b8be-1154-030e-7372dbad0bbd.png)

左のメニューからSecretsを選び、先ほどのAPIキーとDeployGateのユーザー名を追加します。

![スクリーンショット 2020-11-16 22.59.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411927/ed06cb69-b2d0-0c89-d3fe-1249173d2f06.png)

いい感じ

準備終わり！

# デプロイのタイミング
今回はプルリクエストベースでプロジェクトが進んでいたので、レビューしてもらってApproveをもらい、マージされたタイミングでデプロイするようにしています。

PR出す→レビュー(通らなかったら修正)→Approveをもらったらマージ→デプロイが走る

# やり方
まずはプロジェクトのルートに.github/workflowsとディレクトリを作ります。
.github/workflowsの中に適当な名前でyamlファイルを作っていきましょう。

サンプルでdeploy.ymlと名付けました

[Github Actionsのトリガー](https://docs.github.com/ja/free-pro-team@latest/actions/reference/events-that-trigger-workflows#pull_request)を見てみるとclosedのタイミングはあるけど、マージされたタイミングというのは実はないのです。

クローズされたタイミングで毎回走らせてしまうと、間違えてPR出してクローズした際もデプロイされてしまいます。それは不便ですよね。

なのでマージされたタイミングをWebHookで取得します。

[プルリクエストのWebHookのペイロード](https://developer.github.com/webhooks/event-payloads/#pull_request)を見てみると、mergedというプロパティがあるのがわかりますね。
これがtrueになればマージされているということなので、Github Actionsのトリガーと合わせて使えそうです。

あとはワークフローを書いていくだけ！

全体はこんな感じ

```yaml:deploy.yml
name: Deploy CI

on:
  pull_request:
    types: [closed]
    branches: [master]

jobs:
  build:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-18.04

    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
      - name: Build App Bundle
        run: ./gradlew assembleRelease
      - name: Distribute App
        run: |
          curl \
            -H "Authorization: token ${{secrets.DEPLOY_GATE_API_KEY}}" \
            -F "file=@app/build/outputs/apk/release/app-release.apk" \
            -F "message=${{github.event.pull_request.title}}" \
            -v "https://deploygate.com/api/users/${{secrets.DEPLOY_GATE_USER_NAME}}/apps"
```




pull_requestをトリガーとして、typesでアクティビティタイプを指定(今回はマージ(クローズ)したタイミングなのでclosed)、branchesでどのブランチにpull_requestを出した時から指定します。

ちなみアクティビティタイプに関してはオープンしたタイミング、アサインされたタイミング、ラベルをつけたタイミング等いっぱいあるので遊んでみてください。


```yaml
on:
  pull_request:
    types: [closed]
    branches: [master]
```

ここからjobの開始
ifでマージされたタイミングだけ走らせるように指定します。

```yaml

jobs:
  build:
    if: github.event.pull_request.merged == true
```

ちなみにこの

```
github.event.pull_request.merged
```
がWebHookのpayloadの取得です。
これもトリガーの一つだと思ってたんですが、WebHookの取得だったんですね、最近知りました

これはAndroidのビルドをする環境を用意

```yaml
steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 1.8
        uses: actions/setup-java@v1
        with:
          java-version: 1.8
```

これでapkの作成

```yaml
- name: Build App Bundle
        run: ./gradlew assembleDebug
```

**ここが今回の本題**

```yaml
- name: Distribute App
        run: |
          curl \
            -H "Authorization: token ${{secrets.DEPLOY_GATE_API_KEY}}" \
            -F "file=@app/build/outputs/apk/release/app-release.apk" \
            -F "message=${{github.event.pull_request.title}}" \
            -v "https://deploygate.com/api/users/${{secrets.DEPLOY_GATE_USER_NAME}}/apps"
```

curlコマンドで[DeployGateのAPI](https://docs.deploygate.com/reference#upload)を叩いていきます。
ヘッダーに先ほどDeployGateからメモったAPI Keyを追加します。
Secretsに入れた値は

```yaml
${{ secrets.hogehoge}}
```

で取得できます。便利ですね

あとはfileにapkを指定。

```yaml
-F "file=@app/build/outputs/apk/release/app-release.apk" \
```

DeployGateの更新をする際のメッセージはプルリクエストのタイトルを使うことにします。
こちらもWebHookのpayloadから取得

```yaml
-F "message=${{github.event.pull_request.title}}" \
```

最後にapiのURLを指定するだけ
ちなみにDeployGateのデプロイ先はapplicationIdで自動で変わってくれるので、特に指定はいりません。
なので環境ごと(develop, staging, production)のサフィックスを入れておけば、それぞれ違うデプロイ先になってくれます。

```yaml
-v "https://deploygate.com/api/users/${{secrets.DEPLOY_GATE_USER_NAME}}/apps"
```

# まとめ
やっぱり自動化ってとにかく楽でいいですね。
ビルドしてapkの作成を待って、DeployGateにドラッグ＆ドロップ
大規模アプリの場合はビルドだけでもかなり時間が取られますし、何よりヒューマンエラーがなくなります。(環境を変え忘れるなど)

現在色んなことを自動化しているのでどんどん紹介していきたいと思います。(どんなことをしているかはTwitterを見ればなんとなくわかるかも？)

# P.S.
筆者はcurlコマンド滅多に使わないので、かなり勉強になりました。
複数行curlコマンドを書いていくときに、バックスラッシュを忘れて上手く動かず、なんでや！！となっていたのはいい思い出