当前位置: 首页 > 面试题库 >

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

谷梁玺
2023-03-14
问题内容

我正在开发一个项目,并希望使用Jenkins。该配置应由目标很少的简单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)工作可完美运行:

Console Output

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

But the executing of PHPDox is failing:

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软件包中也遇到了同样的问题,这些软件包已
全局安装并从中使用COMPOSER_HOME/bin(例如PHP_Codesniffer)。

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

build.xmlwith ant作品的直接执行

Composer的环境变量设置正确-我可以通过CLI 调用工具(CMD或GitBash / MinGW)。因此,问题一定是
由其他原因引起的。会是什么

如何使Jenkins处理通过Composer在全球安装的软件包?


问题答案:

Linux (in my case Ubuntu 14.04 Server))

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

$ echo $COMPOSER_HOME
/usr/share/.composer

请注意,$COMPOSER_HOME不应将/不应将其设置为(root)用户(例如/root/.composer)的子文件夹,因为它可能导致权限
问题:

Execute failed: java.io.IOException: Cannot run program “phpcs”: error=13,
Permission denied

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

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

首先我得到了错误

Execute failed: java.io.IOException: Cannot run program “phpcs”: error=2,
The system cannot find file specified

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

<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>

But it didn’t work and only causes the next error:

D:\path\to\build.xml:34: Execute failed: java.io.IOException: Cannot run
program “C:\path\to\Composer\vendor\bin\phpcs”: CreateProcess error=193, %1
is not a valid Win32 application

It’s not a Jenkins, but an Ant issue. The cause and the solution are described
on the Ant docu page for
Exec:

Windows Users

The <exec> task delegates to Runtime.exec which in turn apparently calls
::CreateProcess. It is the latter Win32 function that
defines the exact semantics of the call. In particular, if you do not put a
file extension on the executable, only “.EXE” files are looked for, not
“.COM”, “.CMD” or other file types listed in the environment variable
PATHEXT. That is only used by the shell.

Note that .bat files cannot in general by executed directly. One normally
needs to execute the command shell executable cmd using the /c switch.

So in my case the working target specification looks as follows:

<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>

From now the build was passing through. But there was still an issue with
phpcs:

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

This is easily fixed by adding PHP to the Path environment variable in
Jenkins (Manage Jenkins -> Configure System -> Global properties -> Environment variables):

enter image description here

That’s it. :)



 类似资料:
  • 问题内容: 在我的build.xml我定义了一些工作,应该由工具来执行,我安装global立法院通过作曲。这意味着,二进制文件存储在/root/.composer/vendor/bin/(我在root本地VM上工作)。 我PATH在composer configs中设置了环境变量(没有它,构建过程将失败): 现在,构建过程正在运行权限问题: 二进制文件对于每个人都是可执行的: 我已经安装了Auth

  • 问题内容: 某些软件(例如NetBeans IDE )将Linux安装程序随附在.sh文件中。我很好奇他们如何将整个IDE打包为“ shell脚本”,我在编辑器中打开了文件。我看到了一些纯文本shell脚本代码,然后看到了一些乱码,我认为是“二进制”或非普通文本。 我想知道他们如何混合普通的shell脚本,然后可能将它们称为“不可读的”东西,即二进制文件。 有什么见解吗? 问题答案: 基本上,这是

  • 问题内容: 使用带有角的ResponseEntity下载任何文件不起作用 我需要在客户端使用angular下载文件,该文件可以具有pdf或excel或image或txt的任何格式…我的方法仅适用于txt文件,但给我excel和image的失败格式,对于pdf,它会给出一个空的pdf。 所以在我的控制器中,这里是调用service方法的函数: 而我的service.js具有: 我的服务方法是这样的:

  • 问题内容: 为了将二进制文件上传到URL,建议使用本指南。但是,该文件不在目录中,而是存储在MySql db的BLOB字段中。BLOB字段在JPA中映射为属性: 我以这种方式稍微修改了指南中的代码: 我没有使用分块流。使用的标头是: 主机正确接收了所有标头。它还接收上载的文件,但不幸的是,它抱怨该文件不可读,并且断言所接收文件的大小比我的代码输出的大小大37个字节。 我对流,连接和byte []的

  • 问题内容: 目前,我可以按如下方式检索文本页面 假设get以二进制文件为目标。如何将其正确保存到磁盘? 问题答案: 只是不要通过-从中读取数据并将其写入。

  • 问题内容: 我有一个字节列表作为整数,这类似于 如何将此列表作为二进制文件写入文件? 这行得通吗? 问题答案: 这正是用于: 如果您使用的是Python 3.x,则可以改用(也许应该这样做,因为它可以更好地表明您的意图)。但是在Python 2.x中,这是行不通的,因为它只是的别名。像往常一样,使用交互式解释器进行显示比使用文本进行解释要容易,所以让我这样做。 Python 3.x: Python