【後編】GridsomeとContentfulを使って、簡単に更新できる静的LPページを作ってみる

diffeasyアドベントカレンダー23日目の記事で、前回の「[【前編】GridsomeとContentfulを使って、簡単に更新できる静的LPページを作ってみる](https://qiita.com/tk07Sky/items/1e42656b50349efb0378)」の続きです。

みなさん、あと2日でクリスマスですがいかがお過ごしでしょうか？
僕はというもの、12月に入ってから彼女からアドベントカレンダー、自称：[沙枝ベントカレンダー](https://twitter.com/search?q=%E6%B2%99%E6%9E%9D%E3%83%99%E3%83%B3%E3%83%88%E3%82%AB%E3%83%AC%E3%83%B3%E3%83%80%E3%83%BC&src=typed_query&f=live)を毎日もらっては開けているのですが、早くメインのプレゼントが開けたくて開けたくて喉から手が出そうです😈（自室の手の届くところにすでに置いてあるので…）

そんなことはさておき、前回

```
1. Contentfulでお知らせコンテンツの作成
2. Gridsomeで 1. で作ったお知らせコンテンツの表示
```

までを作りました。
今回は、

```
1. Firebase Hostingへのデプロイ
2. Github Actionsを使ってContentfulでの変更を検知し、自動デプロイ
```

を作っていきたいと思います💪

サンプルリポジトリも作ったので、よかったら見てください😉
https://github.com/tk07Sky/deadvent-2019-gridsome-sample

## 事前準備🙇‍♂️

今回はFirebase Hostingを使うので、Firebaseプロジェクトの作成（名前はなんでもいいです）と、[Firebase CLIのインストール](https://firebase.google.com/docs/cli?hl=ja)を行ってください。
また、GitHubも使うので、アカウントの作成や、Gridsomeで作ったアプリケーションをアップするリポジトリ（名前はなんでもいいです）を作成しておいてください。


## Firebase Hostingにデプロイしてみる

### Firebase Hostingのセットアップ

まず、ターミナルで`firebase init`を打って、プロジェクトにFirebaseの設定を行っていきます。
次に、どの設定を組み込むのかを問われるので、Hostingのみにチェックを入れます。
<img width="1043" alt="スクリーンショット 2019-12-22 0.59.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/4d7fa325-f0e7-cf2c-6d71-f4a98766af26.png">


次にプロジェクトを作るか選択するか問われるので`Use an existing project`を選択し、事前準備で用意してもらっているプロジェクト名を選択します。
その後は、一旦エンターを押し続けてFirebaseの設定を終わらせます。
<img width="525" alt="スクリーンショット 2019-12-22 0.59.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/eb4cfdbc-d482-a4c1-2950-7dc912310149.png">

Firebaseの設定を終えると、プロジェクトルートに`public`フォルダができていると思いますが、使わないので削除しておいてください。


### Gridsomeコマンドで静的ページを生成し、Hostingのアップロード対象に設定する

Gridsomeの`build`コマンドを使って、Firebase Hostingにアップロードするための静的ページを作ります。

```sh
$ npm run build
```

上コマンドを実行すると、プロジェクトルートに`dist`フォルダができるので、このフォルダをFirebase Hostingのアップロード対象に設定します。
`firebase init`をした際に、プロジェクトルートに`firebase.json`が生成されていると思うので、中身を書き換えていきます。

```json:firebase.json
{
  "hosting": {
    "public": "dist", // ←ここ
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```

### デプロイしてみる

ターミナルで

```sh
$ firebase deploy --only hosting
```

を実行してみましょう！
成功すれば、下画像のように **Deploy complete!** の文字とHosting先のURLが表示されるはずです。

<img width="690" alt="スクリーンショット 2019-12-22 2.03.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/1d067d49-bf41-69d7-bcef-e234c7900777.png">

🎉🎉🎉🎉🎉


## Github Actionsを使ってContentfulでの変更を検知し、自動デプロイされるようにする

### Firebase Hostingのアクセストークンを取得する

自動デプロイする際に必要なので取得していきます。
ターミナルで

```sh
$ firebase login:ci
```

を入力すると、`firebase login`したときと同じように認証画面に飛ぶので、流れに沿って進みます。
認証が終わるとターミナルにトークンが表示されるので、コピーしておきます。


### Github Actionsを設定する

まずはGithub Actionsのワークフローを作っていきます。
Github Actionsのワークフローはプロジェクト直下に`.github/workflows/**.yml`の形で追加してきます。

```sh
$ touch .github/workflows/ci.yml
$ vim .github/workflows/ci.yml
```

まずワークフロー名を決めます

```yaml:.github/workflows/ci.yml
# 今回はciと名付けます
name: ci
```

次に、何のアクションを起点として発火するかを決めます。
今回はmasterブランチにpushされたときか、外部からリポジトリにGitHub APIを叩かれたときに発火するよう設定します。
外部からのイベントをキャッチするには、[repository_dispatch](https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#)というGitHubのWebhookイベントを使用します。

```yaml:.github/workflows/ci.yml
on:
  push:
    branches:
      - master
  repository_dispatch:
```

次に、GitHub Actions上でGridsomeのビルドとデプロイをするjobを書きます。

大まかな部分の説明は[公式ドキュメント](https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/configuring-a-workflow)やプラグインのドキュメントに載っているので割愛しますが、今回知ってほしい点を説明すると

- 外部に公開できない`.env`の内容やFirebase tokenなどは、GitHubのSecretsという機能を使って、そこから呼び出すようにする
- 開発の際に使っていた`.env`はgitの監視外にありそのまま使えないので、ビルドするときに指定するようにする

という感じです。

```yaml:.github/workflows/ci.yml
jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Install Dependencies
        run: yarn install
      - name: Build
        run: yarn build
        env:
          CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }}
          CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }}
      - name: Archive Production Artifact
        uses: actions/upload-artifact@master
        with:
          name: dist
          path: dist

  deploy:
    name: deploy
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Download Artifact
        uses: actions/download-artifact@master
        with:
          name: dist
      - name: Deploy to Firebase
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}
```

以上の説明をガッチャンコすると、下のようになります。

```yaml:.github/workflows/ci.yml
name: ci

on:
  push:
    branches:
      - master
  repository_dispatch:

jobs:
  build:
    name: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Install Dependencies
        run: yarn install
      - name: Build
        run: yarn build
        env:
          CONTENTFUL_SPACE_ID: ${{ secrets.CONTENTFUL_SPACE_ID }}
          CONTENTFUL_ACCESS_TOKEN: ${{ secrets.CONTENTFUL_ACCESS_TOKEN }}
      - name: Archive Production Artifact
        uses: actions/upload-artifact@master
        with:
          name: dist
          path: dist

  deploy:
    name: deploy
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repo
        uses: actions/checkout@master
      - name: Download Artifact
        uses: actions/download-artifact@master
        with:
          name: dist
      - name: Deploy to Firebase
        uses: w9jds/firebase-action@master
        with:
          args: deploy --only hosting
        env:
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}

```


### Secretsを登録する

GitHubには、外部に公開したくない情報を管理する`Secrets`という機能があります。
ContentfulのAPIキーやFirebase tokenは外部に漏らすとまずいので、ここに設定していきます。
事前に作ってもらっていたリポジトリの画面から`Settings → Secrets`を選択してください。

Secretsには今回

- CONTENTFUL_SPACE_ID
- CONTENTFUL_ACCESS_TOKEN
- FIREBASE_TOKEN

の3つを登録します。
登録は一つずつ行ってください。

<img width="1088" alt="スクリーンショット 2019-12-22 3.22.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/5dbdb052-fef4-2bdb-6e6b-65edd8043676.png">

**登録例**

```
Name
CONTENTFUL_SPACE_ID

Value
YOUR_CONTENTFUL_SPACE_ID
```

下画像のようになれば、登録完了です✨

<img width="770" alt="スクリーンショット 2019-12-22 3.29.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/4b47910a-25ff-67c3-569d-fb2c070d3eaf.png">


### GitHub Personal access tokenを取得する

外部（今回はContentful）からのWebhookイベントを受信するために必要なPersonal access tokenを取得します。
`右上の自分のアイコン → Settings → Developer settings → Personal access tokens`から`Generate new token`を選択します。
下のような画面が出てくるので、Noteには覚えやすい名前を設定し、repoにチェックを入れてください。

<img width="803" alt="スクリーンショット 2019-12-22 3.39.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/ffed0c55-66c2-180b-1240-e3c854932453.png">

最後に一番下の`generate`を押すとトークンが発行されます。次で必要になるので、どこかに控えておいてください。


## ContentfulのWebhookの設定をする

最後に、ContentfulのWebhook設定をします。

## NameとURLの設定
Contentfulの画面を開いて`Settings → Webhooks`から、右上の`Add Webhook`を選択してください。
すると、下画像の画面が開くので、Nameには好きな名前を、URLには`https://api.github.com/repos/${YOUR_GITHUB_ID}/${YOUR_RIPOSITORY_NAME}/dispatches`を指定してください。

<img width="1680" alt="スクリーンショット 2019-12-22 3.53.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/fef079d8-7287-2294-70a8-54a1149e10ee.png">

### トリガーの設定

そしてこのままだとContentfulで行ったすべての行動がWebhookを発動するトリガーになるので、Triggersは下のようにしておいたほうがいいです！

<img width="1188" alt="スクリーンショット 2019-12-22 3.56.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/2613a300-3f92-5778-4b25-ec3669ffac63.png">

### Headerの設定

Headersも追加していきましょう。
今回は

- Accept
- Authorization
- User-Agent

を追加していきます。
Headersセクションの`Add custom header`を選択して、下のように追加してください(User-Agentは自分のGitHub IDに変更してください)。
ついでに`Content type`も`application/json`にしましょう。

<img width="1295" alt="スクリーンショット 2019-12-22 3.59.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/1ecd6c55-ac05-a6b3-032a-7eb0d7bc6a16.png">

### Payloadの設定

PayloadはGitHubのAPIで`{"event_type": "event name"}`を指定しないといけないらしいので、指定していきます。
`Customize the webhook payload`を選択し、下のように指定します。

<img width="938" alt="スクリーンショット 2019-12-22 4.02.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/222222/d379b71a-9a16-07e7-e052-7e9a71abf7ea.png">


すべて設定が終わったら、右上の`Save`を押して保存しましょう！
保存後、新しく記事をPublishすると、GitHub Actionsがうまく動いてるはずです！👍

これですべて終了です！
お疲れさまでした🎊


## 終わりに

いかがでしたか？
思ってた以上に結構ボリューミーになったのですが、作って公開までできればサクッとメンテしたりページ追加できると思うので、よかったらぜひ試してみてください✨