RedmineとSubversionの連携を強制的に行う
Redmineの機能の1つとしてSubversionとの連携があります。リポジトリコミット時にチケット番号を入れることでコミットとチケットを1対1で関連付けられてとても便利です。
しかし、Redmineは(おそらく)チームで使うものです。自分は正しく入力していても他のメンバーが入力を怠っていたらせっかくの機能が無駄になってしまいます。
なんとか入力を習慣づけてもらうために策を講じました。普通は運用ルールを作って守ってもらうのがよいと思いますが、そうは言ってもこちらが意図したとおりの操作を行ってくれるのは少ないものです。
ぼくはこういうのでとてもイライラしてしまう性質なので、コンピュータ側で入力を強制してもらうようにしています。(この場合、周りのメンバーとよく話をしろ、というのは別の話にしてください)
コミットメッセージにチケット番号が入っているかチェックする
単純にコミットメッセージをチェックするシンプルな方法です。
Redmineはコミットメッセージから"refs xxx"などのキーワードを読み取って関連付けするので、Subversionのフック機構を使ってメッセージをチェックします。
こんなスクリプトです。
※c:\Program FilesにVisualSVN Serverをインストール(リポジトリはc:\Repositories)している前提です。ご自分の環境に適宜読み替えてください。
pre-commit.bat
@echo off set APR_ICONV_PATH=C:\Program Files\Subversion\iconv cd C:\Repositories\hook_scripts CScript //Nologo C:\Repositories\hook_scripts\commit_block.vbs %1 %2
c:\Respositories\hook_scripts\commit_block.vbs
set objArgs = WScript.Arguments strRepoPath = objArgs(0) 'リポジトリパス strTransaction = objArgs(1) 'トランザクション Dim strMessage Set objShell = WScript.CreateObject("WScript.Shell") ' ログメッセージの取得 Set objExec = objShell.Exec("c:\Program Files\VisualSVN Server\bin\svnlook.exe log " + strRepoPath + " -t " + strTransaction) strMessage = objExec.StdOut.ReadLine Dim objRE Set objRE = new RegExp objRE.pattern = ".+ refs ([0-9]+)" If objRE.Test(strMessage) = False Then WScript.StdErr.WriteLine("エラー:" & strMessage) WScript.StdErr.WriteLine("ログメッセージの1行目にrefsキーワードが入っていません。チケット番号と共に追記をお願いします。") WScript.StdErr.WriteLine("チケット番号が存在しない場合は新しくチケットを発行してからコミットしてください。") WScript.StdErr.WriteLine("わからないことは…、わかりそうな人に確認してください。") WScript.Quit(1) End If
これでコメントに"refs xxx"を入力しないとコミットできなくなります。これだけでもそれなりに効果がありますが、これだけだと、適当に番号さえ入れればコミットできてしまうので、効果は限定的です。
コミット時にチケット番号が正しいかをRedmineに問い合わせる
もう少しスマートにRedmineにチケット番号を問い合わせてみましょう。今度はRedmine側の修正も必要です。
※もしもRedmineの修正がなくても大丈夫そうなら教えてください!
まずは先ほどのcommit_block.vbsに下記を追加します。
Set matchs = objRE.Execute(strMessage) Set sc = CreateObject("ScriptControl") sc.Language = "JScript" Set js = sc.CodeObject On Error Resume Next issues_id = matchs(0).SubMatches(0) Set http = CreateObject("MSXML2.ServerXMLHTTP") url = "http://[サーバ]/issues/" & issues_id & "/confirm_repository_path?path=/" & js.encodeURI(strDirsChanged) http.open "GET", url, False http.send result = http.responseText Set http = Nothing WScript.StdErr.WriteLine(result) If result <> "true" Then WScript.StdErr.WriteLine("チケットが所属するプロジェクトのリポジトリの設定が正しくありません。") WScript.StdErr.WriteLine("コミット対象のフォルダとRedmineのプロジェクトの設定を見直してください。") WScript.StdErr.WriteLine("チケット番号:" & issues_id) WScript.StdErr.WriteLine("リポジトリパス:" & strDirsChanged) WScript.Quit(1) End If If Err.Number <> 0 Then WScript.StdErr.WriteLine(Err.Description) WScript.StdErr.WriteLine(Err.Source) WScript.Quit(1) End If
ここからはRedmine側を修正します。まずはクライアントからの問い合わせを受けるアクション用のルートを作ってあげます。
config\route.rbの125行目くらいに追加
issues_views.connect 'issues/:id/confirm_repository_path', :action => 'confirm_repository_path', :id => /\d+/
app\controllers\issues_controller
before_filter :find_issueとbefore_filter :authorizeに:confirm_repository_pathを追加
confirm_repository_pathアクションを作成
before_filter :find_issue, :only => [:show, :edit, :reply, :confirm_repository_path] before_filter :authorize, :except => [:index, :changes, :gantt, :calendar, :preview, :update_form, :context_menu, :confirm_repository_path] def confirm_repository_path repo = @project.repository if repo and params[:path] repo_path = repo.url[repo.root_url.length .. -1] repo_path = URI.decode(repo_path) result = params[:path].include?(repo_path) else result = false end render :text => result end
これでぼくの環境ではコミット時にチケットが所属するプロジェクトのリポジトリ設定が正しくないとコミットできないようになりました。
興味があったら試してみてください。