I am currently working on a generic pipeline which is going to be used via shared library to replace existing jobs so that it's easier to manage all jobs from a more centralized place. Most of the existing jobs have these three stages:
- allocates a node
- checks out the code from git repository and builds it
- deploys the code to a testing repository
Some of the jobs have a few if/else
s in their stages which do things based on parameters or environment variables, but overall the jobs are quite similar otherwise. The solution which comes to my mind is to use Closures to allow for additional logic code to be executed in those stages, but I am having difficulties figuring out how to secure this so that the only possible "steps" you can execute are sh
and bat
.
Here is an oversimplified example vars/genericPipeline.groovy
to illustrate what I'm talking about:
def call(body)
{
def config = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = config
body()
String AGENT_LABEL = config.getOrDefault('label', 'mvn3')
Closure MVN_BUILD = config.getOrDefault('build', {
sh "mvn clean install"
})
Closure MVN_DEPLOY = config.getOrDefault('deploy', { BRANCH_NAME, ARTIFACT_COORDINATES, SERVER_ID, REPO, TMP_REPO ->
def SERVER_URL = REPO
if (BRANCH_NAME != 'master')
{
SERVER_URL = TMP_REPO
}
sh label: "Deploying ${ARTIFACT_COORDINATES}",
script: "mvn deploy" +
" -DskipTests" +
" -DaltDeploymentRepository=${SERVER_ID}::default::${SERVER_URL}"
})
pipeline {
agent {
node {
label AGENT_LABEL
}
}
environment {
GROUP_ID = readMavenPom().getGroupId()
ARTIFACT_ID = readMavenPom().getArtifactId()
VERSION = readMavenPom().getVersion()
ARTIFACT_COORDINATES = "${readMavenPom().getGroupId()}:${readMavenPom().getArtifactId()}:${readMavenPom().getVersion()}"
}
stages {
stage('Building...') {
steps {
MVN_BUILD()
}
}
stage('Deploying...') {
steps {
MVN_DEPLOY(BRANCH_NAME, env.ARTIFACT_COORDINATES, config.serverId, config.repo, config.tmpRepo)
}
}
}
}
}
This could later be used in the jobs as:
genericPipeline {
build = {
sh "mvn clean install"
}
// could be set for the "corner cases" or could skipped to use the
// default deploy closure for all other cases.
deploy = {
sh "mvn deploy"
}
}
As you can see, the deploy
uses two different repositories to deploy to, based on the branch
name. I am aware I could simply just put the logic in the stage
, but the problem is that some of the jobs are not multi-branch and they would not have this if/else
logic. However they would still have the same pipeline structure without any other changes and I would prefer to have to maintain one pipeline than 5 relatively similar pipes for all the different if/else
cases which could occur in the deploy stage. :)
So, the question here - is it possible to only white-list the execution of specific steps (i.e. sh/bat
) in the MVN_BUILD
and MVN_DEPLOY
closures? Or if there is another, perhaps even better way to handle this case?