React コードを隠したまま GitHub Pages でサイトを公開する
はじめに
GitHub には GitHub Pages というリポジトリから簡単に静的サイトを公開できる便利な機能がありますが、公開するリポジトリは public リポジトリである必要があります。一方、React を使っていると再利用可能な独自コンポーネントやライブラリなどを使いたくなり、それらは隠蔽しておきたいというニーズがあるかと思います。なので React を使った開発コードは private リポジトリで管理し、ビルドによって生成されたファイルのみを public リポジトリに格納して GitHub Pages で公開するのが理想的です。
(index.html
等のビルドファイルはブラウザからも閲覧でき、そもそも公開情報なので public リポジトリ上にあっても問題ないという判断です。)
本記事は TypeScript + React + Vite でプロジェクトを構築し、開発用と本番用の2つのリポジトリを利用した GitHub Pages への展開フローを紹介します。
環境構築
リポジトリの準備
GitHub上で開発用の private リポジトリ(以降portfolio-dev
)と公開用の public リポジトリ(以降portfolio-prod
)を用意して、それぞれのリポジトリをローカル環境にclone
してきます。
ローカル環境の準備
早速プロジェクトを作成したいところですが、その前に node のバージョン管理ツールであるvolta
を導入します。特に様々なプロジェクトをPC内に同居させているとバージョン管理が後々大変になるので導入しておくことを推奨します。
プロジェクトの作成
今回は TypeScript + React + Vite でページを作っていきたいのでそのプロジェクトを作成します。ありがたいことに Vite にはそれを作成する公式コマンドが用意されているのでそれを使います。
まず、clone
してきたportfolio-dev
のフォルダにターミナルから入って、以下のコマンドを入力します。
npm create vite@latest . -- --template react-swc-ts
不慣れな場合はnpm create vite@latest
でインタラクティブに操作するほうが良いですが、プロジェクト名を指定せずにカレントディレクトリ.
を指定する必要があります。
ここでエラーなくプロジェクトが作成できたら、以下のコマンドを打って動作を確認してみましょう。
npm install
npm run dev
そうすると "Vite + React" と書かれたページが表示されるはずです。
また、使用するnode
バージョンについて、package.json
に下記コマンドで固定します。
volta pin node@20.10.0
これで一旦デプロイの準備が整いました。
Github Pages に react アプリを手動デプロイ
ルートのパスについて設定ファイルの修正
Github Pages へデプロイする際の注意として、下記点に注意する必要があります。
https://<USERNAME>.github.io/<REPO>/ にデプロイする場合(例: リポジトリーは https://github.com/<USERNAME>/<REPO>)、base を '/<REPO>/' と設定してください。
このため、開発リポジトリportfolio-dev
下のvite.config.ts
ファイルを調整します。portfolio-prod
は公開用のリポジトリ名です。
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
+ base: '/portfolio-prod/'
})
ビルドファイルの生成
開発リポジトリportfolio-dev
において下記のコマンドを実行し、ビルドファイルを生成します。
npm run build
ビルドが完了すると、dist
ディレクトリ下に下記のファイルのようなファイルが生成されます。
.
├── assets
│ ├── index-4sK4E3Wk.css
│ ├── index-AcNxFZZN.js
│ └── react-h3aPdYU7.svg
├── index.html
└── vite.svg
これらdist
ディレクトリ下のファイルを公開用リポジトリportfolio-prod
にコピーし、リモートリポジトリに pushします。
Github 上でサイトを公開する設定
しばらくすると、Github Actions で上記の設定により作成された workflow pages build and deployment
が実行され Github Pages に展開されます。
[GitHub Pages] の下で [サイトにアクセスする] から展開した web ページにアクセス可能になります。
GitHub Actions を利用して開発リポジトリから公開用リポジトリへ自動デプロイ
前節では、開発リポジトリ(dev)から公開リポジトリ(prod)へ GitHub Pages のデプロイを行いました。
しかし、更新した内容を公開する度にビルドによって dist
ディレクトリへ生成されたファイルを手動で公開用リポジトリへのコピー & push する作業が発生するため継続的な手間が発生してしまいます。
この節では、開発用リポジトリでリリースタグを作成した際に、自動デプロイを実現する仕組みを作成します。
Github Actions とは?
Github Actions は GitHub が提供する CI/CD のサービスです。
Github Actions はリポジトリへの push やプルリクエスト作成時などのイベントに発火して、指定したアクションを GitHub がホスティングするマシン上で実行させることができます。
このようなアクションを利用することで、テストや本番環境へのデプロイなど、ソフトウェアの運用で必要な煩雑な作業を自動化できます。
workflowの作成
早速ですが、GitHub のイベントに発火して実行されるアクションを記述する workflow(yamlファイル)を作成します。workflow ファイルはリポジトリルートの.github/workflows
ディレクトリ下に配置します。
今回作成する workflow はファイル名をdeploy-prod.yaml
として、開発リポジトリ上に配置します。
# 開発リポジトリのルートディレクトリにいる想定
mkdir -p .github/workflows
cd .github/workflows
touch deploy-prod.yaml
自動デプロイの機能を実現するためには下記の作業を Github Actions の環境で行う必要があります。
- 開発用リポジトリと公開用リポジトリの
git clone
- volta & node のインストール
- node_modules のインストール
- react のビルド
-
dist
ディレクトリ下のファイルを公開用リポジトリへコピー - 公開リポジトリへの push [1]
この作業を workflow に表すと具体的には下記のように記述されます。[2]
# workflow名
name: Deploy prod
# workflowの実行をトリガするイベントを記述する
on:
# 「v0.1.0」のようなリリースタグ作成にトリガーして、workflowを実行
push:
tags:
- v*
# 手動実行
workflow_dispatch:
# NOTE: inputsのデフォルト値を変更した場合はenvのデフォルト値も変更すること
inputs:
DRY_RUN:
type: boolean
description: 'dry run'
required: true
default: true
env:
# actionsで公開リポジトリにpushする際に使用するBOTの名前とメールアドレス
BOT_GITHUB_NAME: github-actions[bot]
BOT_GITHUB_MAIL: 41898282+github-actions[bot]@users.noreply.github.com
# 開発用リポジトリ (github_user は github アカウント名)
REMOTE_DEV_REPOSITORY: github_user/portfolio-dev
# 本番用リポジトリ (github_user は github アカウント名)
REMOTE_PROD_REPOSITORY: github_user/portfolio-prod
# 開発用リポジトリのローカルでのディレクトリ名
LOCAL_DEV_REPOSITORY: dev
# 本番用リポジトリのローカルでのディレクトリ名
LOCAL_PROD_REPOSITORY: prod
# 作成したPERSONAL_ACCESS_TOKENの格納場所
## Settings -> Screts and variavbles -> Actions -> Repository secrets -> New repository secret
PAT: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
# NOTE: envのデフォルト値を変更した場合はinputsのデフォルト値も変更すること
DRY_RUN: ${{ inputs.DRY_RUN || false }}
jobs:
# Job id
deploy-prod:
# Job名
name: deploy-prod
# jobを実行するOS
## NOTE: ubuntu-latestと指定することもできるが、OSバージョンが上がった際に、jobが動かなくなるリスクがあるので非推奨
runs-on: ubuntu-22.04
steps:
- name: Checkout ${{ env.LOCAL_DEV_REPOSITORY }} repository
run: |
set -x
git -v
git clone -b main --single-branch --depth=1 https://${{ env.PAT }}@github.com/${{ env.REMOTE_DEV_REPOSITORY }}.git ${{ env.LOCAL_DEV_REPOSITORY }}
- name: Checkout ${{ env.LOCAL_PROD_REPOSITORY}} repository
run: |
set -x
git -v
git clone -b main --single-branch https://${{ env.PAT }}@github.com/${{ env.REMOTE_PROD_REPOSITORY }}.git ${{ env.LOCAL_PROD_REPOSITORY }}
cd ${{ env.LOCAL_PROD_REPOSITORY }}
git clean -fdx && test $(git ls-files | wc -l) -eq 0 || ls | grep -v "README.md" | xargs git rm -rf
- name: Delete default node and npm
run: |
set -x
node -v
npm -v
rm -f $(which node)
rm -f $(which npm)
- name: Install node with volta
run: |
set -x
curl -V
jq -V
curl https://get.volta.sh | bash
${HOME}/.volta/bin/volta -v
cd ${{ env.LOCAL_DEV_REPOSITORY }}
pwd && ls -la
test ! -e package.json && echo "Error: package.json does not exist." && exit 1
${HOME}/.volta/bin/volta install node@$(jq -r .volta.node package.json)
test ! -e package-lock.json && echo "Error: package-lock.json does not exist." && exit 1
${HOME}/.volta/bin/volta which node
${HOME}/.volta/bin/volta which npm
- name: Install node modules
run: |
set -x
cd ${{ env.LOCAL_DEV_REPOSITORY }}
${HOME}/.volta/bin/volta -v
${HOME}/.volta/bin/volta run --bundled-npm npm ci
- name: Build react
run: |
set -x
cd ${{ env.LOCAL_DEV_REPOSITORY }}
${HOME}/.volta/bin/volta -v
${HOME}/.volta/bin/volta run --bundled-npm npm run build
- name: Copy build artifacts
run: |
set -x
cp -pr ${{ env.LOCAL_DEV_REPOSITORY }}/dist/* ${{ env.LOCAL_PROD_REPOSITORY }}/
cd ${{ env.LOCAL_PROD_REPOSITORY }}
pwd && ls -la
- name: Commit and push to ${{ env.LOCAL_PROD_REPOSITORY }} repository
run: |
set -x
cd ${{ env.LOCAL_PROD_REPOSITORY }}
git -v
git config --local user.name "${{ env.BOT_GITHUB_NAME }}"
git config --local user.email "${{ env.BOT_GITHUB_MAIL }}"
git add .
git commit -m "generated"
if [ ${{env.DRY_RUN}} = 'false' ]; then
git push -u origin main
else
echo '===== dry run ====='
git push -n -u origin main
fi
この workflow の下記ブロックの詳細やTIPSについて説明します。必要に応じて参照して下さい。
on:
on:
ブロックでは、workflow をトリガーして実行するためのGitHubのイベントを記述します。
on:
# 「v0.1.0」のようなリリースタグ作成をトリガして、workflowを実行
push:
tags:
- v*
# 手動実行
workflow_dispatch:
# NOTE: inputsのデフォルト値を変更した場合はenvのデフォルト値も変更すること
inputs:
DRY_RUN:
type: boolean
description: 'dry run'
required: true
default: true
-
push: tags:
でv*
のフォーマットを満たすリリースタグを作成したイベントを検知して workflow が実行されます。(具体例:v1.0.0
)
参考: https://docs.github.com/ja/github-ae@latest/actions/using-workflows/events-that-trigger-workflows -
workflow_dispatch:
は workflow の手動実行を可能にするイベントで、主に workflow のテストをする際に使用します。input
で手動実行時のパラメータを指定しており、DRY_RUN
オプションを指定しています。 -
dry run
とは、空実行を行うオプション[3]で、処理は実施するがその結果は反映しないことを表します。一般に、本番環境で使用される workflow やバッチは処理が失敗した際に開発者やユーザーに与える影響が大きいです。このため、事前に処理が正常に完了するかの確認や workflow の開発時にテスト実行の影響を本番環境へ与えないようにするため、このオプションを用意しておくことが望ましいです。[4] -
dry run
オプションは workflow のフェイルセーフのため、デフォルトで有効にしておく必要があります。
env:
env:
ブロックでは workflow で使用する変数を定義します。
env:
# actionsで公開リポジトリにpushする際に使用するBOTの名前とメールアドレス
BOT_GITHUB_NAME: github-actions[bot]
BOT_GITHUB_MAIL: 41898282+github-actions[bot]@users.noreply.github.com
# 開発用リポジトリ (github_user は github アカウント名)
REMOTE_DEV_REPOSITORY: github_user/portfolio-dev
# 本番用リポジトリ (github_user は github アカウント名)
REMOTE_PROD_REPOSITORY: github_user/portfolio-prod
# 開発用リポジトリのローカルでのディレクトリ名
LOCAL_DEV_REPOSITORY: dev
# 本番用リポジトリのローカルでのディレクトリ名
LOCAL_PROD_REPOSITORY: prod
# 作成したPERSONAL_ACCESS_TOKENの格納場所
## Settings -> Screts and variavbles -> Actions -> Repository secrets -> New repository secret
PAT: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
# NOTE: envのデフォルト値を変更した場合はinputsのデフォルト値も変更すること
DRY_RUN: ${{ inputs.DRY_RUN || false }}
- 公開リポジトリにビルド成果物を push する際に、workflow が commit したことを明確にするため、git アカウントに BOT ユーザーを利用します。
参考: https://qiita.com/thaim/items/3d1a4d09ec4a7d8844ce#github-actionsbot -
inputs.DRY_RUN
は workflow が手動実行以外で実行された場合、default
で値を与えていたとしてもその値はnull
になります。このため、${{ inputs.DRY_RUN || false }}
により GitHub のイベントで実行された場合はfalse
をDRY_RUN
に渡すようにしています。
参考: https://rcmdnk.com/blog/2023/02/06/computer-github/#inputsの値をpushイベントなどで使う
name: Checkout ${{ env.LOCAL_DEV_REPOSITORY }} repository
このブロックでは、開発用リポジトリを GitHub Actions がホスティングするマシンにクローンします。
- name: Checkout ${{ env.LOCAL_DEV_REPOSITORY }} repository
run: |
set -x
git -v
git clone -b main --depth=1 https://${{ env.PAT }}@github.com/${{ env.REMOTE_DEV_REPOSITORY }}.git ${{ env.LOCAL_DEV_REPOSITORY }}
-
set -x
により、bash
のオプションを変更し、実行されるコマンドとその結果をログに表示するよう設定します。workflow に問題が起こった時に問題箇所の発見がしやすくなります。 - 開発用リポジトリは react のビルド用に利用するリポジトリのため、
main
のブランチの commit 履歴は不要です。--depth=1
で最後のコミットだけを取得することで、git clone
を高速化しています。
参考: https://swet.dena.com/entry/2020/12/10/100000 - GitHub Actions は private リポジトリで利用する場合、クレジットを消費するため(無料枠であるGitHub Freeは月当たり2000分)、workflow の最適化を行うモチベーションは比較的高いのではないかと思います。
name: Checkout ${{ env.LOCAL_PROD_REPOSITORY}} repository
このブロックでは、公開用リポジトリを GitHub Actions がホスティングするマシンにクローンします。
- name: Checkout ${{ env.LOCAL_PROD_REPOSITORY}} repository
run: |
set -x
git -v
git clone -b main --single-branch https://${{ env.PAT }}@github.com/${{ env.REMOTE_PROD_REPOSITORY }}.git ${{ env.LOCAL_PROD_REPOSITORY }}
cd ${{ env.LOCAL_PROD_REPOSITORY }}
git clean -fdx && test $(git ls-files | wc -l) -eq 0 || ls | grep -v "README.md" | xargs git rm -rf
-
git clone ...
の詳細はname: Checkout ${{ env.LOCAL_DEV_REPOSITORY }} repository
を参照して下さい。 -
git clean ...
以降のコマンドは、git で未追跡のファイルの削除とREADME.md
ファイル以外のファイルの削除を実施します。その理由として、react のビルドではindex-<ハッシュ値>.json
のようなファイルがビルド毎に生成されるため、すでに不要となったハッシュ値付きのファイルを公開リポジトリに残さないためです。
参考: https://blog.s64.jp/entry/git-rm-all_safely/
name: Delete default node and npm
このブロックでは、デフォルトでインストールされている node と npm について削除します。
- name: Delete default node and npm
run: |
set -x
node -v
npm -v
rm -f $(which node)
rm -f $(which npm)
- 今回実行環境に指定している
ubuntu-22.04
環境にはデフォルトでnode
とnpm
がインストールされている状態でした。しかし、react ビルドで使用したいnode
やnpm
のバージョンは下記のものではないため、意図しないバージョンのバージョンのnode
やnpm
は混乱・事故防止のため削除します。
+ node -v
v18.19.0
+ npm -v
10.2.3
++ which node
+ rm -f /usr/local/bin/node
++ which npm
+ rm -f /usr/local/bin/npm
name: Install node with volta
このブロックでは、voltaのインストールと指定したバージョンの node をインストールします。
- name: Install node with volta
run: |
set -x
curl -V
jq -V
curl https://get.volta.sh | bash
${HOME}/.volta/bin/volta -v
cd ${{ env.LOCAL_DEV_REPOSITORY }}
pwd && ls -la
test ! -e package.json && echo "Error: package.json does not exist." && exit 1
${HOME}/.volta/bin/volta install node@$(jq -r .volta.node package.json)
test ! -e package-lock.json && echo "Error: package-lock.json does not exist." && exit 1
${HOME}/.volta/bin/volta which node
${HOME}/.volta/bin/volta which npm
-
${HOME}/.volta/bin/volta
のようにしているのは、workflow で実行される bash は.bashrc
などのプロファイルが読まれないようになっているため、環境変数の設定をしても有効にならなかったためです。shell: bash
を指定すると GitHub Actions のログ上でshell: /usr/bin/bash --noprofile --norc -e -o pipefail {0}
となるので明確にプロファイルが読まれないことがわかります。 -
jq -r .volta.node package.json
でpackage.json
にvolta pin
された node のバージョンを取得し、指定バージョンの node をインストールします。
name: Install node modules
このブロックでは、node_modules のインストールを行います。
- name: Install node modules
run: |
set -x
cd ${{ env.LOCAL_DEV_REPOSITORY }}
${HOME}/.volta/bin/volta -v
${HOME}/.volta/bin/volta run --bundled-npm npm ci
- CIでは
npm install
でなく、npm ci
を使いましょう。
参考: https://bufferings.hatenablog.com/entry/2023/03/15/215044 -
volta run --bundled-npm npm
でnode
インストールの際にバンドルされていたバージョンのnpm
コマンドを使用できます。
参考: https://docs.volta.sh/reference/run
name: Build react
- name: Build react
run: |
set -x
cd ${{ env.LOCAL_DEV_REPOSITORY }}
${HOME}/.volta/bin/volta -v
${HOME}/.volta/bin/volta run --bundled-npm npm run build
-
volta run --bundled-npm npm run build
でnode
インストールの際にバンドルされていたバージョンのnpm
コマンドを使用して、ビルドを実行します。
name: Copy build artifacts
このブロックでは、ビルド成果物を公開リポジトリへコピーします。
- name: Copy build artifacts
run: |
set -x
cp -pr ${{ env.LOCAL_DEV_REPOSITORY }}/dist/* ${{ env.LOCAL_PROD_REPOSITORY }}/
cd ${{ env.LOCAL_PROD_REPOSITORY }}
pwd && ls -la
-
cp -pr
でdist
下のビルド成果物のファイルを再帰的に-p
で元の権限を維持したまま、公開用リポジトリへコピーを行います。
name: Commit and push to ${{ env.LOCAL_PROD_REPOSITORY }} repository
このブロックでは、公開リポジトリへの push を行います。
- name: Commit and push to ${{ env.LOCAL_PROD_REPOSITORY }} repository
run: |
set -x
cd ${{ env.LOCAL_PROD_REPOSITORY }}
git -v
git config --local user.name "${{ env.BOT_GITHUB_NAME }}"
git config --local user.email "${{ env.BOT_GITHUB_MAIL }}"
git add .
git commit -m "generated"
if [ ${{env.DRY_RUN}} = 'false' ]; then
git push -u origin main
else
echo '===== dry run ====='
git push -n -u origin main
fi
-
git config ...
で成果物ファイルをcommitするユーザー(BOT)を指定します。 -
${{env.DRY_RUN}}
をif
で判定して、dry run で実行するかどうか決定します。 -
git push
の-n
オプションで dry run 動作となるため、実際には push されません。
Personal Access Tokenの作成とRepository secretの設定
作成した workflow で公開リポジトリへの push 操作を行うためには、権限を付与してあげる必要があります。そのために、Personal Access Token を workflow から参照可能にする設定が必要です。
具体的には、env:
ブロックで使用している${{ secrets.PERSONAL_ACCESS_TOKEN }}
です。
PAT: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
- Personal Access Token(classic)を
repo
権限で作成。トークンの値は控えておきましょう。Personal Access Token の作成方法がわからないという方はこちらの記事のトークンの発行を参考にして下さい。 - 開発用リポジトリのSettingsタブ -> Secrets and variables -> Actions -> Repository secrets -> New repository secret に
PERSONAL_ACCESS_TOKEN
の名前で作成。1.で作成した Personal Access Tokenの値を入れて保存します。
以上で自動デプロイが使える状態になりました。
開発リポジトリの Actions のタブからDeploy prod
の workflow を選択して、run workflow
からdry run
実行を試してみて下さい。正常に dry run が完了した方は、dry run を外して手動実行 or リリースタグを作成してトリガ実行を行い GitHub Pages までのデプロイが通るかを確認してみて下さい。
(おまけ)ビルド可能かテストするworkflowを作成
GitHub Pages への自動デプロイの workflow は完成しましたが、少し問題があります。
それは、リリースタグを作成して、自動デプロイを走らせたら、react のビルドでエラーになって GitHub Pages へのデプロイに失敗してしまったというケースです。
ここで、問題なのは本番デプロイ用のブランチmain
にビルドに失敗するようなコードやアセットが含まれてしまった点です。
これを回避するには、main
ブランチにプルリクエストがマージされる前段階、つまり、開発用ブランチへの push の度にビルドが正常に通るかを都度検証する必要があります。
ビルドテストは、下記のような workflow で実現できます。(自動デプロイに類似した処理が多いので説明は特にしません。)
name: Build test
on:
push:
branches:
- main
- dev
workflow_dispatch:
env:
BOT_GITHUB_NAME: github-actions[bot]
BOT_GITHUB_MAIL: 41898282+github-actions[bot]@users.noreply.github.com
REMOTE_DEV_REPOSITORY: github_user/portfolio-dev
LOCAL_DEV_REPOSITORY: dev
PAT: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
jobs:
test-npm-run-build:
name:
runs-on: ubuntu-22.04
steps:
- name: Checkout ${{ env.LOCAL_DEV_REPOSITORY }} repository
run: |
set -x
git -v
git clone -b ${{ github.ref_name }} --depth=1 https://${{ env.PAT }}@github.com/${{ env.REMOTE_DEV_REPOSITORY }}.git ${{ env.LOCAL_DEV_REPOSITORY }}
- name: Delete default node and npm
run: |
set -x
node -v
npm -v
rm -f $(which node)
rm -f $(which npm)
- name: Install node with volta
run: |
set -x
curl -V
jq -V
curl https://get.volta.sh | bash
${HOME}/.volta/bin/volta -v
cd ${{ env.LOCAL_DEV_REPOSITORY }}
pwd && ls -la
test ! -e package.json && echo "Error: package.json does not exist." && exit 1
${HOME}/.volta/bin/volta install node@$(jq -r .volta.node package.json)
test ! -e package-lock.json && echo "Error: package-lock.json does not exist." && exit 1
${HOME}/.volta/bin/volta which node
${HOME}/.volta/bin/volta which npm
- name: Install node modules
run: |
set -x
cd ${{ env.LOCAL_DEV_REPOSITORY }}
${HOME}/.volta/bin/volta -v
${HOME}/.volta/bin/volta run --bundled-npm npm ci
shell: bash
- name: Build react
run: |
set -x
cd ${{ env.LOCAL_DEV_REPOSITORY }}
${HOME}/.volta/bin/volta -v
${HOME}/.volta/bin/volta run --bundled-npm npm run build
共著
-
厳密には、GitHub Pages へのデプロイは本番用リポジトリで自動的に生成される workflow である
pages build and deployment
により、main
ブランチへの push でトリガされ実行されます。また、本番用リポジトリは公開リポジトリであるため、pages build and deployment
によるクレジットの消費がない点は嬉しいです。 ↩︎ -
公開リポジトリの
git push
が、サードパーティであるactions/checkout@4を利用した場合に上手くいかなかったのと、わかりやすさのため手動でやった作業との類似性をもたせたいという理由からjobの処理は全て bash で記述しました。 ↩︎ -
ショートハンドの記法では
-n
と表されることが多いです。 ↩︎ -
テスト実行は、本番へ影響を与える処理はコメントアウトしてから行うのが一番安全だとは思います。 ↩︎
Discussion
GitHub Pagesに関して補足させていただきます。
無料のAccountやOrganizationでは公開リポジトリが必要ですが、GitHub Proなどの有料Accountなどではプライベートリポジトリも利用可能です。
参考になれば幸いです。
補足頂きありがとうございます!
今回の内容は無料のAccountやOrganizationのGithub Pagesで公開することを想定しておりましたが、ご指摘の通り有料プランではプライベートリポジトリでも公開可能ですね!
コメント頂きありがとうございました!