Ant inline exec arguments - ant

I have tasks running in Ant, which I'm quite new to, as part of a CI chain of build events. I used a tutorial to create the file for testing/linting/etc a PHP application.
The first important directives in the build.xml are:
<property name="phpmd" value="phpmd"/>
<property name="phpunit" value="phpunit"/>
This works fine as is, assuming that phpmd/phpunit are on the path, and using phpunit as a further example, is run under the following target:
<target name="phpunit" unless="phpunit.done" depends="prepare" description="Run unit tests with PHPUnit">
<exec executable="${phpunit}" resultproperty="result.phpunit" taskname="phpunit">
<arg value="--configuration"/>
<arg path="${basedir}/phpunit.xml"/>
</exec>
<property name="phpunit.done" value="true"/>
</target>
All this works well as is- but I want to use docker from now on, which I had hoped would simply mean changing <property name="phpunit" value="phpunit"/> to <property name="phpunit" value="docker-compose run php phpunit"/>, but this instead gives me the following error:
Execute failed: java.io.IOException: Cannot run program "docker-compose run -w /var/www/src php phpunit" (in directory "/var/lib/jenkins/jobs/Blah blah blah/workspace/src"): error=2, No such file or directory
I know that you would usually add additional <arg/> nodes to targets- but is it not possible at all to provide the full command with inline arguments on the initial <property>?
Ant is obviously complaining because, along with those inline arguments, that executable doesn't exist. Will I have to use arg nodes and update every single target?
Using docker-compose alone works fine, but I need the args for the correct container and working directory to be used- preferably inline, otherwise I have to insert many arg nodes.

In the end I just created a property for phpunit arguments and then added it by using the <args line="${phpunitArgs}">.
Definitely not ideal, but at least it does what it is supposed to. I certainly prefer using Gulp! XML feels like a bad choice for a build system.

Related

Running an OS command using apache-ant to IIS config

I'm trying to create an ANT script which amongst other things will configure IIS.
To do this, trying to harness the appcmd tool. However getting a strange error. The appcmd command runs fine outside of the ant script, but fails within.
I'm using the exec task to kick it all off :
<exec dir="C:\\Windows\\System32\\inetsrv\\"
executable="C:\\Windows\\System32\\inetsrv\\appcmd.exe" output="d:\out.txt">
<arg value="appcmd set config /section:isapiCgiRestriction /+"
[path='${appian_home}\\jakarta\\ISAPI\\isapi_redirect.dll',
description='Jakarta',allowed='True']"" />
</exec>
The output trapped via ANT is :
Object 'APPCMD SET CONFIG /SECTION:ISAPICGIRESTRICTION /+?
[PATH='D:\PTMP2\APPIAN17\\JAKARTA\\ISAPI\\ISAPI_REDIRECT.DLL',
DESCRIPTION='JAKARTA',ALLOWED='TRUE']' is not supported.
Run 'appcmd.exe /?' to display supported objects.
However when I run
If I c&p that command to the dos prompt it will happily run :
C:\Windows\System32\inetsrv>appcmd set config /section:isapiCgiRestriction
/+"[path='d:\ptmp2\appian17\\jakarta5\\ISAPI\\isapi_redirect.dll',descripti
on='Jakarta',allowed='True']"
Applied configuration changes to section
"system.webServer/security/isapiCgiRestriction" for
"MACHINE/WEBROOT/APPHOST" at configuration commit path "M
ACHINE/WEBROOT/APPHOST"
Needs to escaped single quote as well.
Also changed path separate to /
Use below:
<exec executable="cmd.exe" dir="C:/Windows/System32/inetsrv" failonerror="true">
<arg line="/c appcmd set config /section:isapiCgiRestriction /+"[path=&apos;${appian_home}/jakarta/ISAPI/isapi_redirect.dll&apos;,description=&apos;Jakarta&apos;,allowed=&apos;True&apos;]""/>
</exec>

Configure Jenkins to deploy PHP project that passed PHPUNit

I have PHP Project, that is hosted on GitHub.
Now, I'd like to configure Jenkins to run unit tests so that:
Whenever developer push/commits code to specific branch, it triggers corresponding PHPUnit build job.
If commit passes the unit tests, the source code is deployed (assuming I already have the required script to deploy).
The question is how to trigger the deployment script when source code passes the unit test (i.e. PHPUnit tests succeed)?
Please suggest to me the way to do that, which plugin I should try to achieve the result?
Thanks!
This is going to be a long post, as there's a lot involved, but it works a treat:
You will need:
Ant
Git Publisher plugin
Ant and phpunit will need to be on your PATH
Step 1: Configure your project
In your Jenkins, configure your project to 'Poll SCM' under the Git option. Leave the 'Schedule' as blank. Under 'branches to build' set that as the branch you want to build your release package from.
Reference:
Step 2: Run ant for every build
Add a build step to 'Invoke Ant'
If you don't use Ant already, create a build.xml file in your project root, add it to Git and have the following contents:
<?xml version="1.0" encoding="UTF-8"?>
<project default="full-build">
<property name="phpunit" value="phpunit"/>
<target name="full-build"
depends="phpunit-unittests,-check-failure"
description="runs the tests"/>
<target name="phpunit-unittests"
unless="phpunit-unittests.done"
description="Run unit tests with PHPUnit">
<exec executable="cmd" failonerror="true" resultproperty="result.phpunit" taskname="phpunit-unittests">
<arg value="/c"/>
<arg value="${phpunit}"/>
<arg value="--configuration"/>
<arg path="${basedir}/phpunit.xml"/>
<arg value="--testsuite=Unit"/>
</exec>
<property name="phpunit-unittests.done" value="true"/>
</target>
<target name="-check-failure">
<fail message="PHPUnit did not finish successfully">
<condition>
<not>
<equals arg1="${result.phpunit}" arg2="0"/>
</not>
</condition>
</fail>
</target>
</project>
That will run all unit tests whenever the Ant task is invoked, which is now set for every time the project is built.
Then, install the Git Publisher tool. Configure as follows:
This creates a new release tag upon a successful build. You will use this later to publish the release to the final location. Note: There are different variables that Git Publisher provides for use, commit hash, user etc so use what you want. I stick to an incremental tag of v1.1.BUILD as that's a bit more standard.
Lastly, you will need to add a Git hook which will trigger a build upon a commit/push from any location.
Navigate to your repository folder and within that the 'hooks' directory.
Create a new file named 'post-receive' (you will see examples in there; overwrite this one). Place the following content in:
#!/bin/bash
while read oldrev newrev refname
do
branch=$(git rev-parse --symbolic --abbrev-ref $refname)
if [ "master" == "$branch" ]; then
curl http://YOUR_JENKINS_URL:8080/git/notifyCommit?url=YOUR_GIT_REPOSITORY_URL
fi
done
That should do the job nicely. I have left out implementation details of how you actually release your project as everyone does this differently. There are options to FTP files to a location, and all sorts. Personally I go into the folder where the application resides and do a checkout of the newly created tag - a one line command. Whatever suits your environment.
Other stuff I've ommitted but you will find useful - the Ant build task can do literally anything - In mine, I run composer to install dependences, run bower, run grunt, do syntax checking, coding standard checking, fire up selenium and run web tests, and a load of other stuff. It's a perfect combination of tools to automate the whole project deployment.

JMeter overriding properties with spaces in non GUI mode with ANT

I need to pass parameter values to jmeter properties like this:
#echo off
cd E:\apache-jmeter-2.11\bin
jmeter.bat -n
-t E:\OMS.P01-AccountCreation.jmx
-l E:\result.csv
-j E:\jmeter.log
-Jthreadgroup.count=1
-JPRIMARY_STREET_NUMBER=1234
-JPRIMARY_STREET_NAME=DONALDTRUMP AVENUE
But this will fail as the name 'DONALDTRUMP AVENUE' has an space. It will try to read 'AVENUE' as a different parameter. Is there any way to make it read as a whole value? thanks
EDIT
It works if I add "" to enclose it. However, when I try the same thing with ANT, it throws the same error. Does anyone knows how can I solve it?
EDIT 2
I tried again with command line instead of ant. I think I found the problem. I cant add too many parameters (I'm adding like 22 parameters) I'm not sure if there is a parameter limit or if there is a length limit for the whole command line.
I don't know how you're passing properties to Ant but normally smart people don't have any problems with spaces in property values. Are you aware that:
Ant doesn't know anything regarding -J command line argument
Ant knows nothing about JMeter properties
So if you need to pass to JMeter something you can change via Ant command-line you need to do something like:
In build.xml
<target name="jmeter">
<jmeter
jmeterhome="/path/to/your/jmeter"
testplan ="OMS.P01-AccountCreation.jmx"
resultlog="result.jtl">
<property name="jmeter.save.saveservice.output_format" value="xml"/>
<property name="jmeter.save.saveservice.assertion_results" value="all"/>
<property name="jmeter.save.saveservice.bytes" value="true"/>
<property name="threadgroup.count" value="${threadgroup.count}"/>
<property name="PRIMARY_STREET_NUMBER" value="${PRIMARY_STREET_NUMBER}"/>
<property name="JPRIMARY_STREET_NAME" value="${PRIMARY_STREET_NAME}"/>
</jmeter>
</target>
When launching JMeter test via Ant:
ant -Dthreadgroup.count=1 -DPRIMARY_STREET_NUMBER=1234 -DPRIMARY_STREET_NAME="DONALDTRUMP AVENUE"
References:
Command prompt (Cmd. exe) command-line string limitation
Five Ways To Launch a JMeter Test without Using the JMeter GUI

Ant task hangs due to suspected permissions issue

I have a STAF job which kicks off an Ant script, all run under a functional ID. The ant script does basic 'init' tasks which work fine, and then hangs on one of the following tasks: delete, mkdir, or junit, depending on how much muddling I do in the file system.
<target name="run.nightly.tests" depends="init">
<delete dir="/path/results/latestDate" />
<mkdir dir="/path/results/latestDate" />
<chmod perm="777" dir="/path/results/latestDate" />
<junit printsummary="on" fork="no">
<!-- typical classpath/tests setup snipped -->
</junit>
</target>
I am able to sudo to this functional ID and run the corresponding commands from a shell just fine (ex: rm -rf /path/results/latestDate). Clearly something is different about running in the Ant environment, under the functional id. (In fact, I can run the script just fine with my own id)
/path/results has 777 permissions before my script runs, and when /path/results/latestDate exists it is owned by the same functional id w/ 777 permissions.
STAF launches this script:
export ANT_HOME=/opt/apache-ant-1.8.2
#This entire directory tree and jar files are world r+x
LIB_DIR=/home/afreed/automation/dependencies/mail
ant -debug -verbose -buildfile nightlyTest.xml -lib ${LIB_DIR}/mail.jar:${LIB_DIR}/activation.jar
I would understand if Ant would fail on any of these tasks with a permissions error but I cannot understand why it would hang.
I would like help either a) determining why there is a hang or b) how to convert the hang to a hard failure
Solved, the Ant script was hanging on an exec command that was waiting for input from STDIN. (Execution had continued past that point because it was launched with 'spawn' attribute.) When I removed this 'exec' task from my 'init' target, the Ant script ran as expected.
<!-- hanging task in init-->
<exec executable="blah.sh" spawn="true">

ANT build runs fine with WS_ANT but fails in RAD

Just trying to run ANT script with in IBM RAD\RSA 8 to deploy to websphere .
It works fine when run from command prompt using WS_ANT.bat but inside RAD fails with following error
Unable to determine WAS Home directory. Please use the wasHome task attribute or set the was.root System property.
Following is basic ANT script copied from SO and Modified again runs fine from WS_ANT but not from RAD
<?xml version="1.0"?>
<projectname="project"default="wasListApps"basedir=".">
<description>
Script for listing installed apps.
Example run from:
/opt/IBM/SDP70/runtimes/base_v61/profiles/AppSrv01/bin
</description>
<propertyname="was_home"location="C:\Program Files\ibm\SDP80\runtimes\base_v7"/>
<pathid="was.runtime">
<filesetdir="${was_home}/lib">
<includename="**/*.jar"/>
</fileset>
<filesetdir="${was_home}/plugins">
<includename="**/*.jar"/>
</fileset>
</path>
<propertyname="was_cp"value="${toString:was.runtime}">
</property>
<propertyname="was_server"value="server1"/>
<propertyenvironment="env">
</property>
<targetname="wsStopServer">
<taskdefname="wsStopServer"classname="com.ibm.websphere.ant.tasks.StopServer"classpath="${was_cp}">
</taskdef>
<wsStopServerserver="${was_server}"failonerror="false"/>
</target>
<targetname="wsStartServer" depends="wsStopServer">
<taskdefname="wsStartServer"classname="com.ibm.websphere.ant.tasks.StartServer"classpath="${was_cp}">
</taskdef>
<wsStartServerserver="${was_server}"failonerror="true"/>
</target>
<targetname="wasListApps"depends="wsStartServer">
<taskdefname="wsListApp"classname="com.ibm.websphere.ant.tasks.ListApplications"classpath="${was_cp}">
</taskdef>
<wsListAppwasHome="${was_home}"/>
</target>
</project>
If you look at the ws_ant.bat file you will find it calls the setupCmdLine.bat first thing to, you guessed it, setup the command line. That file tries to determine the WAS_HOME environment variable by setting it to the parent directory.
SET CUR_DIR=%cd%
cd /d "%~dp0.."
SET WAS_HOME=%cd%
cd /d "%CUR_DIR%"
This is fine when you run from the command line. You are usually in the ~/SDP/runtimes/base_v7/bin (or other server version) directory. The parent is where you want to be.
I would look into setting the working directory when you run the ws_ant.bat script. That is probably the most likely cause.

Resources