动态生成Jenkins中的并行阶段。

huangapple go评论56阅读模式
英文:

Dynamic generation of parallel stages in jenkins

问题

这是你要翻译的部分:

我正在尝试在Jenkins中生成动态并行阶段。我已经达到了使其工作的阶段,但它们不是动态的:

pipeline {
  agent {
    label "node-18"
  }
  parameters {
    ...
  }
  environment {
    ...
  }
  stages {
    stage('whatever previos stage') {
      script {
        .... 这里有一些先前的内容(不重要)
      }
    }
  }

  stage('Run test in parallel') {
    parallel {
      stage('test 0') {
        agent {
          label "node-18"
        }
        steps {
          script {
            runTest('0')
          }
        }
        post {
          always {
            publishrepo('0') //此方法使用HTML发布器
          }
        }
      }
      stage('test 1') {
        agent {
          label "node-18"
        }
        steps {
          script {
            runTest('1')
          }
        }
        post {
          always {
            publishrepo('1') //此方法使用HTML发布器
          }
        }
      }
    }
  }
}

请注意,以下是代码部分,我将跳过翻译,只提供您请求的翻译内容。如果您需要其他翻译,请告诉我。

def maxParallelSteps = [:]
pipeline {
  agent {
    label "node-18"
  }
  parameters {
    ...
  }
  environment {
    ...
  }
  stages {
    stage('whatever previos stage') {
      script {
        .... 这里有一些先前的内容(不重要)
      }
    }
  }

  stage('Check number of stages and create them') {
    steps {
      script {
        def max = checkMaxParallel()
        for (int i = 0; i < max; i++) {
          maxParallelSteps.put("test ${i}", generateStage(i))
        }
      }
    }
  }

  stage('Run test in parallel') {
    steps {
      script {
        parallel maxParallelSteps
      }
    }
  }
}

def generateStage(slot) {
  return {
    stage('test ' + slot) {
      agent {
        label 'node-18'
      }
      steps {
        script {
          runTest('1')
        }
      }
      post {
        always {
          publishrepo('1') //此方法使用HTML发布器
        }
      }
    }
  }
}

如果您需要更多帮助,请告诉我。

英文:

I am trying to generate dynamic parallel stages in jenkins. I have reach a point in which it work but they are not dynamic:

pipeline{
  agent {
    label &quot;node-18&quot;
  }
  parameters{
    ...
  }
  environment{
    ...
  }
  stages{
    stage(&#39;whatever previos stage&#39;){
      script{
        .... whatever previos things here (it doesnt matter)
      }
    }
  }

  stage(&#39;Run test in parallel&#39;){
    parallel{
      stage(&#39;test 0&#39;){
        agent{
          label &quot;node-18&quot;
        }
        steps{
          script{
            runTest(&#39;0&#39;)
          }
        }
        post{
          always{
            publishrepo(&#39;0&#39;) //this method use the html publisher
          }
        }
      }
      stage(&#39;test 1&#39;){
        agent{
          label &quot;node-18&quot;
        }
        steps{
          script{
            runTest(&#39;1&#39;)
          }
        }
        post{
          always{
            publishrepo(&#39;1&#39;) //this method use the html publisher
          }
        }
      }
    }
  }
}

This works perfect and also publish the HTML reports in the jenkins page so, so far so good, the problem is that there are not always two stages, there is a method that calculate the max numbers of paralelization and according to this numbers I have to create 0 to N stages.

I tried this checking some post on the internet and so on:


def maxParallelSteps = [:]
pipeline{
  agent {
    label &quot;node-18&quot;
  }
  parameters{
    ...
  }
  environment{
    ...
  }
  stages{
    stage(&#39;whatever previos stage&#39;){
      script{
        .... whatever previos things here (it doesnt matter)
      }
    }
  }

  stage(&#39;Check number of stages and create them&#39;){
    steps{
      script {
        def max = checkMaxParallel()
        for(int i = 0 ; i&lt; max ; i++){
           maxParallelSteps.put(&quot;test ${i}&quot;, generateStage(i)
        }
      }
    }
  }

  stage(&#39;Run test in parallel&#39;){
    steps{
      script{
        parallel maxParallelSteps 
      }
    }
  }
}

def generateStage(slot){
  return {
    stage(&#39;test &#39; + slot){
      agent{
        label &#39;node-18&#39;
      }
      steps{
        script{
          runTest(&#39;1&#39;)
        }
      }
      post{
        always{
          publishrepo(&#39;1&#39;) //this method use the html publisher
        }
      }
    } 
  }
}

In this case I am getting the following error:

动态生成Jenkins中的并行阶段。

take into account that I didnt copy and paste but the idea is that test 0 and so on are P0_test and so on.

I also tried to move the for loop just in one stage and a lot of crazy things. I dont know what else to test and where to find a proper example of doc about how to dynamically do that.
The point is that the first code I showed you works perfectly the only point will be to be able to according to just a number create X number of stages.

I hope I have explain properly my issue and thanks in advance to all!

答案1

得分: 1

在声明式流水线中创建真正的动态并行步骤确实不可能,所以你使用了唯一可用的方法,即使用parallel关键字,该关键字取自脚本化流水线语法(因此需要script上下文)。
这意味着传递给并行步骤的执行代码也应该以脚本化语法编写,对于你的情况,generateStage函数正在生成声明式语法代码,因此会导致错误。

要解决这个问题,你可以将函数修改为脚本化语法:

def generateStage(slot) {
  return {
    stage("test ${slot}") {
       node('node-18') {
          try {
             runTest('1')
          }
          finally {
              publishrepo('1') //此方法使用HTML发布器
          }
      }
    }
  }
}

顺便说一下,你不必将其拆分为一个函数,可以在阶段内运行它:

pipeline{
  agent {
    label "node-18"
  }
  parameters{
    ...
  }
  environment{
    ...
  }
  stages{
    stage('whatever previos stage'){
      script{
        .... 在这里执行任何先前的操作(没有关系)
      }
    }
  }

  stage('Create and run stages'){
    steps{
      script {
        def parallelSteps = (1..checkMaxParallel()).collectEntries {
          ["test ${i}" : {
              stage("test ${slot}") {
                  node('node-18') {
                     try {
                        runTest('1')
                     }
                     finally {
                        publishrepo('1') //此方法使用HTML发布器
                     }
                 }
              }
           }]
        parallel parallelSteps 
      }
    }
  }
}
英文:

Creating real dynamic parallel steps in declarative pipeline is indeed not possible, so you used the only available way which is to use the parallel keyword which is taken from the scripted pipeline syntax (thus requires the script context).
This means that the execution code that is passed to the parallel step should be also written in scripted syntax, in your case the generateStage function is generating decelerative syntax code and therefore the errors.

To solve it you can modify your function to scripted syntax:

def generateStage(slot) {
  return {
    stage(&quot;test ${slot}&quot;) {
       node(&#39;node-18&#39;) {
          try {
             runTest(&#39;1&#39;)
          }
          finally {
              publishrepo(&#39;1&#39;) //this method use the html publisher
          }
      }
    }
  }
}

Btw you don't have to separate into a function and can run it inside the stage:

pipeline{
  agent {
    label &quot;node-18&quot;
  }
  parameters{
    ...
  }
  environment{
    ...
  }
  stages{
    stage(&#39;whatever previos stage&#39;){
      script{
        .... whatever previos things here (it doesnt matter)
      }
    }
  }

  stage(&#39;Create and run stages&#39;){
    steps{
      script {
        def parallelSteps = (1..checkMaxParallel()).collectEntries {
          [&quot;test ${i}&quot; : {
              stage(&quot;test ${slot}&quot;) {
                  node(&#39;node-18&#39;) {
                     try {
                        runTest(&#39;1&#39;)
                     }
                     finally {
                        publishrepo(&#39;1&#39;) //this method use the html publisher
                     }
                 }
              }
           }]
        parallel parallelSteps 
      }
    }
  }
}

huangapple
  • 本文由 发表于 2023年6月1日 00:15:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375493.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定