Declare Your Pipelines!Declarative Pipeline 1.0 is here!
This is first in a series of blog posts that will show some of the cool features of
Declarative Pipeline.
For several of these posts, I’ll be revisiting some of my
previous posts
on using various plugins with (Scripted) Pipeline,
and seeing how those are implemented in Declarative Pipeline.

To start though, let’s get familiar with the basic structure of a Declarative Pipeline
by creating a simple Pipeline for a Maven-based Java project - the
Jenkins JUnit plugin.
We’ll create a minimal Declarative Pipeline,
add the settings needed to install Maven and the JDK,
and finally we’ll actually run Maven to build the plugin.

Set up

With Declarative, it is still possible to run Pipelines edited directly in the
Jenkins web UI, but one of the key features of "Pipeline as Code" is
checking-in and being able to track changes. For this post, I’m going to use
the
blog/add-declarative-pipeline
branch of
my fork of the JUnit plugin.
I’m going to set up a Multi-branch Pipeline and point it at my repository.

I’ve also set this Pipeline’s Git configuration to automatically "clean after
checkout" and to only keep the ten most recent runs.

Writing a Minimal Pipeline

As has been said before, Declarative Pipeline provides a more structured,
"opinionated" way to create Pipelines. I’m going to start by creating a minimal
Declarative Pipeline and adding it to my branch. Below is a minimal Pipeline
(with annotations) that just prints a message:

If you are familiar with Scripted Pipeline, you can toggle the above
Declarative code sample to show the Scripted equivalent.

Once I add the Pipeline above to my Jenkinsfile and run "Branch Indexing", my
Jenkins will pick it up and run run it. We see that the Declarative Pipeline
has added stage called "Declarative: Checkout SCM":

This a "dynamic stage", one of several the kinds that Declarative Pipeline adds
as needed for clearer reporting. In this case, it is a stage in which the
Declarative Pipeline automatically checkouts out source code on the agent.

Declarative Pipeline syntax is a little more verbose than the equivalent Scripted Pipeline,
but the added detail gives a clearer, more consistent view of what the Pipeline is supposed to do.
It also gives us a structure into which we can add more configuration details about this Pipeline.

Adding Tools to Pipeline

The next thing we’ll add in this Pipeline is a tools section to let us use
Maven. The tools section is one of several sections we can add under
pipeline, which affect the configuration of the rest of the Pipeline. (We’ll
look at the others, including agent, in later posts.) Each tool entry will
make whatever settings changes, such as updating PATH or other environment
variables, to make the named tool available in the current pipeline. It will
also automatically install the named tool if that tool is configured to do so
under "Managing Jenkins" → "Global Tool Configuration".

Configure this Pipeline to use the Maven version matching "Maven 3.3.9"
(configured in "Managing Jenkins" → "Global Tool Configuration").

3

Configure this Pipeline to use the Maven version matching "jdk8"
(configured in "Managing Jenkins" → "Global Tool Configuration").

4

These will show the values of PATH and M2_HOME environment variables.

When we run this updated Pipeline the same way we ran the first, we see that
the Declarative Pipeline has added another stage called "Declarative: Tool
Install": In the console output, we see that during this particular stage "Maven 3.3.9" gets installed,
and the PATH and M2_HOME environment variables are set:

Running a Maven Build

Finally, running a Maven build is trivial. The tools section already added
Maven and JDK8 to the PATH, all we need to do is call mvn install. It
would be nice if I could split the build and the tests into separate stages,
but Maven is famous for not liking when people do that, so I’ll leave it alone
for now.

Instead, let’s load up the results of the build using the JUnit plugin,
however the version that was just built, sorry.

Conclusion

The new Declarative syntax is a significant step forward for Jenkins Pipeline.
It trades some verbosity and constraints for much greater clarity and
maintainability. In the coming weeks, I’ll be adding new blog posts
demonstrating various features of the Declarative syntax along with some recent
Jenkins Pipeline improvements.

Links

Liam started his software career as a tester, which might explain why he’s such a fan of CI/CD and Pipeline as Code.
He has spent the majority of his software engineering career implementing Continuous Integration systems at companies big and small.
He is a Jenkins project contributor and an expert in Jenkins Pipeline, both Scripted and Declarative.
Liam currently works as a Jenkins Evangelist at CloudBees.
When not at work, he enjoys testing gravity by doing Aikido.