Goodbye Trac, Hello Redmine!
TracLightning3.1.1 ãã Redmine 1.3.0 ã¸å¼ã£è¶ããæã®ã¡ã¢ã§ãã
Redmineã使ããããã©ãä»ã¾ã§ã®Tracã®ãã¼ã¿ãããããªããã¨ããããã®åèã«ãªãã°å¹¸ãã§ãã
年度æ«ã®ãµã¼ãã¹ã¤ã³ãæ§ãããå¿ãããã®ææã«ä½ã§ãããªãã¨ããã£ãã®ãï¼ ã®çç±ã¯âこちら
ç®æ¬¡
- Redmine ã»ããã¢ããã»è¿½å ãã©ã°ã¤ã³ãªã©
- SVNãªãã¸ããªä½æãè¨å®ãªã©
- ãã¼ã¿ç§»è¡äºå
- ãã¼ã¿ç§»è¡å½æ¥
- ãã¼ã¿ç§»è¡äºå¾
Redmineæ¬ä½ã¤ã³ã¹ãã¼ã«ã»è¿½å ãã©ã°ã¤ã³ãªã©
Redmineæ¬ä½
bitnami-redmine-*.*.*-*-windows-installerãbitnamiå ¬å¼ãµã¤ãããå ¥æãã¤ã³ã¹ãã¼ã«ãã¾ãããç¹ã«æ³¨æãè¦ãããã¨ããªãããããªãã¤ã³ã¹ãã¼ã«ã§ãã¾ããã
ä»åã¯Windows Servernã«ã¤ã³ã¹ãã¼ã«ããã®ã§ãWindows ãã¡ã¤ã¢ã¦ã©ã¼ã«ã«ã¦ä¸è¨ããã°ã©ã ã®æ¥ç¶ã許å¯ãã¾ããã
ã©ã¤ãã©ãª FasterCSV
å¥ã§ãããredmine_importerã§ä½¿ãã©ã¤ãã©ãªã ãããã¤ã³ã¹ãã¼ã«ã§ãã¦ããããªãã§ãã¦ãªããããªãã¡ãã£ã¨ä¸å®ãªæãã§ãã
- ã¢ã¸ã¥ã¼ã«åå¾ (ä»å㯠fastercsv-1.5.1.gem ããã§ã¤ã¹ï¼
- ãã©ã«ããä½ã£ã¦
- ã¤ã³ã¹ãã¼ã«
- gem install fastercsv-1.5.1.gem --local
redmine_importer
CSVå½¢å¼ã®ãã±ãããã¼ã¿ãåãè¾¼ã¿ã¾ããTracã®ãã±ãããã¼ã¿ã移è¡ããæã«ä½¿ãã¾ããã
ãã±ããã大éç»é²ããæã«ã使ãããã§ããï¼ä½åº¦ã試ãã¾ããããæ´æ°ã¯ä¸æãããã¾ããã§ãã・・・ ^^;;)
ã¤ã³ã¹ãã¼ã«ã¯こちらãåèã«ããã¦ããã ãã¾ãã
- ã¢ã¸ã¥ã¼ã«åå¾
- 解åãã¦ã§ãããã£ã¬ã¯ããªãC:\Program Files\BitNami Redmine Stack\apps\redmine\vendor\pluginsã«ã³ãã¼
- "redmine_importer"ã«ãªãã¼ã
- ã¤ã³ã¹ãã¼ã«
- Redmineåèµ·å
ãã¼ãã³ã°ããããã£ã¼ã
- ã¢ã¸ã¥ã¼ã«åå¾
- 解åãã¦ã§ãããã£ã¬ã¯ããªããC:\Program Files\BitNami Redmine Stack\apps\redmine\vendor\plugins
- "parking_lot_chart"ã«ãªãã¼ã
- Redmineãåèµ·å
WorkTimeãã©ã°ã¤ã³
ããããã§ãï¼æä¼ã®æ¨æ¥å®ç¸¾å ±åã§ä½¿ã£ã¦ã¾ãã
- ã¢ã¸ã¥ã¼ã«åå¾
- ã¤ã³ã¹ãã¼ã«
SVNãªãã¸ããªä½æãè¨å®ãªã©
BitNami Redmine Stack ã«ã¯æåãã Subversion ãä»ãã¦ããã®ã§ãã¤ã³ã¹ãã¼ã«ã¯ä¸è¦ã§ã
(1) ãªãã¸ããªã®ä½æ
C:\Program Files\BitNami Redmine Stack\use_redmine.bat
svnadmin create C:\repos\dev
(2) ã·ã¹ãã ç°å¢å¤æ°ã®Pathç»é²
C:\Program Files\BitNami Redmine Stack\subversion\bin
(3) ã¢ã¸ã¥ã¼ã«ã³ãã¼
C:\Program Files\BitNami Redmine Stack\subversion\binã®ä»¥ä¸2ã¤ã ã\apache2\modules ã¸ã³ãã¼
(4) ã¢ã¸ã¥ã¼ã«æå¹å
ï¼ httpd.confããµã¼ãã®ãAdministratorãã¦ã¼ã¶ãããªãã¨ç·¨éã§ãã¾ããã§ããã
- ã³ã¡ã³ãIN
- 追è¨
(5) ãã±ã¼ã·ã§ã³å®ç¾©ã追å
ï¼ httpd.confãåããã¦ActiveDirectoryã®ç¹å®ã®ã°ã«ã¼ãã®ã¦ã¼ã¶ã¼ã«ã®ã¿ã¢ã¯ã»ã¹ã許å¯
- SVNPath: ãªãã¸ããªã¸ã®ãã«ãã¹ãã»ãã
- Require ldap-group: ActiveDirectoryã®ç¹å®ã®ã°ã«ã¼ãã®ã¦ã¼ã¶ã¼ã«ã®ã¿ã¢ã¯ã»ã¹ã許å¯
- AuthzSVNAccessFile : ã¢ã¯ã»ã¹å¶å¾¡ã®å®ç¾©ãè¡ããã¡ã¤ã«ãæå®ãã¾ãã
ãµã³ãã«ã§ã
DAV svn SVNPath C:/repos/dev AuthType Basic AuthBasicProvider ldap AuthName "SVN Repo Authentication(dev)" AuthzLDAPAuthoritative off AuthLDAPURL "é©å®" AuthLDAPBindDN é©å® AuthLDAPBindPassword é©å® AuthLDAPGroupAttribute member AuthLDAPGroupAttributeIsDN on Require ldap-group é©å® Require valid-user AuthzSVNAccessFile C:/repos/AuthzSVNAccess_dev.conf
â AuthzSVNAccess_dev.confãµã³ãã«ãâ»åèãµã¤ãã¯こちら
[groups] devmembers = yamakai,yamamoto [/] * = r [/trunk] hoge = rw @devmembers = rw
(6) ç°å¢å¤æ°ã®å¤æ´ãåæ ãããããã«Windowsãåèµ·å
(7) 確èª
"http://localhost/dev/"ã§ãã©ã¦ã¶ãããªãã¸ã§ã³0ãè¦ãããã¨ã確èªãã
ãã¼ã¿ç§»è¡ äºå
こちらã§è©³ç´°ãæ¸ãã¾ããããéçºãã¼ã ã¨ã¯å¥ã«å°å ¥æ¡ä»¶ã®SVNãªãã¸ããªãä½ãã¾ããã
- æ¡ä»¶æ¯ã®ç©ºSVNãªãã¸ããªäºåä½æ (trunk, branches, tags)
- æ¡ä»¶æ¯ãªãã¸ã㪠SVN権éè¨å® (Apache > httpd.conf)
- æ¡ä»¶æ¯ã®trunkãåæ¡ä»¶ã®ã¡ã³ãã¼ã®PCã«ãã§ãã¯ã¢ã¦ããã¦ããã¦ããã(移è¡å¾ã¯ãã¡ãã«ãã¼ã¿ãå ¥ã£ã¦ãã)
- ä½æ¥éå§åããã¯ã¢ãã
ãã¼ã¿ç§»è¡ å½æ¥
(1) SVNãªãã¸ããªãã¼ã¿
- @æ§ãµã¼ããã¾ãä»ã®ãªãã¸ããªããã³ãã
- svnadmin dump /path/to/svn/repos > repos.dump
- ãã³ããããã®ãæ°ãµã¼ãã¸ãã£ã¦ãã
- ï¼ æ°ãµã¼ããã¾ããªãã¸ããªãä½æãã¦ãæ§ãµã¼ããããã£ã¦ãããã³ããæµãè¾¼ãã ãã
(2) éå»ãã±ãã
- csvã¤ã³ãã¼ããã©ã°ã¤ã³ã使ãã¾ãããTracããã¨ã¯ã¹ãã¼ããããã±ãããã¼ã¿ãRedmineç¨ã«æ´å½¢ããæã®ãã¤ã³ãã¯ä»¥ä¸ã®ã¨ãã
- æ¥ä»ãã©ã¼ããã㯠yyyy-mm-dd
- ã¦ã¼ã¶åãè¨å®ããã¨ããã¯ãååã§ãªãã¦Redmineä¸ã®ã¦ã¼ã¶IDã使ã
- ãã±ããã¹ãã¼ã¿ã¹æè¨ãå¤æ´ãclosed â çµäºãnew â æ°è¦ ãªã©
- æ¹è¡ã³ã¼ããLFã§åæåãæ··ããã¾ããã§ãæä¸ãç¶æ ã ã£ãã®ã§ãæ¹è¡ã³ã¼ããåé¤ãã¾ããã
- æ·»ä»ãã±ããã«ã¤ãã¦ã¯ãã±ãã移è¡å®äºå¾ã«ãåå¥ã§è²¼ãä»ã
Tracãããã±ãããã¼ã¿ãã¨ã¯ã¹ãã¼ãããã¨ãã«ä½¿ã£ãã¯ã¨ãªã®ãµã³ãã«
SELECT p.value AS __color__, (CASE status WHEN 'closed' THEN 'color: #777; background: #ddd; border-color: #ccc;' ELSE (CASE owner WHEN '$USER' THEN 'font-weight: bold' END) END) AS __style__, id AS ticket, t.type AS 'tracker', summary AS 'title', status AS 'status', priority AS 'priority', owner AS 'æ å½è ', c6.value AS 'éå§æ¥', c7.value AS 'ææ¥', description AS '_description', milestone AS '対象ãã¼ã¸ã§ã³', reporter AS 'ç»é²è ', time AS 'ç»é²æ¥ä»', c10.value AS 'Rev', keywords AS 'Keywords', c1.value AS 'æ¤åºæ¥', c5.value AS 'æ¤åºå±é¢', c4.value AS 'å®äºæ¥', c3.value AS '確èªè ', c2.value AS '確èªæ¥', c11.value AS 'TestCases', c12.value AS 'TroubleReason', resolution FROM ticket t LEFT OUTER JOIN enum p ON p.name = t.priority AND p.type='priority' --ä¿®æ£ãªãã¸ã§ã³âRev LEFT OUTER JOIN ticket_custom c10 ON (t.id = c10.ticket AND c10.name = 'rev') --ãã¹ãã±ã¼ã¹NoâTestCases LEFT OUTER JOIN ticket_custom c11 ON (t.id = c11.ticket AND c11.name = 'testcase_id') --éå§äºå®æ¥âéå§æ¥ LEFT OUTER JOIN ticket_custom c6 ON (t.id = c6.ticket AND c6.name = 'due_assign') --å®äºäºå®æ¥âææ¥ LEFT OUTER JOIN ticket_custom c7 ON (t.id = c7.ticket AND c7.name = 'due_close') --é害åå åé¡âTroubleReason LEFT OUTER JOIN ticket_custom c12 ON (t.id = c12.ticket AND c12.name = 'trouble_reason') --æ¤åºæ¥ LEFT OUTER JOIN ticket_custom c1 ON (t.id = c1.ticket AND c1.name = 'detected_date') --æ¤åºå±é¢ LEFT OUTER JOIN ticket_custom c5 ON (t.id = c5.ticket AND c5.name = 'detection_phaset') --å®äºæ¥ LEFT OUTER JOIN ticket_custom c4 ON (t.id = c4.ticket AND c4.name = 'complete') --確èªè LEFT OUTER JOIN ticket_custom c3 ON (t.id = c3.ticket AND c3.name = 'close_checker') --確èªæ¥ LEFT OUTER JOIN ticket_custom c2 ON (t.id = c2.ticket AND c2.name = 'close_check_date') ORDER BY t.id
Tracãããã±ããã®ã³ã¡ã³ãå±¥æ´ãã¨ã¯ã¹ãã¼ãããã¨ãã«ä½¿ã£ãã¯ã¨ãªã®ãµã³ãã«
select ticket, newvalue from ticket_change c where field = 'comment' and newvalue not like '' order by ticket, time
Tracããæããããã¼ã¿ãExcelã®ãã¯ãã使ã£ã¦Redmineç¨ã«æ´å½¢ããåºåãã¾ããé
ç®å¤å¤æã¯lookupé¢æ°ããå§ãã§ãã
Option Explicit Sub WRITE_REDMINE_TICKET() Const cnsTITLE = "åºåå¦ç" Const cnsFILTER = "ããã¹ããã¡ã¤ã« (*.csv;*.*),*.csv;*.*" Dim xlAPP As Application ' Applicationãªãã¸ã§ã¯ã Dim intFF As Integer ' FreeFileå¤ Dim strFILENAME As String ' OPENãããã¡ã¤ã«å(ãã«ãã¹) Dim strREC As String ' æ¸ãåºãã¬ã³ã¼ãå 容 Dim GYO As Long ' å容ããã»ã«ã®è¡ Dim GYOMAX As Long ' ãã¼ã¿ãå容ãããæçµè¡ Dim lngREC As Long ' ã¬ã³ã¼ã件æ°ã«ã¦ã³ã¿ ' Applicationãªãã¸ã§ã¯ãåå¾ Set xlAPP = Application ' ãååãä»ãã¦ä¿åãã®ãã©ã¼ã ã§ãã¡ã¤ã«åã®æå®ãåãã xlAPP.StatusBar = "åºåãããã¡ã¤ã«åãæå®ãã¦ä¸ããã" strFILENAME = xlAPP.GetSaveAsFilename(InitialFileName:="IKOU_TICKETS.csv", _ FileFilter:=cnsFILTER, Title:=cnsTITLE) ' ãã£ã³ã»ã«ãããå ´åã¯ä»¥éã®å¦çã¯è¡ãªããªã If StrConv(strFILENAME, vbUpperCase) = "FALSE" Then Exit Sub ' å容æçµè¡ã®å¤å®(Excelèªç¥ã®æçµè¡ããä¸ã«åãã£ã¦ãã¼ã¿ãããè¡ãæ¢ã) GYOMAX = Cells.SpecialCells(xlCellTypeLastCell).Row Do While Cells(GYOMAX, 1).Value = "0" GYOMAX = GYOMAX - 1 Loop If GYOMAX < 2 Then xlAPP.StatusBar = False MsgBox "ãã¼ã¿ã2è¡ç®ããå ¥åãã¦ããèµ·åãã¦ä¸ããã", , cnsTITLE Exit Sub End If ' FreeFileå¤ã®åå¾(以éãã®å¤ã§å ¥åºåãã) intFF = FreeFile ' æå®ãã¡ã¤ã«ãOPEN(åºåã¢ã¼ã) Open strFILENAME For Output As #intFF ' 1è¡ç®ããéå§ GYO = 1 ' æçµè¡ã¾ã§ç¹°ãè¿ã Do Until GYO > GYOMAX ' Nåå 容ãã¬ã³ã¼ãã«ã»ãã(å é ã¯3è¡ç®) strREC = Cells(GYO, 1).Value & "," & _ Cells(GYO, 2).Value & "," & _ """" & Cells(GYO, 3).Value & """" & "," & _ Cells(GYO, 4).Value & "," & _ Cells(GYO, 5).Value & "," & _ Cells(GYO, 6).Value & "," & _ Replace(Cells(GYO, 7).Value, "/", "-") & "," & _ Replace(Cells(GYO, 8).Value, "/", "-") & "," & _ """" & Cells(GYO, 9).Value & """" & "," & _ Cells(GYO, 10).Value & "," & _ Cells(GYO, 11).Value & "," & _ Cells(GYO, 12).Value & "," & _ """" & Cells(GYO, 13).Value & """" & "," & _ """" & Cells(GYO, 14).Value & """" & "," & _ Replace(Cells(GYO, 15).Value, "/", "-") & "," & _ Cells(GYO, 16).Value & "," & _ Replace(Cells(GYO, 17).Value, "/", "-") & "," & _ Cells(GYO, 18).Value & "," & _ Replace(Cells(GYO, 19).Value, "/", "-") & "," & _ """" & Cells(GYO, 20).Value & """" & "," & _ """" & Cells(GYO, 21).Value & """" ' æ¹è¡ãã¯ãªã¢ã㦠strREC = Replace(strREC, vbLf, "") strREC = Replace(strREC, vbCr, "") ' Redmineç¨ã« LFã§æ¹è¡ strREC = strREC & vbLf If strREC <> "" Then ' ã¬ã³ã¼ã件æ°ã«ã¦ã³ã¿ã®å ç® lngREC = lngREC + 1 ' ã¬ã³ã¼ããåºåãã»ãã³ãã³ã§CRLFã®æ¹è¡ææ¢ Print #intFF, strREC; End If 'è¡ãå ç® GYO = GYO + 1 Loop ' æå®ãã¡ã¤ã«ãCLOSE Close #intFF xlAPP.StatusBar = False MsgBox "ãã¡ã¤ã«åºåãå®äºãã¾ããã" & vbCr & "ã¬ã³ã¼ã件æ°=" & lngREC & "件", vbInformation, cnsTITLE End Sub