With 1.2 a grat new feature was created, library "pipeline templates", which prevents very similar pipelines to be duplicated in many places (a maintenance nightmare, and makes it difficult to enforce organization-wide processes).

      However it still has some limitations (see https://issues.jenkins-ci.org/browse/JENKINS-53658)   One of these, however, is really damaging.

      Currently one cannot use the library pipeline from a declarative pipeline (jenkinsfile for instance) and this error happens:
      java.lang.IllegalStateException: Only one pipeline { ... } block can be executed in a single run.
      This forces the use of scripted pipelines to use them, which undermines the efforts to use preferably declarative ones.

      It would be alright to put some limits on this.  We don't need arbitrary levels of nesting.  But at least being able to call a library declarative pipeline from the main declarative pipeline  should be possible.  Not sure if this simplifies anything in terms of implementation, but could limit use of resources (memory etc.).

          [JENKINS-53670] Nested declarative pipelines

          Note:  Before someone says this, it is still useful to use the library pipeline templates from very small scripted ones that basically just provide the parameters for the specific library pipeline use.  I am doing this.  But to get a process pipeline that uses several standardized subprocesses in the form of library pipelines one should not be restricted to make the Jenkinsfile one a scripted one. 

          Fernando Nasser added a comment - Note:  Before someone says this, it is still useful to use the library pipeline templates from very small scripted ones that basically just provide the parameters for the specific library pipeline use.  I am doing this.  But to get a process pipeline that uses several standardized subprocesses in the form of library pipelines one should not be restricted to make the Jenkinsfile one a scripted one. 

          Hi Andrew, I understood that having nested pipeline {} blocks was  not possible.

          However I found out now that one cannot run pipeline {} blocks in parallel.

          So I also get a 
          java.lang.IllegalStateException: Only one pipeline { ... } block can be executed in a single run.
          when trying to invoke it on one of the parallel blocks:

          (the ettPipeline is a declarative "pipeline template"; only one of it runs perfectly to completion)

              try {

                  stage('Parallel Builds') {

                      parallel (

                          Build1: { node {

                              ettPipeline (

                                  task: "${ETT_TASK}",

                                  pkg: "${ETT_PACKAGE}",

                                  scm_url: "${SCM_URL}",

                                  clentry: "${NOTE}",

                                  email: "${EMAIL}"

                              )

                          }},

                          Build2: { node {

                              ettPipeline (

                                  task: "${ETT_TASK2}",

                                  pkg: "${ETT_PACKAGE2}",

                                  scm_url: "${SCM_URL2}",

                                  clentry: "${NOTE2}",

                                  email: "${EMAIL}"

                              )

                          }},

                      )

                  }

              }

              catch(e)

          {         currentBuild.result = "FAILED"         throw e     }

          Fernando Nasser added a comment - Hi Andrew, I understood that having nested pipeline {} blocks was  not possible. However I found out now that one cannot run pipeline {} blocks in parallel. So I also get a  java.lang.IllegalStateException: Only one pipeline { ... } block can be executed in a single run. when trying to invoke it on one of the parallel blocks: (the ettPipeline is a declarative "pipeline template"; only one of it runs perfectly to completion)     try {         stage('Parallel Builds') {             parallel (                 Build1: { node {                     ettPipeline (                         task: "${ETT_TASK}",                         pkg: "${ETT_PACKAGE}",                         scm_url: "${SCM_URL}",                         clentry: "${NOTE}",                         email: "${EMAIL}"                     )                 }},                 Build2: { node {                     ettPipeline (                         task: "${ETT_TASK2}",                         pkg: "${ETT_PACKAGE2}",                         scm_url: "${SCM_URL2}",                         clentry: "${NOTE2}",                         email: "${EMAIL}"                     )                 }},             )         }     }     catch(e) {         currentBuild.result = "FAILED"         throw e     }

          A similar use case: start several pipeline templates (only ONE level) in a loop. Suppose you have a template pipeline that builds/deploys some microservice but you have several microservices that are built/deployed in a similar way. Currently you have to build one by one. The same applies to any kind of thing you do with a template pipeline.

          Fernando Nasser added a comment - A similar use case: start several pipeline templates (only ONE level) in a loop. Suppose you have a template pipeline that builds/deploys some microservice but you have several microservices that are built/deployed in a similar way. Currently you have to build one by one. The same applies to any kind of thing you do with a template pipeline.

            Unassigned Unassigned
            fnasser Fernando Nasser
            Votes:
            1 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: