Variable expansion in Jenkins Pipeline - jenkins-pipeline

I am trying to expand a variable in a Jenkinsfile. I first concatenate a couple of strings to create this variable and would like for it to be expanded so that it is interpreted as my environment variable.
I am looking for something like the exclamation mark ! in bash.
pipeline {
agent: any
environment:{
CRED_DEV_PROJ = "my_credentials"
}
stages {
stage("my_stage"){
steps{
script{
LST = [
["DEV", "PROJ"],
... some more lists ...
for (def i= 0; i < LST.size(); i++) {
CRED = "CRED_" + LST[i][0] + "_" + LST[i][1]
sshagent (credentials: [CRED]) {
... do stuff ...
}
}
}
}
}
}
The variable CRED should be expanded so that it leads to my_credentials, so that the line sshagent (credentials: [CRED]) is executed correctly.

That should be env.“${CRED}“.
See also my answer here: https://stackoverflow.com/a/51338110/4279361

Related

Puppet test defined variable with an empty string

I'm trying to test if a variable has a value with a simple if in puppet, but it never reachs the else condition that I'm trying to achieve.
ex :
if $::some_var['some:name'] != undef {
$var = $::some_var['some:name']
}
else {
$var = $::some_var['another:name']
}
some_var cames from a json file, and if the ::some_var['some:name'] is emtpy it will put $var as empty, but what I'm trying to achieve is, if the var is defined but is empty to actually go through the else, can this be achieved using for instance
if defined($::some_var['some:name']) {
$var = $::some_var['some:name']
}
else {
$var = $::some_var['another:name']
}
I resolved it by using
$var = ''
if $var =~ String[1] {
notify{"The value is: ${var}": }
}
else {
notify{"The value is: empty": }
}
file {'/tmp/helloworld.txt': ensure => present, content => "Hello World!", }
If I define $var whit some value, I'll met the if condition, if $var is empty I'll met the else.

In the following code variable 'checkNumber' is not incrementing to 1 even after 'if' block get executed and so that Break is not working

In the following code variable 'checkNumber' is not incrementing to 1 even after 'if' block get executed and so that Break is not working where i need to break the loop
var checkNumber =0
for (let i = 0; i < totalRowCountAllocPrj; i++){
allocationObjects.getAllocationStatusfromGrid(i).then(text => {
appAllocStatus = Cypress.$(text).text()
cy.log("Allocation Status :" + appAllocStatus)
if(appAllocStatus == userData.approvalReservedAllocStatus){
allocationObjects.getAppAllCheckBoxesfromGrid(i).click()
checkNumber=checkNumber+1
cy.log("index="+i)
}
else{
cy.log("Project is not Reserved")
}
})
cy.log("number="+checkNumber)
if(checkNumber==1)
{
break
}
The variable checkNumber gets incremented inside an asynchronous command, but the loop is running synchronously.
You can't use break but you should be able to stop executing the commands with the inverse check.
Since checkNumber never should go above 0, it's more sensible to use a boolean
let found = 0
for (let i = 0; i < totalRowCountAllocPrj; i++) {
cy.then(() => {
if (!found) {
allocationObjects.getAllocationStatusfromGrid(i).then(text => {
appAllocStatus = Cypress.$(text).text()
if (appAllocStatus === userData.approvalReservedAllocStatus) {
allocationObjects.getAppAllCheckBoxesfromGrid(i).click()
found = true
}
})
}
})
}
BTW you should be able to rewrite allocationObjects.getAllocationStatusfromGrid() to directly search for userData.approvalReservedAllocStatus and get rid of the loop altogether.

How to pass pipeline stage variable to makefile

I am calculating the value of local variable (S_STACK_ID) inside dynamic stage of jenkins pipeline
I need to pass S_STACK_ID variable to makefile so that it could be used in makefile to uniquely identify ECS Stack to be deployed
I have tried below code but it passes blank 'ARGS' to makefile
stage('build') {
steps {
script {
def stages = [failFast:true]
for (int i=1; i<5; i++) {
stages["LG ${i}"]={
stage ("LG ${i}"){
S_STACK_ID=env.STACK_ID+i
withCredentials([[
sh 'make ARGS="${S_STACK_ID}" build'
}
}
}
}
parallel stages
}
}
}
sh 'make ARGS="myStack" build' //This correclty passes "myStack" to makefile
sh 'make ARGS="${S_STACK_ID}" build' // Passess blank to makefile and not the value of S_STACK_ID which is an issue for me
Thanks
This worked as "" are required for shell commands to interpolate string literals
sh "make clean \"ARGS=${S_STACK_ID}\""

I have 3 stages to build in jenkins using pipeline code (Scripted0

I have 3 stages(a,b,c) to run on jenkins using pipeline code(scripted), I
need to run stage a,b in parallel and run c after a is success (I am
doing this using pipeline code) but in blue ocean it showing only task
name but I wanna see stage names(in this case I have only 2 tasks with 3
stages and stage a and c are in one task). can someone help how can view
all three stages according to this situation.
def stages = [failFast: false]
def testList = ["a", "b", "c"]
def tasks = [:]
tasks["a-and-c"] = {
stage ("a"){
ansiColor('xterm') {
sh " ls -lart; sleep 30 "
}
if (currentBuild.currentResult == 'SUCCESS') {
stage("c") {
ansiColor('xterm') {
sh " ls -lart "
}
}
} else {
sh 'exit'
}
}
}
tasks["c"] = {
stage ("c"){
ansiColor('xterm') {
sh " ls -lart; sleep 20"
}
}
}
parallel tasks
I am expecting to have a separate view in blueocean for all three stages,
right now I am getting a-and-c and b parallel but I looking for a,b as
parallel and c after a is success. Thank you in advance.

std::process::Command cannot run hdiutil on macOS (mount failed - No such file or directory) but the command works fine when run in the terminal

hdiutils, when fed a correct path to a valid file, returns error 2, no such file or directory. When I join the indices of the command array with " ", print them, copy them and run the exact string in a terminal, it works fine.
This is the function edited to contain only the relevant bits. In order to reproduce my error, you will need a disk image located at ~/Downloads/StarUML.dmg.
use std::env;
use std::fs;
use std::process::Command;
fn setup_downloads(download_name: &str) {
let downloads_path: String = {
if cfg!(unix) {
//these both yield options to unwrap
let path = env::home_dir().unwrap();
let mut downloads_path = path.to_str().unwrap().to_owned();
downloads_path += "/Downloads/";
downloads_path
} else {
"we currently only support Mac OS".to_string()
}
};
let files_in_downloads =
fs::read_dir(&downloads_path).expect("the read_dir that sets files_in_downloads broke");
let mut file_path: String = "None".to_string();
for file_name in files_in_downloads {
let file_name: String = file_name
.expect("the pre string result which sets file_name has broken")
.file_name()
.into_string()
.expect("the post string result which sets file_name has broken")
.to_owned();
if file_name.contains(&download_name) {
file_path = format!("'{}{}'", &downloads_path, &file_name);
}
}
let len = file_path.len();
if file_path[len - 4..len - 1] == "dmg".to_string() {
let mount_command = ["hdiutil", "mount"];
let output = Command::new(&mount_command[0])
.arg(&mount_command[1])
.arg(&file_path)
.output()
.expect("failed to execute mount cmd");
if output.status.success() {
println!(
"command successful, returns: {}",
String::from_utf8_lossy(&output.stderr).into_owned()
);
} else {
println!(
"command failed, returns: {}",
String::from_utf8_lossy(&output.stderr).into_owned()
);
}
}
}
fn main() {
setup_downloads(&"StarUML".to_string());
}
Split your Command into a variable and print it using the debugging formatter after you have specified the arguments:
let mut c = Command::new(&mount_command[0]);
c
.arg(&mount_command[1])
.arg(&file_path);
println!("{:?}", c);
This outputs
"hdiutil" "mount" "\'/Users/shep/Downloads/StarUML.dmg\'"
Note that Command automatically provides quoting for each argument, but you have added your own set of single quotes:
format!("'{}{}'", &downloads_path, &file_name);
// ^ ^
Remove these single quotes.

Resources