jenkins NonCPS and CPS

study NonCPS from documentation

参考文档

查看jenkins文档有时候别人的方案是加@NonCPS, CPS究竟是什么,可以看看如下文档 https://www.jenkins.io/doc/book/pipeline/CPS-method-mismatches/

CPS是什么

  • jenkins的pipeline使用groovy CPS库运行,通过编码形成一个可以运行的程序program.batpipeline里面会用到groovy的东西,这些groovy运行默认是CPS模式

pipeline里面会用到groovy的东西,这些groovy运行默认是CPS模式

  • CPS对于用户是透明的(意味着在pipeline里面的groovy特性是有限的,且可能会有很多意料之外的错误)
  • 由于CPS相当于一层封装,所以CPS可以引用non CPS的,non CPS只能引用non CPS

CPS作用的场景

  • 几乎所有的pipeline块的内容包含库
  • 大部分的step包括代码块的内容

NonCPS

  • 编译好的java代码,比如java平台
  • jenkins自己的插件和代码
  • groovy运行时
  • 带有NonCPS的引注
  • 构造groovy函数

文档的几个例子

例子1

在函数前增加@NonCPS,加了就相当于原生groovy而不是在这层封装里面,注意函数里面不能使用CPS的东西

例子2

这里sortByLength是一个我们写的函数(CPS),调用了一个groovy函数(NONCPS)

1
2
3
4
5
def sortByLength(List<String> list) {//CPS
  list.toSorted { a, b -> Integer.valueOf(a.length()).compareTo(b.length()) } //NonCPS
}
def sorted = sortByLength(['333', '1', '4444', '22'])//CPS
echo(sorted.toString())

最外层我们是CPS 尝试调用一个CPS里面套了一个NONCPS的,所以可能还会尝试用CPS的方法去解释,所以报错了,自己做实验需要jenkins admin approve这个valueof 正确的为

1
2
3
4
5
6
@NonCPS
def sortByLength(List<String> list) {
  list.toSorted { a, b -> Integer.valueOf(a.length()).compareTo(b.length()) }
}
def sorted = sortByLength(['333', '1', '4444', '22'])
echo(sorted.toString())

例子3

构造函数本身是NonCPS的,当我们下面的结构尝试调用是CPS的,说白了是CPS下不识别这个new等信息,所以函数前需要加一个NonCPS, 正确的为

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@NonCPS
class Test {
  def x
  public Test() {
    setX()
  }
  private void setX() {
    this.x = 1;
  }
}
def x = new Test().x
echo "${x}"

总结

  • CPS是jenkins pipeline使用groovy库的一层壳,默认情况能够运行良好,如果我们只用里面的东西
  • 当我们需要自定义一些带有groovy特性的,这层壳可能会工作失灵,需要加NonCPS
  • 注意好CPS的引用关系,Non可以引用Non,但是不可以引用CPS,CPS可以引用non,但是CPS和non不要写在一个函数里面