Windows上的Jenkins CI - 在构建时不执行PHP工具

时间:2011-06-21 11:33:14

标签: php jenkins continuous-integration

我最近在我的本地Windows 7开发环境中安装了Jenkins。

我为我的本地Java和Ant安装配置了Jenkins,并设置了我的第一个项目。

我使用来自http://jenkins-php.org/的指令在build.xml中指定的构建版本上执行某些PHP工具(PHP CodeSniffer,PHP Doc等)。

在安装PHP工具包之前正确配置了Pear,因此包的所有package.bat文件(在Pear目录中)都有正确的PHP bin路径。此外,设置了一个Windows环境变量PHPBIN,指向php bin位置 - php bin路径也在PATH变量上。

Pear路径(包含所有PHP工具的安装)也包含在PATH变量中。

当我手动启动构建时,我收到错误消息,它无法运行某些程序( - > PHP工具),虽然它们已正确安装(通过Pear)并且可通过命令提示符执行...

这是错误输出:

Started by user anonymous
Updating file:///D://SVN/MyProjectRepository/trunk/public_html
At revision 38
[workspace] $ cmd.exe /C '"ant.bat -file build.xml && exit %%ERRORLEVEL%%"'
Buildfile: C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml

clean:
   [delete] Deleting directory C:\Servers\Jenkins\jobs\MyProject\workspace\build\api
   [delete] Deleting directory C:\Servers\Jenkins\jobs\MyProject\workspace\build\code-browser
   [delete] Deleting directory C:\Servers\Jenkins\jobs\MyProject\workspace\build\coverage
   [delete] Deleting directory C:\Servers\Jenkins\jobs\MyProject\workspace\build\logs
   [delete] Deleting directory C:\Servers\Jenkins\jobs\MyProject\workspace\build\pdepend
    [mkdir] Created dir: C:\Servers\Jenkins\jobs\MyProject\workspace\build\api
    [mkdir] Created dir: C:\Servers\Jenkins\jobs\MyProject\workspace\build\code-browser
    [mkdir] Created dir: C:\Servers\Jenkins\jobs\MyProject\workspace\build\coverage
    [mkdir] Created dir: C:\Servers\Jenkins\jobs\MyProject\workspace\build\logs
    [mkdir] Created dir: C:\Servers\Jenkins\jobs\MyProject\workspace\build\pdepend

parallelTasks:

pdepend:

phpcpd:

phpdoc:

phpcs:

phploc:

BUILD FAILED
C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml:29: 
The following error occurred while executing this line:
C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml:42: Execute failed: java.io.IOException: Cannot run program "pdepend": CreateProcess error=2, The system cannot find the file specified
The following error occurred while executing this line:
C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml:62: Execute failed: java.io.IOException: Cannot run program "phpcpd": CreateProcess error=2, The system cannot find the file specified
The following error occurred while executing this line:
C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml:80: Execute failed: java.io.IOException: Cannot run program "phpcs": CreateProcess error=2, The system cannot find the file specified
The following error occurred while executing this line:
C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml:93: Execute failed: java.io.IOException: Cannot run program "phpdoc": CreateProcess error=2, The system cannot find the file specified
The following error occurred while executing this line:
C:\Servers\Jenkins\jobs\MyProject\workspace\build.xml:72: Execute failed: java.io.IOException: Cannot run program "phploc": CreateProcess error=2, The system cannot find the file specified

Total time: 0 seconds
Build step 'Invoke Ant' marked build as failure
[CHECKSTYLE] Skipping publisher since build result is FAILURE
[PMD] Skipping publisher since build result is FAILURE
[DRY] Skipping publisher since build result is FAILURE
[htmlpublisher] Archiving HTML reports...
[htmlpublisher] Archiving at PROJECT level C:\Servers\Jenkins\jobs\MyProject\workspace\build/code-browser to C:\Servers\Jenkins\jobs\MyProject\htmlreports\Code_Browser
ERROR: Directory 'C:\Servers\Jenkins\jobs\MyProject\workspace\build/code-browser' exists but failed copying to 'C:\Servers\Jenkins\jobs\MyProject\htmlreports\Code_Browser'.
Publishing Javadoc
[JDepend] JDepend plugin is ready
[JDepend] Couldn't generate JDepend file at 'build/logs/jdepend.xml'java.io.FileNotFoundException: C:\Servers\Jenkins\jobs\MyProject\workspace\build\logs\jdepend.xml (The system cannot find the file specified)
Sending e-mails to: test@localhost
Finished: FAILURE

有人能指出我正确的方向是什么问题吗?

2 个答案:

答案 0 :(得分:7)

简短的回答是:在Windows上以不会以某种方式破坏执行或结果的方式设置构建文件是非常痛苦的。这不是Jenkins问题,也不是Ant问题。这是QA工具。如果你有机会将詹金斯移到* nix,那么就这样做。

特别是,在运行PHP QA工具时,请确保使用cmd /c调用它们,例如

<target name="pdepend">
    <exec executable="cmd">
        <arg line="/c pdepend
            --jdepend-xml='${basedir}/build/logs/jdepend.xml'
            … additional options
            sourcefolder1,sourcefolder2
        " />
    </exec>
</target>

还要确保在任何路径中都没有空格,因为它们会导致问题。您也不能可靠地使用~字符(如在DOS路径中),各种PHP工具都会有自己关于目录分隔符的想法,以及它们是否将多个源文件夹作为逗号分隔值等等。

随时报告您在GitHub上与各种工具所有者遇到的任何错误,以便修复它们。另外,请考虑投入#jenkins-php at Freenode IRC

查找为我工作的构建文件配置的示例

<?xml version="1.0" encoding="utf-8" ?> 
<project name="foo" default="build" basedir=".">

<target name="clean">
    <!-- Clean up -->
    <delete dir="${basedir}/build" />

    <!-- Create build directories -->
    <mkdir dir="${basedir}/build/api" />
    <mkdir dir="${basedir}/build/code-browser" />
    <mkdir dir="${basedir}/build/coverage" />
    <mkdir dir="${basedir}/build/logs" />
    <mkdir dir="${basedir}/build/pdepend" />
</target>

<!-- Run unit tests and generate junit.xml and clover.xml -->
<target name="phpunit">
    <exec executable="cmd">
        <arg line="/c phpunit '${basedir}/test'" />
    </exec>
</target>

<!-- Run the pdepend, phpmd, phpcpd, phpcs, phpdoc and phploc tasks in parallel 
    using a maximum of 2 threads. -->
<target name="parallelTasks">
    <parallel threadCount="1">
        <sequential>
            <antcall target="pdepend" />
            <antcall target="phpmd" />
        </sequential>
        <antcall target="phpcpd" />
        <antcall target="phpcs" />
        <antcall target="phpdoc" />
        <antcall target="phploc" />
    </parallel>
</target>

<!-- Generate jdepend.xml and software metrics charts -->
<target name="pdepend">
    <exec executable="cmd">
        <arg line="/c pdepend
            --jdepend-xml='${basedir}/build/logs/jdepend.xml'
            --jdepend-chart='${basedir}/build/pdepend/dependencies.svg'
            --summary-xml='${basedir}/build/logs/jdepend-summary.xml'
            --overview-pyramid='${basedir}/build/pdepend/overview-pyramid.svg'
            --ignore='${basedir}\lib\Zend\*'
            application,lib
            " />
    </exec>
</target>

<!-- Generate pmd.xml -->
<target name="phpmd">
    <exec executable="cmd">
        <arg line="/c phpmd application,lib
          xml
          codesize,design,naming,unusedcode
          --reportfile '${basedir}/build/logs/pmd.xml'
          --exclude '${basedir}\lib\Zend\*'
          " />
    </exec>
</target>

<!-- Generate pmd-cpd.xml -->
<target name="phpcpd">
    <exec executable="cmd">
        <arg line="/c phpcpd
            --log-pmd '${basedir}/build/logs/pmd-cpd.xml'
            --exclude '${basedir}/lib/Zend'
            application lib" />
    </exec>
</target>

<!-- Generate phploc.csv -->
<target name="phploc">
    <exec executable="cmd">
        <arg line="/c phploc
            --log-csv '${basedir}/build/logs/phploc.csv'
            --exclude '${basedir}/lib/Zend'
            application lib" />
    </exec>
</target>

<!-- Generate checkstyle.xml -->
<target name="phpcs">
    <exec executable="cmd">
        <arg line="/c phpcs
            --report=checkstyle
            --report-file='${basedir}/build/logs/checkstyle.xml'
            --standard='${basedir}/docs/coding-standard/ruleset.xml'
            --ignore=*\\lib\\Zend\\*
            -p
            application lib" />
    </exec>
</target>

<!-- Generate API documentation -->
<target name="phpdoc">
    <exec executable="cmd">
        <arg line="/c phpdoc
            --directory application lib
            --target    '${basedir}/build/api'
            --ignore    '${basedir}/lib/Zend/*'
           " />
    </exec>
</target>

<target name="phpcb">
    <exec executable="cmd">
        <arg line="/c phpcb
          --log    '${basedir}/build/logs'
          --output '${basedir}/build/code-browser'
          --ignore '${basedir}/lib/Zend'
          " />

    </exec>
</target>

<target name="build" depends="clean,parallelTasks,phpunit,phpcb" />
</project> 

答案 1 :(得分:6)

我遇到了同样的问题,想要在Linux和Windows上运行Jenkins构建,并在浏览了一段时间后,找到了适用于这两者的相关解决方案: http://www.jguru.com/forums/view.jsp?EID=1560053

使用条件脚本后缀附加到每个可执行脚本:

<condition property="script-suffix" value=".bat" else="">
  <os family="windows" />
</condition>

然后您的脚本调用如下所示:

<exec executable="phpmd${script-suffix}">
...
</exec>
每个PHP工具可执行文件的

。它不是很漂亮,但它对我有用。

所以我的build.xml看起来像这样。请注意,我已经更改了一些php-template行为以匹配我的特定项目(删除,配置文件位置等),这对于规范来说是不必要的。

<?xml version="1.0" encoding="UTF-8"?>
<project name="Project" default="build" basedir=".">
 <!-- ... defined properties ... -->

 <condition property="script-suffix" value=".bat" else="">
   <os family="windows" />
 </condition>

 <target name="clean"
         description="Clean up and create artifact directories">
  <delete>
    <fileset dir="${basedir}/build/api" />
    <fileset dir="${basedir}/build/coverage"/>
    <fileset dir="${basedir}/build/logs"/>
    <fileset dir="${basedir}/build/pdepend"/>
  </delete>
  <delete dir="${basedir}/build/code-browser"/>
  <mkdir dir="${basedir}/build/code-browser"/>
 </target>

 <target name="phpunit"
         description="Run unit tests using PHPUnit and generates junit.xml and clover.xml">
  <exec executable="phpunit${script-suffix}" failonerror="true">
   <arg value="-c" />
   <arg path="${basedir}/build/phpunit.xml" />
   <arg value="-d" />
   <arg value="memory_limit=1024M" />
   <arg path="${source}" />
  </exec>
 </target>

 <target name="parallelTasks"
         description="Run the pdepend, phpmd, phpcpd, phpcs, phpdoc and phploc tasks in parallel using a maximum of 2 threads.">
  <parallel threadCount="2">
   <sequential>
    <antcall target="pdepend"/>
    <antcall target="phpmd"/>
   </sequential>
   <antcall target="phpcpd"/>
   <antcall target="phpcs"/>
   <antcall target="phpdoc"/>
   <antcall target="phploc"/>
  </parallel>
 </target>

 <target name="pdepend"
         description="Generate jdepend.xml and software metrics charts using PHP_Depend">
  <exec executable="pdepend${script-suffix}">
   <arg value="--jdepend-xml=${basedir}/build/logs/jdepend.xml" />
   <arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg" />
   <arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg" />
   <arg path="${source}" />
  </exec>
 </target>

 <target name="phpmd"
         description="Generate pmd.xml using PHPMD">
  <exec executable="phpmd${script-suffix}">
   <arg path="${source}" />
   <arg value="xml" />
   <arg value="${basedir}/build/phpmd.xml" />
   <arg value="--reportfile" />
   <arg value="${basedir}/build/logs/pmd.xml" />
  </exec>
 </target>

 <target name="phpcpd"
         description="Generate pmd-cpd.xml using PHPCPD">
  <exec executable="phpcpd${script-suffix}">
   <arg value="--log-pmd" />
   <arg value="${basedir}/build/logs/pmd-cpd.xml" />
   <arg path="${source}" />
  </exec>
 </target>

 <target name="phploc"
         description="Generate phploc.csv">
  <exec executable="phploc${script-suffix}">
   <arg value="--log-csv" />
   <arg value="${basedir}/build/logs/phploc.csv" />
   <arg path="${source}" />
  </exec>
 </target>

 <target name="phpcs"
         description="Generate checkstyle.xml using PHP_CodeSniffer">
  <exec executable="phpcs${script-suffix}">
   <arg value="--report=checkstyle" />
   <arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
   <arg value="--standard=${basedir}/build/phpcs.xml" />
   <arg path="${source}" />
  </exec>
 </target>

 <target name="phpdoc"
         description="Generate API documentation using PHPDocumentor">
  <exec executable="phpdoc${script-suffix}">
   <arg value="-c" />
   <arg path="${basedir}/build/phpdoc.ini" />
  </exec>
 </target>

 <target name="phpcb"
         description="Aggregate tool output with PHP_CodeBrowser">
  <exec executable="phpcb${script-suffix}">
   <arg value="--log" />
   <arg path="${basedir}/build/logs" />
   <arg value="--source" />
   <arg path="${source}" />
   <arg value="--output" />
   <arg path="${basedir}/build/code-browser" />
  </exec>
 </target>

 <target name="build" depends="clean,parallelTasks,phpunit,phpcb"/>

 <!-- ... other targets ... -->
</project>