Adding version number to Jenkins build artifact - jenkins

I have been ordered to migrate a dotnet build from Bamboo to Jenkins. I used a Freestyle job to run a powershell script, using the PowerShell plugin and successfully built it. However I need to add version number to the built artifact. The Bamboo job uses:
~\.dotnet\tools\dotnet-lambda.exe package -pl $fullDir -f "netcoreapp3.1" -o Payment.${bamboo.majorVersion}.${bamboo.minorVersion}.${bamboo.revisionVersion}.${bamboo.buildNumber}.zip
I went into Jenkins Configuration and in Global Properties, created Environment variables named - buildNumber, majorVersion, minorVersion and revisionVersion, giving it values and in the Build part of the Freestyle job, I used:
~\.dotnet\tools\dotnet-lambda.exe package -pl $fullDir -f "netcoreapp3.1" -o Payment.${env.majorVersion}.${env.minorVersion}.${env.revisionVersion}.${env.buildNumber}.zip
However the name of the built artifact is: Payment.....zip
How can I pass the variable values?
Is there a way to auto increment the revisionNumber and buildNumber, instead of hard coding it?
I'm very new to both Bamboo and Jenkins. Any help would be extremely helpful.
Regards
Ramesh

Personally, I'd not configure this things globally as they seem job specific. Nevertheless,
Install the Environment Injector plugin. You now have two options:
General tab
[ X ] Prepare an environment for the run
Build Environment tab
[ X ] Inject environment variables to the build process
Set the "Properties Content" (that's an environment variable).
In your shell step( no need to preface with ${env....} ):
Execute Shell step:
#!sh -
echo ${FOO}.${BUILD_NUMBER}
echo ${LABEL}
Output:
[EnvInject] - Loading node environment variables.
[EnvInject] - Preparing an environment for the build.
[EnvInject] - Keeping Jenkins system variables.
[EnvInject] - Keeping Jenkins build variables.
[EnvInject] - Injecting contributions.
Building in workspace C:\Users\jenkins\.jenkins\workspace\Foo
[EnvInject] - Executing scripts and injecting environment variables after the SCM step.
[EnvInject] - Injecting as environment variables the properties content
FOO=bar
[EnvInject] - Variables injected successfully.
[Foo] $ sh - C:\Users\jenkins\AppData\Local\Temp\jenkins281351632631450693.sh
bar.8
Finished: SUCCESS
You'll also see at the bottom of the Execute Shell step a link to ${JENKINS_URL}/env-vars.html which lists variables available to shell scripts, which includes BUILD_NUMBER; use that in lieu of buildNumber.
The plugin also supports configuration same at both the Global and the Node level.
You can also have individual build steps to inject / change variables between job steps (we use this to set specific JAVA_HOME for SonarQube step).
You will also see an [Environment variables] button on the LH side of each build log to inspect what you ran with (see below).
If you add Build With Parameters plugin then you can be prompted to supply values for variables when triggering the job which can be consumed in the same fashion without re-configuring the job (it won't remember them, but you will see a [Parameters] button on the LH side of each build log to inspect what you ran with.
The Version Number plugin can provides greater flexibility, say you want to AutoIncrement and the "BUILD_NUMBER" option is too limiting, it offers a variable BUILDS_ALL_TIME, which can use the above defined variables or hard-coded constants to aggregate a version label and optionally control which it is incremented (eg: only increment on successful builds). eg:
[ X ] Prepare an environment for the run
Properties Content
FOO=bar
[ X ] Create a formatted version number
Environment Variable Name [ BUILD-${FOO}.${BUILDS_ALL_TIME} ]
Skip Builds worse than [ SUCCESS ]
Execute Shell step:
#!sh -
echo ${FOO}.${BUILD_NUMBER}
echo ${LABEL}
Output:
[Foo] $ sh - C:\Users\jenkins\AppData\Local\Temp\jenkins4160554383847615506.sh
bar.10
BUILD-bar.2

Related

Accessing Jenkins-set environment variables from a Jenkins Plugin

If there is a Jenkins shell script build step, environment variables are set so that, for example, if you echo $WORKSPACE you see the current working directory. I am writing a custom plugin which also can execute shell commands but WORKSPACE is not set when this plugin executes.
I could see that Jenkins sets all those env variables prior to executing the shell commands the Jenkins project specifies so that they would not be already set for a custom plugin. If that is the case, it would seem like there is no way to access those env variables.
But if there is a way to obtain the values of the env variables that would be useful.

Need to get jenkins build number

In my Jenkins job configure section I am calling an expect script to run.I need to get the current build number value in a variable in the expect script. is it possible to get the build number in a variable?
example. in my Jenkins job i am calling an expect script sample_text.exp in which i need to get current build number in a variable Build_no
is it possible?
yes, it is possible. There is environment variable BUILD_NUMBER. What you mean by "Jenkins job configure section"? In "Execute Windows batch command" in (build section) you can do:
echo %BUILD_NUMBER%
to get this number in a different variable:
set "BUILD_NO=%BUILD_NUMBER%"
echo %BUILD_NO%
Very much possible. You can use the environment variable, BUILD_NUMBER for that in execute shell section. To get a list of all the environment variables that one can use, go to
<your_jenkins_url>/env-vars.html
For example:
http://my-jenkins-box:8080/env-vars.html
Logic that I spoke off in my below comment
if [ -z ${JOB_URL} ]; then
echo "*************************** This is not a Jenkins build ***********"
# Do your stuff here :)
else
echo "**************************** This is a jenkins build so maven project is built before this script is executed via Jenkins ***************************"
fi
Also, remember that if you are running your script with sudo, these environment variables will not be available then

Jenkins Persistent Editable Global Variable

I'm looking for a plugin/approach that lets me set and read a persistent global variable for use between jobs.
The scenario is that I have CI job that runs tests on various branches of the codebase and I want to associate a build number that corresponds to the last stable build of the release branch. i.e.
Build No Branch Result GolbalSharedThingVal
5 release Success 1.5
6 dev Fail 1.5
7 dev Success 1.7
8 release Unstable 1.7
9 release Success 1.9
10 release Fail 1.9
Then in my deployment job I want to annotate the build with the version using a groovy post build action:
manager.addShortText(" ${manager.build.env.get('GolbalSharedThingVal')}")
Does anyone have any advice about what GolbalSharedThingVal could be?
Many Thanks,
Vackar
EnvInject plugin is the plugin for anything related to environment variables.
Don't know about setting a persistent global variable (that goes against the design principles of Jenkins), but you could have the job export a value to a properties file, and other jobs read the value from the properties file at initialization and expose it as environment variable to other build steps.
Of course the property file would have to be centrally located on Jenkins master somewhere
If you make sure that the different jobs/stages run on the same agent, you can use a file as a persistent storage. In a declarative pipeline this could look like
stage('myStage') {
steps {
echo 'in myStage'
sh '''
# get value from file into environment variable
export PERSISTENTVAR=`cat $HOME/persistent_var_file`
# do some stuff here to e.g. change $PERSISTENTVAR
# save env variable into file for later use
echo $PERSISTENTVAR > $HOME/persistent_var_file
'''
}
}

How to set environment variables in Jenkins?

I would like to be able to do something like:
AOEU=$(echo aoeu)
and have Jenkins set AOEU=aoeu.
The Environment Variables section in Jenkins doesn't do that. Instead, it sets AOEU='$(echo aoeu)'.
How can I get Jenkins to evaluate a shell command and assign the output to an environment variable?
Eventually, I want to be able to assign the executor of a job to an environment variable that can be passed into or used by other scripts.
This can be done via EnvInject plugin in the following way:
Create an "Execute shell" build step that runs:
echo AOEU=$(echo aoeu) > propsfile
Create an Inject environment variables build step and set "Properties File Path" to propsfile.
Note: This plugin is (mostly) not compatible with the Pipeline plugin.
The simplest way
You can use EnvInject plugin to injects environment variables at build startup. For example:
How you know it's working
In my case, I needed to add the JMETER_HOME environment variable to be available via my Ant build scripts across all projects on my Jenkins server (Linux), in a way that would not interfere with my local build environment (Windows and Mac) in the build.xml script. Setting the environment variable via Manage Jenkins - Configure System - Global properties was the easiest and least intrusive way to accomplish this. No plug-ins are necessary.
The environment variable is then available in Ant via:
<property environment="env" />
<property name="jmeter.home" value="${env.JMETER_HOME}" />
This can be verified to works by adding:
<echo message="JMeter Home: ${jmeter.home}"/>
Which produces:
JMeter Home: ~/.jmeter
In my case, I had configure environment variables using the following option and it worked-
Manage Jenkins -> Configure System -> Global Properties -> Environment Variables -> Add
You can try something like this
stages {
stage('Build') {
environment {
AOEU= sh (returnStdout: true, script: 'echo aoeu').trim()
}
steps {
sh 'env'
sh 'echo $AOEU'
}
}
}
You can use Environment Injector Plugin to set environment variables in Jenkins at job and node levels. These are the steps to set them at job level:
From the Jenkins web interface, go to Manage Jenkins > Manage Plugins and install the plugin.
Go to your job Configure screen
Find Add build step in Build section and select Inject environment variables
Set the desired environment variable as VARIABLE_NAME=VALUE pattern. In my case, I changed value of USERPROFILE variable
If you need to define a new environment variable depending on some conditions (e.g. job parameters), then you can refer to this answer.
EnvInject Plugin aka (Environment Injector Plugin) gives you several options to set environment variables from Jenkins configuration.
By selecting Inject environment variables to the build process you will get:
Properties File Path
Properties Content
Script File Path
Script Content
and finally Evaluated Groovy script.
Evaluated Groovy script gives you possibility to set environment variable based on result of executed command:
with execute method:
return [HOSTNAME_SHELL: 'hostname'.execute().text,
DATE_SHELL: 'date'.execute().text,
ECHO_SHELL: 'echo hello world!'.execute().text
]
or with explicit Groovy code:
return [HOSTNAME_GROOVY: java.net.InetAddress.getLocalHost().getHostName(),
DATE_GROOVY: new Date()
]
(More details about each method could be found in build-in help (?))
Unfortunately you can't do the same from Script Content as it states:
Execute a script file aimed at setting an environment such as creating
folders, copying files, and so on. Give the script file content. You
can use the above properties variables. However, adding or overriding
environment variables in the script doesn't have any impacts in the
build job.
There is Build Env Propagator Plugin which lets you add new build environment variables, e.g.
Any successive Propagate build environment variables step will override previously defined environment variable values.
Normally you can configure Environment variables in Global properties in Configure System.
However for dynamic variables with shell substitution, you may want to create a script file in Jenkins HOME dir and execute it during the build. The SSH access is required. For example.
Log-in as Jenkins: sudo su - jenkins or sudo su - jenkins -s /bin/bash
Create a shell script, e.g.:
echo 'export VM_NAME="$JOB_NAME"' > ~/load_env.sh
echo "export AOEU=$(echo aoeu)" >> ~/load_env.sh
chmod 750 ~/load_env.sh
In Jenkins Build (Execute shell), invoke the script and its variables before anything else, e.g.
source ~/load_env.sh
This is the snippet to store environment variable and access it.
node {
withEnv(["ENABLE_TESTS=true", "DISABLE_SQL=false"]) {
stage('Select Jenkinsfile') {
echo "Enable test?: ${env.DEVOPS_SKIP_TESTS}
customStep script: this
}
}
}
Note: The value of environment variable is coming as a String. If you want to use it as a boolean then you have to parse it using Boolean.parse(env.DISABLE_SQL).
extending the answer of #JSixface:
To define environment variables globally for access from within all the stages of a declarative pipeline, you can add the environment section within the pipeline block.
pipeline {
agent {
node {
label 'myAgent'
}
}
environment {
AOEU = "${sh(returnStdout: true, script: 'echo aoeu').trim()}"
}
stages {
...
}
}
Try Environment Script Plugin (GitHub) which is very similar to EnvInject. It allows you to run a script before the build (after SCM checkout) that generates environment variables for it. E.g.
and in your script, you can print e.g. FOO=bar to the standard output to set that variable.
Example to append to an existing PATH-style variable:
echo PATH+unique_identifier=/usr/local/bin
So you're free to do whatever you need in the script - either cat a file, or run a script in some other language from your project's source tree, etc.
For some reason sudo su - jenkins does not log me to jenkins user, I ended up using different approach.
I was successful setting the global env variables using using jenkins config.xml at /var/lib/jenkins/config.xml (installed in Linux/ RHEL) - without using external plugins.
I simply had to stop jenkins add then add globalNodeProperties, and then restart.
Example, I'm defining variables APPLICATION_ENVIRONMENT and SPRING_PROFILES_ACTIVE to continious_integration below,
<?xml version='1.0' encoding='UTF-8'?>
<hudson>
<globalNodeProperties>
<hudson.slaves.EnvironmentVariablesNodeProperty>
<envVars serialization="custom">
<unserializable-parents/>
<tree-map>
<default>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
</default>
<int>2</int>
<string>APPLICATION_ENVIRONMENT</string>
<string>continious_integration</string>
<string>SPRING_PROFILES_ACTIVE</string>
<string>continious_integration</string>
</tree-map>
</envVars>
</hudson.slaves.EnvironmentVariablesNodeProperty>
</globalNodeProperties>
</hudson>
You can use either of the following ways listed below:
Use Env Inject Plugin for creating environment variables. Follow this for usage and more details https://github.com/jenkinsci/envinject-plugin
Navigate below and can add
Manage Jenkins -> Configure System -> Global Properties -> Environment Variables -> Add
Scripted Pipeline syntax that we use is this:
env.AEOU = sh label:'set env var',
returnStdout: true,
script : '''#!/bin/bash
echo "aeou"
'''
sh label:'checkit',
script : '''#!/bin/bash
echo "${AEOU}"
'''
Note the use of triple-single-quote notation for the script parameter to the sh step. This ensures that the ${AEOU} does not get interpolated by Groovy and does get interpolated by the bash shell.
We use groovy job file:
description('')
steps {
environmentVariables {
envs(PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: true)
}
}

Run Jenkins ant build within special shell environment

Our internal build system uses a shell script to setup the environment for building projects. Then the actual build tools (ant or make) can reference environment variables for configuring various things. In essence, it does:
$ /path/to/setup_env.sh .
[build env] $ ant compile
Note that the first command launches and initializes a new shell and expects all subsequent build operations to be performed in that shell.
Now I am trying to replicate the same within Jenkins. How do I run a shell script and then have the subsequent ant build step take place in the same environment?
The 'Execute Shell' built-in as well as the EnvInject plugin didn't help since they discard any changes to the environment before moving to the next build step.
I'd prefer not to modify the ant build file since the same should continue to work in the current internal build system.
This is a "solution" that worked out for us. The key idea is that the setup_env.sh script launches a new shell in which it exports a bunch of environment variables. What we needed was access to those variable definitions. So we did a three part Jenkins Build:
Step 1 - Execute Shell
Use the 'Execute Shell' Jenkins built-in to run our setup_env.sh script. Then feed the newly launched shell a simple python script that dumps the environment to a file.
/path/to/setup_env.sh . <<< 'python <<SC
print "Exporting env to buildenv.properties file"
import os
f = open("buildenv.properties", "w")
env = os.environ
for k in env:
f.write("%s=%s\n" % (k, env[k]))
f.close()
print "Done exporting env"
SC'
Step 2 - Inject Environment Variables
Now we use the EnvInject Plugin to inject environment variables from the file dumped in the previous step. The config here is simple, just specify the dumped properties file name as the Properties File Path field value.
Step 3 - Invoke Ant
Here, we kick off the normal ant build. Since the environment now contains all the required definitions, the build completes as normal.
Try EnvInject Plugin.

Resources