バカンス駆動開発

この前バカンスって言ったら「古っ」って言われました

gitのリモートリポジトリをさくらのVPSに設置して自動ビルドさせる方法

前提

すでに公開ディレクトリに走らせているソースコードがある。
今までは一人で管理していたが、複数人でgitで管理することにする。
ローカルからプッシュすると公開ディレクトリに自動でビルドされるようにする
サーバー環境はさくらのVPSでCentOS5.6。
gitはすでにインストール済み。
公開ディレクトリを/var/www/html/website/とする。
中央リポジトリ/var/www/git/website.gitに置く。

流れ

  1. 作業グループを作成してユーザーを所属させる
  2. 中央リポジトリを作成
  3. 公開ディレクトリ以下をgitで管理
  4. 公開ディレクトリから中央リポジトリにプッシュ
  5. 公開ディレクトリを消去して新規作成
  6. 公開ディレクトリ上で中央リポジトリをクローン
  7. ディレクトリの権限等をきちんと設定 ←一番大事!
  8. 中央リポジトリにローカルからプッシュすると公開ディレクトリに自動でビルドさせるようにする
  9. ローカルからプッシュ

作業グループと作業ユーザーを作成

複数人で同じリポジトリを扱うので全てのユーザーが共通で所属するグループを作成(ここではteamとする)。

//teamグループ作成
$ sudo groupadd team

//確認
$ sudo cat /etc/group
・・・
team:x:501:      //501という数字は連番でふられるので各々違います

次に作業ユーザーをこのグループに所属させる。

//hogehogeユーザーとfugafugaユーザーを所属させる
//直接ユーザー名をコンマ繋ぎで書けばOK
$ sudo vi /etc/group
・・・
team:x:501: hogehoge,fugafuga

中央リポジトリを作成

$ cd /var/www/git/

//中央リポジトリのディレクトリは慣例的に末尾に.gitを付ける
$ mkdir website.git
$ cd website.git
$ git init --bare --shared

--bareオプションを付けるとソースファイルの実態が置かれるworkspaceがない状態でinitされます。中央リポジトリではソースファイルは管理せず、その変更履歴だけ管理します。

公開ディレクトリ以下をgitで管理

$ cd  /var/www/html/website/
$ git init
$ git add .
$ git commit -m "first commit! yahoo!!!"
$ git remote add origin /var/www/git/website.git
$ git push -u origin master

中央リポジトリでコミットログを確認

$ cd /var/www/git/website.git
$ git log

first commit! yahoo!!! 的なのが出ればOK!

公開ディレクトリを消去して新規作成

今後各ユーザーがローカル中央リポジトリにプッシュしてその内容を公開ディレクトリからプルするようにしますが、公開ディレクトリのリポジトリは中央リポジトリからクローンしてきたものではありませんのでこのままだと上手くいきません。
なのでリモートブランチを公開ディレクトリに作成して、さらにローカル(公開ディレクトリ)のブランチがリモートブランチを追跡するように繋げないといけませんが、面倒なので公開ディレクトリごと消して中央リポジトリからクローンし直します。
消す前にはバックアップを取りましょう。
また消さずにブランチをつなぎ合わせる方法はこちらで初回されています。

introduction-to-git/09_clone.md at master · Shinpeim/introduction-to-git

//一旦公開ディレクトリを消します
$ rm -rf /var/www/html/website

//再度空ディレクトリを作成
$ mkdir /var/www/html/website

公開ディレクトリ上で中央リポジトリをクローン

$ git clone /var/www/git/website.git/ /var/www/html/website
Cloning into '/var/www/html/website'...
done.

簡単ですね。

ディレクトリの権限等をきちんと設定

複数人でリポジトリを操作する場合、パーミッションをきちんと設定することが大事です。
まず中央リポジトリの所有グループをteamにします。

$ cd /var/www/git
$ chgrp -R team website.git

ls -laでwebsite.gitディテクトリとそれ以下のディレクトリの所有グループがteamであることを確認します。

次に、公開ディレクトリも同様に所有グループをteamにします。

$ cd /var/www/html
$ chgrp -R team website

また、今後websiteディレクトリ内に生成させるファイルやディレクトリの所有者がteamになるようにします。

$ chmod -R 2775 team

中央リポジトリの場合はgit init時に--sharedオプションを付けることで同様の事をしています。

中央リポジトリにローカルからプッシュすると公開ディレクトリに自動でビルドさせるようにする

gitには様々な状態の変化に反応してスクリプトを動かす仕組みがあり、様々なタイミングでビルドサーバーを叩いたり、メールを送信したりできます。
今回はプッシュが成功したら、自動的に公開ディレクトリからプルを行わせます。
プッシュが成功すると/var/www/git/website.git/hooks/post-receiveが動きます。初期の時点ではpost-receive.sampleがありますのでコピーしてpost-receiveファイルを作成します。僕の環境には無かったですが。
post-receiveには以下を書き込みます。

#!/bin/sh
#
# An example hook script for the "post-receive" event.
#
# The "post-receive" script is run after receive-pack has accepted a pack
# and the repository has been updated.  It is passed arguments in through
# stdin in the form
#  <oldrev> <newrev> <refname>
# For example:
#  aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master
#
# see contrib/hooks/ for a sample, or uncomment the next line and
# rename the file to "post-receive".

#. /usr/share/git-core/contrib/hooks/post-receive-email

cd /var/www/html/website/
git --git-dir=.git pull

コメント部分はサンプルのまんまで、やってることは公開ディレクトリに移動してプルしてるだけです。
注意点としてはpost-receiveに実行権限を付けることです。

$ cd /var/www/git/website.git/hooks
$ chmod +x post-receive

ローカルからプッシュ

ローカルにクローンします。 公開鍵認証方式で接続する場合はすでにhogehogeユーザーの公開鍵をサーバー側にあずけている前提で話をすすめます。

//ローカル
$ git clone ssh://hogehoge@49.123.45.67:22/var/www/git/website.git/ 作業ディレクトリ

作業ディレクトリ内で何かファイルを作ってプッシュしてみます。

//ローカル
$ vi index.php

hello world

$ git add .
$ git commit -m "indexファイル作成"
$ git push -u orign mster

上手くプッシュが出来たかと思います。

さて、最後に公開ディレクトリに反映されているか確認します。

//サーバー
$ cd /var/ww/html/website
$ git log

indexファイル作成 的な文字が出てればOK!!

ポイント

たぶんよくひっかかるパターンとして、pushすると.git/objects/にどんどんディレクトリが生成されるけれど、それの所有グループがプッシュしたひとのグループになっていて、他の人がプッシュする際にそいつらにアクセスする権限がなくエラーを吐くというのだと思います。
ですので、パーミッションを2775にするということがとても大事です。 というお話。

参考

  1. gitの中央repos運用時のパーミッションの調整 - (ひ)メモ
  2. リポジトリを後から共有できるようにする。 - kuma8の日記