jenkins pipeline PR build contains wrong branch name - jenkins

I am using Jenkins multi branch pipeline with bitbucket and I see an issue where the automatic build created for a PR fails as I rely on env.BRANCH_NAME.
Problem is that this env now holds not the feature branch name as expected, instead it holds the PR is (e.g. PR-2 instead of feature/test-branch).
I have code in my job that pushes to branch based on the BRANCH_NAME. This code obviously now fails as there is no branch named PR-2.
Anyone saw this before and has a workaround?

I have a stage in my pipeline setting the build name accordingly in case I have to use the CHANGE_BRANCH instead of the normal branch name.
stage('Set Build Name') {
steps {
script {
if (env.BRANCH_NAME.startsWith('PR')) {
currentBuild.displayName = "#${env.BUILD_NUMBER} - ${env.CHANGE_BRANCH}"
} else {
currentBuild.displayName = "#${env.BUILD_NUMBER} - ${env.BRANCH_NAME}"
}
}
}
}

Related

Jenkins pipeline determine if a branch is for Bitbucket pull request

I'm using Jenkins together with the Bitbucket branch source plugin.
Everything works great, but I want to be able to run/exclude certain stages in my pipeline depending on whether the branch is associated with a pull request or not, such as:
pipeline {
stages {
stage('build') {
//compile
}
stage('package') {
when {
environment name: 'IS_PULL_REQUEST', value: 'true'
}
//create deployable package
}
}
}
Jenkins knows when the branch is for a PR because it merges the source with the target and also displays the branch in the pull request folder on the multibranch pipeline page.
Is there an environment variable I can use within the pipeline to exclude/include stages?
You can use BRANCH_NAME and CHANGE_ID environment variables to detect pull requests. When you run a multibranch pipeline build from a branch (before creating a pull request), the following environment variables are set:
env.BRANCH_NAME is set to the repository branch name (e.g. develop),
env.CHANGE_BRANCH is null,
env.CHANGE_ID is null.
But once you create a pull request, then:
env.BRANCH_NAME is set to the PR-\d+ name (e.g. PR-11),
env.CHANGE_BRANCH is set to the real branch name (e.g. develop),
env.CHANGE_ID is set to the pull request ID (e.g. 11).
I use the following when condition in my pipelines to detect pull requests:
when {
expression {
// True for pull requests, false otherwise.
env.CHANGE_ID && env.BRANCH_NAME.startsWith("PR-")
}
}
In Declarative Pipelines, you can also use the built-in condition changeRequest inside the when directive to determine if the branch is associated with a pull request.
stage('package') {
when {
changeRequest()
}
//create deployable package
}
You can also check if the pull request is targeted at a particular branch:
stage('package') {
when {
changeRequest target: 'master'
}
//create deployable package
}
See https://jenkins.io/doc/book/pipeline/syntax/#when.

Is there a way for a Jenkins Pipeline, in a Multibranch setup, to automatically checkout the branch that is at the latest revision?

I'm trying to configure job in Jenkins Multibranch pipeline. There are a lot of branches in SVN and I want the job to checkout only the latest one and ignores the rest of them. This job triggers a pipeline that does multiple checks on the whole build... so I always need to trigger this on the latest branch because there I will have the latest revision of the build.
The SVN structure is like this: V01_01_01 till the latest one V01_08_03. Currently I have it set up like the below and in the Jenkins pipeline I have "checkout scm", but if a new branch appears e.g. V01_08_04 I need V01_08_03 to be replaced by V01_08_04. Is there any way to do this ?
My set-up in Jenkins Multibranch pipeline
I found a hack to this. I created a python script that checks the whole repository for the latest folder that was updated.
pipeline
{
agent any
parameters
{
string(name: 'latest_folder', defaultValue: '')
}
stages
{
stage ('find latest folder')
{
steps
{
withPythonEnv('System-CPython-3.8')
{
sh 'pip3 install svn'
script {
def folder_name = sh(script: 'python3 latest_folder_svn.py', returnStdout: true)
env.latest_folder = folder_name
}
}
}
}
stage ('Checkout Step')
{
steps
{
echo "${env.latest_folder}"
}
}
}
}
This variable I will add it in the checkout step in order to have always the latest branch.
The python script is pretty straightforward. I use svn library to parse the repository and extract what I need.

Jenkins Pipeline Multibranch doesn't run post steps if there is merge conflicts

I have a multibranch pipeline with the following behaviors:
And the following Jenkinsfile:
pipeline {
agent {
label 'apple'
}
stages {
stage('Lint') {
when {
changeRequest()
}
steps {
sh 'fastlane lint'
}
}
}
post {
success {
reportSuccess()
}
failure {
reportFailure()
}
}
}
I use a slave to run the actual build, but the master still needs to checkout the code to get the Jenkinsfile. For that, it seems to use the same behaviors as the one defined in the job even though it really only needs the Jenkinsfile.
My problem is that I want to discover pull requests by merging the pull request with the current target branch revision, but when there is a merge conflict the build will fail before the Jenkinsfile is executed. This prevents any kind of reporting done in post steps.
Is there a way to have the initial checkout not merge the target branch, but still have it merged when actually running the Jenkinsfile on a slave?
You may want to check out using "Current Pull Request revision" strategy, and then on a successful build issue a git merge command.

How to graphically visualize/tag build branch in Jenkins?

I am building Jenkins build pipeline and I was wondering if it is possible to somehow tag/visualize the build branch in Jenkins in the similar way as it is automatically possible in TeamCity.
I am using declarative pipeline defined in separate git repository and Jenkins 2.46.3.
From the picture it is not obvious that the last 2 builds were executed on a separate branch:
Thanks
You can modify the current build's display name and description using the following code:
currentBuild.displayName = env.BRANCH_NAME
currentBuild.description = 'Final Release'
This was recently highlighted in the BlueOcean 1.1 announcement, which shows both of them, in contrast to the regular interface, which only shows the displayName.
An example of a modified displayName from our public instance looks as follows:
You can find the code which generates this in our shared library here and here, essentially it is:
currentBuild.displayName = "#${currentBuild.getNumber()} - ${newVersion} (${increment})"
As you are mentioning Declarative Pipelines, let add that you have to wrap this code in a script block, of course. So probably (untested):
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
script {
currentBuild.displayName = env.BRANCH_NAME
}
}
}
}
}
Alternatively, you can extract it into a separate function.

How to go about seeing the branch name of builds in the build history view of Jenkins?

I installed the Feature Branch Notifier Plugin in my instance of Jenkins.
I have checked the "Show full length branch name in the build history view" checkbox at jenkins:8080/configure
I am expecting to see the branch names in build history view, but even after restarting Jenkins I am not seeing the branch names in the build history, as can be seen in the enclosed image.
The project issue queue lists no open issues, and when I try to log in to post an issue, I get the message "Proxy Error - The proxy server received an invalid response from an upstream server. The proxy server could not handle the request POST /account/doSignup. Reason: Error reading from remote server Apache/2.2.14 (Ubuntu) Server at jenkins-ci.org Port 443"
Does anyone know how to go about seeing the branch name of builds in the build history view of Jenkins? Thanks!
Albert.
You can use Build Name Setter Plugin, and set Set Build Name something like #${BUILD_NUMBER} - ${GIT_BRANCH}.
Build-Name-setter-plugin no longer works. I tried on 2.319.1, and the setting never appears in the pipline.
The solution I found is to use the build environment variables to apply to your display name for the build in a step script.
Adjust your Jenkinsfile to pull the branch name as a environmental variable (I am using CURRENT_BRANCH_NAME). Then I created a new stage / step, that runs before any other, and ran a script to adjust the displayname there:
pipeline {
agent {any}
environment {
CURRENT_BRANCH_NAME = "${GIT_BRANCH.split('/').size() > 1 ? GIT_BRANCH.split('/')[1..-1].join('/') : GIT_BRANCH}"
}
stages {
stage('Set branch name') {
steps {
script{
currentBuild.displayName = "#"+currentBuild.number+": "+CURRENT_BRANCH_NAME
}
}
}
stages {
stage('Ok now start doing testing') {
steps {
sh '''#!/bin/bash
echo "Im gona test everything"
'''
}
}
}
}
Now when your Jenkins test starts to build, the name will update once the step is complete.
Note: this solution was tested in a single pipeline (not multi-pipeline), and was for a SCM repo integration.
Sources:
Get git branch name in Jenkins Pipeline/Jenkinsfile
https://sleeplessbeastie.eu/2021/01/29/how-to-define-build-name-and-description-in-jenkins/

Resources