【发布时间】:2016-10-31 06:55:18
【问题描述】:
任何人都有一个 Jenkins Pipeline 脚本,可以将自上次成功构建以来的所有更改填充到变量中?我正在使用 git 和多分支管道作业。
【问题讨论】:
任何人都有一个 Jenkins Pipeline 脚本,可以将自上次成功构建以来的所有更改填充到变量中?我正在使用 git 和多分支管道作业。
【问题讨论】:
好吧,我设法拼凑了一些东西。我很确定我可以更好地迭代数组,但这是我现在所拥有的:
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;
}
【讨论】:
lastSuccessfulBuild()函数中,为什么if()语句是build.result != SUCCESS?
currentBuild.rawBuild.changeSets 是在调用checkout scm 期间初始化的。如果您在此说明之前拨打电话,您将一无所获。
根据 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 部分非常有用,仅在某些文件更改时运行阶段。不过,我还没有达到那部分,我很想以此创建一个共享库,并使其可以传递一些通配符模式以进行检查。
编辑:Check the docs 顺便说一句,以防您想更深入地研究。您应该能够将所有 object.getSomeProperty() 调用转换为 entry.someProperty。
【讨论】:
这是我用过的:
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()
【讨论】:
【讨论】:
对于任何使用 Accurev 的人来说,这里是对 andsens 答案的改编。无法使用 andsens 答案,因为 Accurev 插件没有实现 getAffectedFiles。扩展 ChangeLogSet.Entry 类的 AccurevTransaction 的文档可以在here.找到。
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
【讨论】:
为了将更改作为字符串列表返回,而不仅仅是打印它们,您可以使用此函数(基于@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()
}
【讨论】: