how to set string input default value when the input value is null in jenkins pipeline - jenkins

I am set a string parameter in Jenkins pipeline(groovy script) like this:
def call(String type, Map map) {
if (type == "gradle") {
pipeline {
agent any
parameters {
string(name: 'k8sResourceType', defaultValue: "${map.k8sResourceType}", description: 'Kubernetes Resource Type')
}
}
}
is it possible to set a default value when ${map.k8sResourceType} is null? if the ${map.k8sResourceType} is null set the Kubernetes resource type to Deployment. Because 90% of apps are Deployment and only special apps are StatefulSet in Kubernetes. I am a newbie in groovy.

You better use environment instead of parameters to achieve what you want
pipeline {
agent any
environment {
k8sResourceType = getResourceType(map.k8sResourceType)
}
stages {
stage('Hello World') {
steps {
echo "Value: ${env.k8sResourceType}"
}
}
}
}
def getResourceType(value) {
return value == null ? "Deployment" : value
}

Related

Converting a gstringimpl to java.lang.string in a Jenkinsile

I have a pipeline which takes a persistent string parameter input. The pipeline then checks whether the parameter value is present in a list.
The problem is that the persisted string is of type gstringimpl, and the list items are java.lang.string type. When I use the .contains() method, even though the value is in the list, it won't return true, which I believe is due to the different data types.
I've tried everything online, including the toString() method but I can't get it to work. I'm attaching my code below.
String ver = ""
pipeline {
agent {
docker{
image 'registry/abc/builder:0.1.5'
args '-t -d -v maven-m2-cache:/home/node/.m2'
}
}
parameters {
persistentString(name: 'Version', defaultValue: '8.4.7.8', description: 'Version to build', successfulOnly: false)
}
stages {
stage('Analyze Parameter'){
steps{
script{
ver = "${Version}".toString()
}
}
}
stage('Build'){
steps{
script{
def version_list1 = ['8.4.7.8','8.3.7.9','8.5.4.7']
if (version_list1.contains("${ver}")){
println("build version branch")
} else {
println("${ver}")
println("${ver}".getClass())
println(version_list1[0])
println(version_list1[0].getClass())
println("build master branch")
}
}
}
}
}
}
The pipeline always goes into the else block and prints the following:
8.4.7.8
class org.codehaus.groovy.runtime.GStringImpl
8.4.7.8
java.lang.string
build master branch
Don't use String interpolation to resolve Parameters. Instead directly access it like params.PARAM_NAME, example below.
script{
def version_list1 = ['8.4.7.8','8.3.7.9','8.5.4.7']
if (version_list1.contains(params.Version)){
println("build version branch")
} else {
println("build master branch")
}
}

Jenkinsfile: parameter precedence

Say I have a Jenkinsfile with stages based on a conditional such as the following. Then, in the Jenkins UI for a particular Pipeline Project, I may or may not have a (Global Variable String Parameter) parameter named CITY defined for a particular job.
If the CITY parameter is defined in the Jenkins project in the UI, I'd like it to use whatever city the user inputs. If the user doesn't input anything, I'd like it to default to a value in "Global Properties" (in "Manage Jenkins > Configure System > Global Properties")
If the CITY parameter is NOT defined in the UI (like if someone forgot to define that parameter in the Pipeline Project UI), I'd like it to somehow default to a value defined in the Jenkinsfile.
Simply put, I'd like to define a default in the Jenkinsfile such that if someone forgets to configure a Global Variable String Parameter in the Job UI, the default will be used.
I'm pretty new to Jenkins and Groovy, I'm not quite sure how to do this. How can I go about defining a default parameter in a Jenkinsfile that can be overridden by user input in the UI or a default from "Global Properties"? Any advice is appreciated.
pipeline {
agent any
stages {
stage('Always') {
steps {
script {
sh 'echo Welcome CITY=$CITY'
}
}
stage('Chicago') {
when {
expression {
params.CITY == "CHICAGO"
}
}
steps {
script {
sh 'echo Welcome to Chicago "CITY=$CITY"'
}
}
}
stage('NYC') {
when {
expression {
params.CITY == "NYC"
}
}
steps {
script {
sh 'echo Welcome to NYC "CITY=$CITY"'
}
}
}
}
}
there is no need to declare each city just add a string parameter with a default value and create a single stage that will take the default parameter if the user did not enter one
if this works for you please mark answer as correct :-)
pipeline {
agent any
parameters {
string(name: 'CITY', defaultValue: 'TEL_AVIV', description: 'this is the default if user dosnt enter parameter in the UI')
}
stages {
stage('CITY') {
steps {
script {
sh 'echo Welcome $CITY'
}
}
}
}
}

how to get jenkins parameter's default value

I want to have a check in jenkins job, where if the jenkins parameters have been modified then I want to display an Input modal to proceed or abort the job .But for that I need to verify if the parameters have been modified.
So, I can get modified parameters value in jenkins job, but how to retrieve default values of those parameters so that I can verify if any parameters have been modified?
def DEFAULT_VALUE = "42"
pipeline {
agent any
parameters { string(name: 'MY_PARAM', defaultValue: DEFAULT_VALUE, description: '') }
stages {
stage('Example') {
steps {
script {
if (params.MY_PARAM == DEFAULT_VALUE) {
echo 'Default value used'
} else {
echo 'Non-default value used'
}
}
}
}
}

Value returned from a script does not assigned to a variable declared in jenkins declarative pipeline stage

I am working on adding a jenkins Declarative pipeline for automation testing. In the test run stage i want to extract the failed tests from the log. i am using a groovy function for extracting the test result. this function is not a part of the jenkins pipeline. It is another script file. The function works fine and it build a string containing the failure details. Inside a pipeline stage i am calling this function and assinging the returned string to another variable. But when i echo the variable value it prints empty string.
pipeline {
agent {
kubernetes {
yamlFile 'kubernetesPod.yml'
}
}
environment{
failure_msg = ""
}
stages {
stage('Run Test') {
steps {
container('ansible') {
script {
def notify = load('src/TestResult.groovy')
def result = notify.extractTestResult("${WORKSPACE}/testreport.xml")
sh "${result}"
if (result != "") {
failure_msg = failure_msg + result
}
}
}
}
}
post {
always {
script {
sh 'echo Failure message.............${failure_msg}'
}
}
}
}
here 'sh 'echo ${result}'' print empty string. But 'extractTestResult()' returns a non-empty string.
Also i am not able to use the environment variable 'failure_msg' in post section it return an error 'groovy.lang.MissingPropertyException: No such property: failure_msg for class: groovy.lang.Binding'
can anyone please help me with this ?
EDIT:
Even after i fixed the string interpolation, i was getting the same
error. That was because jenkins does not allow using 'sh' inside
docker container. there is an open bug ticket in jenkins issue
board
I would suggest to use a global variable for holding the error message. My guess is that the variable is not existing in your scope.
def FAILURE_MSG // Global Variable
pipeline {
...
stages {
stage(...
steps {
container('ansible') {
script {
...
if (result != "") {
FAILURE_MSG = FAILURE_MSG + result
}
}
}
}
}
post {
always {
script {
sh "${FAILURE_MSG}" // Hint: Use correct String Interpolation
}
}
}
}
(Similar SO question can be found here)

Conditional environment variables in Jenkins Declarative Pipeline

I'm trying to get a declarative pipeline that looks like this:
pipeline {
environment {
ENV1 = 'default'
ENV2 = 'default also'
}
}
The catch is, I'd like to be able to override the values of ENV1 or ENV2 based on an arbitrary condition. My current need is just to base it off the branch but I could imagine more complicated conditions.
Is there any sane way to implement this? I've seen some examples online that do something like:
stages {
stage('Set environment') {
steps {
script {
ENV1 = 'new1'
}
}
}
}
But I believe this isn't setting the actually environment variable, so much as it is setting a local variable which is overriding later calls to ENV1. The problem is, I need these environment variables read by a nodejs script, and those need to be real machine environment variables.
Is there any way to set environment variables to be dynamic in a jenkinsfile?
Maybe you can try Groovy's ternary-operator:
pipeline {
agent any
environment {
ENV_NAME = "${env.BRANCH_NAME == "develop" ? "staging" : "production"}"
}
}
or extract the conditional to a function:
pipeline {
agent any
environment {
ENV_NAME = getEnvName(env.BRANCH_NAME)
}
}
// ...
def getEnvName(branchName) {
if("int".equals(branchName)) {
return "int";
} else if ("production".equals(branchName)) {
return "prod";
} else {
return "dev";
}
}
But, actually, you can do whatever you want using the Groovy syntax (features that are supported by Jenkins at least)
So the most flexible option would be to play with regex and branch names...So you can fully support Git Flow if that's the way you do it at VCS level.
use withEnv to set environment variables dynamically for use in a certain part of your pipeline (when running your node script, for example). like this (replace the contents of an sh step with your node script):
pipeline {
agent { label 'docker' }
environment {
ENV1 = 'default'
}
stages {
stage('Set environment') {
steps {
sh "echo $ENV1" // prints default
// override with hardcoded value
withEnv(['ENV1=newvalue']) {
sh "echo $ENV1" // prints newvalue
}
// override with variable
script {
def newEnv1 = 'new1'
withEnv(['ENV1=' + newEnv1]) {
sh "echo $ENV1" // prints new1
}
}
}
}
}
}
Here is the correct syntax to conditionally set a variable in the environment section.
environment {
MASTER_DEPLOY_ENV = "TEST" // Likely set as a pipeline parameter
RELEASE_DEPLOY_ENV = "PROD" // Likely set as a pipeline parameter
DEPLOY_ENV = "${env.BRANCH_NAME == 'master' ? env.MASTER_DEPLOY_ENV : env.RELEASE_DEPLOY_ENV}"
CONFIG_ENV = "${env.BRANCH_NAME == 'master' ? 'MASTER' : 'RELEASE'}"
}
I managed to get this working by explicitly calling shell in the environment section, like so:
UPDATE_SITE_REMOTE_SUFFIX = sh(returnStdout: true, script: "if [ \"$GIT_BRANCH\" == \"develop\" ]; then echo \"\"; else echo \"-$GIT_BRANCH\"; fi").trim()
however I know that my Jenkins is on nix, so it's probably not that portable
Here is a way to set the environment variables with high flexibility, using maps:
stage("Environment_0") {
steps {
script {
def MY_MAP = [ME: "ASSAFP", YOU: "YOUR_NAME", HE: "HIS_NAME"]
env.var3 = "HE"
env.my_env1 = env.null_var ? "not taken" : MY_MAP."${env.var3}"
echo("env.my_env1: ${env.my_env1}")
}
}
}
This way gives a wide variety of options, and if it is not enough, map-of-maps can be used to enlarge the span even more.
Of course, the switching can be done by using input parameters, so the environment variables will be set according to the input parameters value.
pipeline {
agent none
environment {
ENV1 = 'default'
ENV2 = 'default'
}
stages {
stage('Preparation') {
steps {
script {
ENV1 = 'foo' // or variable
ENV2 = 'bar' // or variable
}
echo ENV1
echo ENV2
}
}
stage('Build') {
steps {
sh "echo ${ENV1} and ${ENV2}"
}
}
// more stages...
}
}
This method is more simple and looks better. Overridden environment variables will be applied to all other stages also.
I tried to do it in a different way, but unfortunately it does not entirely work:
pipeline {
agent any
environment {
TARGET = "${changeRequest() ? CHANGE_TARGET:BRANCH_NAME}"
}
stages {
stage('setup') {
steps {
echo "target=${TARGET}"
echo "${BRANCH_NAME}"
}
}
}
}
Strangely enough this works for my pull request builds (changeRequest() returning true and TARGET becoming my target branch name) but it does not work for my CI builds (in which case the branch name is e.g. release/201808 but the resulting TARGET evaluating to null)

Resources