如何在Jenkins Pipeline中正确使用CPS notation解决readJSON调用报错
问题根源
@NonCPS注解的作用是标记完全不需要CPS转换的纯Groovy逻辑方法,这类方法内部禁止调用任何Jenkins Pipeline内置步骤。你为sendEmailNewErrors添加了@NonCPS注解,但该方法内部调用了readJSON、mail两个Jenkins内置步骤,两者逻辑冲突,因此触发方法匹配错误。
修复方案
- 移除
sendEmailNewErrors方法的@NonCPS注解,该方法包含Jenkins内置步骤,不允许使用该注解 - 保留
findItemInChangelog的@NonCPS注解,该方法仅使用纯Groovy API处理XML,符合@NonCPS使用规则 - 将
sendEmailNewErrors内的.each循环替换为普通for循环,不需要注解即可兼容CPS转换 - 建议后续将硬编码的构建号、文件路径替换为Jenkins内置环境变量(如
BUILD_NUMBER),提升流水线通用性
修正后代码
import groovy.json.JsonSlurper // 移除该方法的@NonCPS注解 def sendEmailNewErrors(){ def submitter = findItemInChangelog("changeUser") def Emails = readJSON file: "D:/Emails.json" def email = "test@email.com" def msgList = [] def url = "http://localhost:8080/job/job1/1374/cppcheck/new/api/json" def json = new JsonSlurper().parseText(new URL(url).text) for (key in Emails.keySet()) { if (submitter == key){ email = Emails.get(key) } } // 替换each为普通for循环 for (issue in json.issues) { def msg = "New ERROR found in static analysis, TYPE OF ERROR ${issue.type}"+ ", SEVERITY: ${issue.severity}, ERROR MESSAGE: ${issue.message}"+ ", FILE ${issue.fileName} AT LINE: ${issue.lineStart}" msgList.add(msg) } // 替换each为普通for循环 for (msg in msgList) { println msg mail to: email, subject: "New errors found in job1 build pipeline", body: "$msg" } } @NonCPS def findItemInChangelog(item){ def result = "Build ran manually" def found = false def file = new XmlSlurper().parse("C:/Users/User/.jenkins/jobs/job1/builds/1374/changelog5966810591791724161.xml") file.entry.each { entry -> entry.changenumber.each { changenumber -> changenumber.children().each { tag -> if(tag.name() == item && found != true){ result = tag.text() found = true } } } } return result.toString() } pipeline { agent any stages { stage("test"){ steps{ script{ sendEmailNewErrors() } } } } }
内容的提问来源于stack exchange,提问作者Jesus Fernandez
相关产品推荐
相关产品推荐

