espenalb
espenalb

Reputation: 548

How to configure Jenkins to display the name and commit of the merged branch

We are using Jenkins with Git and feature branches, but I was not happy about how the Git plugin exposes commit information to the build process when we use the "Merge before build" git option.

The GIT plugin

  1. Checks out the feature branch to build
  2. Merges the feature branch onto master

Because of this, the current branch is now origin/master, and the current HEAD is a local commit that does not yet exist anywhere except on our build server. This could be fixed by pushing the merged code back up to GitHub - maybe even to a temporary branch, but we did not want that behavior, we want manual control.

So the question is: How to

  1. Expose the branch name and commit hash to subsequent build steps
  2. Decorate the build information with a link so the user can browse the commit(s) that triggered the build.

Upvotes: 2

Views: 1593

Answers (1)

espenalb
espenalb

Reputation: 548

If you only want the branch name, and you do not need the branch name for anything during build, the following groovy script is usefull:

def matcher = manager.getLogMatcher(/.*Merging Revision ([0-9a-f]+)\s+\((.*)\).*/)
if (matcher?.matches())
{
   commit = matcher.group(1)
   mergeBranch = matcher.group(2)    
   println "buildLog claims we are buidling ${commit} on '${mergeBranch}'"
   manager.build.setDisplayName( mergeBranch);
}
if (manager.logContains(".*ERROR: Branch not suitable for integration.*") )
{  
    manager.addShortText("Merge conflict");
}

This will set the build name - which is very usefull if the build never starts due to "Branch not suitable for integration".

Another option (the simple obvious one) is to use the GIT_BRANCH environment variable - but this will contain origin/feature-foo - so won't work if you only want 'feature-foo'

The complex solution seems to be:

  1. Install the groovy plugin
  2. Install the EnvInject plugin
  3. Configure the EnvInject plugin with script below

Groovy script:

build = Thread.currentThread().executable
workDir = new File(build.getWorkspace().getRemote())

gitlogProcess = "git log -n 2 --format=\"%H %h %d\"".execute(null,workDir)
log = gitlogProcess?.text // Get the result
items = log?.readLines()?.getAt(1)?.split() // Second line is the commit that was merged onto master
// Parse it
commit = items?.getAt(0)
shortCommit = items?.getAt(1) 
mergeBranch = items?.getAt(2)?.minus("(")?.minus(")")?.minus(" ")?.minus("origin/")
// Update build name and description
//buildNumber = build.getEnvironment(listener)?.get("BUILD_NUMBER") <-- This does not work, presumably because the environment is not yet created - if you need this, execute this script as a build step
displayName = "${mergeBranch}-${shortCommit}"
build.setDisplayName(displayName)

githuburl = build.getParent()?.getProperty("com.coravy.hudson.plugins.github.GithubProjectProperty")?.getProjectUrl()?.commitId(commit)
description = "<a href='${githuburl}'>${shortCommit}-${mergeBranch}</a>"
build.setDescription(description)


// Return a map - this will be added to the environment variables
return [
  MERGE_BRANCH:mergeBranch,
  MERGE_COMMIT:commit,
  MERGE_COMMIT_SHORT:shortCommit
]

Comments?

Ideally, these properties would be exposed by the Git plugin itself...

Upvotes: 1

Related Questions