LoginSignup
5
1

More than 1 year has passed since last update.

ヘッドレスCMSのContentfulをHugoと連携してGithub Pagesで公開する(5)

Last updated at Posted at 2021-09-09

概要

ContentfulとHugoを連携したコンテンツ作成の最終回。
ラストの今回はContentfulでのデータ更新をイベントトリガーとしてGithub Actionsを発火させる方法について解説する。

最終的には以下のような構成となる。

contentful-hugo-Copy of Page-1.drawio.png

注目してほしいのはワークフローのピンクのブロックで、投稿者がブログを更新したら自動的に公開されるということ。
つまり途中のゴチャゴチャした過程は意識しなくてよい。

最終的なソース → higebobo/hugo-contentful-blog: Blog sample with Hugo and Contentful
完成したブログ → Hugo Contentful Blog

準備

既に説明してあるのでContentfulのトークンは取得済みとする(メニューからSettings>API Keys>Add API keyを実行)。

Githubのトークン取得

GithubのAPIを利用するためにはPersoanl access tokensと呼ばれるトークンが必要になる。
ダッシュボード画面右上のDevelopper settings>Persoanl access tokens>Generate new tokenを順次クリック。

Screenshot at 2021-09-09 07-21-01.png

名前は適当につけてExpirationは無期限設定のNo expirationとし(もちろん期限付きで設定してもよい)、Select scopesはとりあえずrepoをチェック。

FireShot Capture 103 - New personal access token - github.com.png

最後にGenerate tokenをクリックすると発行される。二度とお目にかかれないと警告が出ているのでコピーしておくこと。
もし忘れたら再発行するしかない。

FireShot Capture 104 - Personal Access Tokens - github.com.png

ちなみにこのトークンはレポジトリではなくアカウントに紐付いているので既に発行済で別レポジトリで使用しているトークンがあればそちらをつかってもよい。

確認

curlが実行できる環境ならこの時点で設定確認ができる。

curl -X POST \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Authorization: token <取得したトークン>" \
-d '{"event_type": "Wehook test"}' \
https://api.github.com/repos/<アカウント名>/<レポジトリ名>/dispatches

これを実行して何も返ってこなければ成功。とやや紛らわしい。
なので上記に-iオプションをつけてみるとヘッダ情報が取得できる。

HTTP/2 204 
server: GitHub.com
...

204を返せばOK。
ちなみに例えばわざと間違ったトークンを渡すとこんなエラーが返ってくる。

{
  "message": "Bad credentials",
  "documentation_url": "https://docs.github.com/rest"
}

ContentfulのWebhook設定

次にコンテンツ更新をGithubにお知らせするためWebhookをContentfulに設定する。
ダッシュボード上部メニューのSettings>Webhook>Add Webhookをクリック。
そして設定を行う。
基本的には上記curlでの確認テストの項目を渡すように設定してやれば良い。

まずNameは適当でURLhttps://api.github.com/repos/<アカウント名>/<レポジトリ名>/dispatchesとする。
Nameはなんでもよいがわかりやすくしたほうがよいので私の場合は<アカウント名>/<レポジトリ名>としている。

TriggersSelect specific triggering eventsにチェック。
CONTENT EVENTSは下図参照。ここまでの設定はこんな感じ。

FireShot Capture 105 - New Webhook — Webhooks — The example project — Contentful_ - app.contentful.com.png

画面をスクロールしてHeadersのセクションまで行く。
ここでAdd custom headerをクリックしてヘッダーを追加する。ただしトークンのようにセキュリティ関連の情報は非表示にしたいのでその場合はAdd secret headerを使う。
設定するヘッダは以下

  • Accept: application/vnd.github.everest-preview+json
  • User-Agent: Contentful Webhook (値は適当でよい)
  • Authorization: token <上記で取得したGithubのPersonal access tokens>

Authorizationの値は先頭にtokenを加えるのを忘れないように。
例えばトークンの値がabcだったらtoken abcとすること。

FireShot Capture 106 - New Webhook — Webhooks — The example project — Contentful_ - app.contentful.com.png

更にスクロールしてPayloadまで行く。
GithubのAPIを叩くためにはリクエストボディにevent_typeという値が必要となる。
なのでCustomize the webhook payloadを選択し以下のように適当に値を設定する。

FireShot Capture 107 - New Webhook — Webhooks — The example project — Contentful_ - app.contentful.com.png

最後にSaveをクリックして完了。
このまま適当にコンテンツを更新してWebhookの起動を試してもよいが、受け側のGithubの設定ができていないのでそれを次に行う。

Github Actionsの設定変更

Github Actionsはrepository_dispatch:を追加するだけである。

.github/workflows/gh-pages.yaml(全文)

name: GitHub Pages

on:
  push:
    branches:
      - main
  repository_dispatch: # ここ

jobs:
  deploy:
    runs-on: ubuntu-latest
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}

    steps:
      - uses: actions/checkout@v2
        with:
          submodules: true
          fetch-depth: 0
      - name: Setup Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 14.x
      - run: npm ci

      - name: Setup Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'
          extended: true

      - name: Build
        # run: npm run build
        run: ./node_modules/.bin/contentful-hugo && hugo --minify --baseUrl="https://higebobo.github.io/hugo-contentful-blog/"
        env:
          CONTENTFUL_SPACE: ${{ secrets.CONTENTFUL_SPACE }}
          CONTENTFUL_TOKEN: ${{ secrets.CONTENTFUL_TOKEN }}

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        if: ${{ github.ref == 'refs/heads/main' }}
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public

上記修正を加えてレポジトリにプッシュすればブログのコンテンツは再ビルドされるが、これはワークフローでいうところの開発者のフローである。

Contentfulに投稿して動作確認する。

実際にContentfulでのコンテンツ更新でビルドプロセスが走るか試してみる。
今現在は2つの投稿しか無い。

01.png

新規投稿をしてみる。

FireShot Capture 109 - contentful-hugoを用いた自動ビルドおよび公開 — Content — The example project — Conte_ - app.contentful.com.png

書き終わったらPublish状態にする。

Contenful側の確認

ダッシュボード>Settings>Webhooksをクリック。

FireShot Capture 110 - Webhooks — The example project — Contentful - app.contentful.com.png

こんなふうになっていたら成功。念の為view detailsで下っていくと最終的なリクエストとレスポンスのログが確認できる。

FireShot Capture 111 - higebobo _ hugo-contentful-blog — Webhooks — The example project — Co_ - app.contentful.com.png

Github側の確認

ダッシュボード>Actionsをクリック。

FireShot Capture 112 - Actions · higebobo_hugo-contentful-blog - github.com.png

最下行のaccespt webhook(タイポでスマソ)がレポジトリのmainブランチにプッシュしたときのコミットログ。
その上にあるWebhook from ContentfulがContenful側からのWebhook。
上記payloadのevent_typeで設定した値が表示される。
3つあるのはコンテンツ作成時にブログ本文と画像とタグを新規登録したからそのたびにWebhookが走っている。

そして

FireShot Capture 113 - Hugo Contentful Blog - higebobo.github.io.png

はい。できました。

まとめ

五回に分けてHugoとContenfulの連携およびGithub Pagesでの自動公開を説明した。
スタティックサイトジェネレータとしてHugoに魅了されたのだが、その仕様ゆえヘッドレスCMSとの連携が難しいのを歯がゆく思っていた。
しかし、工夫次第でなんとでもなることを示すことができた。
仕様が固まりソース自体の変更が無い状態になれば、ContentfulとGithub間だけのサービスに完結する完全なサーバレス環境となる。
つまり、極端に言えばローカル環境にHugoやNode.jsは不要になるのだ。

最終的なソース → higebobo/hugo-contentful-blog: Blog sample with Hugo and Contentful
完成したブログ → Hugo Contentful Blog

謝辞

Hugoの開発チーム、GithubやContenfulの運営者は当然ながら、このすばらしいライブラリを提供してくれたModiiMediaさん、またHugoのGithub Actionsを作成していただいたpeaceirisさん(いつもLGTMありがとうございます)に多大なる感謝を申し上げます。
これを機に少しでもHugoユーザが増えれば幸いです。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1