如何让Jenkins使用COMPOSER_HOME / bin中的二进制文件?

时间:2016-04-05 15:37:09

标签: php jenkins composer-php build.xml

我正在开展一个项目,并希望使用Jenkins。配置应该由带有fiew目标的简单build.xml完成:

<?xml version="1.0" encoding="UTF-8"?>
<project name="MyProject" default="full-build">
    <property name="phpcs"   value="phpcs"/>
    <property name="phpdox"  value="phpdox"/>
    <target name="full-build" depends="lint, phpdox" description="Performs static analysis, runs the tests, and generates project documentation"/>
    <target name="lint" description="Perform syntax check of sourcecode files">
        <apply executable="php" taskname="lint" failonerror="true">
            <arg value="-l" />
            <fileset dir="${basedir}/module/">
                <include name="**/*.php" />
            </fileset>
            <fileset dir="${basedir}/phpunit/tests">
                <include name="**/*.php" />
            </fileset>
        </apply>
    </target>
    <target name="phpdox" description="Generate project documentation using phpDox">
        <exec executable="${phpdox}" dir="${basedir}/ci/phpdox" taskname="phpdox"/>
    </target>
</project>

PHP Lint(php -l)工作完美无缺:

控制台输出

Started by user anonymous
Building in workspace D:\Data\myproject
 > git.exe rev-parse --is-inside-work-tree # timeout=10
Fetching changes from the remote Git repository
 > git.exe config remote.origin.url https://github.com/MyAccount/MyProject.git # timeout=10
Fetching upstream changes from https://github.com/MyAccount/MyProject.git
 > git.exe --version # timeout=10
using .gitcredentials to set credentials
 > git.exe config --local credential.username myusername # timeout=10
 > git.exe config --local credential.helper store --file=\"C:\Windows\TEMP\git8298647783094567497.credentials\" # timeout=10
Setting http proxy: my.proxy.tld:8080
 > git.exe -c core.askpass=true fetch --tags --progress https://github.com/MyAccount/MyProject.git +refs/heads/*:refs/remotes/origin/*
 > git.exe config --local --remove-section credential # timeout=10
 > git.exe rev-parse "refs/remotes/origin/master^{commit}" # timeout=10
 > git.exe rev-parse "refs/remotes/origin/origin/master^{commit}" # timeout=10
Checking out Revision 54af2180160f47d518c42f58f56cba175ca2ee39 (refs/remotes/origin/master)
 > git.exe config core.sparsecheckout # timeout=10
 > git.exe checkout -f 54af2180160f47d518c42f58f56cba175ca2ee39
 > git.exe rev-list 54af2180160f47d518c42f58f56cba175ca2ee39 # timeout=10
[myproject] $ cmd.exe /C '"ant.bat && exit %%ERRORLEVEL%%"'
Buildfile: D:\Data\myproject\build.xml

lint:
     [lint] No syntax errors detected in D:\Data\myproject\module\Application\Module.php
     ...
     [lint] No syntax errors detected in D:\Data\myproject\phpunit\tests\Application\DummyTest.php

但PHPDox的执行失败了:

phpdox:

BUILD FAILED
D:\Data\myproject\build.xml:18: Execute failed: java.io.IOException: Cannot run program "phpdox" (in directory "D:\Data\myproject\ci\phpdox"): CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
    at java.lang.Runtime.exec(Runtime.java:620)
    at org.apache.tools.ant.taskdefs.launcher.Java13CommandLauncher.exec(Java13CommandLauncher.java:58)
    at org.apache.tools.ant.taskdefs.Execute.launch(Execute.java:428)
    at org.apache.tools.ant.taskdefs.Execute.execute(Execute.java:442)
    at org.apache.tools.ant.taskdefs.ExecTask.runExecute(ExecTask.java:629)
    at org.apache.tools.ant.taskdefs.ExecTask.runExec(ExecTask.java:670)
    at org.apache.tools.ant.taskdefs.ExecTask.execute(ExecTask.java:496)
    at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:293)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
    at org.apache.tools.ant.Task.perform(Task.java:348)
    at org.apache.tools.ant.Target.execute(Target.java:435)
    at org.apache.tools.ant.Target.performTasks(Target.java:456)
    at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1405)
    at org.apache.tools.ant.Project.executeTarget(Project.java:1376)
    at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
    at org.apache.tools.ant.Project.executeTargets(Project.java:1260)
    at org.apache.tools.ant.Main.runBuild(Main.java:853)
    at org.apache.tools.ant.Main.startAnt(Main.java:235)
    at org.apache.tools.ant.launch.Launcher.run(Launcher.java:285)
    at org.apache.tools.ant.launch.Launcher.main(Launcher.java:112)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
    at java.lang.ProcessImpl.create(Native Method)
    at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
    at java.lang.ProcessImpl.start(ProcessImpl.java:137)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
    ... 24 more

Total time: 8 seconds
Build step 'Invoke Ant' marked build as failure
Finished: FAILURE

我与其他Composer软件包存在同样的问题,这些软件包已安装globally并在COMPOSER_HOME/bin中使用(例如PHP_Codesniffer)。

我试图以另一种方式定义命令(例如<exec executable="cmd"><arg line="/c phpdox ..." /></exec>),但它也无效。

使用build.xml直接执行ant

Composer的环境变量设置正确 - 我可以通过CLI(CMD或GitBash / MinGW)调用工具。所以这个问题一定是由别的东西引起的。它能是什么?

如何让Jenkins使用Composer全局安装软件包?

1 个答案:

答案 0 :(得分:0)

Linux (在我的案例中是Ubuntu 14.04服务器)

在Jenkins配置中设置环境变量(Manage Jenkins -> Configure System -> Global properties -> Environment variablesname=PATH, value=$PATH:$COMPOSER_HOME/vendor/bin/)解决了这个问题。

enter image description here

$ echo $COMPOSER_HOME
/usr/share/.composer

注意,$COMPOSER_HOME应该/可能不会设置为(root)用户的子文件夹(例如/root/.composer),因为它可能导致permission issues:< / p>

  

执行失败:java.io.IOException:无法运行程序&#34; phpcs&#34;:错误= 13,权限被拒绝

Windows (在我的情况下是Windows Server 2008 r2)

除了设置Composer路径之外,还需要一些其他步骤:

我首先得到了错误

  

执行失败:java.io.IOException:无法运行程序&#34; phpcs&#34;:error = 2,系统无法找到指定的文件

在我读过的论坛上,目标需要获取可执行文件的路径,如下所示:

<target name="phpcs">
    <exec executable="C:\path\to\Composer\vendor\bin\phpcs" taskname="phpcs">
        <arg value="--standard=PSR2" />
        <arg value="--extensions=php" />
        <arg value="--ignore=autoload.php" />
        <arg path="${basedir}/module/" />
    </exec>
</target>

但它没有起作用,只会导致下一个错误:

  

D:\ path \ to \ build.xml:34:执行失败:java.io.IOException:无法运行程序&#34; C:\ path \ to \ Composer \ vendor \ bin \ phpcs&#34;: CreateProcess error = 193,%1不是有效的Win32应用程序

它不是Jenkins,而是Ant问题。原因和解决方案在Ant docu page for Exec

中描述
  

Windows用户

     

<exec>任务代表Runtime.exec,显然也是如此   电话   ::CreateProcess。   后者的Win32函数定义了它的确切语义   电话。特别是,如果你没有放置文件扩展名   可执行文件,只有&#34; .EXE&#34;寻找文件,而不是&#34; .COM&#34;,&#34; .CMD&#34;要么   环境变量PATHEXT中列出的其他文件类型。那是   仅由shell使用。

     

请注意, .bat 文件通常不能直接执行。一   通常需要使用。执行命令shell可执行文件cmd   /c切换。

     

...

因此,在我的情况下,工作目标规范如下所示:

<target name="phpcs">
    <exec executable="cmd" taskname="phpcs">
        <arg value="/c" />
        <arg value="C:\path\to\Composer\vendor\bin\phpcs" />
        <arg value="--standard=PSR2" />
        <arg value="--extensions=php" />
        <arg value="--ignore=autoload.php" />
        <arg path="${basedir}/module/" />
    </exec>
</target>

从现在开始,构建正在通过。但phpcs还存在问题:

phpcs:
    [phpcs] 'php' is not recognized as an internal or external command,
    [phpcs] operable program or batch file.
    [phpcs] Result: 1

通过将PHP添加到Jenkins中的Path环境变量(Manage Jenkins -> Configure System -> Global properties -> Environment variables)可以轻松解决此问题:

enter image description here

那就是它。 :)