Jenkinsfile - get all changes between builds

丶灬走出姿态 提交于 2019-12-20 12:36:20

问题


With reference to this question is there a way to get the equivalent information from when using the mult-branch pipeline? Specifically - the list of commits since the last successful build.

Currently we use the following

def scmAction = build?.actions.find { action -> 
    action instanceof jenkins.scm.api.SCMRevisionAction
}
return scmAction?.revision?.hash

but this only returns the last commit that triggered the build if multiple commits were pushed. I accept that the very first build of a new branch might be ambiguious but getting a list of commits that triggered the build when possible would be very useful.


回答1:


I have found a solution that seems to work for us. It revolves around getting the currentBuild commit hash and then the lastSuccessfulBuild commit hash. First we wrote a utility method for getting a commit hash of a given Jenkins build object:

def commitHashForBuild(build) {
  def scmAction = build?.actions.find { action -> action instanceof jenkins.scm.api.SCMRevisionAction }
  return scmAction?.revision?.hash
}

then use that to get the lastSuccessfulBuild's hash:

def getLastSuccessfulCommit() {
  def lastSuccessfulHash = null
  def lastSuccessfulBuild = currentBuild.rawBuild.getPreviousSuccessfulBuild()
  if ( lastSuccessfulBuild ) {
    lastSuccessfulHash = commitHashForBuild(lastSuccessfulBuild)
  }
  return lastSuccessfulHash
}

finally combine those two in a sh function to get the list of commits

  def lastSuccessfulCommit = getLastSuccessfulCommit()
  def currentCommit = commitHashForBuild(currentBuild.rawBuild)
  if (lastSuccessfulCommit) {
    commits = sh(
      script: "git rev-list $currentCommit \"^$lastSuccessfulCommit\"",
      returnStdout: true
    ).split('\n')
    println "Commits are: $commits"
  }

you can then use the commits array to query various things in Git as your build requires. E.g. you can use this data to get a list of all changed files since the last successful build.

I have put this into a complete example Jenkinsfile Gist to show how it fits together in context.

A possible improvement would be to use a Java/Groovy native Git library instead of shelling out to a sh step.




回答2:


I think Jenkins Last changes plugin can provide the information you need, take a look here: https://wiki.jenkins-ci.org/display/JENKINS/Last+Changes+Plugin, following is an example:

node {
      stage("checkout") {
        git url: 'https://github.com/jenkinsci/last-changes-plugin.git'
      }

      stage("last-changes") {
        def publisher = LastChanges.getLastChangesPublisher "LAST_SUCCESSFUL_BUILD", "SIDE", "LINE", true, true, "", "", "", "", ""
              publisher.publishLastChanges()
              def changes = publisher.getLastChanges()
              println(changes.getEscapedDiff())
              for (commit in changes.getCommits()) {
                  println(commit)
                  def commitInfo = commit.getCommitInfo()
                  println(commitInfo)
                  println(commitInfo.getCommitMessage())
                  println(commit.getChanges())
              }
      }

}

Note that by default (without the need for groovy scripting) the plugin makes the list of commits available for browsing on the jenkins UI, see here.

I hope it helps.



来源:https://stackoverflow.com/questions/43334453/jenkinsfile-get-all-changes-between-builds

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!