Declarative vs Scripted Pipeline – Key differences
Share this post

Choosing the right programming approach for the project is crucial for the success of the project. In this article, we explain what the Jenkins pipeline is and what the different types of pipelines are in this open source tool. Learn the differences between a scripted pipeline and a declarative pipeline.

When creating a Jenkins pipeline, the engineers have a choice–they can decide to build a scripted pipeline or a declarative pipeline. In Jenkins, a pipeline can be briefly defined as a collection of events/jobs linked with others. The purpose of this combination of plugins is to support the implementation and integration of continuous delivery pipelines. You can decide to create a Jenkins scripted pipeline or a declarative one. In order to learn more about those two solutions, let’s do a comparison: a Jenkins declarative vs a scripted pipeline.

What is Jenkins?

If you are looking for an open source automation tool for your company, you should consider Jenkins. This Java-based automation tool simplifies the process of the software integration and delivery process by means of Continuous Integration and Continuous Delivery. It is a quite commonly used tool in the CI/CD process, especially because of its special features known as scripted and declarative pipelines. Jenkins pipelines make the delivery process much easier and help companies adopt DevOps in no time. 

Pipeline scripting

Before you choose which one is better – a scripted or a declarative pipeline – you need to understand what a Jenkins Pipeline is and why you need one. Let’s start from a continuous delivery pipeline – it is a process of getting your software from version control straight to your users and clients. It represents all kinds of workflows, activities, and automation required to move the new functionality from the ideation stage to the release. Imagine having a set of plugins which will support implementing and integrating continuous delivery pipelines into Jenkins. 

The pipeline can be implemented as DSL (Domain Specific Language) code with a JenkinsFile (a text file that defines the pipeline). You can use this file to write the steps needed for running a Jenkins Pipeline. This way, you’ll be able to build pipelines automatically for all branches. It also allows you to execute pull requests with just one JenkinsFile.

Jenkins pipeline – declarative vs scripted pipelines

Jenkins allows users to use one of the two pipelines – declarative or scripted. You should compare declarative vs scripted pipelines to learn about their differences before you decide which syntax suits you better. The Jenkins scripted pipeline was the only available option when this open source automation tool was first introduced. The declarative pipeline came later, and its popularity is growing. 

Scripted pipeline

Originally, Jenkins only allowed the user to write the pipeline as a code, hence a scripted pipeline. Such a pipeline is written in a JenkinsFile on the web UI of the Jenkins tool. You can write a scripted pipeline with DSL (domain specific language) and use Groovy based syntax. And what is Groovy? It is a JVM-based programming language. By using it in a scripted Jenkins pipeline, you gain access to the wide group of APIs packaged with the Java Development Kit (JDK).

Like every solution, a scripted pipeline in Jenkins has its benefits and drawbacks.

Reasons to use a Jenkins scripted pipeline:

  • Using DSL (domain specific language) simplifies a lot of tasks for a Jenkins developer.
  • Groovy code can be injected into the pipelines any time.
  • It provides big control over the script and allows you to build a complex pipeline in the code. 

The drawbacks of the scripted pipeline in Jenkins: 

  • There are many IT experts with Java and Groovy skills, but those who aren’t experienced with Jenkins often write rather complicated Groovy code to add functionality which is already available through the Jenkins DSL.
  • In fact, there are no limits as to what a scripted pipeline can do programmatically, but there is also no established formal structure or flow for it, which can lead to the creation of unstable pipeline code that is difficult to maintain or interpret. 

Declarative pipeline script

Declarative pipelines are a relevantly new feature in Jenkins. Thanks to this option, the code of the pipeline is easier to write and read later. But it is quid pro quo – the code is simplified because declarative syntax is more limited. You won’t be able to inject code into the pipelines whenever you want. Such a pipeline model is not really the best choice if you plan to build a pipeline with complex logic.

Is the declarative pipeline the modern way of building pipelines?

  • Even though it has many limitations, it seems that declarative pipelines have already become the standard in developing pipelines.
  • By developing using declarative syntax, you gain more structured and simpler pipelines.
  • Declarative pipelines have integration with the Blue Ocean interface.

Is there any reason not to use declarative pipeline in Jenkins?

  • Not all plugins are compatible with Declarative Pipelines.
  • Declarative syntax is stricter, so using declarative pipelines steals a bit of the developer’s freedom.

Scripted vs declarative pipelines in Jenkins – differences 

So, what are the main differences to sum up the comparison of declarative vs scripted pipelines in Jenkins? Here are some of the most important things you should know:

  • Basically, declarative and scripted pipelines differ in terms of the programmatic approach. One uses a declarative programming model and the second uses an imperative programming mode.
  • Declarative pipelines break down stages into multiple steps, while in scripted pipelines there is no need for this. Example below
 pipeline {  
   agent {    
     // executes on an executor with the label 'some-label' or 'docker'
     label "some-label || docker"    
   }   

   stages {   
     stage("foo") {     
       steps {       
         // variable assignment (other than environment variables) can only be done in a script block
         // complex global variables (with properties or methods) can only be run in a script block
         // env variables can also be set within a script block
         script {          
           foo = docker.image('ubuntu')
           env.bar = "${foo.imageName()}"
           echo "foo: ${foo.imageName()}"          
         }        
       }      
     }
     stage("bar") {
       steps{  
         echo "bar: ${env.bar}"
         echo "foo: ${foo.imageName()}" 
       }      
     }
   } 
 }
  • Scripted pipelines permit a developer to inject code, while the declarative Jenkins pipeline doesn’t. Example below:
node {
 
  git url: 'https://github.com/jfrogdev/project-examples.git'
  
  // Get Artifactory server instance, defined in the Artifactory Plugin administration page.
  def server = Artifactory.server "SERVER_ID"
  
  // Read the upload spec and upload files to Artifactory.
  def downloadSpec =       
       '''{
       "files": [     
         {
            "pattern": "libs-snapshot-local/*.zip",
            "target": "dependencies/",
            "props": "p1=v1;p2=v2"
         }      
       ]    
   }'''
 
  def buildInfo1 = server.download spec: downloadSpec
 
  // Read the upload spec which was downloaded from github.
  def uploadSpec =
     '''{
     "files": [
       {
          "pattern": "resources/Kermit.*",
          "target": "libs-snapshot-local",
          "props": "p1=v1;p2=v2"
       },
       {
          "pattern": "resources/Frogger.*",
          "target": "libs-snapshot-local"
       }
      ]
   }'''
  
  
  // Upload to Artifactory.
  def buildInfo2 = server.upload spec: uploadSpec
  
  // Merge the upload and download build-info objects.
  buildInfo1.append buildInfo2

  // Publish the build to Artifactory
  server.publishBuildInfo buildInfo1
}

As a matter of fact, the differences seem to be subtle. The runtime performance, scalability, and flexibility of these two types of Jenkins pipelines are similar, but…although it may seem that declarative pipelines give developers less flexibility than scripted pipelines, many say that the new Jenkins functionality is better than the original solution. Why is that?

Is a declarative pipeline better than a scripted pipeline?

A declarative pipeline uses a simpler and more strict syntax for creating a Jenkins Pipeline. The declarative character of this solution puts limitations on what the developer can do and forces him or her to work within predefined structures. Because of its simplicity, it’s a great choice for developing non-complex continuous delivery pipelines. The Jenkins scripted pipeline model is recommended for those who have numerous specific requirements for their continuous delivery pipeline. You may also consider leveraging a “best of both worlds” approach, by using declarative pipelines with script() step to run a created scripted pipeline. 

As usual, choosing the right solution for your project depends on its specific requirements and the developer’s skill set, experience and preferences. If you haven’t found the answers to all your questions in this article, we encourage you to look for them on our blog. You can also contact us directly. We will be happy to analyse your needs and help you overcome any challenges.

Check out our blog for more in-depth articles on Databricks:

Data Pipeline Automation_2

Share this post