我在post always阶段从声明性管道调用此函数:
import groovy.json.JsonSlurper
import com.cloudbees.groovy.cps.NonCPS
@NonCPS
def call(){
String path = "C:\\Users\\tests"
String jsonFileToRead = new File(path).listFiles().findAll { it.name.endsWith(".json") }
.sort { -it.lastModified() }?.head()
JsonSlurper jsonSlurper = new JsonSlurper()
Map data = jsonSlurper.parse(new File(jsonFileToRead))
Map testResults = [:]
int totalTests = data.results.size()
int totalFailures = 0
int totalSuccess = 0
def results = []
//Map test names and results from json file
for (int i = 0; i < data.results.size(); i++) {
testResults.put(i, [data['results'][i]['TestName'], data['results'][i]['result']])
}
//Iterate through the map and send to slack test name and results and then a summary of the total tests, failures and success
for (test in testResults.values()){
String testName = test[0]
String testResult = test[1]
String msg = "Test: " + testName + " Result: " + testResult
if(testResult == "fail")
{
totalFailures++
println msg
try {
slackSend color : "danger", message: "${msg}", channel: '#somechannel'
} catch (Throwable e) {
error "Caught ${e.toString()}"
}
}
else if(testResult == "pass")
{
totalSuccess++
println msg
try {
slackSend color : "good", message: "${msg}", channel: '#somechannel'
} catch (Throwable e) {
error "Caught ${e.toString()}"
}
}
else
{
println "Unknown test result: " + testResult
}
}
def resultsSummary = "Total Tests: " + totalTests + " Total Failures: " + totalFailures + " Total Success: " + totalSuccess
slackSend color : "good", message: "${resultsSummary}", channel: '#somechannel'
println resultsSummary
但我一直收到这个错误,即使我使用的是@NonCPS。我有点困惑,好像我注解掉了调用slackSend功能的3行,一切都很好,我在控制台中输出了正确的消息,管道成功完成,但如果我像这样运行它,即使我只是尝试发送摘要并注解掉其他2个slackSend,我也会收到这个错误:
13:53:23 [Pipeline] echo
13:53:23 Test: triggers_attackMove Result: pass
13:53:23 [Pipeline] slackSend
13:53:23 Slack Send Pipeline step running, values are - baseUrl: <empty>, teamDomain: forgottenempires, channel: #test_harness_logs_phoenix, color: good, botUser: true, tokenCredentialId: Slack_bot_test, notifyCommitters: false, iconEmoji: :goose, username: Jenkins Wizard, timestamp: <empty>
13:53:23 [Pipeline] error
13:53:24 [Pipeline] }
13:53:24 [Pipeline] // script
13:53:24 Error when executing always post condition:
13:53:24 hudson.AbortException: Caught CpsCallableInvocation{methodName=slackSend, call=com.cloudbees.groovy.cps.impl.CpsFunction@149776fc, receiver=null, arguments=[org.jenkinsci.plugins.workflow.cps.DSL$ThreadTaskImpl@25def8]}
13:53:24 at org.jenkinsci.plugins.workflow.steps.ErrorStep$Execution.run(ErrorStep.java:64)
13:53:24 at org.jenkinsci.plugins.workflow.steps.ErrorStep$Execution.run(ErrorStep.java:51)
13:53:24 at org.jenkinsci.plugins.workflow.steps.SynchronousStepExecution.start(SynchronousStepExecution.java:37)
13:53:24 at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:322)
13:53:24 at org.jenkinsci.plugins.workflow.cps.DSL.invokeMethod(DSL.java:196)
enter code here
....
我尝试用@NonCPS装饰器将slackSend功能转移到另一个函数,并从该函数内部调用它,但我一直得到相同的错误,老实说,我完全弄不懂这一点
1条答案
按热度按时间q35jwt9p1#
slackSend
是一个管道步骤,因此不能从@NonCPS
上下文调用。只有少数例外(如echo
)可以从@NonCPS
上下文调用。有关详细信息,请参阅使用@NonCPS中的管道步骤。在这种情况下,我的方法是从调用步骤的函数中删除
@NonCPS
,只将实际需要@NonCPS
的代码移到单独的@NonCPS
函数中,在您的情况下,这可能只是使用File
和JsonSlurper
类的代码。此外,我们需要确保
@NonCPS
函数返回的任何数据都是可序列化的。JsonSlurper
返回的LazyMap
不是。正如OP所评论的,最简单的解决方案是使用JsonSlurperClassic
,它返回一个常规的、可序列化的Map
(或者在根是数组的情况下返回List
)。