# Is it possible to dynamically compose declarative pipeline "blocks"?

**URL:** <https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856>\
**Category:** Using Jenkins\
**Tags:** question\
**Created:** [June 28, 2022, 10:25am UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856 "2022-06-28T10:25:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![vlad](https://avatars.discourse-cdn.com/v4/letter/v/3bc359/32.png) [@vlad](https://community.jenkins.io/u/vlad)\
**Post date:** [June 28, 2022, 10:25am UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856/1 "2022-06-28T10:25:26Z")

</div>

I’m trying to figure out something about declarative pipelines. I know that shared libraries can have entire pipelines as a last statement in `call` function; however, the pipeline would still have a predefined structure. What I’m wondering is whether it’s possible to compose and return a _declarative_ pipeline from shared library. Eventually I’d like to achieve this:

```auto
library 'shared'

myPipeline {
   stages {
       ...
   }
}

```

`myPipeline` would then augment the `stages` block passed to it with other stages and properties, and return a `pipeline`. Just having scripted statements in `stages` doesn’t work obviously, I also tried to return parsed AST from shared library but that also doesn’t work. Maybe it can be accomplished by writing a plugin? Ideally this plugin would be just some glue code so that the logic can still be implemented in the shared library.

Would appreciate any thoughts on this!

---

<div class="post-metadata">

**Author:** ![vlad](https://avatars.discourse-cdn.com/v4/letter/v/3bc359/32.png) [@vlad](https://community.jenkins.io/u/vlad)\
**Post date:** [June 28, 2022, 1:21pm UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856/2 "2022-06-28T13:21:38Z")

</div>

Also tried creating and returning `org.jenkinsci.plugins.pipeline.modeldefinition.model.Root` from Jenkinsfile – didn’t work

---

<div class="post-metadata">

**Author:** ![halkeye](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/halkeye/32/8_2.png) [@halkeye](https://community.jenkins.io/u/halkeye)\
**Post date:** [June 28, 2022, 4:34pm UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856/3 "2022-06-28T16:34:35Z")

</div>

One of the main purposes of declarative is to have the entire pipeline parseable at start for flow control.

What you are essentially describing is scripted pieplines which is considered the advanced mode of declarative.

I would recommend looking into scripted, then you can have a compositable pipeline really easily

---

<div class="post-metadata">

**Author:** ![vlad](https://avatars.discourse-cdn.com/v4/letter/v/3bc359/32.png) [@vlad](https://community.jenkins.io/u/vlad)\
**Post date:** [June 28, 2022, 8:20pm UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856/4 "2022-06-28T20:20:09Z")

</div>

Thank you for the reply! Yes, I already implemented something similar with scripted pipeline, basically:

`myPipeline.groovy`

```auto
def call(Closure body) {
  pipeline {
    stages {
      stage {
        steps {
          script {
            body()
          }
        }
      }
    }
  }
}

```

`Jenkinsfile`

```auto
myPipeline {
  echo 'test'
}

```

However, this way some advantages of declarative pipelines are lost, namely:

1. stages can’t be determined before the pipeline is executed
2. extended static validation can’t be performed
3. it’s difficult or impossible to pass blocks like options or parameters
4. some declarative blocks like `matrix` or `when` are not available
5. developers have to get used to custom API that I would define in `call` function, and can’t use regular Jenkins declarative constructs

> One of the main purposes of declarative is to have the entire pipeline parseable at start for flow control.

That’s what I would like to keep, while also being able to compose the structure of the pipeline.

---

<div class="post-metadata">

**Author:** ![halkeye](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/halkeye/32/8_2.png) [@halkeye](https://community.jenkins.io/u/halkeye)\
**Post date:** [June 28, 2022, 10:06pm UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856/5 "2022-06-28T22:06:22Z")

</div>

> [@vlad](#):
>
> ```auto
> pipeline {
> stages {
> stage {
> steps {
> script {
> 
> ```

thats declarative btw, if it has pipeline {} its declarative.

> [@vlad](#):
>
> - some declarative blocks like `matrix` or `when` are not available

That would be parallel and if statements in scripted

I’m not saying your wrong, but declarative doesn’t really support this, you can’t really do super advanced custom things in declarative. The best I could find is like making a fake custom post like step - [https://github.com/halkeye/jenkins-shared-library/blob/f2b30f61541b21f345b4677e29bba647e1e63da7/vars/buildDockerfile.groovy#L115-L124](https://github.com/halkeye/jenkins-shared-library/blob/f2b30f61541b21f345b4677e29bba647e1e63da7/vars/buildDockerfile.groovy#L115-L124)

You might want to look into the idea of having jenkinsfile being generated by an external templating like script that updates your SCM, so by the time jenkins sees it, the Jenkinsfile is deterministic, plus it would be in CI if you ever needed to go back to a previous build.

---

<div class="post-metadata">

**Author:** ![vlad](https://avatars.discourse-cdn.com/v4/letter/v/3bc359/32.png) [@vlad](https://community.jenkins.io/u/vlad)\
**Post date:** [June 29, 2022, 7:06am UTC](https://community.jenkins.io/t/is-it-possible-to-dynamically-compose-declarative-pipeline-blocks/2856/6 "2022-06-29T07:06:47Z")

</div>

> [@halkeye](#):
>
> thats declarative btw, if it has pipeline {} its declarative.

Yeah you’re right – I meant it’s a `script` block within a declarative pipeline.

> [@halkeye](#):
>
> You might want to look into the idea of having jenkinsfile being generated by an external templating like script that updates your SCM, so by the time jenkins sees it, the Jenkinsfile is deterministic, plus it would be in CI if you ever needed to go back to a previous build.

Yeah I saw that implemented once actually – with a microservice that would render Jenkinsfiles from templates stored in git.

I was just hoping there’s a way to achieve this by leveraging existing APIs and maybe writing some glue code plugin.

Anyway thanks for your answers again, I will probably stick with my example posted above. If you have any suggestions on the general direction to look at (like what code or plugins I could read), would appreciate if you let me know
