如何 运行 并行阶段但 select 代理在脚本的 "lower level" 上?

How to run stages in parallel but select agents on "lower level" of script?

我想 运行 在多个平台(AIX、pi、macOS、Windows、Linux)上进行一系列测试。显然那个关卡是可以并行执行的。

    pipeline {
      agent any
      stages {
        stage ("Run Tests") {
          steps {
            parallel (
                     pi:{...}
                     aix: {...}
etc.

但是“pi”的测试不能在任何 pi 上 运行 - 我正在针对软件的多个版本进行测试,并且需要 select 每个测试的特定平台,所以 pi-测试(以及aix)然后继续:

                     catchError(buildResult: "UNSTABLE", stageResult: "FAILURE") {
                       script{
                         def E="" // define some variables per platform
                         def res=""  
                         stage ("pi&&Version1") {
                           agent {
                             label "pi&&Version1"
                           }
                           script {
                             echo "NODE_NAME = ${env.NODE_NAME}"            
                             ...intense code to test V1...
                           }
                         }
                         stage ("pi&&Version2") {
                           agent {
                             label "pi&&Version2"
                           }
                           script {
                             echo "NODE_NAME = ${env.NODE_NAME}"            
                             ...intense code to test V2...
                           }
                         }
                       }
                     }

因此平台上的每个测试都需要一个带有特定标签的代理,这意味着该代理在代码中 select 被“更深入”。而且我还没有看到任何这样做的例子——也许我读错了文档或者没有很好地理解它——但我只是找不到一种方法来构建我的脚本,以允许我这样做。

脚本失败 Invalid step "stage" used - not allowed in this context - The stage step cannot be used in Declarative Pipelines

我们将不胜感激任何有关如何实现此功能的建议。

您似乎混淆了声明式管道语法和脚本式管道语法。
乍一看,您似乎在起诉旧样式 parallel syntax for your pipeline which has since been replaced with a more declarative parallel syntax,它看起来类似于以下内容:

pipeline {
    agent any
    stages {
       stage ("Run Tests") {
           parallel {
              stage('pi') {
                 ...
              }
              stage('aix') {
                 ...
              }
           }
        }
    }
}

无论您使用哪种语法,在并行阶段的代码块中,您都在使用脚本管道语法(由 script 指令暗示),它允许您使用更多高级代码但会阻止您使用声明性关键字,例如 agent 指令。
因此,您需要做的是将阶段中的代码转换为脚本语法,这意味着使用 node 指令进行代理分配。
它看起来像:

script{
   catchError(buildResult: "UNSTABLE", stageResult: "FAILURE") {
       def E="" // define some variables per platform
       def res=""
       stage ("pi&&Version1") {
           node("pi&&Version1") {
               echo "NODE_NAME = ${env.NODE_NAME}"
               ...intense code to test V1...
           }
       }
       stage ("pi&&Version2") {
           node("pi&&Version2"){
               echo "NODE_NAME = ${env.NODE_NAME}"
               ...intense code to test V2...
           }
       }
   }
}

script 指令(这意味着回退到脚本管道语法)只需要一次来包装脚本,并且在子阶段中不再需要。

完整的管道看起来像:

pipeline {
   agent any
   stages {
       stage ("Run Tests") {
           parallel {
               stage('pi') {
                   steps {
                      script {
                          catchError(buildResult: "UNSTABLE", stageResult: "FAILURE") {
                              def E = "" // define some variables per platform
                              def res = ""
                              stage("pi&&Version1") {
                                  node("pi&&Version1") {
                                      echo "NODE_NAME = ${env.NODE_NAME}"
                                      ... intense code to test V1 ...
                                  }
                              }
                              ... other stages ...
                          }
                      }
                  }
                  stage('aix') {
                      ...
                  }
               }
           }
       }
   }
}