Calling functions in jenkinsfile with variables - jenkins

I need some help in calling a function in Jenkinsfile along with a variable.
I have created a bash function to copy certain test results from jenkins slave to Jenkins master's userContent directory.
I want to use this function across diff jobs. Different jobs might have different report path, instead of hardcoding the path inside the function i want to use a variable in jenkinsfile to pass along with the function.
Here is my function:
def call() {
sh '''
mkdir -p $JOB_NAME
foldername="$BUILD_NUMBER.$(date '+%d-%m-%Y')"
echo ${foldername}
mkdir -p $JOB_NAME/${foldername}
pwd
reportPath=""
dest="./$JOB_NAME/${foldername}"
cp -R ${reportPath}/*.xml ${dest}
scp -r $JOB_NAME jenkins#master_ip:/var/lib/jenkins/userContent/
'''
}
How do i call the function in jenkinsfile and have a variable with report path?

I guess you want to copy Jenkins Slave artifact to master. You can use following plugin https://wiki.jenkins.io/display/JENKINS/Copy+Artifact+Plugin
You can use following method for declarative pipeline jobs:
stages {
stage('Copy Archive') {
steps {
script {
step ([$class: 'CopyArtifact',
projectName: 'Create_archive',
filter: "packages/infra*.zip",
target: 'Infra']);
}
}
}

Related

Jenkins build failed due to command not being recognized

I have this build error saying pandoc command is not recognize, when I build my pipeline on Jenkins :
But when I run the exact same command using cmd.exe from the same repository it works perfectly :
So what's wrong here, my command pandoc is well installed and can perfectly be used from cmd.exe, why doesn't it works from Jenkins ?
Here is my Jenkins code (the part causing the error is in the "Build" stage):
pipeline {
agent any
stages {
stage('Prerequisites') {
steps {
//bat 'RMDIR C:\\wamp64\\www\\html\\doc'
bat 'MKDIR C:\\wamp64\\www\\html\\doc'
}
}
stage('Build') {
steps {
bat 'pandoc -s C:\\wamp64\\www\\index.md -o C:\\wamp64\\www\\index.html'
bat 'pandoc -s C:\\wamp64\\www\\index.md -o C:\\wamp64\\www\\index.docx'
}
}
stage('Deploy') {
steps {
bat 'COPY C:\\wamp64\\www\\index.html COPY C:\\wamp64\\www\\html\\index.html'
bat 'COPY C:\\wamp64\\www\\index.docx COPY C:\\wamp64\\www\\html\\doc\\index.docx'
}
}
}
}
Thanks for helping.
Jenkins doesn't automatically take your Windows (path) environment variables. Instead, what you need to do is to go to Jenkins -> Configure System -> Global properties -> Environment variables and add a new variable called Path. For the value, set $Path, and your path variables should start getting registered.
The issue has been discussed extensively in this question.

Assign Terraform output to a variable within Jenkins Pipeline

I am creating an EC2 instance using aws_cloudformation_stack and capturing it's output for private_ip. I want to use this output within my jenkins pipeline so that I can assign it to a variable and then inject that variable into my ansible vars file.
I am having a lot of trouble assigned the value of the terraform output to my private_ip variable in jenkins.
Is something like this possible in terraform or should I be working with a template file instead?
TF code :
resource "aws_cloudformation_stack" "test_instance" {
...
}
output "test_instance_private_ip" {
value = aws_cloudformation_stack.test_instance.outputs.PrivateIp
}
Jenkins pipeline code :
def private_ip
stage('terraform'){
sh """
terraform init
terraform plan
terraform apply --auto-approve
"""
private_ip = sh(returnStdout: true, script: "terraform output test_instance_private_ip").trim()
}
stage('ansible') {
sh """
ansible-playbook -i inventory.yml --limit testgroup -e "private_ip=${private_ip}" playbook.yml -v
"""
}
Current output :
Warning: No outputs found
Warning: Empty or non-existent state

variable does not get resolved in my jenkinsfile

I am new to jenkins/groovy and I am currently facing following issue...
I defined a deployment pipeline in a jenkinsfile, it consists in deploying scripts on two different environments running under linux. Deployment script copy_files.sh has to run under a specific user to preserve permissions:
def my_dst = '/opt/scripts'
pipeline {
agent { label '<a generic label>' }
stages {
stage('Deployment env1') {
agent { label '<a specific label>' }
steps {
script {
echo 'Deploying scripts...'
sh '/bin/sudo su -c "${WORKSPACE}/copy_files.sh ${WORKSPACE} ${my_dst}" - <another user>'
}
}
}
stage('Deployment env2') {
agent { label '<another specific label>' }
steps {
script {
echo 'Deploying scripts...'
sh '/bin/sudo su -c "${WORKSPACE}/copy_files.sh ${WORKSPACE} ${my_dst}" - <another user>'
}
}
}
}
}
I defined the destination path where files are supposed to be copied as a variable (my_dst same on both envs). While the env variable $WORKSPACE gets resolved my variable my_dst does not, resulting in an abort of the copy_files.sh script because of missing argument...
How can I quote my command properly in order my variable to be resolved? running sudo command with hard-coded destination path /opt/scripts works.
txs in advance
So you want Groovy to inject the my_dst, but the WORKSPACE to come from the shell environment, so you will need to use double quotes (so groovy does the templating), and escape the $ in WORKSPACE so Groovy doesn't template it and it gets passed to the shell as-is:
sh "/bin/sudo su -c \"\${WORKSPACE}/copy_files.sh \${WORKSPACE} ${my_dst}\" - <another user>"

Groovy in Jenkins pipeline - create a file with content

I am using Jenkins' shared library and my Jenkins file has a stage like this:
stage('sonarqube') {
when { branch 'master' }
steps {
generateUnitTestsReport()
}
}
I want to keep programmers' repos clean from scripts that create various reports, so my idea is to keep definitions of scripts in a shared library, and then, during step execution, create a file with the content.
For instance (file generateUnitTestsReport.groovy in shared library):
def call(){
def SCRIPT_CONTENT = '''
#!/bin/bash
#SCRIPT CONTENT
'''
sh '''echo''' +SCRIPT_CONTENT+ ''' > ut-report.sh'''
sh 'chmod +x ./ut-report.sh'
}
but it doesn't work like this. I also tried Groovy's new File, but no luck there either. How could this be done (note that this is a Jenkins slave node)?

How to use inject environment variables (Properties File Path) in Jenkins Pipeline

Want to use the below functionality(shown in image link) in Jenkins as code, but i'm failing to do, kindly help me replicate the functionality in the image to groovy script
stage ('Build Instance') {
sh '''
bash ./build.sh -Ddisable-rpm=false
'''
env "/fl/tar/ver.prop"
}
Jenkins GUI usage of Env Inject
Got a simple workaround :
script {
def props = readProperties file: '/fl/tar/ver.prop' //readProperties is a step in Pipeline Utility Steps plugin
env.WEATHER = props.WEATHER //assuming the key name is WEATHER in properties file
}

Resources