Subversionのフック・スクリプトでコミット前にRedmineのチケットを確認
RedmineのチケットとSubversionのリビジョンの連携を徹底するために、コミット時にチケット番号の指定を強制するようにした。
Subversionのフックとは?*1
- 特定のタイミングで特定の外部プログラムを実行することであり、そのプログラムはフック・スクリプトと言われる。
- 外部プログラムを実行する条件は次の通り。
- 実行可能なファイル(コミット関連)
- start-commit ファイル
- pre-commit ファイル
- post-commit ファイル
- コミットされ、新しいリビジョンが作られた後に実行。
- 第一引数 : リポジトリへのパス
- 第二引数 : 今回作られたリビジョン番号
- 終了コードは無視される。
コミットに制約を設ける
制約内容:
- 参照用(refs)のチケット番号が指定されていて、そのチケットがRedmimeに存在すること。
- 完了用(fixes)のチケット番号が指定されていた場合は、そのチケットがRedmineに存在して、かつ、完了していないこと。
- pre-commitの内容
#!/bin/sh REPOS="$1" TXN="$2" # Make sure that the log message contains some text. SVNLOOK=/usr/bin/svnlook #$SVNLOOK log -t "$TXN" "$REPOS" | \ # grep "[a-zA-Z0-9]" > /dev/null || exit 1 #参照用のチケット番号の確認 $SVNLOOK log -t "$TXN" "$REPOS" | \ grep -i -E "refs[ ]*[#]*[0-9]+" > /dev/null || \ { echo "No refs ticket number.(refs #)" 1>&2 && exit 1; } #チケット進捗状態確認の関数 getTicketRatio() { mysql -s -u root redmine <<__REDMINE__ select issue_statuses.default_done_ratio from issues , issue_statuses where issues.id = ${1} and issues.status_id = issue_statuses.id ; __REDMINE__ } #参照用のチケット番号の取り出し TICKET_NO=`$SVNLOOK log -t "$TXN" "$REPOS" | sed -e "s/.*refs[ ]\+[#]*\([0-9]\+\).*/\1/i" | grep -i -E "^[0-9]+$"` if [ "NULL" == ${TICKET_NO:-NULL} ]; then echo "No refs ticket number.(refs #)" 1>&2 exit 1 else #チケット進捗状態確認 TICKET_RATIO=`getTicketRatio ${TICKET_NO}` #進捗状態が確認できない場合はコミット不可 if [ "NULL" == ${TICKET_RATIO:-NULL} ]; then echo "Ticket #${TICKET_NO} is nothing." 1>&2 exit 1 fi fi #完了用のチケット番号の取り出し TICKET_NO=`$SVNLOOK log -t "$TXN" "$REPOS" | sed -e "s/.*fixes[ ]\+[#]*\([0-9]\+\).*/\1/i" | grep -i -E "^[0-9]+$"` if [ "NULL" != ${TICKET_NO:-NULL} ]; then #チケット進捗状態確認 TICKET_RATIO=`getTicketRatio ${TICKET_NO}` #100%の時はコミット不可 if [ "NULL" == ${TICKET_RATIO:-NULL} ]; then echo "Ticket #${TICKET_NO} is nothing." 1>&2 exit 1 elif [ 100 -eq ${TICKET_RATIO} ]; then echo "Ticket #${TICKET_NO} is complite." 1>&2 exit 1 fi fi # Check that the author of this commit has the rights to perform # the commit on the files and directories being modified. #commit-access-control.pl "$REPOS" "$TXN" commit-access-control.cfg || exit 1 # All checks passed, so allow the commit. exit 0
テスト
先ずはサンプルのリポジトリを作成
- FSFSでリポジトリ作成
cd /home/svnrepos svnadmin create --fs-type fsfs test chown -R apache:apache test
- モジュール登録
cd /home/test svn import -m 'Import project' test http://localhost/svn/test
ローカルPCでテスト
- ローカルPCに作業コピー
cd ~ svn co http://svnServer/svn/test/trunk test
- Redmineでチケット作成
- ローカルPCでファイルを追加
cd ~/test >test.html svn add test.html
- ローカルPCでコミット
- コミットログなしのパターン
cd ~/test svn commit --- 結果 --- 追加しています test.html ファイルのデータを送信しています .svn: コミットに失敗しました (詳しい理由は以下のとおりです): svn: 'pre-commit' hook failed with error output: No refs ticket number.(refs #)
-
- 参照用チケット番号指定なしのパターン
cd ~/test svn commit -m "ファイル追加 refs" --- 結果 --- 追加しています test.html ファイルのデータを送信しています .svn: コミットに失敗しました (詳しい理由は以下のとおりです): svn: 'pre-commit' hook failed with error output: No refs ticket number.(refs #)
-
- 参照用チケット番号が存在しないのパターン
cd ~/test svn commit -m "ファイル追加 refs 9999" --- 結果 --- 追加しています test.html ファイルのデータを送信しています .svn: コミットに失敗しました (詳しい理由は以下のとおりです): svn: 'pre-commit' hook failed with error output: Ticket #9999 is nothing.
-
- 完了用チケット番号が存在しないのパターン
cd ~/test svn commit -m "ファイル追加 refs 1 fixes 9999" --- 結果 --- 追加しています test.html ファイルのデータを送信しています .svn: コミットに失敗しました (詳しい理由は以下のとおりです): svn: 'pre-commit' hook failed with error output: Ticket #9999 is nothing.
-
- 完了用チケット番号が完了しているパターン
cd ~/test svn commit -m "ファイル追加 refs 1 fixes 12" --- 結果 --- 追加しています test.html ファイルのデータを送信しています .svn: コミットに失敗しました (詳しい理由は以下のとおりです): svn: 'pre-commit' hook failed with error output: Ticket #12 is complite.
-
- OKのパターン
cd ~/test svn commit -m "ファイル追加 refs 1 fixes 1" --- 結果 --- 追加しています test.html ファイルのデータを送信しています . リビジョン ? をコミットしました。