pipeline job为了支持能够在jenkins重启后恢复继续运行,jenkins在后台定期地将job的运行状态保存到硬盘。保存的动作一般在每个step结束后,或者在一些step的中间,例如sh step的中间。
jenkins保存的job的状态,包括整个控制流程,例如局部变量,循环所在的位置,等等。正因为如此,groovy里的任何变量必须是number,string或可序列化的类型,其他的例如网络连接等是不能够序列化的。
然而最安全的方法是将不可序列化的语句隔离到函数中,且在函数的前面增加属性@NonCPS。通过这种方法pipeline将识别此函数为native且不保存对应的局部变量。另外使用了@NoCPS的函数中不能够调用其他的pipeline steps
因此把获取git变更记录语句封装成一个函数放在pipeline语句外面:
pipeline
{
agent any
stages
{
stage('DownloadTestCode')
{
steps
{
echo '############ test ############'
}
}
}
post
{
always
{
script
{
changes = getChanges()
wrap([$class: 'BuildUser'])
{
sh "python /home/Jenkins/DdRobot/DdRobot.py $env.JOB_NAME $BUILD_USER $env.BUILD_URL $currentBuild.currentResult $currentBuild.timeInMillis $changes"
}
}
}
}
}
@NonCPS
def getChanges()
{
MAX_MSG_LEN = 100
def changeString = ""
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]
change_msg = entry.msg.take(MAX_MSG_LEN)
changeString += " ${change_msg} \n"
}
}
if (!changeString)
{
changeString = " No changes "
}
return changeString
}