My requirement is simple, i just want to externalize some 'values' to make my Jenkinsfile more re usable and for this i need to load the properties from a file which is going to be right next to Jenkinsfile, and make sure that these properties are available anywhere in the pipeline. I am still new to groovy and Jenkins code but never thought such a simple thing would be so difficult. I enabled some methods in script security plugin but the following code (and several variations i tried around it) always pose errors or print null or give me NPE. I have tried multiple combinations and the below code is just one of them.
properties = null
@NonCPS
def loadProperties() {
checkout scm
File propertiesFile = new File('${workspace}/pipeline.properties')
propertiesFile.withInputStream {
properties.load(propertiesFile)
}
}
pipeline {
agent none
stages {
stage ('prepare') {
agent any
steps {
script {
loadProperties()
echo "${properties['repo']}"
}
}
}
stage('Build') {
agent any
steps {
sh 'echo ${properties.repo}'
}
}
}
}
The basic statements and expressions which are valid in Declarative Pipeline follow the same rules as Groovy's syntax with the following exceptions: The top-level of the Pipeline must be a block, specifically: pipeline { } . No semicolons as statement separators. Each statement has to be on its own line.
Declarative Pipeline is a relatively recent addition to Jenkins Pipeline which presents a more simplified and opinionated syntax on top of the Pipeline sub-systems. All valid Declarative Pipelines must be enclosed within a pipeline block, for example: pipeline { /* insert Declarative Pipeline here */ }
I figured out a couple of ways to externalize properties in Jenkins pipelines. You can choose your pick based on the main difference.
1) Using groovy code entirely. This code snippet would require you to enable several method signatures in 'In-process script approval' which comes in with script security plugin, and hence this should be done only after due consideration.
properties = null
def loadProperties() {
node {
checkout scm
properties = new Properties()
File propertiesFile = new File("${workspace}/pipeline.properties")
properties.load(propertiesFile.newDataInputStream())
echo "Immediate one ${properties.repo}"
}
}
pipeline {
agent none
stages {
stage ('prepare') {
agent any
steps {
script {
loadProperties()
echo "Later one ${properties.branch}"
}
}
}
stage('Build') {
agent { label 'master' }
steps {
// works fine. properties is available everywhere
echo properties.branch
}
}
}
}
2) Using pipeline utility steps plugin - Pipeline suite of plugins include this by default and it allows a better way to load properties without requiring to enable security exceptions. I would recommend this method.
properties = null
def loadProperties() {
node {
checkout scm
properties = readProperties file: 'pipeline.properties'
echo "Immediate one ${properties.repo}"
}
}
pipeline {
agent none
stages {
stage ('prepare') {
agent any
steps {
script {
loadProperties()
echo "Later one ${properties.ansible}"
}
}
}
stage('Build') {
agent any
steps {
echo properties.branch
}
}
}
}
Thanks for Answer #1. It helped a lot, I used option 2. I faced some problems, and would like to share my solution:
1) I added a "prepare" stage, inside the pipeline section of the declarative pipeline:
stage ('Prepare') {
steps {
script {
properties = readProperties file: 'scripts/jenkins-pipelines/branch-specific.properties'
echo "Running build ${JOB_NAME} # ${BUILD_NUMBER} on git repo ${properties.GitURL} branch ${properties.nextBranchName}"
}
}
}
}
The format of the properties file is:
nextBranchName=next
stableBranchName=master
[email protected]:foo.git
Please note that there are no quote on the properties.
I used the properties as ${properties.nextBranchName} also on other steps, stages and post. As mentioned on answer 1: there is a need to install "pipeline utility steps" plugin
Using the "pipeline utility steps" plugin, you can define general vars available to all stages. For example, let props.txt
as:
version=1.0
fix=alfa
and mix script and declarative Jenkins pipeline as:
def props
def VERSION
def FIX
def RELEASE
node {
props = readProperties file:'props.txt'
VERSION = props['version']
FIX = props['fix']
RELEASE = VERSION + "_" + FIX
}
pipeline {
stages {
stage('Build') {
echo ${RELEASE}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With