Subversionでバージョン管理をしている場合、各開発者のローカル環境以外に、実際に公開する環境へ反映する必要がある。

手っ取り早い方法は、個人の開発環境などにチェックアウトしたファイルをSCPやFTPでファイルをアップするという方法ですが、これでは、せっかくのバージョン管理が生かせなくなってしまいます。
必ず、ローカルの環境を最新にし、コミットしてからアップするという運用手順で回避できる規模もあるかもしれませんが、どうしても漏れが出てきてしまうと思います。
せっかくのバージョン管理の利点が半減です。

私の会社では次のような手段で本番環境までの反映をしています。

  1. 各開発者は、自分の修正をSVNにコミット
  2. 実際に確認する本番環境や共通のステージング環境で、svnコマンドを使用し svn update をする
  3. 「.svn」などのSVN用のファイルを除き、公開ドキュメントルートへ rsyncを使用し同期

実際には、そのまま本番へアップということはありえませんので、ステージング環境までを上記方法で反映し、その後、ステージング環境>本番環境への反映もrsyncにて同期することになります。

今回、自分の環境を作成するにあたり、せっかくなので仕事と同じような環境を作ってみました。
仕事では、コミッターが複数いますので、口頭などでSVNへの修正のコミット状況を確認してから、ステージングへの反映シェルバッチを手動にて実行しています。

しかし、ひとりしかコミッターがいない自分の環境では、そこまでする必要がありません。
なので、SVNにコミットしたと同時に開発環境までの反映をされるようにしてみました。

まずは、反映スクリプトを書いてみます。
SVN_DIRと TO_DIRは適宜自分の環境にあわせてください。

#!/bin/sh
SVN_DIR=/var/svn/repos/
FROM_DIR=$SVN_DIR
TO_DIR=/home/www/htdocs/

## svn update
cd $SVN_DIR
/usr/bin/svn update
cd -

/usr/bin/rsync \
        --dry-run \
        --delete \
        --checksum \
        --archive \
        --recursive \
        --verbose \
        --exclude '.svn' \
        $FROM_DIR \
        $TO_DIR

answer=$1

if [ $answer = "-y" ];
then
    answer="y"
else
    echo -n "rsync ok? [y/n]"
    read answer
fi

if [ $answer = "y" ];
then

/usr/bin/rsync \
        --checksum \
        --archive \
        --recursive \
        --verbose \
        --exclude '.svn' \
        $FROM_DIR \
        $TO_DIR

fi

ステージング環境への反映ということで「stg_release.sh」というファイルで作成してみます。
手動で実行した場合には、[y/n]で反映確認が出来るようにしておきました。

あとは、これを手動で動かしてみて実際に反映できるかを確認します。
実際の環境では、–exclude等で除外するファイルをもっと指定する必要があるかもしれません。

次に、SVNのコミット時に自動実行するように設定してみます。

リポジトリのフォルダ内に以下のようなフォルダがあります。

README.txt  conf  dav  db  format  hooks  locks

この hooksフォルダの中に、各イベント時に実行される処理のテンプレートファイルがあります。
今回使用するのは、コミット後なので「post-commit.tmpl」を使用します。

$ cd /path/to/repos/hooks
$ cp post-commit.tmpl post-commit
$ chmod +x post-commit

実行権限まで付けてあげる必要があります。

コミット時にこのファイルが実行されますので、ここで先ほど作成した、反映用のバッチを呼び出してあげればOKです。

$ cat post-commit
#!/bin/sh

# POST-COMMIT HOOK
# ...コメントがいっぱい書いてありますが 略。

#REPOS="$1"
#REV="$2"

#commit-email.pl "$REPOS" "$REV" commit-watchers@example.org
#log-commit.py --repository "$REPOS" --revision "$REV"

##auto update
/bin/sh /path/to/stg_release.sh -y > /dev/null 2>&1

元から書かれているコミット後実行のサンプルはとりあえずコメントアウトし、自分が必要な処理だけ実行するようにしました。

あとは、同じ要領で、svn updateを除いたシェルバッチを書いてあげて、パスをステージング>本番にすれば、本番反映バッチも完了です。

もうちょっと工夫して、ブラウザ上から本番反映を動くようにすれば、いちいちシェルログインしなくても作業が出来て楽チンですね。

この方法はあくまで、私が便利になると思ってやったことですが、SVNから本番反映までの流れを一本にしておくと、余計なトラブルが防げると思います。