groovy.lang.MissingMethodException:没有方法签名:sh()适用于在Groovy中测试AWS CLI命令时的参数类型

Chr*_*s F 5 groovy jenkins-pipeline

$ groovy --version
Groovy Version: 2.4.15 JVM: 1.8.0_171 Vendor: Oracle Corporation OS: Mac OS X
Run Code Online (Sandbox Code Playgroud)

我想在Groovy中执行一些AWS CLI命令,当然最终在Jenkins文件中运行Jenkins.

但是对于原型设计,我想在我的Mac上编码并将其作为一个普通的Groovy脚本执行.所以我有这个,例如.

#!/usr/bin/env groovy

def getEBSVolumes(awsRegion) {
  def regions
  if (awsRegion == "all") {
    regions = sh(returnStdout: true, script: """#!/usr/bin/env bash
                   aws ec2 describe-regions --output text|awk '{print \$3}'
                 """
                )
  }
  else {
    regions = awsRegion
  }
  echo "Regions: regions"
}

getEBSVolumes("all")
Run Code Online (Sandbox Code Playgroud)

当我执行它时,我得到了

$ ./x.groovy 
Caught: groovy.lang.MissingMethodException: No signature of method: x.sh() is applicable for argument types: (java.util.LinkedHashMap) values: [[returnStdout:true, script:#!/usr/bin/env bash
                   aws ec2 describe-regions --output text|awk '{print $3}'
                 ]]
Possible solutions: use([Ljava.lang.Object;), is(java.lang.Object), run(), run(), any(), each(groovy.lang.Closure)
groovy.lang.MissingMethodException: No signature of method: x.sh() is applicable for argument types: (java.util.LinkedHashMap) values: [[returnStdout:true, script:#!/usr/bin/env bash
                   aws ec2 describe-regions --output text|awk '{print $3}'
                 ]]
Possible solutions: use([Ljava.lang.Object;), is(java.lang.Object), run(), run(), any(), each(groovy.lang.Closure)
    at x.getEBSVolumes(x.groovy:9)
    at x$getEBSVolumes.callCurrent(Unknown Source)
    at x.run(x.groovy:20)
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下神秘的错误信息吗?谢谢!

注意代码在Jenkinsfile中执行时有效,因此我特别询问了CLI Groovy.

Szy*_*iak 9

您无法仅使用Groovy在本地运行此脚本,因为它会因sh脚本中缺少方法而失败.此sh方法是Jenkins Pipeline DSL库提供的步骤 - https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#code-sh-code-shell-script

我建议您运行本地Jenkins - 最简单的方法是使用现有的Docker镜像.我使用例如以下docker-compose.yml文件:

jenkins:
  image: jenkins:2.60.3-alpine
  container_name: jenkins
  ports:
    - 8080:8080
  volumes:
    - ./home:/var/jenkins_home
Run Code Online (Sandbox Code Playgroud)

每当我想运行我的本地Jenkins时,我就会去存储此文件的目录,例如

cd ~/workspace/jenkins
Run Code Online (Sandbox Code Playgroud)

我只是打电话

docker-compose up -d
Run Code Online (Sandbox Code Playgroud)

我可以通过http:// localhost访问Jenkins :8080在这个本地实例中,我能够在Groovy Sandbox中测试管道脚本,或者通过设置脚本管道.

替代方案:JenkinsPipelineUnit测试库

如果要对管道脚本进行单元测试,可以使用JenkinsPipelineUnit库,它允许您对管道流进行单元测试.但是在这种情况下,您必须注册自己的sh方法,因为BasePipelineTest该类使用NOOP进行模拟:

helper.registerAllowedMethod("sh", [Map.class], null)
Run Code Online (Sandbox Code Playgroud)

这意味着每次与sh步骤的交互都会被计算,但它不会触发使用script: ''property 定义的脚本.

我想说,设置你自己的本地Jenkins沙箱,你可以在其中使用Jenkinsfile脚本是最简单的方法.