最近在写pipeline时踩到一小坑,记录如下。

代码需求比较简单:记录一个测试运行的时间,原型如下。

pipeline {
    agent none
    stages {
        stage('Example') {
            steps {
                script {
                    def startTime = new Date()
                    sleep 1
                    def endTime = new Date()
                    println (endTime.getTime() - startTime.getTime()) / 1000 as Integer
                }
            }
        }
    }
}

一般加入一个新的方法时,Jenkins会提示scriptApproval,然后需要人工批准这个方法。但是有的时候这个提示不会出现,而且pipeline是可以正常运行的,只是偶尔会抛出RejectedAccessException异常。

网上搜索也有人遇到了类似的问题,并且暂时没有解决方法。

https://stackoverflow.com/questions/50819298/jenkins-pipeline-exception-when-using-date-object

而对于具体问题,则可以绕开这个问题,解决方法是用其他方法获取时间。

pipeline {
    agent none
    stages {
        stage('Example') {
            steps {
                script {
                    def startTime = currentBuild.duration
                    sleep 1
                    def endTime = currentBuild.duration
                    println (endTime - startTime) / 1000 as Integer
                }
            }
        }
    }
}

参考: https://opensource.triology.de/jenkins/pipeline-syntax/globals

结论:Jenkins pipeline虽然用的是Groovy的语法,但毕竟被Jenkins封装过,有着种种限制。所以尽量使用pipeline syntax及Jenkins自己的变量,而不是使用Groovy及Java的方法。