自上次成功构建jenkins管道以来如何获得更改?

时间:2016-06-28 19:32:43

标签: jenkins jenkins-pipeline

任何人都有一个Jenkins管道脚本可以填充自上次成功构建变量以来的所有更改?我正在使用git和multibranch管道工作。

6 个答案:

答案 0 :(得分:15)

好吧,我设法凑齐了一些东西。我非常确定你可以更好地迭代阵列,但这是我现在所拥有的:

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;
  }

答案 1 :(得分:8)

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.

答案 2 :(得分:1)

这是我用过的:

def listFilesForBuild(build) {
  def files = []
  currentBuild.changeSets.each {
    it.items.each {
      it.affectedFiles.each {
        files << it.path
      }
    }
  }
  files
}

def filesSinceLastPass() {
  def files = []
  def build = currentBuild
  while(build.result != 'SUCCESS') {
    files += listFilesForBuild(build)
    build = build.getPreviousBuild()
  }
  return files.unique()
}

def files = filesSinceLastPass()

答案 3 :(得分:0)

答案 4 :(得分:0)

对于使用Accurev的任何人,这里都是andsens答案的改编。无法使用andsens答案,因为Accurev插件未实现getAffectedFiles。可以在here.

中找到扩展ChangeLogSet.Entry类的AccurevTransaction文档。
import hudson.plugins.accurev.*

def changes = "Changes: \n"
build = currentBuild
// Go through the previous builds and get changes until the
// last successful build is found.
while (build != null && build.result != 'SUCCESS') {
    changes += "Build ${build.id}:\n"

    for (changeLog in build.changeSets) {
        for (AccurevTransaction entry in changeLog.items) {
            changes += "\n    Issue: " + entry.getIssueNum()
            changes += "\n    Change Type: " + entry.getAction()
            changes += "\n    Change Message: " + entry.getMsg()
            changes += "\n    Author: " + entry.getAuthor()
            changes += "\n    Date: " + entry.getDate()
            changes += "\n    Files: "
            for (path in entry.getAffectedPaths()) {
                changes += "\n        " + path;
            }
            changes += "\n"
        }
    }
    build = build.previousBuild
}
echo changes
writeFile file: "changeLog.txt", text: changes

答案 5 :(得分:0)

为了将更改作为字符串列表返回,而不仅仅是打印它们,您可以使用此功能(基于@andsens答案):

def getChangesSinceLastSuccessfulBuild() {
    def changes = []
    def build = currentBuild

    while (build != null && build.result != 'SUCCESS') {
        changes += (build.changeSets.collect { changeSet ->
            (changeSet.items.collect { item ->
                (item.affectedFiles.collect { affectedFile ->
                    affectedFile.path
                }).flatten()
            }).flatten()
        }).flatten()

        build = build.previousBuild
    }

    return changes.unique()
}