Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-53162

Blueocean support for visualizing stages in parallel block in scripted pipeline

      As suggested in JENKINS-38442 I created this new feature request which I would like to use to explicitely target the support for visualising one level of stages in parallel blocks, like:

      parallel (
        "first": {
          stage("JUnit") {
          }
          stage("Firefox") { 
          }
        },
        "second" : {
          stage("D3Unit") {
          }
          stage("Edge") {
          }
        },
        "third" : {
          stage("Safari") {
          }
        }
      )
      

      As an example on how a possible visualization could look like please check the attached png.

          [JENKINS-53162] Blueocean support for visualizing stages in parallel block in scripted pipeline

          Joerg Schwaerzler created issue -

          Very interested in this as we only used scripted pipelines and was disappointed that the other issue only addressed declarative.

          Jared Kauppila added a comment - Very interested in this as we only used scripted pipelines and was disappointed that the other issue only addressed declarative.
          Devin Nusbaum made changes -
          Link New: This issue relates to JENKINS-38442 [ JENKINS-38442 ]

          Hi,

          I would definitely love to see this on scripted pipelines as well

          Vladislav Zedano added a comment - Hi, I would definitely love to see this on scripted pipelines as well
          Taras Postument made changes -
          Link New: This issue is duplicated by JENKINS-53751 [ JENKINS-53751 ]

          leromarinvit added a comment -

          I dug into this a little and found that BlueOcean explicitly disables rendering sequential stages in parallel branches unless the build is a declarative pipeline run. So a quick and dirty workaround is to fake a declarative pipeline in a scripted one. Then arrange your stages similarly to what declarative would do (namely create a wrapper stage with the same name as each parallel branch), and it will be rendered nicely.

          Needless to say, this is an ugly hack and might break in unforeseen ways. Though it seems to work in my tests, and the only side effect I saw was that a "Restart from Stage" option appeared in the build's menu, with an empty dropdown list. This seems benign enough, but I don't know what else it could cause, so be warned.

          So how do you fake a declarative run? BlueOcean checks for an action of type ExecutionModelAction, so that's what we have to add:

          import org.jenkinsci.plugins.pipeline.modeldefinition.actions.ExecutionModelAction
          import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages
          
          if (!currentBuild.rawBuild.getAction(ExecutionModelAction))
              currentBuild.rawBuild.addAction(new ExecutionModelAction(new ModelASTStages(null)))
          

          This won't work in a sandboxed script, but it does in a global shared library. So it's probably not worth the effort (and potential risk) to make jobs with hand-written parallel-sequential stages render properly, but it might just be a workaround if you generate jobs with such a structure from library functions.

          leromarinvit added a comment - I dug into this a little and found that BlueOcean explicitly disables rendering sequential stages in parallel branches unless the build is a declarative pipeline run. So a quick and dirty workaround is to fake a declarative pipeline in a scripted one. Then arrange your stages similarly to what declarative would do (namely create a wrapper stage with the same name as each parallel branch), and it will be rendered nicely. Needless to say, this is an ugly hack and might break in unforeseen ways. Though it seems to work in my tests, and the only side effect I saw was that a "Restart from Stage" option appeared in the build's menu, with an empty dropdown list. This seems benign enough, but I don't know what else it could cause, so be warned. So how do you fake a declarative run? BlueOcean checks for an action of type ExecutionModelAction , so that's what we have to add: import org.jenkinsci.plugins.pipeline.modeldefinition.actions.ExecutionModelAction import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages if (!currentBuild.rawBuild.getAction(ExecutionModelAction)) currentBuild.rawBuild.addAction( new ExecutionModelAction( new ModelASTStages( null ))) This won't work in a sandboxed script, but it does in a global shared library. So it's probably not worth the effort (and potential risk) to make jobs with hand-written parallel-sequential stages render properly, but it might just be a workaround if you generate jobs with such a structure from library functions.

          leromarinvit: Doesn't work for me using BlueOcean 1.8.2. That is: The job's green but BlueOcean still won't show me any stages which have been defined inside a parallel branch. Which version of BlueOcean did you use?

          Joerg Schwaerzler added a comment - leromarinvit : Doesn't work for me using BlueOcean 1.8.2. That is: The job's green but BlueOcean still won't show me any stages which have been defined inside a parallel branch. Which version of BlueOcean did you use?
          Jake Hilborn made changes -
          Attachment New: Screen Shot 2019-05-30 at 2.49.21 PM.png [ 47533 ]

          Jake Hilborn added a comment -

          leromarinvit Wow that actually works for scripted pipelines. The key is to have a stage inside the parallel block that has the same name as the parallel stage. Here's a working example.

          parallel (
            "one": {
              stage("one") {
                stage("one-child1") {
                  println "one-child1"
                }
                stage("one-child2") {
                  println "one-child2"
                }
              }
            },
            "two": {
              stage("two") {
                stage("two-child1") {
                  println "two-child1"
                }
                stage("two-child2") {
                  println "two-child2"
                }
              }
            },
            "three": {
              stage("three") {
                stage("three-child1") {
                  println "three-child1"
                }
                stage("three-child2") {
                  println "three-child2"
                }
              }
            }
          ) 

          Jake Hilborn added a comment - leromarinvit Wow that actually works for scripted pipelines. The key is to have a stage inside the parallel block that has the same name as the parallel stage. Here's a working example. parallel ( "one" : { stage( "one" ) { stage( "one-child1" ) { println "one-child1" } stage( "one-child2" ) { println "one-child2" } } }, "two" : { stage( "two" ) { stage( "two-child1" ) { println "two-child1" } stage( "two-child2" ) { println "two-child2" } } }, "three" : { stage( "three" ) { stage( "three-child1" ) { println "three-child1" } stage( "three-child2" ) { println "three-child2" } } } )

          Damien Merlin added a comment -

          Hi Jake,

          Can you please let us know which version of Jenkins and Bitbucket Plugin you are using ?

          I tested your pipeline code using Jenkins ver. 2.176.1 and Blue Ocean version 1.17.0 and the rendering is showing only one stage per parallel.

          Thanks

           

          Damien Merlin added a comment - Hi Jake, Can you please let us know which version of Jenkins and Bitbucket Plugin you are using ? I tested your pipeline code using Jenkins ver. 2.176.1 and Blue Ocean version 1.17.0 and the rendering is showing only one stage per parallel. Thanks  

            olamy Olivier Lamy
            macdrega Joerg Schwaerzler
            Votes:
            72 Vote for this issue
            Watchers:
            74 Start watching this issue

              Created:
              Updated:
              Resolved: