Teamcity, set configuration parameter for next build - teamcity

I'm trying to set/change a build parameter from build 1 to be used in build 2.
In build 1 I have a build step that sets a configuration parameter like this:
echo "##teamcity[setParameter name='ENVIRONMENT' value='%Target environment%']"
And in a build step on build 2, I want to use this environment variable in a rake task by
specifying %ENVIRONMENT%
The problem I have is that the configuration parameter is not visible in build 2. I have surely missed something essential.
I have also tried with env variables but that seems like the wrong approach as this is just configuration variables which is not needed in a build script.
Any clues?
Thanks

You can publish an artifact with the value you want in build 1, introduce an artifact dependency from build 2 to build 1, and in the first step of build 2 transform that artifact into a configuration value again for the other steps in build 2 by using the echo (or better Write-Host) statement you mentioned.

You can solve this in the same way I did for:
Is it possible to permanently update the value of a TeamCity build parameter as a result of a custom run?
Build 1 can update a variable which is being used in build 2 rather than build 2 trying to read a parameter in build 1.
Download and install CURL on build agent:
Add a command line step to build 1:
curl -v --request PUT -d "%Target environment%" --Header "Content-Type: text/plain" http://username:password#servername:8080/httpAuth/app/rest/projects/Build2Project/parameters/ENVIRONMENT
This updates the value of a parameter on a project, but you can use the REST API to update it on a particular build configuration if you prefer.
All REST.API documentation for TeamCity v8 can be found on their website

You can reference MyVariable variable which you set in Build configuration 1 in a script in Build configuration X such way: %dep.BuildConfiguration1Id.MyVariable%

Related

Share parameter with dynamic build configure ID in teamcity

I have a build chain with two jobs: B depends on A. B needs to get a build counter from A.
dep.btID.property name could share parameters from A to B.
However, the btID is dynamic create by git for each branch
I have add following to build steps of B(bash):
ABuildID=dep.dev_branch_A.env.BUILD_NUMBER
echo '%$ABuildID%'
or
echo '%${ABuildID}%'
It will lead to no compatible agent
Following could work however, I need to adapt to all branchs
echo '%dep.dev_branch_A.env.BUILD_NUMBER%'
Is there any way in TeamCity 9 to pass a build configuration parameter with dynamic btID from a project A to its dependency (in the same build chain)?
---------------------Update after finding the solution, hope it will help someone in the future------------------------
I have found a solution by request last successful build of projectA via rest api.
In bash:
curl -s https://teamcity_host_name/guestAuth/app/rest/buildTypes/dev_branch_A/builds?status=SUCCESS&state=finished&count=1
The response will provide the many parameter of project_A, build number is included
Please find introduction of teamcity rest API:
https://www.jetbrains.com/help/teamcity/rest-api.html#RESTAPI-URLStructure
Thanks Niraj Gajjar for the answser
You have add projectA in ProjectB as either Snapshot Dependency or Artifact Depedency ( for that go to Dependencies from left panel menu)
After that you can use build counter of ProjectA like
%dep.ProjectA.build.counter%
or
echo %dep.ProjectA.build.counter%

Does TeamCity support build steps that execute other TeamCity builds?

Using TeamCity, I've set up several builds in a project. Most of the time I want to run each build as a standalone. However, sometimes I want to execute several builds with the same set of parameters. The builds all use the same template, so all of their parameters could, theoretically, be supplied by a single build.
I can't find anything in the documentation that says this is possible, but it seems like it should be. (searching for "execute builds from another build in teamcity" gives me plenty of documentation on build dependencies, but not what I'm looking for)
I know I can manually queue up all of my builds, but that would require re-entering the same parameters each time.
Does TeamCity support build steps that execute other TeamCity builds? If so, How?
Not exactly. However, in TeamCity you can have a build chain (builds the invoke other dependant builds) by adding a snapshot dependency.
If you add a snapshot dependency on another build configuration, then you can access all its defined parameters and even source and artefacts.
I achieve this by calling the TeamCity REST API:
Add a new step at the end of your build, using Command Line runner
Do curl
curl -X POST -H "Authorization: Bearer %TeamCityToken%"
--header "Content-Type:application/xml"
-d"
<buildType id="Remote Deploy"/>
<property name="tag" value="%NewVersion%"/>
"
http://teamcity.example.com/app/rest/buildQueue
You will need to change:
TeamCityToken to your access token, refer to this page to create one: https://www.jetbrains.com/help/teamcity/rest/teamcity-rest-api-documentation.html#REST+Authentication
Build type id "Remote Deploy" to your build type id.
The properties to whatever you need.
And, of cause, the teamcity url.

Get Artifactory artifact by Jenkins build number

I'm investigating a Maven/Jenkins/Artifactory set up as a possible solution for a CI/Release process.
I have a job in Jenkins - call it MYJOB - that builds and deploys an artifact to Artifactory. Now, I want another job that I can run manually that will copy the artifact of a particular build of MYJOB from Artifactory and put it somewhere (not too bothered where right now, but eventually it'll be another server).
For example, let's say build #123 went green, and now my QA team want to deploy the built artifact to their environment for further testing (the idea being to keep this artifact intact and unchanged throughout the testing process, before marking it as releasable). I want them to be able to enter '123' into Jenkins as a job parameter and then kick off the build.
So, I figure I need a free-style job that uses a script to do this.
My question is: How can I pass the number of a previous MYJOB build to the job, so that it will get the correct artifact from artifactory?
Alternative methods of achieving my goal are welcomed :)
So I got it working. I put the following code in the Build Step section of a Jenkins Freestyle Build Configuration after defining a parameter called 'REQ_BUILD_NUMBER':
SOMETHING=$(curl "http://MYARTIFACTORYLOCATION/artifactory/api/search/prop?build.number=$REQ_BUILD_NUMBER" | jq --raw-output '.results[0].uri')
echo $SOMETHING
SOMETHING_ELSE=$(curl $SOMETHING | jq --raw-output '.downloadUri')
echo $SOMETHING_ELSE
wget -N --directory-prefix=/var/lib/jenkins/artifacts/ $SOMETHING_ELSE
(NB: I'm barely competent at shell scripting. I'm sure it can be done in a better way)
EDIT: This requires installing 'jq' for the command line.
Create a Parameterized build for the second job. The QA team can put the build number when they start the build. This build number will be available as an environment variable which can be accessed in the scripts which can then retrieve the packages from the repository.

How to prevent build steps running for personal builds

We have a build configuration in TeamCity with 3 build steps. Is there a way to prevent step 2 from running for personal builds such that normal VCS triggers executes steps 1, 2 and 3 - but only 1 and 3 are run for personal builds?
There is a variable BUILD_IS_PERSONAL set to true for personal builds, but it isn't defined if not:
http://confluence.jetbrains.com/display/TCD8/Predefined+Build+Parameters
How are you meant to use the variable as whenever I use it in a build configuration script, it asks me to define the value manually?
BUILD_IS_PERSONAL is a usual environment variable. It is only set if build is personal. Your build step can check for presence of this variable and exit immediately if it is defined.
For unix shell something like this should work:
if [ -n "$BUILD_IS_PERSONAL" ]; then
echo "Build is personal, exiting"
exit 0
fi
You could clone your build configuration (you could leverage templates, if your build configuration is not yet based on a template), and have two build configurations: one for normal builds and another for personal builds. On the personal build configuration, you would disable step 2.
I modified the configuration for the second step to be wrapped in this if statement:
IF "%%BUILD_IS_PERSONAL%%"=="" (
rem do stuff
)
The thing I had been missing was escaping the TeamCity variable syntax with an extra '%'.

Jenkins: How to use a variable from a pre-build shell in the Maven "Goals and options"

I have a Maven job in Jenkins. Before the actual build step I have an "Execute shell" pre-build step. In that shell I set a variable:
REVISION=$(cat .build_revision)
I would like to use that variable in the Maven build job in "Goals and options":
clean install -Drevision=${REVISION}
But that does not work! The "Drevision" is set to "${REVISION}" not the actual value of ${REVISION}. Output:
Executing Maven: -B -f /home/gerrit/.jenkins/jobs/<job_name>/workspace/pom.xml clean install -Drevision=${REVISION}
It works with Jenkins environment variables:
clean install -Dbuild=${BUILD_NUMBER}
It sets "Dbuild" to the actual build number. Output:
Executing Maven: -B -f /home/gerrit/.jenkins/jobs/<job_name>/workspace/pom.xml clean install -Dbuild=54
My question: How to use a shell variable in Maven "Goals and options"??
EDIT:
I tried using Jenkins EnvInject Plugin to "Inject environment variables" after the pre-build shell, and my variable is now accessible by e.g. post-build shells, but it is still not available in Maven "Goals and options".
Then it is possible to set "Inject environment variables to the build process" using the EnvInject Plugin, which actually makes those variables available in Maven "Goals and options", but those are set right after SCM checkout, i.e. before pre-build steps, and do not support expression evaluations.
You're on the right track here, but missed a third feature of the EnvInject-Plugin: The "Inject environment variables" build step that can inject variables into following build steps based on the result of a script or properties.
We're using the EnvInject plugin just like that; A script sets up a resource and communicates its parameters using properties that are then propagated by the plugin as environment variables.
i.e. setting up a temporary database for the build:
I had a very similar problem, trying to compute a build version and inject it into the build. After running into all the same issues (not expanding, etc), I used the "Generate environment variables from script" option, which interprets the output as tag=value pairs into Jenkins variables. The script :
#generate a version code that is high enough to surpass previously published clients
val=`expr 150000 + $BUILD_NUMBER`
echo VERSION_CODE=$val
After this, I was able to inject $VERSION_CODE into maven as follows :
-Dbuild.vercode=${VERSION_CODE}
Hope that works for you.
This issue is caused by a bug in the Jenkins Maven Project Plugin as detailed in this bug report opened on 2012-06-22. The plugin has not yet been fixed as of version 2.1.
A fix has been proposed for the Maven Project Plugin, but has not yet been integrated. Here is the link to the pull request: https://github.com/jenkinsci/maven-plugin/pull/14
If you build the plugin yourself with the pull request patch applied, the variables are injected and made available to the "goals and options" field as expected.
I see there is an accepted answer, but for a newbie in Jenkins I found it hard to grasp it all. That's why I would add a bit more detail in this answer and show how I did it.
As #jjungnickel suggested you need to have EnvInject Plugin installed for Jenkins. Then in the Build section > Add build step you'll get option "Inject environment variables".
Basically the idea is:
Add variables you want to access later to a file (might be added by a shell script or it could be file from the file system).
Inject the file with the variables.
Use the variables.
Here a sample setup:
Since I want to use them in maven goal I need to check the Inject Build Variables checkbox.
Then at the end of the build I remove the file just because I want to keep the environment as it was before the build.
I think your best shot is to try the EnvInject plugin for this along with your initial pre-scm step.
You run the pre-scm as you already do.
You use the env inject to load the file for the main job's build steps
Consider loading your file's content (properties format) or execute a script which will load the file as you want and make a variable available for the rest of the job with the "Prepare an environment for the run" option.
I hope this helps.
I needed to resolve the variables before the injection was done so I put this in script content:
Example: (note it doesn't seem possible to simply export variables here so I wrote to files and the help section in jenkins seems to indicate this is expected)
git ls-tree --name-only -r ${sha1} | grep -v -c "*\.md" > diff.bak
git diff origin/master --shortstat | grep "1 files changed" && echo 1 > count.bak || echo 0 > count.bak
I then added this in the groovy script, using the output files I can create a map:
def procDiff = "cat $WORKSPACE/diff.bak".execute()
def procCount = "cat $WORKSPACE/count.bak".execute()
def diff = procDiff.text
def count = procCount.text
print "string val = $diff and count = $count "
if ("0".equals(diff) || !"1".equals(count)){
def map = ["GOAL": "clean verify"]
return map
} else {
def map = ["GOAL": "clean"]
return map
}
Then I could reference $GOAL in my maven build to conditionally trigger a "clean" or a "clean verify" based on the type of PR raised.

Resources