How to use regular expression in a JenkinsFile multibranch pipeline? - jenkins

I've a multibranch pipeline jenkins file. I would like to be able to use a custom workspace, which includes this:
pipeline {
agent {
node{
label 'windows-node'
customWorkspace "${env.BRANCH_NAME}"
}
}
//...
}
I would like to be able to extract one part of my branch name to do the regular expression.
my branches have the following structures:
master
develop
feature/BR-1-some-text
bugs/BR-5-some-text
And I would like my workspace to be only BR-X if present, so in my case:
master
develop
BR-1
BR-5
I'm totally capable to do one regular expression to extract this from this text, but I don't see how to extract this regex and use it as customWorkspace.
Any idea?

If understand correctly, I use the condition checks in pipeline like this, I abort my pipeline if branch is not of this pattern.
when {
not {
anyOf {
branch 'feat/*';
branch 'feature/*'
branch 'bug/*'
branch 'bugfix/*'
branch 'release/*'
branch 'hotfix/*'
branch 'PR-*'
branch 'e2e/*'
branch 'develop'
branch 'fix/*'
}
}
}
or you can also use
when { branch pattern: "release-\\d+", comparator: "REGEXP"}

Related

Jenkins pipeline with a conditional trigger

My Jenkins pipeline is as follow:
pipeline {
triggers {
cron('H */5 * * *')
}
stages {
stage('Foo') {
...
}
}
}
The repository is part of a Github Organization on Jenkins - every branch or PR pushed results in a Jenkins job being created for that branch or PR.
I would like the trigger to only be run on the "main" branch because we don't need all branches and PRs to be run on a cron schedule; we only need them to be run on new commits which they already do.
Is it possible?
yes - it's possible. To schedule cron trigger only for a specific branch you can do it like this in your Jenkinsfile:
String cron_string = (scm.branches[0].name == "main") ? 'H */5 * * *' : ''
pipeline {
triggers {
cron(cron_string)
}
// whatever other code, options, stages etc. is in your pipeline ...
}
What it does:
Initialize a variable based on a branch name. For main branch it sets requested cron configuration, otherwise there's no scheduling (empty string is set).
Use this variable within pipeline
Further comments:
it's possible to use it also with parameterizedCron (in a case you'd want / need to).
you can use also some other variables for getting branch name, e.g: env.BRANCH_NAME instead of scm.branches[0].name. Whatever fits your needs...
This topic and solution is discussed also in Jenkins community: https://issues.jenkins.io/browse/JENKINS-42643?focusedCommentId=293221#comment-293221
EDIT: actually a similar question that leads to the same configuration - here on Stack: "Build Periodically" with a Multi-branch Pipeline in Jenkins
You can simply add a when condition to your pipeline.
when { branch 'main' }

Is it possible to pass stages into a Jenkinsfile via pipeline parameters

I'm currently working with a Jenkinsfile I can't directly add code to as it is not developed by my team, however I was thinking there might be some way that I could get the owners of the Jenkinsfile (just another team in my company) to allow us to add "pre" and "post" type variables to the Jenkinsfile, where we could than pass in the stages and logic.
A sample Jenkinsfile today might look like
pipeline {
stages {
stage('Clean-Up WS') {
steps {
cleanWs()
}
}
stage('Do more....
And the desired Jenkinsfile might look like
def x = stage('Clean-Up WS') {
steps {
cleanWs()
}
}
pipeline {
stages {
x()
stage('Do more....
Where x in the above example could be passed in via a Jenkins parameter
I've played around with the above and tried with similar syntax but nothing seems to work
Does anyone know if anything like this possible using Jenkinsfiles?

Jenkins Git-Push with master branch only

This might be a very basic question in terms of jenkins and github integration. However, I am thinking good to ask.
What I am basically looking to do is if anything pushed to master branch of git only then my jenkins job must get triggered. Considering there are multiple feature branches and multiple commits happening on different branches but I am interested only in master branch push.
I did not find good documentation over, could anybody give me any pointer on this.
Help is appreciated, thanks!
OK, so you got two options:
Create a single branch pipeline
Just click on create new item, select pipeline and under "Pipeline" configure as "Pipeline script from SCM" and put your GitHub and in "branches to build" put "*/master".
Add brach conditions
Alternatively you could add when conditions to your stages if you use declarative syntax:
pipeline {
agent any
stages {
stage("Build") {
when { branch 'master' }
steps {
// do your build
}
}
}
}
Or if you're using scripted:
node {
stage('Build') {
if (env.BRANCH_NAME == 'master') {
// do your build
}
}
}
See "flow control".

How can I parameterize Jenkinsfile jobs

I have Jenkins Pipeline jobs, where the only difference between the jobs is a parameter, a single "name" value, I could even use the multibranch job name (though not what it's passing as JOB_NAME which is the BRANCH name, sadly none of the envs look suitable without parsing). It would be great if I could set this outiside of the Jenkinsfile, since then I could reuse the same jenkinsfile for all the various jobs.
Add this to your Jenkinsfile:
properties([
parameters([
string(name: 'myParam', defaultValue: '')
])
])
Then, once the build has run once, you will see the "build with parameters" button on the job UI.
There you can input the parameter value you want.
In the pipeline script you can reference it with params.myParam
Basically you need to create a jenkins shared library example name myCoolLib and have a full declarative pipeline in one file under vars, let say you call the file myFancyPipeline.groovy.
Wanted to write my examples but actually I see the docs are quite nice, so I'll copy from there. First the myFancyPipeline.groovy
def call(int buildNumber) {
if (buildNumber % 2 == 0) {
pipeline {
agent any
stages {
stage('Even Stage') {
steps {
echo "The build number is even"
}
}
}
}
} else {
pipeline {
agent any
stages {
stage('Odd Stage') {
steps {
echo "The build number is odd"
}
}
}
}
}
}
and then aJenkinsfile that uses it (now has 2 lines)
#Library('myCoolLib') _
evenOrOdd(currentBuild.getNumber())
Obviously parameter here is of type int, but it can be any number of parameters of any type.
I use this approach and have one of the groovy scripts that has 3 parameters (2 Strings and an int) and have 15-20 Jenkinsfiles that use that script via shared library and it's perfect. Motivation is of course one of the most basic rules in any programming (not a quote but goes something like): If you have "same code" at 2 different places, something is not right.
There is an option This project is parameterized in your pipeline job configuration. Write variable name and a default value if you wish. In pipeline access this variable with env.variable_name

How to get the displayName of a Jenkins Multibranch Pipeline Job

I've put all my Jenkins logic in a structured pipeline script (aka Jenkinsfile).
If something goes wrong, i m sending mails. For the subject i want to use the displayName of the job and not the jobs id env.JOB_NAME (as they are driven by access control patterns and not readability).
With a normal pipeline job i could use currentBuild.rawBuild.project.displayName but for multibranch pipelines this is just the branch name.
Or is there a even better way to get the userfriendly name, then traversing the rawBuild?
For now i found no convinient public api, so this seems to be the way to go:
String getDisplayName(currentBuild) {
def project = currentBuild.rawBuild.project
// for multibranch pipelines
if (project.parent instanceof WorkflowMultiBranchProject) {
return "${project.parent.displayName} (${project.displayName})"
} else {
// for all other projects
return project.displayName
}
}
I use currentBuild.fullProjectName which is set to multibranch_pipeline_name/branch_name or pipeline_name depending if you are using a multibranch pipeline or normal pipeline.

Resources