How To Reference Map of Maps Variable in Jenkins Pipeline - jenkins

I have the below Jenkins pipeline and I am trying to echo out SolutonName and TargetVersion value. I tried different approaches and it either gave me error or not the result I wanted.
If I use echo "Solution Name: $solution['SolutionName']", it gave a result of Solution Name: SolutionA={SolutionName=SolutionA, TargetVersion=1.0.0.0}['SolutionName'], which is the map itself with ['SolutionName'] at the end.
If I use echo "Solution Name: ${solution.SolutionName}", it throws an error of org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.util.AbstractMap$SimpleImmutableEntry SolutionName
def NodeLabel = 'windows'
// Solution
def SolutionMap = [
SolutionA: [
SolutionName: 'SolutionA',
TargetVersion: '1.0.0.0'
],
SolutionB: [
SolutionName: 'SolutionB',
TargetVersion: '2.1.0.0'
]
]
pipeline {
agent { node { label "${NodeLabel}" } }
stages {
stage('Test') {
steps {
script {
SolutionMap.each { solution ->
stage(solution.key) {
echo "Solution Name: ${solution['SolutionName']}"
echo "Solution Name: ${solution['TargetVersion']}"
}
}
}
}
}
}
}

I figured it out, apparently I need to call:
echo "Solution Name: $Solution.value.SolutionName"
So it seems like calling $Solution does not assume it wants its value so I need to call $Solution.value to get the value and from there call .SolutionName to get the child value.

Related

Groovy code in script block to replace general build step step()

Among the possible steps one can use in a Jenkins pipeline, there is one with the name step, subtitled General Build Step. https://www.jenkins.io/doc/pipeline/steps/workflow-basic-steps/#step-general-build-step . I need to iterate on calling this step based on the contents of a file. I have created a groovy script to read the file and perform the iteration, but I am not sure how to create the equivalent of my step() in the groovy script. Here is the general format of the step I am trying to perform:
stage ('title') {
steps {
step([
$class: 'UCDeployPublisher',
siteName: 'literal string',
deploy: [
$class: 'com.urbancode.jenkins.plugins.ucdeploy.DeployHelper$DeployBlock',
param1: 'another literal string',
param2: 'yet another string'
]
])
}
}
The script step I have developed looks like this:
steps {
script {
def content = readFile(file:'data.csv', encoding:'UTF-8');
def lines = content.split('\n');
for (line in lines) {
// want to insert equivalent groovy code for the basic build step here
}
}
}
I'm expecting there is probably a trivial answer here. I'm just out of my element in the groovy/java world and I am not sure how to proceed. I have done extensive research, looked at source code for Jenkins, looked at plugins, etc. I am stuck!
Check the following, simply move your UCDeployPublisher to a new function and call that from your loop.
steps {
script {
def content = readFile(file:'data.csv', encoding:'UTF-8');
def lines = content.split('\n');
for (line in lines) {
runUCD(line)
}
}
}
// Groovy function
def runUCD(def n) {
stage ("title $n") {
steps {
step([
$class: 'UCDeployPublisher',
siteName: 'literal string',
deploy: [
$class: 'com.urbancode.jenkins.plugins.ucdeploy.DeployHelper$DeployBlock',
param1: 'another literal string',
param2: 'yet another string'
]
])
}
}
}
This is showing the code related to my comment on the accepted answer
pipeline {
stages {
stage ('loop') {
steps {
script {
... groovy to read/parse file and call runUCD
}
}
}
}
}
def runUCD(def param1, def param2) {
stage ("title $param1") {
step([
....
])
}
}

Jenkins file groovy issues

Hi My jenkins file code is as follows : I am basically trying to make call to a python script and execute it, I have defined some variables in my code : And when i am trying to run it, It gives no such property error in the beginning and I cant find out the reason behind it.
I would really appreciate any suggestions on this .
import groovy.json.*
pipeline {
agent {
label 'test'
}
parameters {
choice(choices: '''\
env1
env2'''
, description: 'Environment to deploy', name: 'vpc-stack')
choice(choices: '''\
node1
node2'''
, description: '(choose )', name: 'stack')
}
stages {
stage('Tooling') {
steps {
script {
//set up terraform
def tfHome = tool name: 'Terraform 0.12.24'
env.PATH = "${tfHome}:${env.PATH}"
env.TFHOME = "${tfHome}"
}
}
}
stage('Build all modules') {
steps {
wrap([$class: 'BuildUser']) {
// build all modules
script {
if (params.refresh) {
echo "Jenkins refresh!"
currentBuild.result = 'ABORTED'
error('Jenkinsfile refresh! Aborting any real runs!')
}
sh(script: """pwd""")
def status_code = sh(script: """PYTHONUNBUFFERED=1 python3 scripts/test/test_script.py /$vpc-stack""", returnStatus: true)
if (status_code == 0) {
currentBuild.result = 'SUCCESS'
}
if (status_code == 1) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
post {
always {
echo 'cleaning workspace'
step([$class: 'WsCleanup'])
}
}
}
And this code is giving me the following error :
hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: vpc for class
Any suggestions what can be done to resolve this.
Use another name for the choice variable without the dash sign -, e.g. vpc_stack or vpcstack and replace the variable name in python call.

Jenkins - matrix jobs - variables on different slaves overwrite each other?

I think i dont get how matrix builds work. When i set some variable in some stage depending on which node i run, then on rest of the stage sometimes this variable is set as it should and sometimes it gets values from other nodes (axes). In example below its like job which runs on ub18-1 sometimes has VARIABLE1='Linux node' and sometimes is VARIABLE1='Windows node'. Or gitmethod sometimes it is created from LinuxGitInfo and sometimes WindowsGitInfo.
Source i based on
https://jenkins.io/doc/book/pipeline/syntax/#declarative-matrix
Script almost exactly the same as real one
#Library('firstlibrary') _
import mylib.shared.*
pipeline {
parameters {
booleanParam name: 'AUTO', defaultValue: true, description: 'Auto mode sets some parameters for every slave separately'
choice(name: 'SLAVE_NAME', choices:['all', 'ub18-1','win10'],description:'Run on specific platform')
string(name: 'BRANCH',defaultValue: 'master', description: 'Preferably common label for entire group')
booleanParam name: 'SONAR', defaultValue: false, description: 'Scan and gateway'
booleanParam name: 'DEPLOY', defaultValue: false, description: 'Deploy to Artifactory'
}
agent none
stages{
stage('BuildAndTest'){
matrix{
agent {
label "$NODE"
}
when{ anyOf{
expression { params.SLAVE_NAME == 'all'}
expression { params.SLAVE_NAME == env.NODE}
}}
axes{
axis{
name 'NODE'
values 'ub18-1', 'win10'
}
}
stages{
stage('auto mode'){
when{
expression { return params.AUTO }
}
steps{
echo "Setting parameters for each slave"
script{
nodeLabelsList = env.NODE_LABELS.split()
if (nodeLabelsList.contains('ub18-1')){
println("Setting params for ub18-1");
VARIABLE1 = 'Linux node'
}
if (nodeLabelsList.contains('win10')){
println("Setting params for Win10");
VARIABLE1 = 'Windows node'
}
if (isUnix()){
gitmethod = new LinuxGitInfo(this,env)
} else {
gitmethod = new WindowsGitInfo(this, env)
}
}
}
}
stage('GIT') {
steps {
checkout scm
}
}
stage('Info'){
steps{
script{
sh 'printenv'
echo "branch: " + env.BRANCH_NAME
echo "SLAVE_NAME: " + env.NODE_NAME
echo VARIABLE1
gitinfo = new GitInfo(gitmethod)
gitinfo.init()
echo gitinfo.author
echo gitinfo.id
echo gitinfo.msg
echo gitinfo.buildinfo
}
}
}
stage('install'){
steps{
sh 'make install'
}
}
stage('test'){
steps{
sh 'make test'
}
}
}
}
}
}
}
Ok i solved the problem by defining variables maps with node/slave names as keys. Some friend even suggested to define variables in yml/json file in repository and parse them. Maybe i will, but so far this works well
example:
before the pipelines
def DEPLOYmap = [
'ub18-1': false,
'win10': true
]
in stages
when {
equals expected: true, actual: DEPLOYmap[NODE]
}

How to correctly call a function in the declarative Jenkins file

Good day!
I would like to call a function that sets a a choice parameter with the list of folder in the branch. I getting null value at the end.
My Jenkins file looks like the below:
void findCollectionDirs() {
directories = sh (
script: "find . -path './[^.]*/*/*' -prune -type d",
returnStdout: true
)
return directories
}
def directories
pipeline () {
agent {
label 'slave'
}
triggers {
cron(cron_string)
}
parameters {
choice(choices: "\n" + directories, description: 'Please select a directory', name: 'directory')
}
stages {
stage ("Checkout scm") {
steps {
deleteDir()
checkout scm
//sh 'directories = findCollectionDirs()'
findCollectionDirs()
}
}
I tried by calling it as below:
sh 'directories = findCollectionDirs()'
or,
findCollectionDirs()
or
directories.findCollectionDirs()
but the value still null.
Can someone help me to call correctly the function so I get the right values in the choice parameter.
Thanks in advance

How to define and get/put the values in Jenkinsfile groovy map

I have this Jenkinsfile below. I am trying to get the key of a map but I am getting "java.lang.NoSuchMethodError: No such DSL method 'get' found among steps". Can someone help me to resolve this?
def country_capital = {
[Australia : [best: 'xx1', good: 'xx2', bad: 'xx3'],
America : [best: 'yy1', good: 'yy2', bad: 'yy3']]
}
pipeline {
agent any
stages {
stage('Test Map') {
steps {
script {
echo country_capital.get('Australia')['best']
}
}
}
}
}
You can get the value using this way
def country_capital = [
Australia: [
best: 'xx1',
good: 'xx2',
bad: 'xx3'
],
America: [
best: 'yy1',
good: 'yy2',
bad: 'yy3'
]
]
pipeline {
agent any
stages {
stage('Test Map') {
steps {
script {
echo country_capital['Australia'].best
}
}
}
}
}
// Output
xx1
For the above example one can also do
country_capital.each { capital_key, capital_value ->
try {
echo "Testing ${capital_value.best}..."
}
catch(ex){
echo "Test failed: ${capital_value.bad}" }
}

Resources