Multiple value parameter in jenkins - jenkins

I have a situation where i need to use multiple value parameter or using extended-choice-parameter for Jenkins where we can select multiple options for my parameter.
I have different protractor test suites {Suite1, Suite2, Suite3, Suite4} which i am using as parameter of build for user to select which suite they want to execute. If they select multiple suite in option, how should i read those values in my shell script?
Currently i am using $Suite to read value but i am not sure what should i use to read multiple values selected. Can someone please help?

One option is:
get input of simple params (S1, S2)
build the string using 'execute shell'
save it to file in the workspace
inject it with the EnvInject plugin
execute-shell block:
#!/bin/sh
SUITS="{"
if [ "${S1}" = "test-1" ]; then
SUITS="${SUITS}test-1 "
fi
if [ "${S2}" = "test-2" ]; then
SUITS="${SUITS}test-2 "
fi
SUITS="${SUITS}}"
# SUITS="{test-1 test2- }"
cat "SUITS=${SUITS}" > suits.file
Then inject the file using the EnvInject plugin and SUITS will be available in the workspace

Related

How to send credentials to a powershell script in a jenkins pipeline?

When executing the following code in a Jenkins pipeline, a "The following steps that have been detected may have insecure interpolation of sensitive variables" warning is being added to the build, with a link to https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#string-interpolation with explanation.
powershell script: """
\$ErrorActionPreference = "Stop"
cd "${WORKSPACE}\\MyDirectory"
& .\\myScript.ps1 -user "${creds_USR}" -passw "${creds_PSW}"
"""
I've already tried to change it as described in the link above, but then the variables don't seem to be replaced anymore.
powershell script: '''
\$ErrorActionPreference = \"Stop\"
cd \"$WORKSPACE\\MyDirectory\"
& .\\myScript.ps1 -user \"$creds_USR\" -passw \"$creds_PSW\"
'''
Would somebody know a working solution for this please?
Presumably you have a block like this that's generating those values:
environment {
creds = credentials('some-credentials')
}
So your build environment has those variables available to Powershell. Rather than interpolating the string that constitutes the Powershell script, then, just write the script to pull the data from the environment.
powershell script: '''\
$ErrorActionPreference = "Stop"
cd "$Env:WORKSPACE\MyDirectory"
& .\myScript.ps1 -user "$Env:creds_USR" -passw "$Env:creds_PSW"
'''

How to get the variable value in TFS/AzureDevOps from Build to Release Pipeline?

I've defined a variable in my TFS/AzureDevops Build definition (say it's time)
and assign the value using PowerShell task within my build definition.
Like,
Type: Inline Script.
Inline script:
$date=$(Get-Date -Format g);
Write-Host "##vso[task.setvariable variable=time]$date"
You can refer to this similar example
Now I want to get this value in my release definition pipeline. I configured this build definition as continuous deployment to my release definition.
My Question is
How can I get the value of time in my release definition using some other variable? Is this possible?
The is no official way to pass variables from Build to Release. The only way to accomplish this is to store the values in a file (json, xml, yaml, what have you) and attach that as a Build Artifact. That way you can read the file in the release and set the variable again.
Martin Hinshelwood seems to have gotten frustrated enough by this problem and turned that functionality into an extension for Azure DevOps Pipelines.
Tasks included
Variable Save Task - During your build you can save the variables to a json file stored with your other build assets
Variable Load Task - During your Release you can load the saved variables and gain access to them.
What about using a variable within a variable group?
I managed to set the value of a variable in a variable group to a variable coming from a build pipeline, and then to read that variable in a release pipeline.
For that, it is necessary:
To have previously created the variable group, and the variable (its name identified by $(variableName). Let's assume its value would be stored in $(variableValue)).
To find the variable group ID (stored in $(variableGroupId)), which can be done by navigating on Azure DevOps to that variable group. The group ID will then be in the URL.
A Personal Access Token (PAT) with Read & Write access to group variables (called $(personalAccessToken) )
CI pipeline
- powershell: |
az pipelines variable-group variable update --group-id $(variableGroupId) --name $(variableName) --value $(variableValue)
displayName: 'Store the variable in a group variable'
env:
AZURE_DEVOPS_EXT_PAT: $(personalAccessToken)
Then all that's necessary, is to link the variable group to the release pipeline, and the variable will be seeded to that pipeline.
I found another solution that works even without text files just by using the Azure REST API to get the build parameters.
In my release pipeline I execute this Powershell tasks first to extract any build pipeline parameters:
function Get-ObjectMember {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True)]
[PSCustomObject]$obj
)
$obj | Get-Member -MemberType NoteProperty | ForEach-Object {
$key = $_.Name
[PSCustomObject]#{Key = $key; Value = $obj."$key"}
}
}
$url = "https://dev.azure.com/$(account)/$(project)/_apis/build/builds/$(Build.BuildId)?api-version=6.0"
$build = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
$params = $build.templateParameters
if ($params) {
$params | Get-ObjectMember | foreach {
Write-Host $_.Key : $_.Value
echo "##vso[task.setvariable variable=$($_.Key);]$($_.Value)"
}
}
My build pipeline contained the parameter: RELEASE_VERSION and after I executed the above code, I can use $(RELEASE_VERSION) in my other release tasks.

Can we define a variable inside a Jenkins parameterized build

My scenario is, I have parameterized build and inside the build section, I have executed shell where I define a variable and then echo to print it. But it doesn't print anything in the console output.
I hope I have made myself clear. Could anyone please answer my question?
current_folder=`date +%Y%m%d-%H%M%S`
echo $current_folder
enter image description here
I'm using Jenkins ver. 2.32.3 and a simple freestyle job, running on mac OS, using an execute shell build step of:
current_folder=`date +%Y%m%d-%H%M%S`
echo $current_folder
Gives output of:
$ /bin/sh -xe /var/folders/kh/4fl0eeldofefmmsfd/T/hudson89388543547899686.sh
++ date +%Y%m%d-%H%M%S
+ current_folder=20180613-081712
+ echo 20180613-081712
20180613-081712
Finished: SUCCESS
In a similar fashion, setting the shell:
#!/bin/bash
current_folder=`date +%Y%m%d-%H%M%S`
echo $current_folder
Gives:
$ /bin/bash /var/folders/kh/by0kd93dfew5fgjhy000h6/T/hudson62702345565786787.sh
20180613-081655
Finished: SUCCESS
The same applies to a parameter that is defined as part of the Jenkins job, underneath the
This project is parameterized checkbox once set. For example, if you have a string parameter called userName with a default value of User1, then you can print it's value in an Execute Shell build step using:
echo $userName
echo ${userName}
echo "In a string ${userName}"
Giving:
User1
User1
In a string User1

find env variables for a all builds for a job on jenkins

I need to monitor what are the changes going with a job on jenkins(update the changes to a file). Need to list the env variables of a job. JOB_NAME,BUILD_NUMBER,BUILD_STATUS,GIT_URL for that build(all the builds of a job). I didn't find out a good example with the groovy. What is the best way to fetch all the info?
build.getEnvironment(listener) should get you what you need
Depending on what you would like to achieve there are at least several approaches to retrieve and save environment variables for:
current build
all past builds
Get environments variables for current build (from slave)
Execute Groovy script
// Get current environment variables and save as
// a file in $WORKSPACE.
new File(".",'env.txt').withWriter('utf-8') { writer ->
System.getenv().each { key, value ->
writer.writeLine("${key}:${value}")
}
}
Using Groovy Plug-in.
Get environment variables for current build (from master)
Execute system Groovy script
// Get current environment variables and save as
// a file in $WORKSPACE.
import hudson.FilePath
def path = "env-sys.txt"
def file = null
if (build.workspace.isRemote()) {
file = new FilePath(build.workspace.channel, build.workspace.toString() + "/" + path)
} else {
file = new FilePath(build.workspace.toString() + "/" + path)
}
def output = ""
build.getEnvironment(listener).each { key, value ->
output += "${key}:${value}\n"
}
file.write() << output
Using Groovy Plug-in.
Environment variables returned by Groovy scripts are kept in map. If you don't need all of them, you can access individual values using standard operators/methods.
Get environment variables for all past builds (from master)
This approach expecst that you have installed EnvInject Plug-in and have access to $JENKINS_HOME folder:
$ find . ${JENKINS_HOME}/jobs/[path-to-your-job] -name injectedEnvVars.txt
...
ps. I suspect that one could analyze EnvInject Plug-in API and find a way to extract this information directly from Java/Groovy code.
Using EnvInject Plug-in.
To look for only specific variables you can utilize find, grep and xargs tools .
You can use below script to get the Environment Variables
def thread = Thread.currentThread()
def build = thread.executable
// Get build parameters
def buildVariablesMap = build.buildVariables
// Get all environment variables for the build
def buildEnvVarsMap = build.envVars
String jobName = buildEnvVarsMap?.JOB_NAME // This is for JOB Name env variable.
Hope it helps!

Getting the build status in post-build script

I would like to have a post-build hook or similar, so that I can have the same output as e. g. the IRC plugin, but give that to a script.
I was able to get all the info, except for the actual build status. This just doesn't work, neither as a "Post-build script", "Post-build task", "Parameterized Trigger" aso.
It is possible with some very ugly workarounds, but I wanted to ask, in case someone has a nicer option ... short of writing my own plugin.
It works as mentioned with the Groovy Post-Build Plugin, yet without any extra quoting within the string that gets executed. So I had to put the actual functionality into a shell script, that does a call to curl, which in turn needs quoting for the POST parameters aso.
def result = manager.build.result
def build_number = manager.build.number
def env = manager.build.getEnvironment(manager.listener)
def build_url = env['BUILD_URL']
def build_branch = env['SVN_BRANCH']
def short_branch = ( build_branch =~ /branches\//).replaceFirst("")
def host = env['NODE_NAME']
def svn_rev = env['SVN_REVISION']
def job_name = manager.build.project.getName()
"/usr/local/bin/skypeStagingNotify.sh Deployed ${short_branch} on ${host} - ${result} - ${build_url}".execute()
Use Groovy script in post-build step via Groovy Post-Build plugin. You can then access Jenkins internals via Jenkins Java API. The plugin provides the script with variable manager that can be used to access important parts of the API (see Usage section in the plugin documentation).
For example, here's how you can execute a simple external Python script on Windows and output its result (as well as the build result) to build console:
def command = """cmd /c python -c "for i in range(1,5): print i" """
manager.listener.logger.println command.execute().text
def result = manager.build.result
manager.listener.logger.println "And the result is: ${result}"
For this I really like the Conditional Build Step plugin. It's very flexible, and you can choose which actions to take based on build failure or success. For instance, here's a case where I use conditional build step to send a notification on build failure:
You can also use conditional build step to set an environment variable or write to a log file that you use in subsequent "execute shell" steps. So for instance, you might create a build with three steps: one step to compile code/run tests, another to set a STATUS="failed" environment variable, and then a third step which sends an email like The build finished with a status: ${STATUS}
Really easy solution, maybe not to elegant, but it works!
1: Catch all the build result you want to catch (in this case SUCCESS).
2: Inject an env variable valued with the job status
3: Do the Same for any kind of other status (in this case I catch from abort to unstable)
4: After you'll be able to use the value for whatever you wanna do.. in this case I'm passing it to an ANT script! (Or you can directly load it from ANT as Environment variable...)
Hope it can help!
Groovy script solution:-
Here I am using groovy script plugin to take the build status and setting it to the environmental variable, so the environmental variable can be used in post-build scripts using post-build task plugin.
Groovy script:-
import hudson.EnvVars
import hudson.model.Environment
def build = Thread.currentThread().executable
def result = manager.build.result.toString()
def vars = [BUILD_STATUS: result]
build.environments.add(0, Environment.create(new EnvVars(vars)))
Postscript:-
echo BUILD_STATUS="${BUILD_STATUS}"
Try Post Build Task plugin...
It lets you specify conditions based on the log output...
Basic solution (please don't laugh)
#!/bin/bash
STATUS='Not set'
if [ ! -z $UPSTREAM_BUILD_DIR ];then
ISFAIL=$(ls -l /var/lib/jenkins/jobs/$UPSTREAM_BUILD_DIR/builds | grep "lastFailedBuild\|lastUnsuccessfulBuild" | grep $UPSTREAM_BUILD_NR)
ISSUCCESS=$(ls -l /var/lib/jenkins/jobs/$UPSTREAM_BUILD_DIR/builds | grep "lastSuccessfulBuild\|lastStableBuild" | grep $UPSTREAM_BUILD_NR)
if [ ! -z "$ISFAIL" ];then
echo $ISFAIL
STATUS='FAIL'
elif [ ! -z "$ISSUCCESS" ]
then
STATUS='SUCCESS'
fi
fi
echo $STATUS
where
$UPSTREAM_BUILD_DIR=$JOB_NAME
$UPSTREAM_BUILD_NR=$BUILD_NUMBER
passed from upstream build
Of course "/var/lib/jenkins/jobs/" depends of your jenkins installation

Resources