Chapter 05

GitHub Pagesで公開する

Takei Kazuya
Takei Kazuya
2021.12.19に更新

ここまでのプレゼンテーション作成を済ませれば、ローカルのブラウザ経由で発表などが出来るようになりました。
せっかくなので、ソースをGitHubで管理しながら、GitHub Pages上にビルドしたHTMLを公開してみましょう。

GitHub Pages

簡単な説明

GitHub PagesはGitHubが内包する機能の1つです。
GitHubリポジトリの特定のブランチを、そのままUSERNAME.github.ioのドメイン配下で公開できるようになります。[1]

簡単なデモやドキュメンテーションだけでなく、ブログなどを公開している人もいます。
sphinx-revealjsでは本体リポジトリのPagesでデモを公開しています。
こちらで公開しているので、その他の機能に興味があるなら是非見に来てください。

Pages用のブランチにHTMLをコミットする

前述の通り、Pagesのためブランチを指定した上でコミットとプッシュをすることでPagesの公開・更新が可能となります。
まずは、その手法を考えてみましょう。

一番シンプルな考え方となる方法は、「手元でHTMLをビルドしてまるごとコミットする」となります。
しかし、Pages用ブランチはコンテンツがリポジトリのトップに来ねばならず、ワークスペースとして使いつつ同時にコンテンツをコミットしていくのはそれなりに大変です。

そこで、今回はGitHub Actionsを用いて、このあたりの作業を自動化していきましょう。

GitHub Actions

簡単な説明

GitHub ActionsはGitHubが内包する機能の1つです。
「定型的な作業=何をやるか」と「作業の実行トリガー=いつやるか」をワークフローとして管理して、作業の自動化を実現することが可能になります。

実際にどこを「自動化するか」

もとのソースを管理しつつ、GitHub PagesにビルドしたHTMLを公開するには、以下の工程が必要です。

  1. 必要なソースを一通りコミットする
  2. ソースからHTMLをビルドする
  3. ビルドしたHTMLを特定ブランチにコミットする
  4. 上記のコミットをGitHubにプッシュする

このうち、2-4の工程をGitHub Actionsで自動化していきます。
(なお、1番めのコミットをGitHubにプッシュした時をトリガーとします)

事前準備をする

今回紹介するワークフローを使うために、次の作業をあらかじめ実施してください。

requirements.txtに依存ライブラリを記載する

実際にワークフロー上で動作する環境は、これまでローカルでビルドしたSphinx用の環境と揃っていることが望ましいです。
そのため、あらかじめビルドに必要となる依存ライブラリの取りまとめを行い、これをGitで管理しましょう。

pip freeze > requirements.txt

この作業はSphinx拡張を増やすたびに必要です。忘れないように気をつけましょう。

GitHubのパーソナルトークンを生成する

今回のワークフローでは、ワークフロー内の処理としてGitHubにプッシュする行為が含まれています。
GitHubへのプッシュには認証が必要になりますが、リポジトリのプッシュ権を持つことが必須となります。

今回は、自身のGitHubアカウントのパーソナルアクセストークンを権限指定で作成して、ワークフロー内の認証に使います。

  1. GitHubのPersonal access tokensページにアクセスする
  2. Generate new tokenのボタンをクリックして、トークンの新規作成を進める
  3. 設定を記述してトークンを作成する
    1. Noteには適当な名称でよい
    2. Select scopesは、少なくともrepoにチェックを入れれば大丈夫
    3. ページ最下層のGenerate tokenでトークンを生成する
  4. 生成されたトークンはメモっておく

リポジトリの設定にトークンを保存する

ワークフローでトークンを使うためには、リポジトリ設定にトークンを保存する必要があります。

  1. リポジトリのトップからSettingsタブ経由で設定画面にアクセスする
  2. 左メニューにあるSecretでGitHub Actions用の変数管理画面にアクセスする
  3. New repository secretボタンで変数を登録する
    • Nameには、GH_PATを入力
    • Valueには、先程生成したトークンを入力
  4. Add secretで保存

ワークフローを登録する

ここまで実施したら、ワークフローファイルをコミット・プッシュをするだけです。

GitHub Actionsで使うワークフローの定義は、.github/workflows配下にYAMLファイルで作成する必要があります。
作成されたファイルがコミットされ、GitHubにプッシュしたタイミングで、GitHubがActionsのプロセスが動きます。

ワークフロー全文

.github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v1
      - uses: actions/setup-python@v1
        with:
          python-version: 3.9
      - name: Build pages
        run: |
          pip install -r requirements.txt
          make revealjs
          touch build/revealjs/.nojekyll
      - name: Deploy to GitHub Pages
        uses: maxheld83/ghpages@v0.2.1
        env:
          BUILD_DIR: build/revealjs
          GH_PAT: ${{ secrets.GH_PAT }}

ワークフローの解説

ここからはワークフローファイルの各セクションの解説をしていきます。

なお、nameはGitHub ActionsのWeb画面上で使われるだけなので、解説は省略します。

on

Actionsのトリガーとなるイベントを定義します。

いくつかの種類があるのですが、今回使っているのはpush,workflow_dispatchの2種類です。

pushはGitHubへプッシュが行われたときにワークフローを実行することを意味します。
更に小要素で「特定へのプッシュのみに限定」などが出来ますが、今回はpush:とだけ定義して「全ブランチへのプッシュ」と簡素な定義としています。

もう1つのworkflow_dispatchはGitHubリポジトリなどでのイベントではなくGitHub Actions上で手動実行できるようにするための定義です。
こちらも更に小要素に定義を書くことで、実行時のオプションなどを用意することが出来ます。

jobs

Actionsのトリガーに応じて実際に実行するタスク処理を定義します。

build.runs-onでワークフローの実行環境を呼び出した後に、stepsで定義されたタスクを順に実行する形式になっています。

今回は次のようなステップでテスクが定義されています。

  1. Gitリポジトリのチェックアウトを行い、ソースを取ってくる
  2. Python実行環境をセットアップする
  3. 実際に書いたコマンドを順に実行して、HTMLビルドを行う
  4. GitHub Pages用ブランチにコンテンツをまるごとコミット・プッシュする

jobs:ビルド処理をちょっと細かく

name: Build pagesとあるステップの中身を見てみましょう。

pip install -r requirements.txt
make revealjs
touch build/revealjs/.nojekyll

最初の2コマンドはビルドのためのものですが、最後に見慣れないコマンドがあります。
これは、GitHub PagesとSphinxの仕様によって必要となるファイルを生成しています。

Sphinxの標準構成では、静的ファイルはまとめて/_staticというパスにコピーします。
一方でGitHub PagesはJekyllというソフトで動作しているのですが、Jekyllのデフォルト動作として「アンダースコアで始まるパスは参照できない」という挙動となっています。
そのため、この問題を回避するために.nojekyllというファイルを用意することで、/_static配下のファイルもリクエスト可能にする必要があります。

ワークフローを観察する

これで、プッシュするたびに自動でGitHub Pagesが更新されるようになりました。

ソースのテキストなどを変更して、様子を見てみましょう。

脚注
  1. https://github.com/USERNAME/REPOSITORYに対して、https://USERNAME.github.io/REPOSITORYというサイトになります。 ↩︎