sparse-checkoutでGitのサブディレクトリだけを自動デプロイする

前回の記事で、リモートリポジトリからテストサーバへの自動デプロイができるようになりましたが、この通りだとGitのリポジトリ全体がデプロイ先のドキュメントルートである必要がありました。(つまり、WebサーバにテストアップするファイルのみがGitで管理されている状態。)でも実際はWebサーバにアップするファイルだけでなく、プロジェクトに関連する資料系やサーバにはアップしたくないけど共有管理しておきたいファイルは存在するので、Gitで管理される一部のみ(=サブディレクトリ)がデプロイされるように 改良しました。

before / after

改良前のディレクトリ構造が左、実際に運用したい構造は右です。左はGitで管理しているディレクトリ=Webサイトのドキュメントルートの関係なので、「サーバにはアップしたくないけどGitで管理したいファイル」の扱いがうまくできない状態。実際は、各自がクローン後にローカルで設置しないといけないファイル(ローカル用の.htaccessとか)やちょっとしたドキュメントの共有もしたいですし、「.gitignore」や「.editorconfig」などサーバにアップするのってどうなの、と思うファイルもあるので、基本構造はだいたい右のような形になります。すっきり。

ビフォーアフター図

で、本題はこのサブディレクトリ/html/に入っているファイルだけをどう自動デプロイするか、ということです。

sparse-checkout でサブディレクトリのみをcheckoutする

日本語だとうまく探しきれなかったので英語ですが、次の2つの記事に行き着いて解決することができました。 (両方ともほぼ同じタイトルですが、別々の記事です)

Subdirectory Checkout with git sparse-checkout
Subdirectory Checkouts with git sparse-checkout

上の記事では両方ともgit cloneではなく、デプロイ先でgit initして文字通り「サブディレクトリだけcehckout」してきていますが、今回の場合は実体をまんま取得するのではなく、一旦非公開領域にミラーでクローンしてきて、公開領域(ドキュメントルート)に配置する流れなので、その部分だけ参照サイトと異なるコマンドを採用しました。

前提条件や環境:
  1. デプロイ先のドキュメントルートディレクトリは/html/
  2. デプロイ先の非公開領域に、一旦 ミラー でクローンします
  3. 「.git」という名前(Gitディレクトリ)でクローンします

補足すると、1:はデプロイ先のドキュメントルートディレクトリと、対象となるGitのサブディレクトリ名が同一でないと意図するデプロイができないからで、2と3は、クローンしてくるときのコマンドを毎回同じにして、数も減らして効率化したいから、というのが理由です。

テストサーバの非公開領域にミラーでclone

前回の記事BacklogのGitリポジトリからCPIサーバに自動デプロイすると同様、初回はテストサーバ側に手動でSSHログインし、リモートリポジトリをクローンしてきます。

% pwd
/usr/home/<cpi_user_id>
% git clone --mirror https://<login_id>:<password>@granfairs.backlog.jp/git/test/test.git .git
  1. カレントディレクトリがユーザのルートディレクトリであることを確認
  2. 非公開領域に .git という名前でミラークローン(※1)

※1:このタイミングでユーザのルートディレクトリをFTPで見ると、次のように.git/ディレクトリがクローンにより作成されていることが確認できます。

ミラーでクローンされた図

sparse-checkout でサブディレクトリhtml/だけをcheckoutする

% git config core.sparsecheckout true
% echo html/ > .git/info/sparse-checkout
% git --git-dir=/usr/home/<cpi_user_id>/.git fetch
% git --git-dir=/usr/home/<cpi_user_id>/.git --work-tree=/usr/home/<cpi_user_id> checkout -f
  1. .gitconfig の設定でsparsecheckoutを有効に
  2. sparse-checkoutの設定ファイルにチェックアウト対象ディレクトリを指定(この場合html/
  3. gitディレクトリを指定してfetch
  4. 展開先ディレクトリ(この場合html/html/に展開したいので、指定するのはその親=ユーザルート)にcheckout(※2)

※2:このタイミングでドキュメントルートhtml/配下に最新のサイトデータがデプロイされていることが確認できます。

サブディレクトリのみがデプロイされた図

.git/以外のリポジトリ名でクローンした場合は、上の「1」において、作成したリポジトリディレクトリに移動してから実行する必要があります。また、sparse-checkoutの設定ファイルのパスも作成したリポジトリ名に変えて実行しないとエラーになります。

ここまでで、サブディレクトリだけを 手動で デプロイすることができました(・∀・)v

自動化する

つづいて、手動で実行したコマンドのうち、最後のfetchcheckoutを自動化します。

自動化スクリプトを改変

これは前回の記事で紹介したスクリプトの設定値をちょっと改変するだけでOKです。

元になったスクリプト:BacklogからCPIへのデプロイスクリプト

これの上部の設定値のうち、テストサーバ内のリポジトリディレクトリ名とデプロイ先のディレクトリを、今回手動で設定した内容に合わせて変更します。

// Gitレポジトリの位置の指定(固定で[.git])
$git_dir     = '/usr/home/' . $user_id . '/.git';
// 展開先ディレクトリの指定([html]に展開するので固定で親ルートを指定)
$work_tree   = '/usr/home/' . $user_id;

次に置きました:BacklogのサブディレクトリのみをCPIへのデプロイするスクリプト

Webフックの設定をして完了

後は、この スクリプトファイルをテストサーバのどこか(公開領域内)に設置 して、Backlogに「git Webフック」の設定をすれば 全て完了です!(Backlogに「git Webフック」の設定をする方法は、前回の記事の最後の方を参照してください)

これでやっと、テストアップの自動デプロイに関する課題がクリアできました!
めでたしめでたし (σ・∀・)σゲッツ!!