I am considering to use Jenkins pipeline script recently, one question is that I don\'t figure out a smart to way to create internal reusable utils code, imagine, I have a commo
I prefer creating a buildRepo()
method that I invoke from repositories. Its signature is def call(givenConfig = [:])
so that it can also be invoked with parameters, like:
buildRepo([
"npm": [
"cypress": false
]
])
I keep parameters at an absolute minimum and try to rely on conventions rather than configuration.
I provide a default configuration which is also where I put documentation:
def defaultConfig = [
/**
* The Jenkins node, or label, that will be allocated for this build.
*/
"jenkinsNode": "BUILD",
/**
* All config specific to NPM repo type.
*/
"npm": [
/**
* Whether or not to run Cypress tests, if there are any.
*/
"cypress": true
]
]
def effectiveConfig merge(defaultConfig, givenConfig)
println "Configuration is documented here: https://whereverYouHos/getConfig.groovy"
println "Default config: " + defaultConfig
println "Given config: " + givenConfig
println "Effective config: " + effectiveConfig
Using the effective configuration, and the content of the repository, I create a build plan.
...
derivedBuildPlan.npm.cypress = effectiveConfig.npm.cypress && packageJSON.devDependencies.cypress
...
The build plan is the input to some build methods like:
node(buildPlan.jenkinsNode) {
stage("Install") {
sh "npm install"
}
stage("Build") {
sh "npm run build"
}
if (buildPlan.npm.tslint) {
stage("TSlint") {
sh "npm run tslint"
}
}
if (buildPlan.npm.eslint) {
stage("ESlint") {
sh "npm run eslint"
}
}
if (buildPlan.npm.cypress) {
stage("Cypress") {
sh "npm run e2e:cypress"
}
}
}
I wrote a blog post about this on Jenkins.io: https://www.jenkins.io/blog/2020/10/21/a-sustainable-pattern-with-shared-library/