GitHub Pages用gh-pagesブランチとmasterブランチの自動同期

Gitフックを用いてGitHub Pages用のgh-pagesブランチとmasterブランチを自動同期させる。

結論としては,リポジトリーに以下の内容の.git/hooks/post-commitを格納して,コミットの度に,GitHubのリモートリポジトリーのgh-pagesブランチに,直接masterブランチを上書きで反映させることで実現できた。

git push -f origin master:gh-pages
導入

GitHubの公開リポジトリーは,ソースコードの閲覧が基本機能であり,HTMLの描画はできない。そのため,HTMLを閲覧する場合,HTMLコードをそのまま読むしかなかった。

GitHub Pagesという静的Webページを生成する機能を使うことで,HTMLの描画ページを閲覧可能となる。

GitHub Pagesにより静的Webページの作成方法には以下の3通りがある。

  1. ユーザーサイト: ユーザー名.github.ioリポジトリーを公開
  2. プロジェクトサイト: リポジトリーのgh-pagesブランチを公開
  3. docsディレクトリー: リポジトリーのdocsディレクトリー配下を公開

これらの方法にはそれぞれ利点と欠点がある。自分が思う利点と欠点を以下の表にまとめた。

GitHub Pagesの作成方法の利点と欠点
方法 利点 欠点
ユーザーサイト
  • ファイルの配置が自由
  • 1ユーザーにつき1個だけ。
  • ユーザー名.github.ioリポジトリーへの格納が必要
プロジェクトサイト
  • プロジェクト・リポジトリー単位で公開可能
  • ファイル配置が自由
  • GitHub Pages用にgh-pagesブランチが必要
  • masterブランチのgh-pagesへの反映・同期が必要
docsディレクトリー
  • プロジェクトリポジトリー・単位で公開可能
  • gh-pagesの欠点であるmasterとの同期処理が不要
  • GitHub Pages用にdocsディレクトリーが必要

ユーザーサイトは公開に当たっての制限が少なく一番自由度は高い。ただし,1個しか持てないことから,ユーザー名.github.ioリポジトリー配下にGitのsubmoduleで登録するなどして,自分で公開したいリポジトリーを登録する必要がある。

docsディレクトリーは,リポジトリーのmasterブランチにdocsディレクトリーを用意して公開物を配下に格納するだけで済むので,一番気軽だろう。ただし,GitHubの独自仕様のためにプロジェクトのディレクトリー構成を強制されるのが少々気になる。

個人的にはリポジトリー単位で公開の可否が可能で,ファイル配置の自由度が高いことから,gh-pagesブランチを使ったプロジェクトサイトが一番だと考えている。

ただし,こちらはmasterブランチの内容のgh-pagesブランチへの反映・同期が必要である。手作業で行う場合,以下のコマンドを実行することになる。

git checkout master
# git commit # masterでコミット
git rebase master gh-pages # gh-pagesブランチにmasterの内容を反映
git push origin gh-pages # GitHub Pagesに反映
git checkout master

masterブランチでのコミットの度に上記コマンドを手打ちするのは手間だ。シェルスクリプトにすれば1回のスクリプト実行で済むとはいえ,スクリプトの実行が手間となり実行忘れにもつながる。

そこで,このmasterブランチとgh-pagesブランチの同期を自動化する。

Gitフック

自動化にはGitフックを利用する。Gitには特定のアクションが発生した際にカスタムスクリプトを実行する方法があり,この機能をGitフックと呼ぶようだ。

このフックはクライアントとサーバーの2のグループに分類される。

  • クライアントサイドフック: コミットやマージなどのクライアント操作で実行
  • サーバーサイドフック: コミットの受取などのネットワーク操作で実行

今回はGitフックのクライアントサイドフックを使う。何らかのコミット後に先程のコマンドを実行することで自動同期する。

コミット後の任意のコマンドの実行には,.git/hooks/post-commitにコマンドを記述し,実行権限を付与すればよい。

同期手順

以下のコマンドをリポジトリーの直下で実行して,post-commitファイルを作成することでmasterブランチとgh-pagesブランチを自動同期するフックを作成できる。

mkdir -p .git/hooks
cat <<-EOT >.git/hooks/post-commit git push -f origin master:gh-pages
EOT
chmod +x .git/hooks/post-commit

なお,masterブランチとgh-pagesブランチとの同期方法を手作業の手順から変更したことに注意してほしい。

当初は,以下のコマンドでgh-pagesブランチをmasterブランチに付け替えることで,内容を反映させていた。

git rebase master gh-pages
git push -f origin gh-pages
git checkout master

しかし,この方法ではmasterブランチでgit commit --amendgit rebase -i履歴を変更してしまうと,git rebaseコマンドで競合が発生してしまった。

作業中にコミット忘れやコメントミスなどでgit commit --amendすることはよくある。そのため,git rebaseでの反映には問題があった。

対策を検討していると「実践GitHub Pages運用のユースケースとワークフローの詳細 | ゆっくりと…」を見つけた。こちらの「2.3 gh-pages専用のリポジトリを作って運用する」で解説されている通り,いってしまえば,今回はGitHub Pagesでmasterブランチの内容を描画したいだけだ。

そのため,コミットの度にmasterブランチを直接リモートのgh-pagesブランチにpush -fで強制上書きすることにした。これにより,masterブランチをgh-pagesブランチと自動同期でき,GitHub Pagesを最新に保てる。

ローカルのgh-pagesブランチは使わないため,以下のコマンドで削除しておく。

git branch -D gh-pages

後で参照しやすいように,GItHubのリポジトリーにも同じコードを格納した。

結論

masterブランチの内容を自動的にgh-pagesブランチに反映さえ,GitHub Pagesを常に最新に保つ方法を解説した。

GitHub Pagesを使えば,公開用のドキュメントやプロジェクトのWebサイトを同時に作成できて,効率がいい。

今回の仕組みで自動的にWebサイトに反映できるようになるので,積極的にプロジェクトの情報を公開していきたい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です