When queuing a new build using VS it is possible to pass in arguments to MSBuild which let's you do thing like skipping some steps of the build or do some things conditionally.
Is it possible to pass in such arguments to a build that's triggered by a checkin or a nightly build?
You can check the value of the $(Reason) property in your TfsBuild.proj file.
<Target Name="BuildNumberOverrideTarget" Condition=" '$(Reason)' == 'Schedule' ">
<MyBuildNumberGenerator TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)">
<Output TaskParameter="BuildNumber" PropertyName="BuildNumber" />
</MyBuildNumberGenerator>
</Target>
More details available here:
http://msdn.microsoft.com/en-us/library/cc716772(VS.90).aspx
Related
I created a Junit jenkins test case where a in-memory jenkins instance is launched (as we use #Rule jenkinsrule). The code of the test case is available here.
The test case will create a FreeStyleProject (= seed job) which will use as Groovy script DSL a maven.groovy file
But when the test case is executed, the following message is reported during the the job build execution. The message reports ghe consequence of the import/parsing of the mavenJob.groovy file as the job expects that a new job will be created.
Legacy code started this job. No cause information is available
Running as SYSTEM
Building in workspace /var/folders/t2/jwchtqkn5y76hrfrws7dqtqm0000gn/T/j h5344303144116520886/workspace/test0
Processing provided DSL script
ERROR: java.io.IOException: Unable to read /var/folders/t2/jwchtqkn5y76hrfrws7dqtqm0000gn/T/j h5344303144116520886/jobs/mvn-spring-boot-rest-http/config.xml
Finished: FAILURE
And of course no stack trace of the error is stdout or stderr.
How can I investigate the problem and fix it ?
Remark:
If I use the config.xml file and import it in a separate jenkins instance, the job succeeded
config.xml file generated, it looks good (vs same config.xml file created using the UI)
<?xml version='1.1' encoding='UTF-8'?>
<project>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>false</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers/>
<concurrentBuild>false</concurrentBuild>
<builders>
<javaposse.jobdsl.plugin.ExecuteDslScripts>
<scriptText>mavenJob('mvn-spring-boot-rest-http') {
description 'A Maven Job compiling the project Spring Boot Rest HTTP Example'
parameters {
gitParameter {
name 'SELECTED_TAG'
description 'The Git tag to checkout'
type 'PT_TAG'
defaultValue '2.3.4-2'
branch ''
branchFilter 'origin/(.*)'
quickFilterEnabled false
selectedValue 'DEFAULT'
sortMode 'DESCENDING_SMART'
tagFilter '*'
useRepository '.*rest-http-example.git'
listSize '10'
}
}
scm {
git {
remote {
url 'https://github.com/snowdrop/rest-http-example.git'
// branch('$SELECTED_TAG')
branch('2.3.4-2')
}
}
}
rootPOM 'pom.xml'
goals 'clean install'
}</scriptText>
<usingScriptText>true</usingScriptText>
<sandbox>false</sandbox>
<ignoreExisting>false</ignoreExisting>
<ignoreMissingFiles>false</ignoreMissingFiles>
<failOnMissingPlugin>false</failOnMissingPlugin>
<failOnSeedCollision>false</failOnSeedCollision>
<unstableOnDeprecation>false</unstableOnDeprecation>
<removedJobAction>IGNORE</removedJobAction>
<removedViewAction>IGNORE</removedViewAction>
<removedConfigFilesAction>IGNORE</removedConfigFilesAction>
<lookupStrategy>JENKINS_ROOT</lookupStrategy>
</javaposse.jobdsl.plugin.ExecuteDslScripts>
</builders>
<publishers/>
<buildWrappers/>
</project>
Many thanks in advance for your help.
I created a thread discussion here too: https://groups.google.com/g/jenkinsci-users/c/mRSwARFapyA
Charles
The problem was related to many missing dependencies needed to run the test case.
I upgraded the build.gradle file and now that works.
https://github.com/ch007m/jenkins-job-dsl/blob/jenkins-2.271/build.gradle#L53-L72
BTW, the error message reported was not correlated at all to the root cause and How to fix the problem. that should be improved within the code ;-)
I've tried this gradle plugin https://github.com/schmutterer/gradle-openjpa but it complains that it cannot find certain libraries and doesn't support providedCompile which makes this unusable for me anyway.
I've also tried calling ANT tasks, my latest attempt below is throwing:
Caused by: C:\Work_Java\workspace\PaxHoldRelease\jpa_enhance.xml:5: taskdef class org.apache.openjpa.ant.PCEnhancerTask cannot be found
build.gralde
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'ear'
// Java compilier compliance level
sourceCompatibility = 1.7
targetCompatibility = 1.7
repositories {
mavenLocal()
mavenCentral()
}
ant.importBuild 'jpa_enhance.xml'
war.dependsOn enhance
dependencies {
// Ensure ear plugin gets war file
deploy files(war)
providedCompile 'javax.servlet:javax.servlet-api:3.0.1'
compile 'javax.websocket:javax.websocket-api:1.1'
compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.16'
compile 'com.fasterxml.jackson.jaxrs:jackson-jaxrs-json-provider:2.5.1'
compile 'org.glassfish:javax.json:1.0.4'
providedCompile 'org.apache.openjpa:openjpa:2.2.2'
providedCompile 'com.sybase:jconn3:6.05'
providedCompile files('libs/sqljdbc4-3.0.jar')
}
jpa_enhance.xml
This is the latest version in a long list of attempts and probably complete rubbish as I just ripped everything out in a fit of desperation :-(
<project>
<target name="enhance">
<taskdef name="openjpac" classname="org.apache.openjpa.ant.PCEnhancerTask"/>
<!-- invoke enhancer on all .java files below the model directory -->
<openjpac>
</openjpac>
<echo message="Enhancing complete!"/>
</target>
</project>
Try this Andrew - I loosely based this gradle on the nice Enhancer script provided on S.O. by another member (for the DataNucleus enhancer).
Note that you will need to modify the entity-files (include/exclude) to point to your specific 'to be/to not be' enhanced Java source files. Further, this approach assumes that classpath derives from your parent build.gradle.
task openJPAEnhance {
description "Enhance JPA model classes using OpenJPA Enhancer"
dependsOn compileJava
doLast {
// define the entity classes
def entityFiles = fileTree(sourceSets.main.output.classesDir).matching {
include 'org/foo/mypkg/entity/*.class'
exclude 'org/foo/mypkg/entity/DoNotEnhance.class'
}
println "Enhancing with OpenJPA, the following files..."
entityFiles.getFiles().each {
println it
}
// define Ant task for Enhancer
ant.taskdef(
name : 'openjpac',
classpath : sourceSets.main.runtimeClasspath.asPath,
classname : 'org.apache.openjpa.ant.PCEnhancerTask'
)
// Run the OpenJPA Enhancer as an Ant task
// - see OpenJPA 'PCEnhancerTask' for supported arguments
// - this invocation of the enhancer adds support for a default-ctor
// - as well as ensuring JPA property use is valid.
ant.openjpac(
classpath: sourceSets.main.runtimeClasspath.asPath,
addDefaultConstructor: true,
enforcePropertyRestrictions: true) {
entityFiles.addToAntBuilder(ant, 'fileset', FileCollection.AntType.FileSet)
}
}
}
I hope this helps, and the individual who wrote that first gradle script did not mind that we re-purposed it (from DataNucleus) to OpenJPA.
I have the following code snap in ANT build.xml which is converting WSDL to Java. It works and uses axis-ant.jar 1.4.0
<!-- Build generated jars -->
<target name="axis-WSDL-2-Java" depends="init">
<taskdef resource="axis-tasks.properties" classpathref="axis.classpath" />
<axis-wsdl2java
output="${build.gen.src}"
testcase="true"
verbose="true"
url="${build.src.wsdl.v1}/${build.ws.wsdlfile}" >
</axis-wsdl2java>
<!-- Compile artifacts -->
<echo message="Compiling WS artifact source for Axis..." />
<javac destdir="${build.gen.classes}" debug="true" >
<src path="${build.gen.src}" />
<classpath>
<pathelement path="${build.lib.3rdParty}" />
<path refid="axis.classpath" />
</classpath>
</javac>
<jar .... some jar code here...
</jar>
</target>
Now, I converted the build script to Gradle and came up with the following Gradle code snap..
//wsdl to java
task axisWSDLTojava() << {
println "-- Inside axisWSDLToJava"
def flGen = new File( "$project.buildDir/thidsGen/src" )
flGen.mkdirs()
flGen = new File( "$project.buildDir/thidsGen/classes" )
flGen.mkdirs()
ant {
taskdef(
resource: 'axis-tasks.properties',
classpath: configurations.axisAnt.asPath )
axis-wsdl2java(
output: "$project.buildDir/thidsGen/src",
testcase: "true",
verbose: "true",
url: "$projectDir/src/ws/v1/wsdl/MDSSFileInfo.wsdl")
}
}
//compile generated src to classes
task compileJavaWsArtifacts (type: JavaCompile, dependsOn: axisWSDLTojava) << {
println "-- Inside compileGenSrc"
source = "$project.buildDir/thidsGen/src"
classpath = configurations.axisAnt.asPath
destinationDir = "$project.buildDir/thidsGen/classes"
}
// Build jar with web service artifacts
task jarWsArtifacts( type: Jar, dependsOn: compileJavaWsArtifacts ) << {
println "-- Inside jarWsArtifacts"
// some code here
// some code here to create the jar etc
}
Gradle logic for calling the respective task is all set i.e. I call the above task as dependsOn in CompileJava Gradle task..
// Compile java server components - must have artifacts first
compileJava {
dependsOn jarWsArtifacts
}
Configuration section in Gradle is defined as:
// Custom configurations
configurations {
axisAnt
}
Dependencies section in Gradle is defined as:
// Define dependencies
dependencies {
// Compilation
//compile 'groupid:artifactid:x.x.x'
//compile 'groupid:artifactid:x.x.x#yyy'
//other bunch of dependencies... come here which are required for compile task in Gradle
//axis-wsdl2java generates java files, which generates class files and jard into a -ws.jar file
compile fileTree( dir: 'build/resultantJar', include: "$ProjectName-ws-*.jar" )
// Unit Tests
testCompile 'xxx:yyy:x.x.x'
testCompile 'xxx:yyy:x.x.x'
//more artifacts for testCompile..
// Integration tests
// Everything from compile and testCompile targets
integrationTestCompile configurations.compile
integrationTestCompile configurations.testCompile
// Output of compiling "main" files
integrationTestCompile sourceSets.main.output
// Additional dependencies from war and others
integrationTestCompile 'xxx:yyy:x.x.x'
integrationTestCompile 'xxx:yyy:x.x.x'
//other enteries for IT test task
// All configuration files in conf folder in source control required for IT tests.
integrationTestRuntime files( 'conf' )
//Axis-ANT
axisAnt 'axis:axis-ant:1.4.0'
axisAnt 'othergroupid:otherartifactid:x.x.x'
axisAnt 'othergroupid:otherartifactid:x.x.x'
// comes here which are required for axis-wsdl2java to work
}
BUT, While running "gradle clean build", I'm getting the following error message:
:axisWSDLTojava FAILED
FAILURE: Build failed with an exception.
* Where:
Build file '/production/jenkinsAKS/workspace/DFDailyFeedSvc/build.gradle' line: 90
* What went wrong:
Execution failed for task ':axisWSDLTojava'.
> No such property: axis for class: org.gradle.api.internal.project.DefaultAntBuilder
Possible solutions: ant
Any idea, why it's not able to see axis-wsdl2java (which I see if defined in axis-tasks.properties file within axis-ant.jar version 1.4.0 as following:)
#properties file for taskdefing the public Axis taskdefs
axis-wsdl2java=org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask
axis-java2wsdl=org.apache.axis.tools.ant.wsdl.Java2WsdlAntTask
axis-admin=org.apache.axis.tools.ant.axis.AdminClientTask
OK, resolved.
Changing the following in the Gradle code did the trick. Don't know why Gradle didn't pick it without double quotes way. REASON: In Java/Groovy (Gradle uses Groovy), you can't have a function with a "-" in it's name (you can have giga_fifa but not giga-fifa). Glad, using "" resolved it.
axis-wsdl2java(
with
"axis-wsdl2java"(
Other thing, wherever I used "$project.buildDir .. I changed that to $buildDir as ANT was complaining about project.buildDir not found or buildDir not found when it was written in $project.buildDir format. Using $buildDir resolved those issues.
Also, compileJavaWsArtifacts was NOT seeing the generated src files!!! even though there were generated successfully after wsdl2java operation in Gradle build. So, did the shenzi using the following code:
//compile generated src to classes
//task compileJavaWsArtifacts (type: JavaCompile, dependsOn: axisWSDLToJava) << {
// source = "$buildDir/thidsGen/src"
// classpath = configurations.axisAnt.asPath
// destinationDir = "$buildDir/thidsGen/classes"
//}
//compile generated src to classes
task compileJavaWsArtifacts (dependsOn: axisWSDLToJava) << {
ant {
javac( destdir: "$buildDir/thidsGen/classes", debug: 'true', includeAntRuntime: 'no', classpath: configurations.axisAnt.asPath ) {
src( path: "$buildDir/thidsGen/src" )
}
}
}
I am using Ant as our setup script for our server, and we need to get the fully qualified name of our server. How can I get it using Ant, or is is possible in Ant?
The fully qualified hostname is like: xxx.company.com
<exec executable="hostname" outputproperty="computer.hostname"/>
will work on linux and windows, otherwise use the groovy solution from Marc O'Connor
Also nslookup will work on linux and windows, if you need the fullhostname you have to parse for the entry after Name: in nslookup ServerName output, use :
<groovy>
properties.'hostname' = "hostname".execute().text
//or
properties.'hostname' = InetAddress.getLocalHost().getHostName()
properties.'hostnamefull' = "nslookup ${"hostname".execute().text}".execute().text.find(/Name:\s(.+)/).split(/:\s+/)[1]
</groovy>
<echo>
$${hostname} => ${hostname}
$${hostnamefull} => ${hostnamefull}
</echo>
There is an Ant task called HostInfo that you can use to set properties containing the host name and domain of the current machine.
Alternatively, if you're running on Linux/Unix you could just call out to the hostname command:
<exec executable="hostname" outputproperty="myhostname">
<arg line="-f"/>
</exec>
The fully-qualified host name is then available in ${myhostname}.
EDIT: For a fully platform-independent solution, a custom task something like this (untested) should do the job:
public class GetHost extends Task
{
private String property;
public void setProperty(String property)
{
this.property = property;
}
#Override
public void execute() throws BuildException
{
if (property == null || property.length() == 0)
{
throw new BuildException("Property name must be specified.");
}
else
{
try
{
String hostName = InetAddress.getLocalHost().getHostName();
getProject().setProperty(property, hostName);
}
catch (IOException ex)
{
throw new BuildException(ex);
}
}
}
}
This can be used as follows:
<GetHost property="myhostname" />
Rehashing an answer I did for Maven :-)
Use an embedded groovy script to perform the Java hostname lookup:
<groovy>
properties["hostname"] = InetAddress.getLocalHost().getHostName()
</groovy>
Example
Project is self-documenting:
$ ant -p
Buildfile: /home/mark/tmp/build.xml
This is a demo project answering the followng stackoverflow question:
https://stackoverflow.com/questions/14653733
First install 3rd party dependencies
ant bootstrap
Then run the build
ant
Expect the following output
print-hostname:
[echo] Hostname: ?????
build.xml
<project name="demo" default="print-hostname">
<description>
This is a demo project answering the followng stackoverflow question:
https://stackoverflow.com/questions/14653733
First install 3rd party dependencies
ant bootstrap
Then run the build
ant
Expect the following output
print-hostname:
[echo] Hostname: ?????
</description>
<target name="bootstrap" description="Install 3rd party dependencies">
<mkdir dir="${user.home}/.ant/lib"/>
<get dest="${user.home}/.ant/lib/groovy-all.jar" src="http://search.maven.org/remotecontent?filepath=org/codehaus/groovy/groovy-all/2.1.0/groovy-all-2.1.0.jar"/>
</target>
<target name="print-hostname" description="Retrieve and print the hostname">
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<groovy>
properties["hostname"] = InetAddress.getLocalHost().getHostName()
</groovy>
<echo message="Hostname: ${hostname}"/>
</target>
</project>
Another approach is to write a javascript scriptdef that sets this information in properties.
<scriptdef name="get-hostame" language="javascript">
<attribute name="prefix" /> <![CDATA[
importClass(java.net.InetAddress);
address = InetAddress.getLocalHost();
prefix = attributes.get("prefix");
project.setNewProperty(prefix + ".hostname", address.getHostName());
project.setNewProperty(prefix + ".fqdn", address.getCanonicalHostName());
project.setNewProperty(prefix + ".address", address.getHostAddress());
]]>
</scriptdef>
You can call it like this:
<get-hostame prefix="uwi.host" />
Here is the result:
[echoproperties] uwi.host.address=10.666.666.666
[echoproperties] uwi.host.fqdn=myhost.stackoverflow.com
[echoproperties] uwi.host.hostname=myhos
This is based on some advice I found here:
http://grokbase.com/t/ant/user/051sygfj9b/any-way-to-get-at-the-machine-name
use enviroment
<property name="hostname" value="${env.COMPUTERNAME}"/>
Use javascript which is built-in
<script language="javascript">//<![CDATA[
project.setProperty("hostname", Packages.java.net.InetAddress.getLocalHost().getHostName());
project.setProperty("hostname-full", Packages.java.net.InetAddress.getLocalHost().getCanonicalHostName());
//]]></script>
<echo message="hostname=${hostname}"/>
<echo message="hostname-full=${hostname-full}"/>
In my ant script I want to exit (stop executing build) without failing when a condition is met. I have tried to use:
<if>
<equals arg1="${variable1}" arg2="${variable2}" />
<then>
<fail status="0" message="No change, exit" />
</then>
</if>
Ant script is stopped on condition but build is failed. I want to the build to be stopped but with no errors. I'm using "Invoke Ant" step in Jenkins.
Thanks.
I would suggest to refactor your ant script by reconsidering your approach. If you approach your problem with "execution of a build when a certain condition is met" instead of "failing the build if another condition is met" it is easier to implement:
<!-- add on top of your build file -->
<if>
<equals arg1="${variable1}" arg2="${variable2}" />
<then>
<property name="runBuild" value="true"/>
</then>
<else>
<property name="runBuild" value="false"/>
</else>
</if>
<!-- add to the target that shall be executed conditionally -->
<target name="myTarget" if="${runBuild}">
...
<!-- exit message as separate target -->
<target name="exitTarget" unless="${runBuild}">
<echo message="No Change, exit" />
</target>
Use builtin (since JDK 6) javascript engine,
no additional libraries (antcontrib .. etc.) needed !
1. Java System.exit()
<script language="javascript">
self.log("Ending intentionally \n...\n..\n.");
java.lang.System.exit(0);
</script>
you may get a BUILD FAILED when running in Eclipse :
BUILD FAILED
javax.script.ScriptException: sun.org.mozilla.javascript.internal.WrappedException:
Wrapped org.eclipse.ant.internal.launching.remote.AntSecurityException
=> then use Ant api instead
2. Ant api
<script language="javascript">
self.log("Ending intentionally \n...\n..\n.");
project.fireBuildFinished(null);
</script>
Output Eclipse, no BUILD SUCCESSFUL is printed :
[script] Ending intentionally
[script] ...
[script] ..
[script] .
Total time: 410 milliseconds
Output Console, BUILD SUCCESSFUL is printed 2 times :
[script] Ending intentionally
[script] ...
[script] ..
[script] .
BUILD SUCCESSFUL
Total time: 0 seconds
BUILD SUCCESSFUL
Total time: 0 seconds
Wrap in a macrodef for reuse, f.e. :
<macrodef name="stopbuild">
<attribute name="condition"/>
<attribute name="paramtype" default="math"/>
<attribute name="param1"/>
<attribute name="param2"/>
<attribute name="when" default="true"/>
<sequential>
<script language="javascript">
falsecondition = false;
switch ("#{condition}")
{
case "lt" :
b = "#{paramtype}" == "math" ? parseInt("#{param1}") < parseInt("#{param2}") : "#{param1}" < "#{param2}";
break;
case "gt" :
b = "#{paramtype}" == "math" ? parseInt("#{param1}") > parseInt("#{param2}") : "#{param1}" > "#{param2}";
break;
case "eq" :
b = "#{paramtype}" == "math" ? parseInt("#{param1}") == parseInt("#{param2}") : "#{param1}" == "#{param2}";
break;
default:
self.log("Wrong condition : #{condition}, supported: lt, gt, eq");
falsecondition = true;
}
if(!falsecondition && b == java.lang.Boolean.valueOf("#{when}")) {
self.log("Stopping Build because #{param1} #{condition} #{param2} is #{when} !!");
java.lang.System.exit(0);
// alternatively use
//project.fireBuildFinished(null);
}
</script>
</sequential>
</macrodef>
Examples
<!-- compare int, default paramtype=math and when=true -->
<stopbuild param1="10" param2="11" condition="lt"/>
output :
[script] Stopping Build because 10 lt 11 is true !!
<!-- compare strings, default when=true -->
<stopbuild param1="abc" param2="abcd" paramtype="foo" condition="lt"/>
output :
[script] Stopping Build because abc lt abcd is true !!
Internally <fail> throws a BuildException to fail the build process, so, as long as you are using this task, you will get the ant build exit with errors.
Personally I don't know if there is any other task to "normally" exit the build, but writing one by yourself is not hard at all.
Writing a task which executes the following code should work...
public void execute() {
// do something as you like
System.exit(0);
}