groovy jenkins 管道中的当前范围错误

groovy current scope error in jenkins pipeline

我需要你的帮助

我正在编写 groovy 脚本来列出所有 scm 轮询作业。 该脚本在 jenkins 脚本控制台上运行良好,但是当我将它集成到 jenkinsfile 中并 运行 它在管道中时,我收到此错误:

12:51:21  WorkflowScript: 10: The current scope already contains a variable of the name it
12:51:21   @ line 10, column 25.
12:51:21               def logSpec = { it, getTrigger -> String spec = getTrigger(it)?.getSpec();  if (spec ) println ("job_name  " + it.name + "   job_path  "  +  it.getFullName() + " with spec " + spec )}
12:51:21                             ^
12:51:21  
12:51:21  1 error
12:51:21  
12:51:21    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
12:51:21    at org.codehaus.groovy.control.CompilationUnit.applyToSourceUnits(CompilationUnit.java:958)

这是 jenkins 文件:

#!/usr/bin/env groovy
import hudson.triggers.*
import hudson.maven.MavenModuleSet
import org.jenkinsci.plugins.workflow.job.*
pipeline {
  agent any  
  stages {
    stage('list jobs with scm polling') {
      steps {
          def logSpec = { it, getTrigger -> String spec = getTrigger(it)?.getSpec();  if (spec ) println ("job_name  " + it.name + "   job_path  "  +  it.getFullName() + " with spec " + spec )}
 
          println("--- SCM Frequent Polling for Pipeline jobs ---")
          Jenkins.getInstance().getAllItems(WorkflowJob.class).each() { logSpec(it, {it.getSCMTrigger()}) }
           
          println("\n--- SCM Frequent Polling for FreeStyle jobs ---")
          Jenkins.getInstance().getAllItems(FreeStyleProject.class).each() { logSpec(it, {it.getSCMTrigger()}) }
           
          println("\n--- SCM Frequent Polling for Maven jobs ---");
          Jenkins.getInstance().getAllItems(MavenModuleSet.class).each() { logSpec(it, {it.getTrigger(SCMTrigger.class)}) }
           
          println("--- SCM Frequent Polling for Abstract jobs---")
          Jenkins.getInstance().getAllItems(AbstractProject.class).each() { logSpec(it, {it.getTrigger(SCMTrigger.class)}) }
          
          
          println '\nDone.'

 }} }}

有人可以帮忙吗? 谢谢

it 是闭包中提供的隐式变量,当闭包没有显式声明的参数时。因此,当你声明一个参数时,确保它没有被称为 it 以避免与已经定义 it 的父范围发生冲突(在你的例子中是 .each() 的闭包)。

此外,要将脚本部分集成到管道中,请使用 script 步骤或定义一个可以像内置步骤一样调用的函数。

最后,.each() 在管道代码中效果不佳,这是由于 Jenkins 对管道代码应用的 CPS transformations 施加的限制(除非标记为 @NonCPS - 这有其他限制)。所以 .each() 应该替换为 for 循环。

pipeline {
  agent any  
  stages {
    stage('list jobs with scm polling') {
      steps {
          script {
              def logSpec = { job, getTrigger -> String spec = getTrigger(job)?.getSpec();  if (spec ) println ("job_name  " + job.name + "   job_path  "  +  job.getFullName() + " with spec " + spec )}
     
              println("--- SCM Frequent Polling for Pipeline jobs ---")
              for( item in Jenkins.getInstance().getAllItems(WorkflowJob.class) ) { 
                 logSpec( item, {item.getSCMTrigger()}) 
              }
               
              // ... other code ...
               
              
              println '\nDone.'
          }
 }} }}

具有独立功能的变体:

pipeline {
  agent any  
  stages {
    stage('list jobs with scm polling') {
      steps {
         doStuff()
 }} }}

void doStuff() {
    def logSpec = { job, getTrigger -> String spec = getTrigger(job)?.getSpec();  if (spec ) println ("job_name  " + job.name + "   job_path  "  +  job.getFullName() + " with spec " + spec )}

    println("--- SCM Frequent Polling for Pipeline jobs ---")
    for( item in Jenkins.getInstance().getAllItems(WorkflowJob.class) ) { 
       logSpec( item, {item.getSCMTrigger()}) 
    }

    // ... other code ...


    println '\nDone.'
}