Jenkins Ant and dynamic build.properties files - ant

I have a single code based being used to build an application for multiple platforms.
Locally I have setup a main build-env.properties file, and a series of additional *.properties files that I use to switch settings for the different platforms I am publishing to.
Doing my build on the command line I simply use the command:
ant build -propertyfile dev-build.properties
How can I do this in Jenkins?
I currently use the "Invoke Ant" Build Step with the target set to build, but am at a loss for how to specify the secondary propertyfile?

Although not exactly the same, you can take the contents of those properties and put them into the Jenkins Invoke Ant build step, utilizing the properties advanced field.
The most basic way:
You will need to create a new task for each different set of sub properties you wish to utilize.
In your "Invoke Ant" build step, if you press Advanced..., this reveals a "Properties" field, you can copy the properties from one of your *.properties files into that field.
Repeat for each different properties file you wish to utilize.

Parametrized build plugin might help you. This is assuming the number of properties you are changing is one or two. So when you run a job, you get a drop-down to select you OS and go.
Though, as I have mentioned here , what goes against this plugin is that it makes the process manual
On this thread Hudson / Jenkins: share parameters between several jobs you can read the 2nd option in Anders's answer as an alternate approach.

A better approach for this is using a parameterised job with file parameter(refer to doc for creating the builds). Mentioning the file location as "propertyfile" would help. This would be better than reconfiguring the job again and again to run a build (To copy the properties file to the input location).

Related

How do I use TFS to autobuild a non default configuration

We have a large code base with various labels which need autobuilding.
We are using TFS 2012 Express and VS 2010
Our code is build by a batch file so I have created a dummy solution which the autobuild builds, the build instructions for this solution just run the batch file.
I had the idea of using different configurations in this solution to build different labels.
So, as well as debug and release configurations I added one called LABEL which calls a different batch file and added a new automatic build in TFS which calls this solution with the 'label' configuration in the box Required - Configurations to build.
However, when I try to run it it fails claiming that the 'label' configuration does not exist.
Does anyone know how to do this?
Extra:
It seems to work if I use the Release configuration to call one batch file and the Debug one to call another but it still cannot find user created configurations?
If presume "Autobuild" means "build via TFS build definition".
If by "label" you mean a source control label, then when queuing a build, you can set its "Get Version" parameter to a label - for example, for the label MyLabel use LMyLabel.
If by "label" you mean some definition internal to the batch-file build, then you can pass it via an MSBuild property: Define it in the build definition by adding "/p:label=mylabel" to "MSBuild parameters". Then, where the solution calls your batch, you can use $(label) to get the value from the build definition.
Also, instead of this hacky .sln, you could modify the build template to call your batch file directly, and have a parameter which you set in the build definition, and the template passes it to the batch file.

How to conditionally build other projects?

I have a fairly complicated Jenkins job that builds, unit tests and packages a web application. Depending on the situation, I would like to do different things once this job completes. I have not found a re-usable/maintainable way to do this. Is that really the case or am I missing something?
The options I would like to have once my complicated job completes:
Do nothing
Start my low-risk-change build pipeline:
copies my WAR file to my artifact repository
deploys to production
Start my high-risk-change build pipeline:
copies my WAR file to my artifact repository
deploys to test
run acceptance tests
deploy to production
I have not found an easy way to do this. The simplest, but not very maintainable approach would be to make three separate jobs, each of which kicks off a downstream build. This approach scares me for a few reasons including the fact that changes would have to be made in three places instead of one. In addition, many of the downstream jobs are also nearly identical. The only difference is which downstream jobs they call. The proliferation of jobs seems like it would lead to an un-maintainable mess.
I have looked at using several approaches to keep this as one job, but none have worked so far:
Make the job a multi-configuration project (https://wiki.jenkins-ci.org/display/JENKINS/Building+a+matrix+project). This provides a way to inject the job with a parameter. I have not found a way to make the "build other projects" step respond to a parameter.
Use the Parameterized-Trigger plugin (https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+Trigger+Plugin). This plugin lets you trigger downstream-jobs based on certain triggers. The triggers appear to be too restrictive though. They're all based on the state of the build, not arbitrary variables. I don't see any option provided here that would work for my use case.
Use the Flexible Publish plugin (https://wiki.jenkins-ci.org/display/JENKINS/Flexible+Publish+Plugin). This plugin has the opposite problem as the parameterized-trigger plugin. It has many useful conditions it can check, but it doesn't look like it can start building another project. Its actions are limited to publishing type activities.
Use Flexible Publish + Any Build Step plugin (https://wiki.jenkins-ci.org/display/JENKINS/Any+Build+Step+Plugin). The Any Build Step plugin allows making any build action available to the Flexible Publish plugin. While more actions were made available once this plugin was activated, those actions didn't include "build other projects."
Is there really not an easy way to do this? I'm surprised that I haven't found it and even more surprised that I haven't really seen any one else trying to do this? Am I doing something unusual? Is there something obvious that I am missing?
If I understood it correct you should be able to do this by following these Steps:
First Build Step:
Does the regular work. In your case: building, unit testing and packaging of the web application
Depending on the result let it create a file with a specific name.
This means if you want the low-risk-change to run afterwards create a file low-risk.prop
Second Build Step:
Create a Trigger/call builds on other projects Step from the Parameterized-Trigger
plugin.
Entery the name of your low-risk job into the Projects to build field
Click on: Add Parameter
Choose: Parameters from properties File
Enter low-risk.prop into the Use properties from file Field
Enable Don't trigger if any files are missing
Third Build Step:
Check if a low-risk.prop file exists
Delete the File
Do the same for the high-risk job
Now you should have the following Setup:
if a file called low-risk.prop occurs during the first Build Step the low-risk job will be started
if a file called high-risk.prop occurs during the first Build Step the high-risk job will be started
if there's no .prop File nothing happens
And that's what you wanted to achieve. Isn't it?
Have you looked at the Conditional Build Plugin? (https://wiki.jenkins.io/display/JENKINS/Conditional+BuildStep+Plugin)
I think it can do what you're looking for.
If you want a conditional post-build step, there is a plugin for that:
https://wiki.jenkins-ci.org/display/JENKINS/Post+build+task
It will search the console log for a RegEx you specify, and if found, will execute a custom script. You can configure fairly complex criteria, and you can configure multiple sets of criteria each executing different post build tasks.
It doesn't provide you with the usual "build step" actions, so you've got to write your own script there. You can trigger execution of the same job with different parameters, or another job with some parameters, in standard ways that jenkins supports (for example using curl)
Yet another alternative is Jenkins text finder plugin:
https://wiki.jenkins-ci.org/display/JENKINS/Text-finder+Plugin
This is a post-build step that allows to forcefully mark a build as "unstable" if a RegEx is found in console text (or even some file in workspace). So, in your build steps, depending on your conditions, echo a unique line into console log, and then do a RegEx for that line. You can then use "Trigger parameterized buids" and set the condition as "unstable". This has an added benefit of visually marking the build different (with a yellow ball), however you only have 1 conditional option with this method, and from your OP, looks like you need 2.
Try a combination of these 2 methods:
Do you use Ant for your builds?
If so, it's possible to do conditional building in ant by having a set of environment variables your build scripts can use to conditionally build. In Jenkins, your build will then be building all of the projects, but your actual build will decide whether it builds or just short-circuits.
I think the way to do it is to add an intermediate job that you put in the post-build step and pass to it all the parameters your downstream jobs could possibly need, and then within that job place conditional builds for the real downstream jobs.
The simplest approach I found is to trigger other jobs remotely, so that you can use Conditional Build Plugin or any other plugins to build other jobs conditionally.

How to configure Jenkins in order to build project using ant and custom args

There's too much routine with building next project version using ant. The routine is in several properties files that must be edited before running ant task. I took a look at Jenkins as a system to make builds (including night ones) but I have a problem with changing properties.
Is it possible (if yes, how can I do it) to type parameters in Jenkins configuration before build in order they will be passed to ant?
What I really mean is the following schema (I used in manual builds):
there're 2 properties files that contain data about build version, src destination, emails to notify about new build and so on.
corresponding properties' keys are used in Ant tasks and these properties are changed manually before build.
some properties are read by Java util and used for their own part during build.
there're also 3 or 4 ant XMLs that a imported in build.xml, and these xmls also read properties from mentioned files.
What I want to do is:
change key properties in Jenkins
press build project
my data will overwrite data in properties files OR will be passed as ant vars values straight to the ant's task(s).
as a result I receive new build with corresponding notifications (they're made through ant)
Are there mechanisms that allow one to make such schema work via Jenkins?
Thank you in advance.
In Jenkins, you can use the parameterised build feature to specify those parameters you need to substitute into your build.
For example, if specify a parameter called server and, when clicking "Build Now", you enter test, the build will be executed with an environment variable you can access called ${server}.
Then, in your "Invoke Ant" build step, if you press Advanced..., this reveals a "Properties" field. Here you can enter my.ant.property=${server}.
That's equivalent to calling ant -Dmy.ant.property=${server}, and will be expanded to ant -Dmy.ant.property=test.
Another option : Set environment variables for the scope of the build using this Env plugin. So if the properties you are using are environment variables or can be set as them then you want to use this one. Though it might involve some effort in changing the build scripts, but it can be a good option :
Q : Why would I use this one as I already have parametrized build plugin
A : Because the parametrized build plugin requires human interaction if there is more than 1 choice. For example building for Release 1 or Release 2 or Test branch.
While in the Env plugin, you can set the property once for each choice and then create a respective job for each. Then just schedule the job(s) thereby eliminating the human factor.

Can TFS build multiple solutions using "wildcards" or similar?

If I want to build multiple solutions in TFS Build I can add multiple SolutionToBuild elements to the Build Definition.
However, I want to specify a path to a folder, and then have TFS automatically find and build all solutions in this folder and subfolder, without me adding a SolutionToBuild element for each individual solution.
Is this possible?
Yes, this is possible, but not with the default build template as is. In the early stages of build execution, find a suitable build process trigger and include a step that finds your solutions in a supplied directory, and enter these solutions in the list of the SolutionToBuild variable. Then your script will continue as if you have added multiple SolutionToBuild elements.
No this is not possible. You can open the build default template and see how the projects/solutions to build are built with MSBuild.

TFS 2010 Build Definition

In the TFS 2010 build definition window, under “Process” there are two required items. They are “Configurations to build” and “Projects to build”. Under projects to build, it will allow me to enter something like:
$/TeamProject/Area1/Area2/*
However, this doesn’t seem to do what I expect. The build fails because it’s looking for:
$/TeamProject/Area1/Area2/Sources/*
What I am trying to achieve by this is to build all the solutions held under this area. For example, I have:
$/TeamProject/Area1/Area2/Solution1/Solution1.sln
$/TeamProject/Area1/Area2/Solution2/Solution2.sln
$/TeamProject/Area1/Area2/Solution3/Solution3.sln
There are many more solutions than this, which is why I’m looking for a way to build all solutions under the specified path recursively. Is there a way to do this in TFS 2010?
You can modify the process template. Expand it with the Matching files (I don't have the exact naming now) activity. Add a parameter that passes the information you set in the build defintion to the MachingFiles actvity. Then pass into the build solution activity instead of the argument that you enter in the build definition the files that is found by the MatchingFiles activity.
Now add a dummy solution in the build definition for the solution to build (it is not used anymore).
See the blog post series on the build customization for more information on customizing the build process template.
FWIW,
I've got: "configurations to build" blank
and under "projects to build" I've added my solutions via the ellipsis button
I would setup mappings for
$/TeamProject/Area1/Area2/Solution1/
$/TeamProject/Area1/Area2/Solution2/
$/TeamProject/Area1/Area2/Solution3/
Then in the build definitions enter the three projects to build
$/TeamProject/Area1/Area2/Solution1/Solution1.sln
$/TeamProject/Area1/Area2/Solution2/Solution2.sln
$/TeamProject/Area1/Area2/Solution3/Solution3.sln
You can leave the configurations to build as blank, or if you want to do a certain build you can set it to (for example) something like Debug|Mixed Platforms (check your Configuration Manager... for the solutions you are building to see what is valid)
Alternatively, you can just map the following (depending on how much you have in this folder, if you have Solutions 4+ that you don't want to trigger builds on, don't do it at this level)
$/TeamProject/Area1/Area2
And have one solution which contains the Solution1, Solution2 and Solution3, and build that instead.
By default building your Solution1 which is mapped to
$/TeamProject/Area1/Area2
On a build agent with a working directory that is going to looks something like:
$(SystemDrive)\Builds\$(BuildAgentId)\$(BuildDefinitionPath)
You'll end up with it being build under
C:\Builds\1\Solution1\Binaries
C:\Builds\1\Solution1\Sources
C:\Builds\1\Solution1\TestResults
Which is why you want to make sure that your OutDir's etc are all correct and not hard coded!
If you have a look while building, you'll see the build agent populating the Sources folder, and it should (if configured correctly) put all outputs into the Binaries folder (and then copy them to the Drop Folder configured under Build Defaults in TFS.

Resources