経緯

本ブログのデプロイ先をNetlifyからFirebase Hostingに移行したが、Firebase Hosting単体では静的サイトを生成(generate)する機構がないためContentfulで記事を更新したときや、プログラムソースを修正したときは都度どこかで生成&デプロイする必要がある。ローカルでそれをやっても良いがいちいち面倒なので、
記事更新の際にはContentfulのWEBフックで,ソース修正の際にはgitコミットをトリガーにしてどこかでそれをやってくれるようにするのが常套手段だ。
生成&Firebaseへのデプロイについて、調べたところ色々と選択肢はあるが、CircleCIというサービスを使って実現するのがお手軽にそうだったのでこれを採用した。

を参考にして諸々進めていく。
gitのプロジェクトトップのディレクトリに、 .circleci/config.yml ファイルを作成すればよい。

事象

私のymlファイルはこのような形。

version: 2
jobs:
  deploy: # ジョブ名
    docker:
      - image: circleci/node # ジョブ実行環境のDockerイメージを記述
    steps:
      - checkout # ソースコードのチェックアウト
      - run:
          name: yarn install
          command: yarn install
      - run:
          name: generate
          command: yarn run generate
      - run:
          name: deploy to Firebase Hosting
          command: ./node_modules/.bin/firebase deploy --token=$FIREBASE_TOKEN # プロジェクト上のfirebase-toolsでデプロイします

workflows:
  version: 2
  deploy: # ワークフローの名前
    jobs:
      - deploy # 上で定義したジョブを指定します

上記が最適はわからない。また私自身ファイル内のキーの意味を十分に理解しているわけではない。あくまでも参考ページを問題なさそうな範囲で改変したにすぎない。

注意点は以下の通り

  • versionを2にする(それ以上だと、webhookでのビルドに対応していないとか)
  • imageに指定したnodeは、本当は特定のバージョンを指定したほうがいい
  • インデントは空白2個。タブが混入しないように注意。

ソース修正後のコミットではうまく行ったのだが、Contentfulの記事更新ではうまくいかなかった。

Build-agent version 1.0.41040-dbb76648 (2020-10-09T18:08:18+0000)

Configuration errors: 1 error occurred:

* Cannot find a job named `build` to run in the `jobs:` section of your configuration file.
If you expected a workflow to run, check your config contains a top-level key called 'workflows:'

意訳

config.yml に、build という名前のジョブがありません。
workflowsというキーが定義されているか確認してください

確かにビルドの失敗ログから config.yml を確認すると

version: 2
jobs:
  deploy:
    docker:
    - image: circleci/node
    steps:
    - checkout
    - run:
        name: yarn install
        command: yarn install
    - run:
        name: generate
        command: yarn run generate
    - run:
        name: deploy to Firebase Hosting
        command: ./node_modules/.bin/firebase deploy --token=$FIREBASE_TOKEN
workflows:
  version: 2
  build:
    jobs:
    - build: {}

読み込みたい、 deploy というジョブが定義されていないように見える。。
ソースのコミット時はもちろんビルドに成功していて、ログから確認できるconfig.yml上にもdeployを読み込むようなworkflowsの定義が存在する。。

色々調べたが、結局根本的な原因はわからなかった。

解決策

半ば強引だが、下記を実施するとうまくいった。
APIのペイロードに、呼び出したいjobの名称を指定する。

  1. Contentful > Settings > Webhooks
  2. 下記図の赤枠内をクリック
  3. Contentful API Webhook logs
  4. Webhook Settings タブをクリック
  5. 下の方に Payload とあるので Customize the webhook payload を選択し、入力欄に以下を記入する
{
  "build_parameters": {
    "CIRCLE_JOB": "deploy"
  }
}
  1. Saveボタンをクリック

余談

本事象に対する解決策と関係ないが、作業を進めていて課題だと感じたことをメモしておく

  • 記事を一つ更新すると、複数回CircleCIのジョブが走るので気持ち悪い。
    • おそらく先ほどの解決策4の設定画面にTriggersとあり、フックする単位を細かく制御できるので、こちらをちゃんと設定したほうがいい。私は、 EntryAssetPublish , Unpublish , Delete にチェックが入っている。
  • ブログのソース更新時のビルドタイミングもちゃんと考慮したほうがいい。
    • 今は全てのブランチでコミット時無条件にビルドが走る。特定のブランチのみだったり、プルリクエストマージの時に限定したり、運用も含めて再検討したほうが良い
    • その辺はYAMLファイルで制御できる。
  • テストを実行して、問題なければデプロイといったように、ちゃんとした運用フローを構築したい。。 (けど多分やらないんだろうな)