jenkins管道中的changeSet错误(错误:java.io.NotSerializedException:hudson.plugins.git.GitChangeSetList)

问题描述 投票:0回答:4

我有这个错误:

java.io.NotSerializableException: hudson.plugins.git.GitChangeSetList

ChangeSet!=null
但奇怪的是更新这个插件时发生错误:Pipeline Shared Groovy Libraries,在这个工作正常之前,我使用jenkins v 2.21和pipeline 2.4,我的代码是下一个:

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]
        echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
        def files = new ArrayList(entry.affectedFiles)
        for (int k = 0; k < files.size(); k++) {
            def file = files[k]
            echo "  ${file.editType.name} ${file.path}"
        }
    }
}
changeLogSets= null
git jenkins jenkins-pipeline changeset
4个回答
18
投票

Jenkins 作业可以在执行过程中保存,这需要将它们序列化。 rawBuild 的内容无法序列化,因此如果您访问它,则需要在以

@NonCPS
开头的函数中执行此操作。例如:

showChangeLogs()

@NonCPS
def showChangeLogs() {
  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]
          echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
          def files = new ArrayList(entry.affectedFiles)
          for (int k = 0; k < files.size(); k++) {
              def file = files[k]
              echo "  ${file.editType.name} ${file.path}"
          }
      }
  }
}

1
投票

不完全相同的代码,但是如果在使用局部变量之前不声明它们,也会导致同样的问题。 https://blog.csdn.net/liurizhou/article/details/88236397

因此,除了添加“@NonCPS”之外,您还需要在所有局部变量之前添加“def”


0
投票

我想提供另一个答案,借鉴 BMitch 的答案。

rawBuild
方法存在安全问题,并在 Jenkinsfile 中被阻止。在较新的版本中,
currentBuild
对象直接公开
changeSets
,因此您可以使用这样的脚本

@NonCPS
def showChangeLogs() {
    def changeLogSets = currentBuild.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]
            echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
            def files = new ArrayList(entry.affectedFiles)
            for (int k = 0; k < files.size(); k++) {
                def file = files[k]
                echo "${file.editType.name} ${file.path}"
            }
        }
    }
}

0
投票

与 gmode 提供的方法类似,但使用 .each 循环:

def showChangeLogs() {
    currentBuild.changeSets.each { changeSet ->
        changeSet.items.each { entry ->
            echo "${entry.commitId} by ${entry.author} on ${new Date(entry.timestamp)}: ${entry.msg}"
            entry.affectedFiles.each { file ->
                echo "  ${file.editType.name} ${file.path}"
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.