
GitHub Pagesのデプロイ方法をカスタムワークフローに切り替えてみた
しばたです。
わたしは6年前からGiHub Pagesを使ったサイトを公開し更新し続けています。
公開しているサイトはこちら。(GitHubへのリンクもあります)
先日このサイトのデプロイ方法をGitHub Actionsを使ったカスタムワークフローに切り替えたのでその手順を紹介します。
GitHub Pagesのデプロイ方法おさらい
当初GitHub Pagesのデプロイは「リポジトリの特定ブランチ、ディレクトリ配下を公開する」という方式であり、たとえば下図の場合main
ブランチの/docs
ディレクトリ配下の内容が公開対象となります。
その後2022年にGitHub Actionsを使った利用者独自のカスタムワークフローによるデプロイがベータ版として提供され、2024年に正式機能となりました。
- 2022年 : GitHub Pages: Custom GitHub Actions Workflows (beta)
- 2024年 : GitHub Pages with Custom GitHub Actions Workflows are now generally available
カスタムワークフローによりJekyll以外のサイト生成ツールを使う場合の最適化や利用者独自フローの実現が可能となっています。
ちなみにですが、ディレクトリ配下を公開する方式も内部的にはGitHubが提供するフローをGitHub Actionsで実行します。
(この変更は2021年にいつの間にかリリースされていました)
切り替える動機
私の場合サイトの公開当時からHugoを使っていたのに加え、サイトのページ数がAWSサービス数に比例し年々Gitのコミット対象が増えていく問題がありました。
(本日時点でAWS側が約400サービス[1]あり、更新の都度Markdown400ファイル、HTML400ファイルずつ履歴に残ってしまう...)
デプロイ方法を変えることでGit管理するファイルを減らしコミットログを見やすくしておきたいのが一番の動機でした。
あと、将来的にカスタマイズしやすい様に準備しておきたかったのと単純に機能を試しておきたかったのも補助的な理由となります。
切り替え手順
切り替え手順の基本としては、
- 所定のGitHub Actionを用意する
- GitHub Pagesの設定からデプロイ方法を切り替える
だけですが環境によっては幾つか追加作業が必要となります。
1. DNS設定
私のサイトの場合aws-cli-eq-pwsh.shibata.tech
という独自ドメインを使用しています。
特定ブランチのディレクトリをデプロイする方式では検証のためルートディレクトリにドメイン名を記載したCNAME
ファイルを配置しておく必要がありましたが、GitHub Actionsからデプロイする場合はCNAME
ファイルがあっても無視されます。
このためカスタムドメインの検証をGitHub側で行う様に設定変更しておく必要があります。
具体的な手順は以下のドキュメントにあり、個人アカウントおよびOrganizationでの設定となります。
各リポジトリ毎の設定ではないのでご注意ください。
(初見で少し迷いました...)
個人アカウントから設定する場合、アカウントの「Settings」から「Pages」を選ぶと検証ドメインを設定できます。
アカウントの Settings から Pages を選ぶ
上図は既に検証済みですが、ここから新たに検証したいドメイン名を入力して所定のTXT
レコードをドメインのDNSに登録してやれば検証できます。
2. GitHub Pagesの設定変更
デプロイ方法の変更は各リポジトリの「Settings」から「Pages」を選び、「Source」指定を変更すると直ちに反映されます。
下図は既に変更済みのスクリーンショットですが「Deploy from a branch」から「GitHub Actions」に変更すればOKです。
独自ドメインを使っている場合は切替後もDNSのチェックが成功することを確認しておくと良いでしょう。
独自ドメインを使っている場合はDNSチェックが成功するのも要確認
3. GitHub Actionの追加
続けてデプロイ用のGitHub Actionを追加します。
Actionで最低限必要となる作業は、
- 初期化処理 (actions/configure-pages)
- ソースをビルドして公開サイトのファイル群を生成する
- ビルドしたファイル群をアーティファクトとしてアップロードする (actions/upload-pages-artifact)
- アップロードしたアーティファクトをGitHub Pagesとしてデプロイする (actions/deploy-pages)
となります。
ツールや環境に応じてActionの内容を変えることなりますが、Hugoの場合はドキュメントにサンプルがありほぼそのまま利用可能です。
Hugoのサンプル実装 : クリックして展開
# Sample workflow for building and deploying a Hugo site to GitHub Pages
name: Deploy Hugo site to Pages
on:
# Runs on pushes targeting the default branch
push:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
# Default to bash
defaults:
run:
shell: bash
jobs:
# Build job
build:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.145.0
HUGO_ENVIRONMENT: production
TZ: America/Los_Angeles
steps:
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
- name: Install Dart Sass
run: sudo snap install dart-sass
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
- name: Setup Pages
id: pages
uses: actions/configure-pages@v5
- name: Install Node.js dependencies
run: "[[ -f package-lock.json || -f npm-shrinkwrap.json ]] && npm ci || true"
- name: Cache Restore
id: cache-restore
uses: actions/cache/restore@v4
with:
path: |
${{ runner.temp }}/hugo_cache
key: hugo-${{ github.run_id }}
restore-keys:
hugo-
- name: Build with Hugo
run: |
hugo \
--gc \
--minify \
--baseURL "${{ steps.pages.outputs.base_url }}/" \
--cacheDir "${{ runner.temp }}/hugo_cache"
- name: Cache Save
id: cache-save
uses: actions/cache/save@v4
with:
path: |
${{ runner.temp }}/hugo_cache
key: ${{ steps.cache-restore.outputs.cache-primary-key }}
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./public
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
私の場合だとActionのトリガーを「/hugo/content/
配下のファイルが更新された時」と「手動」に変更し、Hugoのビルドに関わるディレクトリ指定をリポジトリの構成に合わせて変更するだけで問題無く利用できています。
- 実際の設定ファイル : .github/workflows/hugo.yaml
このサンプルではGitHub Actionsのキャッシュも利用していますが現状あまりキャッシュの効果を体感できていません...
とはいえGitHub Actionsのキャッシュは7日間アクセスが無ければ自動的に削除されるので、このままキャッシュを使い続けても特に問題は無いと判断し放置しています。
4. 公開フォルダの削除
この作業は必須では無いのですが、私の場合公開用の/docs
ディレクトリをそのままアーティファクトの出力先として使うことにしたので、Gitのソース管理から/docs
ディレクトリを全て削除し.gitignore
の対象としました。
切替結果
切り替えた後はGitHub Actionを実行して成功すればGitHub Pagesの内容が更新されます。
Deploy Hugo site to Pagesが追加したAction
実行結果はこんな感じになってます。
比較用に従来のディレクトリ配下を公開する方式で実行されていたActionはこんな感じでした。
このbuild
ジョブではJekyllによるビルドとアーティファクトのアップロードが定義されておりHugoを使っていた私にとっては無駄がある状態でした。
新しい方式のGitHub ActionではJobが減り処理が最適化されたもののHugoのセットアップが追加で必要になったため実行時間の面ではあまり改善されませんでした。
ただ、ビルドとデプロイを最適な環境で自動化できたこと自体は大きな改善点です。
余談 : 切り替え後の設定変更は要注意
本記事を書くためにGitHub Pagesの設定を一度UI上で切り替えたところ、変更が直ちに保存されるためそのままデプロイまで発生してしまいました。
前述の通り既に/docs
ディレクトリが削除済みなので空のアーティファクトをアップロードすることになりサイト自体が404エラーを返す様になってしまいました...
この場合設定を再度戻してGitHub Actionsによるデプロイをやり直す必要があります。
このため手動でのAction実行も可能にしておくと安全です。
ちなみにカスタムドメインが検証済みだと設定変更のタイミングでCNAME
ファイルを自動作成しcommitまでする様です。
このcommitに対するrevertも別途必要です。
最後に
以上となります。
GitHub Pagesのデプロイにカスタムワークフローを使える様になった件自体は以前から把握していたのですが惰性で切り替えられずにいました。
デプロイ方法を後から変更する人はそう多くないかもしれませんが、本記事の内容が誰かの役に立てば幸いです。
AWS CLIのサブコマンドで分かれる単位なので実際のサービス数より多くなっています ↩︎