Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the changes since the last successful build in jenkins pipeline?

Anyone have a Jenkins Pipeline script that can stuff all the changes since the previous successful build in a variable? I'm using git and a multibranch pipeline job.

like image 559
CaptRespect Avatar asked Jun 28 '16 19:06

CaptRespect


People also ask

What is used to track the changes between builds in Jenkins?

The simplest way to know what has changed on your Jenkins builds! Last Changes is a Jenkin plugin that shows rich VCS diffs between builds.

Which Jenkins command to get the list of changed files?

You can use the changeSets property of the currentBuild global variable to get information relating to the detected changes of the current build.


2 Answers

Well I managed to cobble something together. I'm pretty sure I you can iterate the arrays better but here's what I've got for now:

node('Android') {
  passedBuilds = []

  lastSuccessfulBuild(passedBuilds, currentBuild);

  def changeLog = getChangeLog(passedBuilds)
  echo "changeLog ${changeLog}"
}

def lastSuccessfulBuild(passedBuilds, build) {
  if ((build != null) && (build.result != 'SUCCESS')) {
      passedBuilds.add(build)
      lastSuccessfulBuild(passedBuilds, build.getPreviousBuild())
   }
}

@NonCPS
def getChangeLog(passedBuilds) {
    def log = ""
    for (int x = 0; x < passedBuilds.size(); x++) {
        def currentBuild = passedBuilds[x];
        def changeLogSets = currentBuild.rawBuild.changeSets
        for (int i = 0; i < changeLogSets.size(); i++) {
            def entries = changeLogSets[i].items
            for (int j = 0; j < entries.length; j++) {
                def entry = entries[j]
                log += "* ${entry.msg} by ${entry.author} \n"
            }
        }
    }
    return log;
  }
like image 53
CaptRespect Avatar answered Sep 26 '22 20:09

CaptRespect


Based on the answer from CaptRespect i came up with the following script for use in the declarative pipeline:

def changes = "Changes:\n"
build = currentBuild
while(build != null && build.result != 'SUCCESS') {
    changes += "In ${build.id}:\n"
    for (changeLog in build.changeSets) {
        for(entry in changeLog.items) {
            for(file in entry.affectedFiles) {
                changes += "* ${file.path}\n"
            }
        }
    }
    build = build.previousBuild
}
echo changes

This is quite useful in stage->when->expression parts to run a stage only when certain files were changed. I haven't gotten to that part yet though, I'd love to create a shared library from this and make it possible to pass it some globbing patterns to check for.

EDIT: Check the docs btw, in case you want to delve a little deeper. You should be able to convert all the object.getSomeProperty() calls into just entry.someProperty.

like image 22
andsens Avatar answered Sep 26 '22 20:09

andsens