如何获取自上次成功构建jenkins pipeline以来的更改?

zi8p0yeb  于 2023-02-07  发布在  Jenkins
关注(0)|答案(6)|浏览(239)

有人有Jenkins管道脚本可以填充自上次成功构建以来的所有更改吗?我使用的是git和多分支管道作业。

pqwbnv8z

pqwbnv8z1#

我设法拼凑了一些东西,我很肯定你可以更好地迭代数组,但现在我得到的是:

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

eaf3rand2#

根据CaptRespect的回答,我编写了以下脚本,用于声明性管道:

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

这在stage->when->expression部件中非常有用,只有当某些文件被更改时才运行stage。虽然我还没有到达那个部件,但我很想从中创建一个共享库,并使它能够传递一些全局匹配模式来检查。
编辑:Check the docs顺便说一句,如果你想深入研究一下的话。你应该能够将所有的object.getSomeProperty()调用转换成entry.someProperty

4dc9hkyq

4dc9hkyq3#

这是我用过的

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()
oipij1gg

oipij1gg5#

对于任何使用Accurev的人,这里是andsens答案的改编版。andsens答案不能使用,因为Accurev插件不实现getAffectedFiles。可以在这里找到扩展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
0ve6wy6x

0ve6wy6x6#

为了以字符串列表的形式返回更改,而不仅仅是打印它们,您可以使用以下函数(基于@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()
}

相关问题