Set variables in a list in Declarative Jenkinsfile - jenkins-pipeline

I have set some environment variables as below :
environment {
IMG_TARGET = "registry/cloud-environemnt-azu:1.x.x"
CREDENTIALS = 'credentials-token'
BUILD_DIR = 'Builddir'
DOMAIN_DIR = 'Domaindir'
BUILD_SOLUTION = 'Dir.Builddir.sln'
}
Some variables are used throughout the Jenkins pipeline and I am looking to separate them from environment variables, such that only credentials and image target are in environment variables.
Is there a way I can use global list/variable/map to store non-environment variables, like :
List<String> variables = [
BUILD_DIR = 'Builddir'
DOMAIN_DIR = 'Domaindir'
BUILD_SOLUTION = 'Dir.Builddir.sln'
]
If so, how can I refer a variable from this list? The variables are being referenced across multiple stages in the pipeline

You can have an environment section for your pipeline and if needed, within each stage define a new environment section to override exisiting variables or define new ones. Example:
pipeline {
agent any
environment {
FOO = "bar"
NAME = "Joe"
}
stages {
stage("Env Variables") {
environment {
NAME = "Alan" // overrides pipeline level NAME env variable
BUILD_NUMBER = "2" // overrides the default BUILD_NUMBER
}
steps {
echo "FOO = ${env.FOO}" // prints "FOO = bar"
echo "NAME = ${env.NAME}" // prints "NAME = Alan"
echo "BUILD_NUMBER = ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 2"
script {
env.SOMETHING = "1" // creates env.SOMETHING variable
}
}
}
stage("Override Variables") {
steps {
script {
env.FOO = "IT DOES NOT WORK!" // it can't override env.FOO declared at the pipeline (or stage) level
env.SOMETHING = "2" // it can override env variable created imperatively
}
echo "FOO = ${env.FOO}" // prints "FOO = bar"
echo "SOMETHING = ${env.SOMETHING}" // prints "SOMETHING = 2"
withEnv(["FOO=foobar"]) { // it can override any env variable
echo "FOO = ${env.FOO}" // prints "FOO = foobar"
}
withEnv(["BUILD_NUMBER=1"]) {
echo "BUILD_NUMBER = ${env.BUILD_NUMBER}" // prints "BUILD_NUMBER = 1"
}
}
}
}
}
Another option is to use parameterised jobs in declarative pipelines and if you're interested, you can read more here.

You can set environment variable specific to each stage by including environment block within the stage like below.
pipeline {
agent any
stages {
stage ("Test Stage"){
environment {
TEST_VARIABLE=test
}
steps {
echo "Hello"
}
}
}
}
If you want all non environment variable into single component then you can use map instead of List, as map will store the data in key value pair and you can retrieve any key at any point of time, with List you cannot store the value as a key value pair.
pipeline {
agent any
stages {
stage ("Test Stage"){
steps {
script {
def testMap = [BUILD_DIR:'Builddir',DOMAIN_DIR:'Domaindir',BUILD_SOLUTION:'Dir.Builddir.sln']
testMap.each {
entry -> echo "${entry.key}"
}
echo "${testMap['DOMAIN_DIR']}"
}
}
}
}
}
Thanks,

Related

Get aws_lambda_event_source_mapping from sqs.tf and use it in lambda.tf

I have my terraform setup this way:
lambda.tf
sqs.tf
In lambda.tf
locals {
my_lambda = aws_lambda_function.vdf_lambda["my-lambda"]
}
...
environment {
variables = {
"MY_QUEUE_URL" = local.my_queue.id
"MY_TRIGGER_ID"= local.my_queue_trigger.uuid
}
}
in sqs.tf
locals {
my_queue = aws_sqs_queue.fifo_queue["my-queue"]
my_queue_trigger = aws_lambda_event_source_mapping.my_lambda_trigger
}
...
resource "aws_lambda_event_source_mapping" "my_lambda_trigger" {
batch_size = 1
event_source_arn = aws_sqs_queue.fifo_queue["my-queue"].arn
function_name = local.my_lambda.function_name
}
When I run terraform plan I got this error:
Error: Cycle: local.my_lambda (expand), aws_lambda_event_source_mapping.my_lambda_trigger,
local.my_queue_trigger (expand), aws_lambda_function.my_lambdas
My guess is the trigger was not created yet when I try to get its UUID in lambda.tf. So how do I fix this? How to get the trigger UUID in lambda.tf?

How to access value of an axis in a label?

...
matrix {
axes {
axis {
name 'FOO'
values 'foo1' 'foo2' //
}
... stages {
stage ('doIt') {
agent{
label '???'
}
...
I would like to build a label instruction that will accept win or mac, if also one of the values of FOO is found. How can I combine the value of the axis with the other strings to form a meaningful label?
You can access the axis variable by its name - FOO. The only thing you need to keep in mind is to use it inside a double-quoted string, so the value can be interpolated correctly.
pipeline {
agent none
stages {
stage('Matrix example') {
matrix {
agent any
axes {
axis {
name 'FOO'
values 'bar1', 'bar2', 'bar3'
}
}
stages {
stage('Test') {
agent {
label "${FOO}"
}
steps {
// ...
}
}
}
}
}
}
}

Jenkins pipeline multiline script command as variable

how can I save a command in a variable and executed anywhere in the stage
tried differnt way, but still success
here is my example
pipeline {
agent any
environment {
myscript = sh '''
echo "hello"
echo "hello"
echo "hello"
'''
}
stages {
stage("RUN") {
steps {
sh "${myscript}"
}
}
}
}
you can do it like this. Not with a groovy variable but can be more dynamic with groovy function/method
def reusableScript(message) {
sh """
echo Hello World
echo Hi ${message}
"""
}
pipeline {
agent any;
stages {
stage('01') {
steps {
script {
reusableScript("From ${env.STAGE_NAME}")
}
}
}
stage('02') {
steps {
script {
reusableScript("From ${env.STAGE_NAME}")
}
}
}
}
}

Issue with loop in Jenkinsfile

I a variable in my Jenkinsfile that contains a list of URLs and i would like a be able to run over them. When i pass the variable $URL to the function, I get an error:
No such property: $URL for class: groovy.lang.Binding
However, I'm able to echo this variable with sh.
pipeline {
agent any
environment {
URL="https://www.aaa.com," \
+ "https://www.bbb.com," \
+ "https://www.ccc.com"
}
stages {
stage ('A') {
//...
}
stage ('B') {
//...
}
stage ('C') {
steps {
script {
sh 'echo $URL'
funcion($URL)
}
}
}
}
}
def funcion(URL) {
sh "echo Going to echo a list"
for (int i = 0; i < URL.size(); i++) {
sh "echo ${URL[i]}"
}
}
What could be the issue?
You should pass this variable to the funcion() method as
function(URL)
instead of
funcion($URL)
The dollar sign $ is used only inside the GString when you want to interpolate a variable. For instance
#!groovy
def name = "Joe"
println "My name is $name"
results in
My name is Joe
You can read more about string interpolation in the Groovy documentation - http://groovy-lang.org/syntax.html#_string_interpolation

Fail Jenkins pipeline stage if some file contains specific strings

I need to fail one Jenkins pipeline stage when one file contains 'errors'
I do not know how to return an error from bash to Jenkins
stage('check if file continas error and exit if true') {
steps {
sh "grep 'error' filetocheck.txt"
}
}
}
reference Is it possible to capture the stdout from the sh DSL command in the pipeline
This worked for me,
def runShell(String command){
def responseCode = sh returnStatus: true, script: "${command} &> tmp.txt"
def output = readFile(file: "tmp.txt")
return (output != "")
}
pipeline {
agent any
stages {
stage('check shellcheck') {
steps {
script {
if (runShell('grep \'error\' file_to_parse.txt')) {
sh "exit 1"
}
}
}
}
}
}
you can try using String.count(charSequence) where String could be a file or string.
def file = 'path/to/file.txt'
if ( file.count('error') > 0 )
return stageResultMap.didB2Succeed = false

Resources