NotionとHugoでつくるblog
はじめに
Notionと静的サイトジェネレーターのHugo、それとGitHub ActionsとGitHub Pagesを組み合わせて自動化されたBlog環境(ヘッドレスCMS)を構築します。
注意:本解説で扱うlounge-n/notion-md-exportアクションは現在開発途中のものです。本ページは動作確認のために書かれたものです。解説に従って環境を整えると一応の動作はしますが正式リリースまでお待ち下さい。正式リリースの後にこの注釈は削除されます。
作業を始める前提となる環境の準備
このページでは以下のことについて説明しません。それぞれ調べてください。
- ローカル(手元のPC)へのhugoおよびgitのインストール
- GitHubリポジトリの作成などGitHubを利用する上での基礎知識
- Notionデータベース作成方法
環境構築 Notion side
ブログ執筆用のNotionデータベース
最低限3つのプロパティが必要となります。タグやカテゴリなどは後からカスタマイズすることが可能なのでまずは次のプロパティ構成のデータベースを作成して下さい。
- Title(種類:タイトル)ブログ記事のタイトルになります。
- Date(種類:日付)記事の投稿日付およびURLパスに用いられます。
- Publish(種類:チェックボックス)GitHubにアップロード記事を指定します。
インテグレーションとコネクト
My Integrationsにアクセスしてインテグレーションを作成します。内部インテグレーションとしてコンテンツの読み取りと更新の2つを許可して下さい。
データベースに戻り、作成したインテグレーションをメニューの「コネクト」から追加して下さい。これによりトークンを用いてデータベースに外部からアクセスすることが可能となります。
環境構築 GitHub side
NotionからMarkdownを書き出すリポジトリとコンテンツを公開するためのリポジトリの2つを用意します。
双方を1つのリポジトリで運用することも可能ですが、2つに分けて棲み分けを行う方法がおすすめです。
GitHubリポジトリ1(Markdown書き出し用)
空のプライベートリポジトリを作成します。リポジトリ名の制約はありません。これはデプロイ元のリポジトリとなります。
次に、Settings > Secrets > Actions より次の環境変数を設定します。
Name | Secret |
---|---|
NOTION_AUTH_TOKEN | My Integrationsで作成したインテグレーションのトークンを値として設定します。 |
NOTION_DATABASE_ID | NotionデータベースURLの次の部分を値として設定します。https://www.notion.so/xxxx/<データベースID> ?v=xxxx |
GitHubリポジトリ2(GitHub Pages公開コンテンツ用)
空のパブリックリポジトリを作成します。リポジトリ名は次のルールに従って下さい。これはデプロイ先のリポジトリとなります。
GitHub Pagesでは1つのアカウントまたは1つのOrganizationにつき公開できるGitHub Page1つだけです。上記ルールに従ったリポジトリのみGitHub Pageとして公開することができます。
次に、リポジトリのSettingより書き込み権限付きのデプロイキーを登録します。
デプロイキーについては デプロイキーの管理 を参照して下さい。ちなみに、デプロイキーとして鍵を生成する場合はパスフレーズを設定しないことに注意して下さい。
リポジトリ1のシークレットキーACTIONS_DEPLOY_KEYに秘密鍵を、リポジトリ2にデプロイキーとして公開鍵を登録します。
Hugo
ローカルでHugo環境を新規作成します。なお、本記事執筆時点で使用したHugoのバージョンは*v0.108.0+extended
*でした。作成したディレクトリに移動してgit初期化します。
$ hugo new site <任意のディレクトリ名>
$ cd <作成されたディレクトリ名>
$ git init
次にテーマを設定します。本サイトはMainroadを使用しています。次のようにthemesディレクトリ配下にcloneするかサブモジュールとして追加します。
$ git clone https://github.com/vimux/mainroad.git themes/mainroad
or
$ git submodule add https://github.com/vimux/mainroad.git themes/mainroad
config.tomlを次のように書き換えて下さい。
baseURL = '/'
languageCode = 'ja'
title = '<ブログのタイトル>'
theme = 'mainroad'
Markdown書き出し用リポジトリをリモートリポジトリに設定し、hugo環境をcommit&pushします。
$ git remote add origin git@github.com:<アカウントorOrganization>/<リポジトリ名>.git
$ git branch -M main
$ git add -A
$ git commit -m "create hugo project"
$ git push -u origin main
GitHub Actions
.github/workflows/
ディレクトリを作成してその中に次の内容でnotion-to-markdown.yaml
ファイルを保存します。
name: Notion to Markdown
on:
workflow_dispatch:
jobs:
export_markdown:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: lounge-n/notion-md-export@main
with:
notion_auth_token: ${{ secrets.NOTION_AUTH_TOKEN }}
notion_database_id: ${{ secrets.NOTION_DATABASE_ID }}
- name: Diff
id: diff
run: |
git add -N .
git diff --name-only --quiet
continue-on-error: true
- name: Commit & Push
run: |
set -x
git config user.name github-actions[bot]
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
git add .
git commit --author=. -m 'update contents'
git push
if: steps.diff.outcome == 'failure'
処理の流れを簡単に説明します。
- actions/checkoutで作業領域へリポジトリの内容をチェックアウトします
- lounge-n/notion-md-exportでNotionデータベースからPublishにチェックの付いたページをMarkdownで書き出す
- Diffにて作業領域に差分が生じていたらCommit & PushでリポジトリへPushする
このアクションを実行するとリポジトリの./contentディレクトリ配下にMarkdownファイルが追加されているはずです。
次に、デプロイリポジトリへコンテンツをPushするためのgithub-pages.yaml
ファイルを以下の内容で保存します。
name: GitHub Pages
on:
workflow_dispatch:
workflow_run:
workflows: [Notion to Markdown]
types:
- completed
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
contents: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
steps:
- uses: actions/checkout@v3
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.108.0'
extended: true
- name: Build
run: hugo --minify
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
# If you're changing the branch from main,
# also change the `main` in `refs/heads/main`
# below accordingly.
if: ${{ github.ref == 'refs/heads/main' }}
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
external_repository: <アカウントorOrganization>/<アカウントorOrganization>.github.io
publish_branch: main
external_repositoryにはデプロイ先のリポジトリを設定します。
デプロイキーが正しく設定されていればこのアクションを実行するとMarkdownファイルを元にコンテンツがビルドされてデプロイリポジトリにPushされます。
デプロイ直後はページが参照できない可能性がありますが、少し時間を置いた後に次のURLでコンテンツを参照することが可能となります。
https://<アカウントorOrganization>.github.io
2つのアクションと運用方針について
本サイトはnotion-to-markdown.yaml
とgithub-pages.yaml
の組み合わせで構築されています。Github Actionsは定期実行することも可能ですが、それほど頻繁にNotionで記事を書くことはないため手動およびリポジトリへのPushをトリガーに動作するようにしています。
Actions | Name | Trigger |
---|---|---|
notion-to-markdown.yaml | Notion to Markdown | 1. GitHubのWeb UIからの手動実行 |
github-pages.yaml | Github Pages | 1. GitHubのWeb UIから手動実行2. Notion to Markdownが実行された後3. mainブランチにPushされた後 |