1行書くだけで GitHub Pages のドキュメントルートをサブディレクトリにする方法

# はじめに

こんにちは。debiru です。

静的ホスティングサーバーとして GitHub Pages は便利ですよね。

しかし、従来はデフォルトではドキュメントルートの設定が `/ (root)` または `/docs` しか選べず、好きなサブディレクトリを設定することができませんでした。

これを回避するために、異なるブランチ（例えば `gh-pages`）を作成し、そのブランチの `/ (root)` をドキュメントルートとして GitHub Pages を設定し、それを `submodule` として `main` ブランチに設置するといった方法が採られてきました。

しかし、2019年にリリースされた GitHub Actions を用いたデプロイ方法を採ることで、簡単に任意のサブディレクトリをドキュメントルートに設定することができます。

![GitHub Pages のデプロイ方法選択画面。GitHub Actions と Deploy from a branch が選べる。](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178936/3e224b62-a5dd-4dd6-8f71-ecf3d2bbe5e9.png)

# ひとつめ： submodule を用いた従来の方法

公開したいブランチ（例えば `main`）のサブディレクトリ（例えば `public`）のデータを、任意のブランチ（例えば `gh-pages`）のルートに設置します。

```text:main branch
/ (root)
├ README.md
└ public/
  └ index.html
```

このような構造であれば、次のようなコマンドで `gh-pages` ブランチを作成します。

```sh:main branch
# git log を破棄してブランチを生成する
git checkout --orphan gh-pages
```

```sh:gh-pages branch
# public ディレクトリの中身でルートディレクトリを置き換える
mkdir .trash && ls -1A | grep -vE '\.git|\.trash' | xargs mv --target .trash
find .trash/public -mindepth 1 -maxdepth 1 | xargs mv --target . && rm -r .trash

# git commit する
git add . && git commit -m "setup public directory contents"
git push origin gh-pages
```

任意のブランチを `gh-pages` に設定した場合は、自動的に GitHub Pages の設定が行われます。それ以外のブランチ名にした場合は、GitHub のリポジトリページから Settings > Pages メニューを選び、"Build and deployment" の項目で "Deploy from a branch" を選択してブランチを設定してください。

これで public ディレクトリの中身が GitHub Pages で公開される状態にはなりましたが、`main` ブランチのサブディレクトリとしてこの `public` が存在している状態にはなっていません。これを関連付けします。

```sh:main branch
# main ブランチへ移動する
git checkout main

# public ディレクトリを削除する
rm -r public

# gh-pages ブランチを public ディレクトリとして submodule 化する
git submodule add -b gh-pages $(git config --get remote.origin.url) public
```

これで `main` ブランチ上にあるサブディレクトリ `public` から `gh-pages` ブランチを辿れるようになります。

ただし、`public` ディレクトリの中身を変更する場合には、`gh-pages` ブランチ側に commit & push する必要があり、`main` ブランチ上での commit と扱いが分かれてしまうのが不便です。

この問題を回避するには、次の GitHub Actions を用いた方法でデプロイを行いましょう。

# ふたつめ：GitHub Actions を用いてデプロイする方法

GitHub のリポジトリページから Settings > Pages メニューを選び、"Build and deployment" の項目で "GitHub Actions" を選択し、"Static HTML" の "Configure" ボタンを押してください。

すると次の画面で YAML ファイルをコミットする操作が求められるので、右上にある緑色の "Commit changes..." ボタンを押し、出てきたポップアップウィンドウの中の緑色の "Commit changes..." ボタンを押します。

この操作により、次のような YAML ファイルがコミットされます。

```yaml:.github/workflows/static.yml
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content 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

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Setup Pages
        uses: actions/configure-pages@v5
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          # Upload entire repository
          path: '.'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4
```

```sh:main branch
# YAML ファイルのコミットを取得する
git pull
```

そして次のように `actions/upload-pages-artifact@v3` アクションの `path` パラメータの値を `public` に変更します。

```diff
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
index f2c9e97..d4c4e5c 100644
--- a/.github/workflows/static.yml
+++ b/.github/workflows/static.yml
@@ -37,7 +37,7 @@ jobs:
         uses: actions/upload-pages-artifact@v3
         with:
           # Upload entire repository
-          path: '.'
+          path: public
       - name: Deploy to GitHub Pages
         id: deployment
         uses: actions/deploy-pages@v4
```

- https://github.com/debiru/gh-pages-subdir-2/commit/e9b9a8fdb73331de7dd3a9c5a0931444210e9cc0

これを commit & push して完了です。

# おわりに

Web 検索しても、GitHub Pages のドキュメントルートをサブディレクトリに変更する方法として「ひとつめ」の方法を紹介する記事しか出てこないようだったのでこの記事を書きました。

Astro も便利なので GitHub Pages で静的サイトの公開を考えている際には Astro の利用を併せてご検討ください。

https://qiita.com/debiru/items/a5ac8219b696045f88f5