現在、SVNでソースのバージョン管理、Redmineで要望や問題のチケット管理を実施している。
重宝してるのがRedmineのリビジョンとチケットを関連づける機能だ。
SVNのコミットコメントにチケット番号をを付けるとチケットにもコメントの内容が表示される。

subjectの文字化けを修正 refs #1234

Redmine-参照用キーワード(refsなど)無しでリビジョンとチケットを関連づける

とても便利な機能だ。ただし、Redmine側がリポジトリの変更を取り込む必要がある。

Redmine-「リポジトリ」を開くまでSubversion等のリポジトリへのコミットが「活動」に表示されません

現在のサーバーではコミット頻度が少なく、cronで定期的に取得するのは無駄が多いため、SVNのpost-commit Hookを使ってコミットのタイミングでRedmineに通知している。

小技(0.9): コミットと同時にリポジトリの情報を取得する

SVNのpost-commit Hook スクリプトは次のような設定にしている。

#!/bin/sh

# POST-COMMIT HOOK
・
・ 中略
・

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

# mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf

# 以下は実際には改行無しで1行で記述
# コレが時間が掛かる?
/usr/local/bin/ruby -ropen-uri -e 'open("https://www.xxxx.com/redmine/sys/fetch_changesets?key=EQkVbNau618MEbsAh21V")' 

# wgetがインストールされていれば以下のようにしてもよいです
#/usr/bin/wget --no-check-certificate -q -O /dev/null https://www.xxxx.com/redmine/sys/fetch_changesets?key=EQkVbNau618MEbsAh21V&

3年ほどこの設定で運用しているが、とても便利で素晴らしい。

だが、クライアント側でcommit時に遅いのが難点だ。

redmine svn commit slow

 

まぁ仕方ないと思っていたがコミットが億劫になりバージョン管理すべきソースをcommitし忘れることが多くなった;;
SVNのpost-commitからRedmineへの通知、なにか速くなる方法が無いか調べてみると、2つ速くなりそうな方法があった。

1.Redmine通知時にプロジェクトを限定する。

/redmine/sys/fetch_changesetsのAPIキーは1つのようだが、Redmineは通知すると全プロジェクトの変更検知するのだろうか?
と思っていたら、記載があった。
fetch_changesetsにidパラメータを指定し、プロジェクト識別子を指定できるようだ。指定しないとすべてのActiveプロジェクトが対象となるようだ。

http://redmine.example.com/sys/fetch_changesets?key= (=> fetches changesets for all active projects)
http://redmine.example.com/sys/fetch_changesets?key=&id=foo (=> fetches changesets for project foo only)

スクリプト版でもプロジェクトを絞れるようだ。(未確認)

redmine/script/runner "Project.find('..projname..').repository.fetch_changesets" -e production

Attaching an existing repository to a project

Is there a way to restrict the fetch changeset process to a specific project? (from within a subversion hook)

 

2.post-commit HookでのRedmine通知方法をBackgroundにする。

post-commitスクリプトで呼び出す場合に「&」つけてバックグラウンド実行すると良いらしい。

Speedup svn post-commit hook for redmine or chiliproject

Frequently Asked Questions

Repositories Commits don't show up in the activity until I click on 'Repository' By default, Redmine fetches the new commits from the repository only when you browse it.

If you want the commits to be retrieved periodically by Redmine in the background for all your repositories, uncheck 'Autofetch commits' setting and add a cron that runs (with appropriate environment):

rake -f /path/to/redmine/Rakefile RAILS_ENV=production redmine:fetch_changesets For SVN repositories you can also add the following command to a post-commit hook:

ruby /path_to_redmine/redmine/script/runner "Repository.fetch_changesets" -e production *Note, the second method of post-commit hook will slow down commits and could possibly cause commits to fail if Redmine is not functioning.

You can bypass these disadvantages by sending the ruby-command to background.

ruby /path_to_redmine/redmine/script/runner "Repository.fetch_changesets" -e production > /dev/null 2>&1 &

 

結局、post-commitスクリプトを次のよう変更したところ、SVNのcommmitがとても速くなった!Redmine通知方法をBackgroundにしたのがとても効いているのだろう。

・「id=プロジェクト識別子」 を指定
・「 > /dev/null 2>&1 & 」でfetch_changesets への通知をバックグランドへ

 

#!/bin/sh

# POST-COMMIT HOOK
・
・ 中略
・

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

# mailer.py commit "$REPOS" "$REV" /path/to/mailer.conf

# 以下は実際には改行無しで1行で記述
#/usr/local/bin/ruby -ropen-uri -e 'open("https://www.xxxx.com/redmine/sys/fetch_changesets?key=EQkVbNau618MEbsAh21V")' 
/usr/local/bin/ruby -ropen-uri -e 'open("https://www.xxxx.com/redmine/sys/fetch_changesets?id=prj1037838446&key=EQkVbNau618MEbsAh21V")'  > /dev/null 2>&1 &

# wgetがインストールされていれば以下のようにしてもよいです
#/usr/bin/wget --no-check-certificate -q -O /dev/null https://www.xxxx.com/redmine/sys/fetch_changesets?key=EQkVbNau618MEbsAh21V&

 

今のところうまくいっているようなので、これで運用してみよう。