I want to integrate Jenkins jobs using Groovy by passing dynamic variables based on the projects for which the job is triggered.
Can anyone please suggest on how to proceed with this?
Looks like you would like to persist data between two jenkins jobs or two runs of the same jenkins job. In both cases, I was able to do this using files. you can use write file to do it using groovy or redirection operator (>) to just use bash.
In first job, you can write to the file like so.
node {
// write to file
writeFile(file: 'variables.txt', text: 'myVar:value')
sh 'ls -l variables.txt'
}
In second job, you can read from that file and empty the contents after you read it.
stage('read file contents') {
// read from the file
println readFile(file: 'variables.txt')
}
The file can be anywhere on the filesystem. Example with a file created in /tmp folder is as follows. You should be able to run this pipeline by copy-pasting.
node {
def fileName = "/tmp/hello.txt"
stage('Preparation') {
sh 'pwd & rm -rf *'
}
stage('write to file') {
writeFile(file: fileName, text: "myvar:hello", encoding: "UTF-8")
}
stage('read file contents') {
println readFile(file: fileName)
}
}
You could also use this file as a properties file and update a property that exists and append ones that don't . A quick sample code to do that looks like below.
node {
def fileName = "/tmp/hello.txt"
stage('Preparation') {
sh 'pwd & rm -rf *'
}
stage('write to file') {
writeFile(file: fileName, text: "myvar:hello", encoding: "UTF-8")
}
stage('read file contents') {
println readFile(file: fileName)
}
// Add property
stage('Add property') {
if (fileExists(fileName)) {
existingContents = readFile(fileName)
}
newProperty = "newvar:newValue"
writeFile(file: fileName, text: existingContents + "\n" + newProperty)
println readFile(file: fileName)
}
}
You could easily delete a line that has a property if you would like to get rid of it
Related
I have a Jenkins job where that needs to copy a file to a specific server per user choice. Till today all was working since I needed to copy the same file to the server that the user choose.
Now I need to copy a specific file per server. I n case the user chooses to deploy Server_lab1-1.1.1.1 so lab1.file.conf file should be copied. in case the user chooses to deploy Server_lab2-2.2.2.2 , lab2.file.conf should be copied.
I’m guessing that I need to add to the function
Check if the Server parameter includes lab1 if so, copy lab1.file.conf file and if the Server parameter includes lab2 if so, copy lab2.file.conf file
parameters {
extendedChoice(name: 'Servers', description: 'Select servers for deployment', multiSelectDelimiter: ',',
type: 'PT_CHECKBOX', value: 'Server_lab1-1.1.1.1, Server_lab2-2.2.2.2', visibleItemCount: 5)
stage ('Copy nifi.flow.properties file') {
steps { copy_file() } }
def copy_file() {
params.Servers.split(',').each { item -> server = item.split('-').last()
sh "scp **lab1.file.conf or lab2.file.conf** ${ssh_user_name}#${server}:${spath}"
}
}
Are you looking for something like below.
def copy_file() {
params.Servers.split(',').each { item ->
def server = item.split('-').last()
def fileName = item.contains('lab1') ? 'lab1.file' : 'lab2.file'
sh "scp ${fileName} ${ssh_user_name}#${server}:${spath}"
}
}
Update Classic if-else
def copy_file() {
params.Servers.split(',').each { item ->
def server = item.split('-').last()
def fileName = "default"
if( item.contains('lab1')) {
fileName = 'lab1.file'
} else if(item.contains('lab2')) {
fileName = 'lab2.file'
} else if(item.contains('lab3')) {
fileName = 'lab3.file'
}
sh "scp ${fileName} ${ssh_user_name}#${server}:${spath}"
}
}
Actually my Jenkinsfile looks like this:
#Library('my-libs') _
myPipeline{
my_build_stage(project: 'projectvalue', tag: '1.0' )
my_deploy_stage()
}
I am trying to pass these two variables (project and tag) to my build_stage.groovy, but it is not working.
What is the correct syntax to be able to use $params.project or $params.tag in my_build_stage.groovy?
Please see the below code which will pass parameters.
In your Jenkinsfile write below code:
// Global variable is used to get data from groovy file(shared library file)
def mylibrary
def PROJECT_VALUE= "projectvalue"
def TAG = 1
pipeline{
agent{}
stages{
stage('Build') {
steps {
script {
// Load Shared library Groovy file mylibs.Give your path of mylibs file which will contain all your function definitions
mylibrary= load 'C:\\Jenkins\\mylibs'
// Call function my_build stage and pass parameters
mylibrary.my_build_stage(PROJECT_VALUE, TAG )
}
}
}
stage('Deploy') {
steps {
script {
// Call function my_deploy_stage
mylibrary.my_deploy_stage()
}
}
}
}
}
Create a file named : mylibs(groovy file)
#!groovy
// Write or add Functions(definations of stages) which will be called from your jenkins file
def my_build_stage(PROJECT_VALUE,TAG_VALUE)
{
echo "${PROJECT_VALUE} : ${TAG_VALUE}"
}
def my_deploy_stage()
{
echo "In deploy stage"
}
return this
I came here from this post Defining a variable in shell script portion of Jenkins Pipeline
My situation is the following I have a pipeline that is updating some files and generating a PR in my repo if there are changes in the generated files (they change every couple of weeks or less).
At the end of my pipeline I have a post action to send the result by email to our teams connector.
I wanted to know if I could somehow generate a variable and include that variable in my email.
It looks something like this but off course it does not work.
#!groovy
String WasThereAnUpdate = '';
pipeline {
agent any
environment {
GRADLE_OPTS = '-Dorg.gradle.java.home=$JAVA11_HOME'
}
stages {
stage('File Update') {
steps {
sh './gradlew updateFiles -P updateEnabled'
}
}
stage('Create PR') {
steps {
withCredentials(...) {
sh '''
if [ -n \"$(git status --porcelain)\" ]; then
WasThereAnUpdate=\"With Updates\"
...
else
WasThereAnUpdate=\"Without updates\"
fi
'''
}
}
}
}
post {
success {
office365ConnectorSend(
message: "Scheduler finished: " + WasThereAnUpdate,
status: 'Success',
color: '#1A5D1C',
webhookUrl: 'https://outlook.office.com/webhook/1234'
)
}
}
}
I've tried referencing my variable in different ways ${}, etc... but I'm pretty sure that assignment is not working.
I know I probably could do it with a script block but I'm not sure how I would put the script block inside the SH itself, not sure this would be possible.
Thanks to the response from MaratC https://stackoverflow.com/a/64572833/5685482 and this documentation
I'll do it something like this:
#!groovy
def date = new Date()
String newBranchName = 'protoUpdate_'+date.getTime()
pipeline {
agent any
stages {
stage('ensure a diff') {
steps {
sh 'touch oneFile.txt'
}
}
stage('AFTER') {
steps {
script {
env.STATUS2 = sh(script:'git status --porcelain', returnStdout: true).trim()
}
}
}
}
post {
success {
office365ConnectorSend(
message: "test ${env.STATUS2}",
status: 'Success',
color: '#1A5D1C',
webhookUrl: 'https://outlook.office.com/webhook/1234'
)
}
}
In your code
sh '''
if [ -n \"$(git status --porcelain)\" ]; then
WasThereAnUpdate=\"With Updates\"
...
else
WasThereAnUpdate=\"Without updates\"
fi
'''
Your code creates a sh session (most likely bash). That session inherits the environment variables from the process that started it (Jenkins). Once it runs git status, it then sets a bash variable WasThereAnUpdate (which is a different variable from likely named Groovy variable.)
This bash variable is what gets updated in your code.
Once your sh session ends, bash process gets destroyed, and all of its variables get destroyed too.
This whole process has no influence whatsoever on Groovy variable named WasThereAnUpdate that just stays what it was before.
I am trying to create New file in Jenkins Pipeline , by getting error.
error:
java.io.FileNotFoundException: /var/lib/jenkins/workspace/Pipeline-Groovy/test.txt (No such file or directory)
But when i am executing below commands without pipeline , It's created new file
def newFile = new File("/var/lib/jenkins/workspace/test/test.txt")
newFile.append("hello\n")
println newFile.text
If i use same code in Pipeline getting above error
pipeline {
agent any
options {
buildDiscarder(logRotator(numToKeepStr: '5'))
timestamps()
}
stages {
stage('Demo1-stage') {
steps {
deleteDir()
script {
def Jobname = "${JOB_NAME}"
echo Jobname
}
}
}
stage('Demo-2stage') {
steps {
script {
def workspace = "${WORKSPACE}"
echo workspace
def newFile = new File("/var/lib/jenkins/workspace/Pipeline-Groovy/test.txt")
newFile.createNewFile()
sh 'ls -lrt'
}
}
}
}
}
It looks like your folder is not present. Do not give absolute path while creating the file unless it is a requirement. I see that in your case, you need a file in workspace. Always use the ${WORKSPACE} to get the current work directory.
def newFile = new File("${WORKSPACE}/test.txt")
newFile.createNewFile()
I'm failing to reference a second groovy file in my src of my repo.
My set up is this: library name pipeline-library-demo
github
I have added a second groovy file to the src folder
app_config.groovy
#!/usr/bin/groovy
def bob(opt) {
sh "docker run --rm " +
'--env APP_PATH="`pwd`" ' +
'--env RELEASE=${RELEASE} ' +
"-v \"`pwd`:`pwd`\" " +
"-v /var/run/docker.sock:/var/run/docker.sock " +
"docker_repo/bob:1.4.0-8" ${opt}
}
def test(name) {
echo "Hello ${name}"
}
The Jenkins file I am using is:
pipeline {
Library('pipeline-library-demo') _
agent {
node {
label params.SLAVE
config = new app_config()
}
}
parameters {
string(name: 'SLAVE', defaultValue: 'so_slave')
}
stages {
stage('Demo') {
steps {
echo 'Hello World'
sayHello 'Dave'
}
}
stage('bob') {
steps {
config.test 'bob'
config.bob '--help'
}
}
}
}
I think I am not referencing the app_config.groovy correctly and it's not finding
Library call should come in starting of the jenkins file, please follow below
If you have added the library configuration in jenkins configuration then call should be like below:-
#Library('pipeline-library-demo')_
If you want to call the library dynamically you should call like below:-
library identifier: 'custom-lib#master', retriever:
modernSCM([$class:'GitSCMSource',remote:
'git#git.mycorp.com:my-jenkins-utils.git', credentialsId:
'my-private-key'])
please refer this link
And please define package in your app_config.groovy. (ex. package com.cleverbuilder)