Я работаю над проектом и хочу использовать для этого Дженкинса. Конфиг должен быть сделан простым build.xml
с целью fiew:
<?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, которые установлены глобально и используется из COMPOSER_HOME/bin
(например, PHP_Codesniffer).
Я пытался определить команды по-другому (например, <exec executable="cmd"><arg line="/c phpdox ..." /></exec>
), но это тоже не работает.
Прямое исполнение build.xml
с ant
работает.
Переменная окружения для Composer установлена правильно — я могу вызывать инструменты через CLI (CMD или GitBash / MinGW). Так что проблема, должно быть, была вызвана чем-то другим. Что это может быть?
Как заставить Дженкинса работать с глобально установленными пакетами через Composer?
Linux (в моем случае Ubuntu 14.04 Server)
Установка переменных среды в конфигурации Jenkins (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
), так как это может вызвать вопросы разрешения:
Ошибка при выполнении: java.io.IOException: не удается запустить программу «phpcs»: ошибка = 13, разрешение отклонено
Windows (в моем случае Windows Server 2008 r2)
В дополнение к настройке пути Composer были необходимы некоторые дальнейшие шаги:
Сначала я получил ошибку
Ошибка при выполнении: java.io.IOException: не удается запустить программу «phpcs»: ошибка = 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: Не удается запустить программу «C: \ path \ to \ Composer \ vendor \ bin \ phpcs»: ошибка CreateProcess = 193,% 1: не является действительным приложением Win32
Это не Дженкинс, а проблема с муравьями. Причина и решение описаны на Страница документа Ant для Exec
:
Пользователи Windows
<exec>
делегаты задачиRuntime.exec
что, в свою очередь, по-видимому,
звонки
:: CreateProcess.
Именно последняя функция Win32 определяет точную семантику
вызов. В частности, если вы не поместите расширение файла на
исполняемый файл, ищутся только «.EXE» файлы, а не «.COM», «.CMD» или
другие типы файлов, перечисленные в переменной окружения PATHEXT. То есть
используется только оболочкой.Обратите внимание, что .летучая мышь Файлы не могут быть выполнены напрямую. Один
обычно требуется выполнить исполняемый файл командной оболочки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
к Path
переменная окружения в Jenkins (Manage Jenkins -> Configure System -> Global properties -> Environment variables
):
Вот и все. 🙂
Других решений пока нет …