2010年6月30日 星期三

寄送 subversion repository 的更新通知

subversion 提供了一個很方便的 hook 功能,可以為對 repository 進行的動作設定相關的動作。詳細的作法請見 svnbook 第 5 章的 Hook Scripts 一節。這裡簡單筆記一下如何用 svn hook 作 repository 的 email 更新通知。



在 subversion repository 目錄裡面有 conf, dav, db, hooks, locks 等目錄。其中 hooks 目錄就是用來存放 hooks 的地方。總共有 5 種 hook:

start-commit: 在 commit 開始之前執行,常用來檢查使用者是否有權執行動作。
pre-commit: 在 transaction 完成而未真正 commit 之前執行,常用來檢查 commit 動作的有效性。可以在這個地方對 commit 時的 log 訊息進行要求。
post-commit: 在 transaction 完成而 commit 結束,建立了新的 revision 之後執行,常用來寄送 e-mail 通知訊息。
pre-revprop-change: subversion 的 revision property 並不會存入 repository,這個 hook 可以在 revision property 變更之前作一些處理,譬如把更新的資訊存到外部的紀錄檔裡面。
post-revprop-change: 用途與 pre-revprop-change 類似,但會在 revision property 變更之後執行。
看起來 hook 在 post-commit 上面最為合適。subversion 提供了 Perl 與 Python 的 email 寄送程式 commit-email.pl 與 mailer.py 。經我測試, commit-email.pl 在寄 email 的時候沒辦法正確處理 non-ascii log message,但 mailer.py 可以寄送 utf8 log message。此外, commit-email.pl 只接受命令列參數,但 mailer.py 則可以用設定檔進行比較多的組態。

Debian 把 subversion 提供的一些補充工具 (像 commit-email.pl 和 mailer.py) 包在 subversion-tools 裡面,請記得安裝。

首先要把 post-commit 打開,假設 $repo 是 repository 所在的目錄,那麼要先建立 $repo/hooks/post-commit 。該目錄下預設就有一個模板檔:

$ cd $repo/hooks
$ cp post-commit.tmpl post-commit
$ chmod a+x post-commit
這是一個 shell script。它不必然要是 shell script,只要是可執行檔即可 (可以用 Perl, Python 或 C 來寫)。原本它使用 commit-email.pl ,我們來把它改成 mailer.py :

#!/bin/sh
REPOS="$1"
REV="$2"
/usr/lib/subversion/hook-scripts/mailer/mailer.py commit $REPOS $REV
mailer.py 要有三個參數,第一個參數是 commit 與 propchange 兩者之一,指定用於 *-commit 或 *prop-change 時的 email 寄送。不過僅是這樣還不能運作,我們得在 $repo/conf 裡放好組態檔 mailer.conf 才行:

cp /usr/lib/subversion/hook-scripts/mailer/mailer.conf.example $repo/conf/mailer.conf
Note

直接執行 /usr/lib/subversion/hook-scripts/mailer/mailer.py 不給參數,就會秀出參數的說明。
我們必須設定組態檔裡 [general] 區塊裡的 mail_command 及 smtp_hostname (一般使用預設值即可),以及 [defaults] 區塊裡的 to_addr 。 to_addr 就是 email 要通知的地址,可以設很多個,其間用空白分隔。

[defaults] 區塊裡還有

commit_subject_prefix 可以用來設定 commit 時 email Subject: 的前飾詞
propchange_subject_prefix 設定 revision property 改變時的 email Subject: 前飾詞
範例:

[general]
diff = /usr/bin/diff -u -L %(label_from)s -L %(label_to)s %(from)s %(to)s
mail_command = /usr/sbin/sendmail
smtp_hostname = localhost
[defaults]
commit_subject_prefix = [repocommit]
propchange_subject_prefix = [repopropchange]
from_addr =
to_addr = my@email.address
reply_to =
generate_diffs = add copy modify
suppress_deletes = yes
如果不指定 from_addr 的話,From: 就會填入 committer 的使用者名稱。

摘自:http://blog.seety.org/everydaywork/2005/7/13/378/

沒有留言:

wibiya widget