æ瀺ãããäŸã¯ã次ã®ããã«ãå¹ åºãèŠèŽè ã«ãšã£ãŠèå³æ·±ããã®ã§ã ä»ã®ãã©ãããã©ãŒã ã®éçºã«ç°¡åã«é©åãããããšãã§ããŸãã
ãšã³ããªãŒ
ãã®èšäºã¯ãå ã®èšäºã®ããã§ãªããã°æžãããããšã¯ãªãã£ãã§ããããå ã®èšäºã¯ããã€ãŠã¯éçºããã»ã¹ã«å¯Ÿããç§ã®ç解ã圢æããäžã§éèŠãªåœ¹å²ãæãããŸããã ãããŠã圌ããèšãããã«ããç§ã¯ãã®æ©äŒãå©çšããããã Eugeneã®çŽ æŽãããèšäºã«æè¬ããããšæããŸããããã¯åå¿è ã«ãšã£ãŠçŽ æŽãããã¹ã¿ãŒãã§ãïŒ ã©ããããããšãïŒãã®èšäºã¯ãæŠããŠãæ ¹æ¬çã«æ°ãããã®ã§ã¯ãããŸããã åãCïŒãããžã§ã¯ããNUnitã§ã®åããã¹ããNAntã§ã®åãèªååã ãããã埮åŠãªéãããããŸãã 第äžã«ãJenkins CIã¯CIãµãŒããŒãšããŠäœ¿çšããã第äºã«ãã¢ã»ã³ããªäžã®ããŸããŸãªãããžã§ã¯ãã¡ããªãã¯ã®åæãšè¡šç€ºã«ããªãã®æ³šæãæãããŸãã
ãã®èšäºã§ã¯ãäœæ¥ç°å¢ãã»ããã¢ãããããœãŒã¹ã³ãŒãã®å€æŽãèªåçã«è¿œè·¡ãããããžã§ã¯ããã³ã³ãã€ã«ãããŠããããã¹ããšæ©èœãã¹ããå®è¡ããã³ãŒãè¡æ°ãéè€ã®æç¡ãæè¡çè² åµã®ãœãŒã¹ã³ãŒãïŒTODOãFIXMEãªã©ïŒã§ãããžã§ã¯ãã®äžå¿ã¯NAntã¹ã¯ãªããã«ãªããŸããNAntã¹ã¯ãªããã¯ãææãèæ ®ãããã«ã€ããŠå€§ãããªããŸãã ãããžã§ã¯ãã¯ã©ã®æ®µéã§ãæ©èœããå®äºã§ããŸããããã¯ãäžåºŠã«ãããžã§ã¯ãå šäœãäœæã§ããªãå Žåããæ瀺ããããã¹ãŠã®æ©èœãå¿ èŠãšããªãå Žåã«éåžžã«äŸ¿å©ã§ãïŒççŽã«èšã£ãŠãäžéšã®åé¡ã§ã¯åé·ã§ãïŒã
ã¯ãŒã¯ã¹ããŒã¹
ã¯ãŒã¯ã¹ããŒã¹ãæ§æããã«ã¯ã次ã®ãã®ãå¿ èŠã§ããOS | GNU / Linux ïŒ openSUSE 12.1ã LXDE ïŒ | ç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ãµãŒããŒãå±éããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã |
CIS | ãžã§ã³ãã³ã¹CI 1.450 | ç¶ç¶ççµ±åãµãŒããŒã |
Vcs | Subversion 1.6.17 | éäžåããŒãžã§ã³ç®¡çã·ã¹ãã ïŒSubversionã®ä»£ããã«ãä»ã®VCSã䜿çšã§ããŸãïŒ |
CLR | ã¢ãã©ã« 2.6.10 | éçºãå®è¡ããããã©ãããã©ãŒã ã |
ãã¹ãäž | NUnit 2.4.8 | ãã¹ããäœæããã³å®è¡ããããã®ããŒã«ïŒãŠããããéãŠããã-誰ããã¹ããäœæãããã«æ¢ã«äŸåããŠããŸãïŒã |
ã»ã¬ã³RC 2.18.0 | æ©èœãã¹ããå®è¡ããããã®ããŒã«ã | |
éçã³ãŒãåæ | ãžã§ã³ããŒã 2.10.0.0 | éçã³ãŒãã¢ãã©ã€ã¶ãŒã |
ã¯ããŒã³åæè£ çœ® 2005-05-30 | éè€ã³ãŒããèŠã€ããããã®ãŠãŒãã£ãªãã£ã | |
StyleCopCmd 0.2.1 | éçã³ãŒãã¢ãã©ã€ã¶ãŒã | |
ãã®ä»ã®ããŒã« | NAnt 0.90 | ãããžã§ã¯ãã®èªåã¢ã»ã³ããªçšãŠãŒãã£ãªãã£ã |
Firefox 7.0.1 | æ©èœãã¹ããäœæããŠå®è¡ããWebãã©ãŠã¶ãŒïŒãã¹ãã¯ä»ã®ãã©ãŠã¶ãŒã䜿çšããŠå®è¡ããããšãã§ããŸãïŒ | |
Selenium IDE 1.6.0 | æ©èœãã¹ããäœæããããã®IDEã |
1. DVDã€ã¡ãŒãžãããŠã³ããŒãã ãOSãã€ã³ã¹ããŒã«ããŸãïŒãã¹ã¯ãããç°å¢ãéžæãããšãã¯ãLXDEãæå®ããŸãïŒã å³å¯ã«èšãã°ãå¥ã®ãã¹ã¯ãããç°å¢ã䜿çšããããšãããŸã£ãã䜿çšããªãããšãã§ããŸãã ãã®äŸã§ã¯LXDEã䜿çšããŠãã»ããã¢ããããã»ã¹ãããç°¡åã«ããŸãã
2.ãªããžããªãèšå®ããŸãã
3.å¿ èŠãªããã±ãŒãžãã€ã³ã¹ããŒã«ããŸããsudo zypper ar http://download.opensuse.org/repositories/Mono/openSUSE_11.4/ Mono sudo zypper ar http://pkg.jenkins-ci.org/opensuse/ Jenkins
sudo zypper in jenkins mono-complete mono-nunit mono-tools nant subversion-server apache2 http://www.dwheeler.com/sloccount/sloccount-2.26-1.i386.rpm
4. rpmããã±ãŒãžãšããŠæäŸãããŠããªãå¿
èŠãªãŠãŒãã£ãªãã£ïŒStyleCopCmdããã³CloneAnalyzerïŒãããŠã³ããŒãããŠã€ã³ã¹ããŒã«ããŸãã ããã€ãã®ãã¥ã¢ã³ã¹ããããŸãã
ãŸããLinuxã§ããã«äœ¿çšã§ãããã€ããªã䜿çšããããšã¯ã§ããŸããã ã¢ããªã±ãŒã·ã§ã³ã¯å šäœãšããŠæ©èœããŸãããReportBuilder.csãã¡ã€ã«ã®460è¡ç®ã«ããŒããã¹ã§èšå®ããããã¹åºåãèšå·ããããããã¬ããŒããã¡ã€ã«ã¯äºæããå Žæã«ã¯ãããŸããã
private static string GetViolationsFile(string outputXmlFile) { var offp = Path.GetFullPath(outputXmlFile); var f = string.Format( CultureInfo.CurrentCulture, "{0}\\{1}.violations.xml", // String No 460, wrong separator here! Path.GetFullPath(Path.GetDirectoryName(offp)), Path.GetFileNameWithoutExtension(outputXmlFile)); return f; }
ä¿®æ£ãããããŒãžã§ã³ãšæ§æãã¡ã€ã«ã¯ã ããããããŠã³ããŒãã§ããŸã ã
第äºã«ãDRYãã©ã°ã€ã³ã¯CloneAnalyzeãŠãŒãã£ãªãã£ã®ã¬ããŒããèªèããªããããCloneAnalyzeã¬ããŒããæ確ãªJenkins'yã®ããããã«å€æããå¿ èŠããããŸãïŒç§ã¯CPDãéžæããŸããïŒã ã¬ããŒãã®äŸãããã³ãœãŒã¹ã³ãŒãã䜿çšãããã€ããã¢ããã³ã³ããŒã¿ãŒã¯ã ããããå ¥æã§ããŸã ã
è¿œå ã®ãŠãŒãã£ãªãã£çšã®ãã£ã¬ã¯ããªãäœæããŸãã
sudo mkdir -p /var/lib/jenkins/tools/{StyleCop,CloneAnalyzer,SeleniumRC} # 1. SlyleCop StyleCopCmd. # ... # 2. CloneAnalyzer cd /var/lib/jenkins/tools/CloneAnalyzer sudo wget http://sourceforge.net/projects/cloneanalyzer/files/latest/download?source=files sudo unzip CloneAnalyzerPluginInstall_20050530.zip sudo mv eclipse/plugins/CloneAnalyzer . rm -rf eclipse # 3. CloneAnalyzer . # ... # 4. Selenium Remoute Control. cd /var/lib/jenkins/tools/SeleniumRC sudo wget http://selenium.googlecode.com/files/selenium-server-standalone-2.19.0.jar
5. Jenkinsã®ãã©ã°ã€ã³ãã€ã³ã¹ããŒã«ããŸãïŒJenkins-> Manage Jenkins-> Manage Plugins-> AvailableïŒïŒ
å¿ é | |
è»¢èŠ | svnãªããžããªãããœãŒã¹ã³ãŒããååŸããæäœãèªååã§ããŸãïŒããã©ã«ãã§ã€ã³ã¹ããŒã«ãããŸãïŒ |
ãŠããã | NUnitã®çµæã«é¢ããã¬ããŒããäœæã§ããŸãã |
Nnt | Jntkinsãããžã§ã¯ãã®ã¢ã»ã³ããªç®æšãšããŠNAntã¹ã¯ãªãããèšå®ã§ããŸãã |
éçã³ãŒãåæ | DRYãã©ã°ã€ã³ã«å¿ èŠã§ãã |
ã¿ã¹ã¯ã¹ãã£ã㌠| ã³ãŒãã§èŠã€ãã£ãã¿ã°ã«é¢ããã¬ããŒããäœæã§ããŸãïŒTODOãªã©ïŒã |
SLOCCount | ãŠãŒãã£ãªãã£SLOCCountã®çµæã«é¢ããã¬ããŒããäœæã§ããŸãïŒæ§ãããªã³ãŒãã¡ããªãã¯ã衚瀺ããŸãïŒã |
Doclinks | ãããžã§ã¯ãã®ã¡ã€ã³ããŒãžã«ããããžã§ã¯ãã®ããã¥ã¡ã³ããžã®ãªã³ã¯ãé 眮ã§ããŸãã |
éå | ããŸããŸãªãŠãŒãã£ãªãã£ã®çµæã«é¢ããã¬ããŒããäœæã§ããŸãã ãã®äŸã¯ãGendarmeãšStyleCopCmdã®çµæã衚瀺ããããã«äœ¿çšãããŸãã |
ãã©ã€ | èŠã€ãã£ãéè€ã³ãŒãã«é¢ããã¬ããŒããäœæã§ããŸãã |
ã»ã¬ããŠã | Seleniumã¬ããŒããžã®ãªã³ã¯ãæçš¿ããŸãã |
èŠå | ã³ã³ãã€ã©ã®èŠåã衚瀺ããŠã¬ããŒããäœæã§ããŸãã |
æšå¥šïŒ | |
Jobconfighistory | ãããžã§ã¯ãèšå®ãžã®å€æŽã®å±¥æŽãä¿æããŸãã |
ããã¯ã¢ãã | ãµãŒããŒããã¯ã¢ããã®äœæããã»ã¹ãç°¡çŽ åã§ããŸãã |
ãªãã·ã§ã³ã§ïŒ | |
ç·è²ã®ããŒã« | éãããŒã«ãç·ã«çœ®ãæããŸãã |
次ã®ãã«ãçªå· | ä»»æã®ã¢ã»ã³ããªçªå·ãèšå®ã§ããŸãã |
ãµã€ãããŒãªã³ã¯ | ãµãŒããŒã®ã¡ã€ã³ããŒãžãšãããžã§ã¯ãã®ããŒãžã«ãªã³ã¯ãäœæã§ããŸãã |
ãã¢ãããžã§ã¯ãã®èª¬æ
æ®å¿µãªãããç§ã¯åçŽãªãã®ãæãä»ãããšãã§ããŸããã§ããããåæã«äž»é¡é åã®ããžãã¯ã§éè² è·ã«ãªããããããžã§ã¯ãã®ãã¹ãã«äŸ¿å©ã§ãã æ瀺ããããããžã§ã¯ãã¯åçŽã§ã-2ã€ã®å ¥åãã£ãŒã«ãã2ã€ã®ãã¿ã³ïŒãåèšãããã³ãé£çµãïŒããã³çµæãã¢ããªã±ãŒã·ã§ã³ãäœæããããã«ã3ã€ã®ãããžã§ã¯ããå«ããœãªã¥ãŒã·ã§ã³ãäœæãããŸããã
- ExampleCore-ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ããžãã¯ãéäžããŠããïŒããã1ç§éã2ã€ã®ã¡ãœãããŸã§ïŒïŒ
- ExampleGUI-ã¢ããªã±ãŒã·ã§ã³ã€ã³ã¿ãŒãã§ã€ã¹ïŒ1ã€ã§ããããã®ããéèŠãªaspxããŒãžããïŒã
- ExampleUTest-ãã¹ãä»ãã®ãããžã§ã¯ãïŒNUnitïŒã
- ExampleFTest-ãœãªã¥ãŒã·ã§ã³ã«å«ãŸããŠããªãæ©èœãã¹ãïŒSeleniumïŒã®ããExampleFTestãã©ã«ããŒãã«ãŒããã£ã¬ã¯ããªã«ãããŸãã
ã¢ã»ã³ããªã¹ã¯ãªãããäœæããããŒã«ãæ§æãã
ãŸããJenkinsãããžã§ã¯ããäœæããå¿ èŠããããŸããããã¯ãhttpïŒ// localhostïŒ8080ïŒJenkinsãããŒã«ã«ã³ã³ãã¥ãŒã¿ãŒã«ã€ã³ã¹ããŒã«ãããŠããå ŽåïŒã§å©çšå¯èœãªWebã€ã³ã¿ãŒãã§ã€ã¹ããå¿ èŠã§ããNewJobãªã³ã¯ãã¯ãªãã¯ãããããžã§ã¯ãã¿ã€ãBuild a free-ã¹ã¿ã€ã«ãœãããŠã§ã¢ãããžã§ã¯ãããããžã§ã¯ãã®ååãå ¥åããŠäœæããŸãã ãããžã§ã¯ããäœæãããŸããåè¿°ã®ããã«ãã¢ã»ã³ããªãããžã§ã¯ãã®ã³ã¢ã¯NAntã¹ã¯ãªããã«ãªããŸãããã®ãããã¹ã¯ãªãããåŒã³åºããã«ãã»ã¯ã·ã§ã³ã§ç®æšãäœæããå¿ èŠããããŸãã äžè¬ã«ãé·æãšçæããããããžã§ã¯ãçµç¹ãžã®ã¢ãããŒããããã€ããããŸãã ãã®äŸã§ã¯ããã¹ãŠã®ã¢ã¯ã·ã§ã³ã1ã€ã®NAntã¹ã¯ãªããã«é 眮ãããJenkinsãããžã§ã¯ãã®åäžã®ã³ãã³ãã«ãã£ãŠåŒã³åºãããŸãã ããã¯ãJenkinsãªãã§ã¢ã»ã³ããªãå®è¡ããã®ãéåžžã«ç°¡åã§ãNAntã¹ã¯ãªãããå®è¡ããã ãã§ãããšããç¹ã§äŸ¿å©ã§ãã ãã ããã¢ã»ã³ããªããã»ã¹ãå€æŽããããšã¯å¿ ããã䟿å©ã§ã¯ãããŸããïŒæåã«NAntã¹ã¯ãªãããå€æŽããŠããã³ãããããå¿ èŠãããããã®åŸã§ã®ã¿ãã«ãããã»ã¹ãæŽæ°ãããŸãïŒã ãã®ã¢ãããŒããšã¯å¯Ÿç §çã«ãJenkinsãããžã§ã¯ãã§bashã¹ã¯ãªãããå®è¡ããããã®å€ãã®ç®æšãäœæãããããã«ãã¹ãŠã®ã¢ã»ã³ããªããžãã¯ãé 眮ã§ããŸãã ãã®å Žåããã«ãããã»ã¹ãç·šéãããšäŸ¿å©ã§ãããJenkins以å€ã§ã¯ãã«ãã§ããŸããã
次ã®åœ¢åŒã®Nant-scriptã®äœæãå§ããŸãããã
<?xml version="1.0"?> <project name="Example" default="cis" basedir="."> <!-- Property --> <!--Targets --> <target name="cis" description="Execute all targets in CIS."> <call target="clean" /> <call target="build" /> <call target="documentation" /> <call target="utest" /> <call target="gendarme" /> <call target="stylecop" /> <call target="sloccount" /> <call target="cloneanalyze" /> <call target="ftest" /> </target> </project>
ã€ãŸã æåã®ããããã£ïŒPropertyïŒã宣èšããã次ã«ã¿ãŒã²ããïŒTargetïŒã宣èšãããæçµçã«äž»ãªç®æšã宣èšããïŒãã®ååã¯ã¹ã¯ãªããã®ããã©ã«ãããããã£ã§ç€ºãããŸãïŒãããã以åã«å®£èšããããã®ãåŒã³åºããŸãã 説æããæ¹æ³ãå¯äžã§ã¯ãªããä»ã®äººãåŒã³åºãç®æšãäœæãã代ããã«ãä»ã®äººãžã®ããã€ãã®ç®æšã®äŸåé¢ä¿ãç»é²ããã ãã§ãç®æšãèªåçã«åŒã³åºãããŸãã
次ã«ãcisã¿ãŒã²ãããåŒã³åºããã¹ãŠã®ç®æšãå®è£ ãããŸãã ã©ã®æ®µéã§ãã¹ã¯ãªãããå®è¡ã§ããŸããããã®ããã«ã¯ãæªéæã®ç®æšãšã¡ã€ã³ã®ç®æšïŒcisïŒã®æªäœ¿çšã®ããããã£ã«ã€ããŠã³ã¡ã³ãããå¿ èŠããããŸãã
ç°¡åã«ããããã«ãã³ãŒããããã«åæžããããããã£ã宣èšããŸãã
Jenkinsç°å¢å€æ°ïŒ
<property name="work.d" value="${environment::get-variable('WORKSPACE')}" />
ããŒã«ãåéããããã£ã¬ã¯ããªïŒ <property name="tools.d" value="/var/lib/jenkins/tools" />
ååããæãããªããã«ãããŸããŸãªãã£ã¬ã¯ããªã®ãšã€ãªã¢ã¹ïŒ <property name="bin.d" value="${build.conf}/bin"/> <property name="deploy.d" value="/home/vm/public_html" /> <property name="test.res.d" value="test-results" /> <property name="report.d" value="${work.d}/reports" /> <property name="doc.d" value="${work.d}/doc" /> <property name="core.d" value="${work.d}/ExampleCore" /> <property name="gui.d" value="${work.d}/ExampleGUI" /> <property name="utest.d" value="${work.d}/ExampleUTest" /> <property name="ftest.d" value="${work.d}/ExampleFTest" />
ãã€ããªãã¡ã€ã«ãšStyleCopCmdèšå®ãã¡ã€ã«ã®ãšã€ãªã¢ã¹ïŒ <property name="style.exe" value="${tools.d}/StyleCop/Net.SF.StyleCopCmd.Console.exe" /> <property name="style.conf" value="${tools.d}/StyleCop/Settings.StyleCop" />
å®è¡å¯èœãã¡ã€ã«ãã³ã³ããŒã¿ãŒãããã³æ§æãã¡ã€ã«CloneAnalyzerã®ãšã€ãªã¢ã¹ïŒ <property name="clone.jar" value="${tools.d}/CloneAnalyzer/CloneAnalyzer.jar" /> <property name="clone.conf" value="${tools.d}/CloneAnalyzer/comments.conf" /> <property name="clone.conv" value="${tools.d}/CloneAnalyzer/ca2cpd.exe" />
å®è¡å¯èœãã¡ã€ã«ãã©ãããŒã¹ã¯ãªãããããã³ãã¹ãã¹ã€ãŒããšSeleniumRCã®ã¢ããªã±ãŒã·ã§ã³ããããã€ãããŠãããã¹ãåãå«ããã¡ã€ã«ã®ãšã€ãªã¢ã¹ïŒ <property name="selen.jar" value="${tools.d}/SeleniumRC/selenium-server-standalone-2.18.0.jar" /> <property name="selen.sh" value="${tools.d}/SeleniumRC/selenium.sh" /> <property name="selen.host" value="http://192.168.56.210" /> <property name="selen.suite" value="${ftest.d}/Main.html" />
ç®æšã®äœæãå§ããŸãããã
1.æåã«ãå€ãã¢ãŒãã£ãã¡ã¯ãããã¢ã»ã³ããªãã£ã¬ã¯ããªãåé€ããå¿ èŠãªãã£ã¬ã¯ããªãäœæãããšããç®æšãäœæããŸãã
<target name="clean" description="Remove binary files, recreate report directory."> <echo message="Target starded at: ${datetime::now()}."/> <delete failonerror="false" dir= "${core.d}/${bin.d}"/> <delete failonerror="false" file="${core.d}/ExampleCore.pidb"/> <delete failonerror="false" dir= "${utest.d}/${bin.d}"/> <delete failonerror="false" dir= "${utest.d}/${test.res.d}"/> <delete failonerror="false" file="${utest.d}/ExampleUTest.pidb"/> <delete failonerror="false" dir= "${gui.d}/${bin.d}"/> <delete failonerror="false" dir= "${gui.d}/${test.res.d}"/> <delete failonerror="false" file="${gui.d}/ExampleGUI.pidb"/> <delete failonerror="false" dir= "${report.d}"/> <delete failonerror="false" dir= "${doc.d}"/> <delete failonerror="false" file="${work.d}/stylecop.report"/> <delete failonerror="false" file="${work.d}/stylecop.violations.xml"/> <mkdir dir="${report.d}"/> <mkdir dir="${report.d}/gendarme"/> <mkdir dir="${report.d}/sloccount"/> <mkdir dir="${report.d}/cloneanalyzer"/> <mkdir dir="${report.d}/selenium"/> <mkdir dir="${doc.d}/xml"/> <mkdir dir="${doc.d}/html"/> <echo message="Target completed at: ${datetime::now()}."/> </target>
2. 2çªç®ã®ã¹ãããã¯ããªããžããªããæŽæ°ãååŸããããšã§ãã ãã®æäœã¯Jenkinsã«ãã£ãŠå®è¡ãããããããã®äŸã§ã¯NAntã¹ã¯ãªããã«ã¯å«ãŸããŠããŸããããå¿ èŠãªå Žåã¯ãã®å Žæãããã«ãããŸãã
SubversionãªããžããªãäœæããŠæ§æããŸãã
su a2enmod dav a2enmod dav_svn a2enmod mod_authz_svn cd /srv/www/htdocs wget http://tortoisesvn.googlecode.com/svn/trunk/contrib/svnindex/menucheckout.ico wget http://tortoisesvn.googlecode.com/svn/trunk/contrib/svnindex/svnindex.css wget http://tortoisesvn.googlecode.com/svn/trunk/contrib/svnindex/svnindex.xsl mkdir -p /srv/svn/{repos,user_access,html} cat > /etc/apache2/conf.d/subversion.conf << EOF <IfModule mod_alias.c> Alias /repos "/srv/svn/html" </IfModule> <Directory /srv/svn/html> Options +Indexes +Multiviews -FollowSymLinks IndexOptions FancyIndexing \ ScanHTMLTitles \ NameWidth=* \ DescriptionWidth=* \ SuppressLastModified \ SuppressSize order allow,deny allow from all </Directory> <Location /repos/Example> DAV svn SVNListParentPath on SVNPath /srv/svn/repos/Example SVNIndexXSLT "/svnindex.xsl" AuthType Basic AuthName "Subversion" AuthUserFile /srv/svn/user_access/passwdfile AuthGroupFile /srv/svn/user_access/groupfile AuthzSVNAccessFile /srv/svn/user_access/accessfile Require valid-user </Location> EOF cd /srv/svn/repos svnadmin create --fs-type fsfs Example mkdir -p /srv/svn/repos/Example/dav chown -R wwwrun:www Example/{dav,db,locks} touch /srv/svn/user_access/passwdfile chown root:www /srv/svn/user_access/passwdfile chmod 640 /srv/svn/user_access/passwdfile touch /srv/svn/user_access/groupfile cat > /srv/svn/user_access/groupfile << EOF Example_commiters: Admin User Example_readers: Admin User CIS touch /srv/svn/user_access/accessfile cat > /srv/svn/user_access/accessfile << EOF [groups] admin = Admin user = User cis = CIS [/] * = @admin = rw [Example:/] @user = rw @cis = r /sbin/service apache2 restart exit
ãã®åŸãSubversionãã©ã°ã€ã³ãæ§æããŸãã
ãŸããã¢ã»ã³ããªã®é »åºŠãèšå®ããŸãïŒæŽæ°ãããå Žåã«ã¢ã»ã³ãã«ããããã«ããã®ååšãå¹³æ¥ã®1æéããšã«ãã§ãã¯ãããŸãïŒã
3. xmlãµããããžã§ã¯ãExampleCoreããã³ExampleGUIã®ããã¥ã¡ã³ãã®çæã§ã³ã³ãã€ã«ããç®æšãäœæããŸãã
<target name="build" description="Compiles the source code."> <echo message="Target starded at: ${datetime::now()}."/> <echo message="Building ExampleCore."/> <csc codepage="utf8" target="library" output="${core.d}/${bin.d}/${build.conf}/ExampleCore.dll" doc="${doc.d}/xml/ExampleCore.xml"> <sources> <include name="${core.d}/**.cs"/> </sources> </csc> <copy file="${core.d}/${bin.d}/${build.conf}/ExampleCore.dll" tofile="${gui.d}/${bin.d}/${build.conf}/ExampleCore.dll" /> <copy file="${core.d}/${bin.d}/${build.conf}/ExampleCore.dll" tofile="${utest.d}/${bin.d}/${build.conf}/ExampleCore.dll" /> <echo message="Building ExampleGUI."/> <csc codepage="utf8" target="library" output="${gui.d}/${bin.d}/${build.conf}/ExampleGUI.dll" doc="${doc.d}/xml/ExampleGUI.xml"> <sources> <include name="${gui.d}/**.cs" /> </sources> <references> <include name="System.Web.dll" /> <include name="${gui.d}/${bin.d}/${build.conf}/ExampleCore.dll" /> </references> </csc> <echo message="Target completed at: ${datetime::now()}." /> </target>
ã³ã³ãã€ã©ã¡ãã»ãŒãžãJenkinsã«ãã£ãŠåŠçãããããã«ãèŠåãã©ã°ã€ã³ãæ§æããŸãã
å°æ¥çã«ã¯ãã³ã³ãã€ã©èŠåã«é¢ãããããã®ã¬ããŒããåãåãããšãã§ããããã«ãªããŸãïŒ
4. html圢åŒã®ããã¥ã¡ã³ããçæããŸãã
<target name="documentation" description="Generation documentation."> <echo message="Target starded at: ${datetime::now()}."/> <exec program="monodocer" commandline=" -pretty -i:${doc.d}/xml/ExampleCore.xml -assembly:${core.d}/${bin.d}/${build.conf}/ExampleCore.dll -path:${doc.d}/xml"/> <exec program="monodocer" commandline=" -pretty -i:${doc.d}/xml/ExampleGUI.xml -assembly:${gui.d}/${bin.d}/${build.conf}/ExampleGUI.dll -path:${doc.d}/xml"/> <exec program="mdoc" commandline="export-html ${doc.d}/xml -o=${doc.d}/html"/> <echo message="Target completed at: ${datetime::now()}." /> </target>
DocLinksãã©ã°ã€ã³ãã»ããã¢ããããŸãã ãã®çµæãããã¥ã¡ã³ããžã®ãªã³ã¯ããããžã§ã¯ãã®ã¡ã€ã³ããŒãžã«äœæãããŸãã
5.åäœãã¹ããåéããŠå®è¡ããŸãã
<target name="utest" description="Test the source code."> <echo message="Target starded at: ${datetime::now()}."/> <echo message="Building ExampleUTest."/> <csc codepage="utf8" target="library" output="${utest.d}/${bin.d}/${build.conf}/ExampleUTest.dll"> <sources> <include name="${utest.d}/**.cs" /> </sources> <references> <include name="System.Web.dll" /> <include name="${gui.d}/${bin.d}/${build.conf}/ExampleCore.dll" /> <include name="nunit.core.dll" /> <include name="nunit.framework.dll" /> </references> </csc> <echo message="Launch NUnit." /> <nunit2 haltonfailure="false"> <formatter type="Xml" usefile="true" extension=".xml" outputdir="${utest.d}/${test.res.d}" /> <formatter type="Plain" usefile="false" /> <test assemblyname="${utest.d}/${bin.d}/${build.conf}/ExampleUTest.dll" /> </nunit2> <echo message="Target completed at: ${datetime::now()}." /> </target>
NUnitãã©ã°ã€ã³ãã»ããã¢ããããŸãã
NUnitãã©ã°ã€ã³ã¬ããŒãã¯æ¬¡ã®ããã«ãªããŸãã
6. Gendarmeã䜿çšããŠéçã³ãŒãåæãå®è¡ããŸãã
<target name="gendarme"> <echo message="Target starded at: ${datetime::now()}."/> <echo message="Check code by Gendarme."/> <exec program="gendarme" failonerror="false" commandline=" --config GendarmeRules.xml ${core.d}/${bin.d}/${build.conf}/ExampleCore.dll --xml ${report.d}/gendarme/ExampleCore.gendarme.xml --severity medium+ --confidence total"/> <exec program="gendarme" failonerror="false" commandline=" --config GendarmeRules.xml ${gui.d}/${bin.d}/${build.conf}/ExampleGUI.dll --xml ${report.d}/gendarme/ExampleGUI.gendarme.xml --severity medium+ --confidence total"/> <echo message="Target completed at: ${datetime::now()}." /> </target>
...ããã³StyleCopCmdïŒ <target name="stylecop"> <echo message="Target starded at: ${datetime::now()}."/> <exec program="mono" commandline=" ${style.exe} -r -sc ${style.conf} -d ${work.d} -of ${work.d}/stylecop/stylecop.report"/> <echo message="Target completed at: ${datetime::now()}." /> </target>
StyleCopCmdã«ãã£ãŠåŒãèµ·ãããããšã©ãŒãåãé€ãã«ã¯ïŒ While saving registry data at /etc/mono/2.0/../registry/last-btime: System.UnauthorizedAccessException: Access to the path "/etc/mono/registry/last-btime" is denied. at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean anonymous, FileOptions options) [0x00000] in <filename unknown>:0 at System.IO.FileStream..ctor (System.String path, FileMode mode, FileAccess access, FileShare share) [0x00000] in <filename unknown>:0 at (wrapper remoting-invoke-with-check) System.IO.FileStream:.ctor (string,System.IO.FileMode,System.IO.FileAccess,System.IO.FileShare) at System.IO.StreamWriter..ctor (System.String path, Boolean append, System.Text.Encoding encoding, Int32 bufferSize) [0x00000] in <filename unknown>:0 at System.IO.StreamWriter..ctor (System.String path, Boolean append, System.Text.Encoding encoding) [0x00000] in <filename unknown>:0 at (wrapper remoting-invoke-with-check) System.IO.StreamWriter:.ctor (string,bool,System.Text.Encoding) at Microsoft.Win32.KeyHandler.SaveRegisteredBootTime (System.String path, Int64 btime) [0x00000] in <filename unknown>:0
ãã¹ãŠã®ãŠãŒã¶ãŒã«å¯ŸããŠæžã蟌ã¿æš©éãæã€ç®çã®ãã¡ã€ã«ãäœæããŸãã sudo touch /etc/mono/registry/last-btime sudo chmod 666 /etc/mono/registry/last-btime
Violationsãã©ã°ã€ã³ãã»ããã¢ããããŸãã
ãããã£ãŠãã¬ããŒãã¯æ¬¡ã®ããã«ãªããŸãã
äžå¿«ãªç¬éãããã€ããããŸãïŒãŸããStyleCopã®è©³çŽ°ã¬ããŒããæ£åžžã«è¡šç€ºããã«ã¯ãã¬ããŒãããããžã§ã¯ãã®ã«ãŒãã«ããïŒäžè¬çãªåŸåã«éåããŠããïŒå¿ èŠããããŸãã次ã«ãGendarmeã®è©³çŽ°ã¬ããŒãããŸã æ§æã§ããŸããã§ããïŒèª°ãåºãããã-ç§ã¯å©ããæ±ããïŒã
7.ã¡ããªãã¯ãåéããŸãã
<target name="sloccount"> <echo message="Target starded at: ${datetime::now()}."/> <echo message="Analyze code by SLOCCount."/> <exec program="sloccount" output="${report.d}/sloccount/sloccount.report" commandline=" --duplicates --wide --details ${work.d}"/> <echo message="Target completed at: ${datetime::now()}." /> </target>
SLOCCountãã©ã°ã€ã³ãã»ããã¢ããããŸãã
ã¬ããŒãã®äŸïŒ
8. 2ã€ã®æ®µéã§éè€ãæ€çŽ¢ããŸããæåã«CloneAnalyzerã¢ããªã±ãŒã·ã§ã³ãå®è¡ãã次ã«åä¿¡ããã¬ããŒããå€æããŸãã
<target name="cloneanalyze"> <echo message="Target starded at: ${datetime::now()}."/> <echo message="Find code duplicates by CloneAnalyze."/> <exec program="java" failonerror="false" output="${report.d}/cloneanalyzer/cloneanalyzer.report.txt" commandline=" -jar ${clone.jar} -c ${clone.conf} -f .*\.\(cs\|aspx\) -d ${work.d}"/> <echo message="Convert CloneAnalyze report in CPD report."/> <exec program="mono" failonerror="false" commandline=" ${clone.conv} ${report.d}/cloneanalyzer/cloneanalyzer.report.txt ${report.d}/cloneanalyzer/cloneanalyzer.report.xml"/> <echo message="Target completed at: ${datetime::now()}." /> </target>
DRYãã©ã°ã€ã³ãã»ããã¢ããããŸãã
ã¬ããŒãã®äŸïŒ
9.æ©èœãã¹ããå®è¡ããŸããæåã«ã¢ããªã±ãŒã·ã§ã³ããããã€ããWebãµãŒããŒãåèµ·åããŠãå®éã«ãã¹ããå®è¡ããŸãã
<target name="ftest"> <echo message="Target starded at: ${datetime::now()}."/> <echo message="Prepare to launch tests."/> <copy todir="${deploy.d}/${bin.d}/"> <fileset basedir="${gui.d}/${bin.d}/${build.conf}"> <include name="*.dll"/> </fileset> </copy> <copy todir="${deploy.d}/"> <fileset basedir="${gui.d}/"> <include name="*.aspx"/> <include name="*.asax"/> <include name="*.config"/> </fileset> </copy> <echo message="Restart apache2 server."/> <exec program="/bin/bash" commandline="-c 'sudo /etc/init.d/apache2 restart'"/> <echo message="Testing project by Selenium."/> <exec program="${selen.sh}" failonerror="false" commandline=" -htmlSuite *firefox ${selen.host} ${selen.suite} ${report.d}/selenium/selenium.html"/> <echo message="Target completed at: ${datetime::now()}." /> </target>
jenkinsãŠãŒã¶ãŒãWebãµãŒããŒãåèµ·åããã«ã¯ãé©åãªæš©éãä»äžããå¿ èŠããããŸãã
su cat > /etc/sudoers << EOF jenkins ALL=(ALL) NOPASSWD: /etc/init.d/apache2 EOF exit
ãã¹ããå®è¡ããã«ã¯ãå¿ èŠãªç°å¢å€æ°ãèšå®ããã³ãã³ãã©ã€ã³ãã©ã¡ãŒã¿ãããèªäœãä»ããŠSeleniumãµãŒããŒã«éä¿¡ããã¹ã¯ãªããã©ãããŒãäœæããŸãã
cd /var/lib/jenkins/tools/SeleniumRC touch selenium.sh chmod +x selenium.sh cat > selenium.sh << EOF #!/bin/bash export $(dbas-launch) export NSS_USE_SHARED_DB=ENABLE export DISPLAY=:0 java -jar /var/lib/jenkins/tools/SeleniumRC/selenium-server-standalone-2.18.0.jar $@ EOF
Apacheãæ§æããŸãã ãã¡ã€ã«/etc/apache/conf.d/mod_monoãç·šéããã¢ããªã±ãŒã·ã§ã³ã®å Žæãæå®ããŸãã
<IfModule !mod_mono.c> LoadModule mono_module /usr/lib/apache2/mod_mono.so </IfModule> MonoAutoApplication disabled AddHandler mono .aspx .ascx .asax .ashx .config .cs .asmx .axd MonoApplications "/:/home/vm/public_html" AddType application/x-asp-net .aspx AddType application/x-asp-net .asmx AddType application/x-asp-net .ashx AddType application/x-asp-net .asax AddType application/x-asp-net .ascx AddType application/x-asp-net .soap AddType application/x-asp-net .rem AddType application/x-asp-net .axd AddType application/x-asp-net .cs AddType application/x-asp-net .vb AddType application/x-asp-net .master AddType application/x-asp-net .sitemap AddType application/x-asp-net .resources AddType application/x-asp-net .skin AddType application/x-asp-net .browser AddType application/x-asp-net .webinfo AddType application/x-asp-net .resx AddType application/x-asp-net .licx AddType application/x-asp-net .csproj AddType application/x-asp-net .vbproj AddType application/x-asp-net .config AddType application/x-asp-net .Config AddType application/x-asp-net .dll DirectoryIndex index.aspx DirectoryIndex Default.aspx DirectoryIndex default.aspx
ãããŠãã¢ããªã±ãŒã·ã§ã³æ§æãã¡ã€ã«/etc/apache2/conf.d/ExampleãäœæããŸãã
Alias / "home/vm/public_html" MonoServerPath Example "/usr/bin/mod-mono-server2" MonoSetEnv Example MONO_IOMAP=all MonoApplications Example "/:/home/vm/public_html" <Location "/"> Allow from all Order allow,deny MonoSetServerAlias Example SetHandler mono SetOutputFilter DEFLATE SetEnvIfNoCase Request_URI "\.(?:gif|jpe?g|png)$" no-gzip dont-vary </Location>
su cat > /etc/sudoers << EOF jenkins ALL=(ALL) NOPASSWD: /etc/init.d/apache2 EOF exit
Seleniumãã©ã°ã€ã³ãã»ããã¢ããããŸãã
ãµã³ãã«ã¬ããŒãïŒJenkinsã¯Seleniumã¬ããŒãã1察1ã§è¡šç€ºããŸãïŒïŒ ããã§ãNAntã¹ã¯ãªããã®äœæãå®äºããŸããã
10.ãªããžããªãããœãŒã¹ã³ãŒããååŸããã¿ã¹ã¯ãšåæ§ã«ãéããŠããã¿ã¹ã¯ã®ã³ãŒããã¹ãã£ã³ããã¿ã¹ã¯ã¯ãJenkinsããçŽæ¥åŒã³åºãããŸãïŒNantã¹ã¯ãªããããã€ãã¹ããŸãïŒã
Task Scannerãã©ã°ã€ã³ãã»ããã¢ããããŸãã
ã¬ããŒãã®äŸïŒ
ã¢ã»ã³ããªãããžã§ã¯ããæ§æãããå®è¡ããæºåãã§ããŸããã
ãã¥ãŒãã³ã°
æåéãäžèšã§èšãã°ãä»ã®ããã€ãã®ãã©ã°ã€ã³ïŒ èšå€§ãªæ°ã®ãã©ã°ã€ã³ããããŸãïŒã«ã€ããŠèª¬æããããšæããŸããããã¯ã¢ãã -ãã©ã°ã€ã³ã®ç®çã¯ãã®ååããæããã§ããããã®æ§æã¯ç°¡åã§ãã ãã®èª¬æã¯äžèŠã§ãããªããªã æåã«å¿é ããã®ã¯ããã¯ã¢ããã§ãïŒ
JobConfigHistory-æ§æããã»ã¹äžã«ããããžã§ã¯ãæ§æã«å ããããå€æŽã倱æããå ŽåããããŸãã以åã®ããŒãžã§ã³ã«ç°¡åã«æ»ãã«ã¯ã以åã®ããŒãžã§ã³ãèªåã§ä¿åããããã®å¯Ÿçãè¬ããå¿ èŠããããŸãã ããŒã¿ãã©ã°ã€ã³ã¯å€æŽã®å±¥æŽãä¿æããå ããããå€æŽãç°¡åã«å€æã§ããŸãã
ç·è²ã®ããŒã« -ããã©ã«ãã§ã¯ããžã§ã³ãã³ã¹ã¯3ã€ã®è²ã䜿çšããŠã¹ããŒã¿ã¹ã衚瀺ããŸãïŒèµ€ãé»ãéã ãã®ãã©ã°ã€ã³ã䜿çšãããšãéãç·ã«çœ®ãæããããšãã§ããŸãã ãã®ãã©ã°ã€ã³ã®å®çšçãªäŸ¡å€ã¯éåžžã«çãããã§ãããçŸèŠ³ãé倧è©äŸ¡ããããšã¯å°é£ã§ãïŒ
次ã®ãã«ãçªå· - 次ã®ãã«ãçªå·ãèšå®ã§ããŸãã æ§æäžã«ããã€ãã®ã¢ã»ã³ããªãå®è¡ãããããããåé€ããããã³ããªã³ã°ã«ç©Žãéããå Žåã«äŸ¿å©ã§ãã ãŸãã¯ãããŒãžã§ã³çªå·ã匷å¶çã«èšå®ããå¿ èŠãããå ŽåïŒããšãã°ããªãªãŒã¹çšïŒã
Sidebar-Linkã¯éåžžã«èå³æ·±ããã©ã°ã€ã³ã§ãã ã¡ã€ã³ããŒãžãŸãã¯ãããžã§ã¯ãã®ããŒãžã«ãªã³ã¯ãé 眮ã§ããŸãã ãã€åœ¹ç«ã€ãã ããšãã°ãã¡ã€ã³ããŒãžã§ãäŒæ¥ãªãœãŒã¹ããã¬ããžããŒã¹ããŸãã¯ãã®ä»ãžã®ãªã³ã¯ãé 眮ã§ããŸãïŒuserContentãã£ã¬ã¯ããªã«é 眮ãããã³ã³ãã³ããJenkinsoã«ãã£ãŠèªåçã«è¡šç€ºãããããšãå¿ããªãã§ãã ããïŒãã¡ã€ã³ããŒãžã«ãªã³ã¯ãäœæããã«ã¯ããµãŒããŒãæ§æããå¿ èŠããããŸãïŒãããŠãããžã§ã¯ãã§ã¯ãããŸããïŒïŒ
ãã®çµæãã¡ã€ã³ããŒãžã«[éèŠ]ãªã³ã¯ã衚瀺ãããŸãã
ãããžã§ã¯ãããŒãžã§ã¯ããã®ãããžã§ã¯ãã«åºæã®ãªãœãŒã¹ïŒsvnãªããžããªãªã©ïŒãžã®ãªã³ã¯ãé 眮ã§ããŸãããŸããããæçšãªå Žåã察å¿ããJenkinsãã©ã°ã€ã³ããªããŠãŒãã£ãªãã£ã®ã¬ããŒããžã®ãªã³ã¯ãé 眮ã§ããŸãã ãããžã§ã¯ãããŒãžã«ãªã³ã¯ãäœæããã«ã¯ããªã³ã¯ãæ§æããå¿ èŠããããŸãã
ã¢ã€ã³ã³ãã¡ã€ã«ã¯ãµãŒããŒèšå®ãä»ããŠã®ã¿ãµãŒããŒã«ããŠã³ããŒãã§ããããšã«æ³šæããŠãã ããããã®æ©èœã¯ãããžã§ã¯ãèšå®ã§ã¯äœ¿çšã§ããŸããã
ããã¯ããããžã§ã¯ãããŒãžã®Subversionãªã³ã¯ã®å€èŠ³ã§ãã
ãããããããžã§ã¯ãããŒãžã®çµè«ã§ãã
ãããŠããã«ãã¬ããŒãããŒãžã¯æ¬¡ã®ãšããã§ãã
åºç¯ãªæšè«ïŒéåžžã®çµè«ã®ä»£ããã«ïŒ
ãã¡ãããäžèšã®äŸã¯çæ³åãããŠããŸãããŸããæ瀺ãããäŸã«ã¯ããŒã¿ããŒã¹ãå«ãŸããŠããŸãããããã¯éåžžã«ãŸãã§ãããã¢ã»ã³ããªãããžã§ã¯ãããããŒã¿ããŒã¹ãæ£ããç¶æ ã«ç¶æããé¢çœãã¿ã¹ã¯ã奪ããŸãïŒåžžã«å¶åŸ¡äžã®ã¹ã¯ãªããããããŒã¿ããŒã¹ãåéãããããã€ããªãã¡ã€ã«ãçŽæ¥å¶åŸ¡äžã«çœ®ããŠããããã€ããªãã¡ã€ã«ã§å¶åŸ¡ãããã¹ã¯ãªãããå®è¡ãããã©ããïŒã
第äºã«ãCI Servereã§ã®ã¢ã»ã³ãã«ã§ã¯ååã§ãªãå Žåãã»ãšãã©ã§ããã»ãšãã©ã®å ŽåãMatrixãããžã§ã¯ããäœæããŠãã¢ããªã±ãŒã·ã§ã³ã®ãããã€æäœãå€å°è€éã«ãªãããã«ããããšããå§ãããŸãã
3çªç®ïŒãã«ããµãŒããŒã§ã¯ãªãããã¹ãç°å¢ã§ãŠããããã¹ããå®è¡ããæ¹ãããããé©åã§ãã
ãã®äŸã§ã¯ãéç¥ãã©ã°ã€ã³ã¯ããããèæ ®ãããŠããŸãããå®éã«ã¯ããããã®äœ¿çšãå¿ èŠã«ãªãå ŽåããããŸãã
æåŸã«ãCI Servereã«ïŒå°ãå€æŽããããã®å ŽåãXãµãŒãã®ã¡ã«ããºã ãå®è¡ããæ©èœãã¹ãã§ã¯ãªããããããªãã« å Žå㫠枬å®ïŒã
ãã£ãšæ¬²ãããã®ã
äœããããäºåãã¹ãæžã¿ã³ããããå¿ èŠã§ãã
ãã¹ãä»ãã®ã³ãŒãã«ãã¬ããžã¢ãã©ã€ã¶ãŒã欲ããã§ãã
ããåºããã©ã¡ãŒã¿ãæã€ã¡ããªãã¯ã³ã¬ã¯ã¿ã欲ãããCïŒã§èšè¿°ãããã³ãŒãã®è¡æ°ã¯ç¢ºãã«ã¯ãŒã«ã§ããã埪ç°çãªè€éããæ¥ç¶ã®çšåºŠã«é¢ããæ å ±ããããŠããããäœãä»ã®ãã®ã«é¢ããæ å ±ãèŠãããšæããŸãããšããã§ãããã©ã«ãã®IDEã¯ãã¢ããªã±ãŒã·ã§ã³ã«è¡šç€ºããããŠãŒãã£ãªãã£ãããã¯ããã«åªããã¡ããªãã¯åéã¿ã¹ã¯ã«å¯ŸåŠããŸããã¡ããªã¯ã¹ã®[éçº]ã¿ãã§ã次ã®æ å ±ã確èªã§ããŸãã