In my previous blog, I briefly gave an introduction to continuous integration, what Jenkins is and we made our first build using Jenkins. Now, in this blog, we will see how can we build a Pipeline in Jenkins.
Pipeline – what and why?
When the number of plugins executed on SCM or code, then it is known as Pipelining.
With the help of Pipeline plugin, users can implement a project’s entire build/test/deploy pipeline in a jenkinsfile and store that alongside their code, treating their Pipeline as another piece of code checked into source control.
Now let’s start making Pipeline for our build.
Follow these simple steps after your Jenkins is up and running:
STEP 1: You have options on the left-hand side of your Jenkins dashboard. Click on New Item.
STEP 2: Now you see this page. Since you want to make a Pipeline for your build, we will select Pipeline and will give a suitable name for that.
STEP 3: Now, as you can see here we can specify our build-related information. Whether to discard any previous old build, anything related to concurrent builds, or if it’s a GitHub project, or if this project is parameterized. [You can select multiple options to specify information about the project]
I am selecting git project. It’ll show a text box where you will need to give the project URL.
Then you can specify build triggers if any. We are skipping this as of now.
STEP 4: And now comes the main thing, Pipeline!
You can give your pipeline script here or you can add jenkinsfile in your code. In any case, you need to select the option from the Definition drop-down. It has two options –
- Pipeline script from SCM
- Pipeline script
If you select the former one, you need to provide the jenkinsfile in the root of your code. Jenkins will read the script from your code. If you select the latter one, then you’ll have to give the script there in the specified box.
Then, for SCM drop-down option select Git. It’ll then ask for Repository URL and Credentials. So, fill it with the repository URL for your project. Until or unless you are giving a private repository URL, you don’t need to explicitly provide the credentials. It’ll use the one you gave them while setting up the Jenkins. Also, by default, it is taking master as your default build branch.
After specifying all the information about your project build, APPLY AND SAVE.
After that, you can follow the same procedure of Build now and can see the Console Output!
Now let’s talk about our Jenkins file which we generally write in Groovy.
We specify what all stages our Pipeline will have. Say, for example, it’ll have Initialization and Maven stages only.
But what’s a stage?
It creates a labeled block.
stage structures your script into a high-level sequence. Stages up as columns in the Pipeline Stage view with average stage times and colors for the stage result.
Stages are the logical segmentation of a Pipeline. Separating work into stages allows separating your pipeline into distinct segments of work.
So, here we are defining stages – giving its name and specifying what all will be done in a particular stage.
So, what’s the advantage of specifying stage?
For example, there are two stages in our Pipeline: Initialization and Maven. And suppose we have mentioned certain commands in these stages.
As soon as we build our project, it’ll show me something like this:
In this case, both the stages are passed successfully. But if this is not the case, then it’ll look something like this:
It’ll show where we went wrong. Now we can easily check which part is responsible for our failed build.
One quick note: Jenkins provides us various installed plugins. But other than those you can install various plugins.
Simply go to Manage Jenkins on your left-hand side options list.
Then, Manage Plugins. Here, you can install plugins from the available list.
node specifies where something shall happen. You give a name or a label, and Jenkins runs the block there.
node: Allocate Node
Allocates an executor on a node(typically a slave) and runs further code in the context of a workspace on that slave.
Any material work within a Pipeline should occur within a node block.
- Why? By default, the Jenkinsfile script itself runs on the Jenkins master, using a lightweight executor expected to use very few resources. Any material work, like cloning code from a Git server or compiling a Java application, should leverage Jenkins distributed builds capability and run an agent node.
Don’t use input within a node block
While you can put an input statement within a node block, you definitely shouldn’t.
- Why? The input element pauses pipeline execution to wait for an approval – either automated or manual. Naturally, these approvals could take some time. The node element, on the other hand, acquires and holds a lock on a workspace and heavyweight Jenkins executor – an expensive resource to hold onto while pausing for input.
So, create your inputs outside your nodes.
A node is basically a processing unit where all your processing will take place. Node is an instance of environment where you want to make a build.
We can specify any node like this:
An agent is for declarative Pipelines and node is for scripted pipelines.
In declarative pipelines, the agent directive is used for specifying which agent/slave the job/task is to be executed on. This directive only allows you to specify where the task is to be executed, which agent, slave, label or docker image.
On the other hand, in scripted pipelines, the node step can be used for executing a script/step on a specific agent, label, slave. The node step optionally takes the agent or label name and then a closure with code that is to be executed on that node.
Let’s start off writing a sample Jenkins file in Groovy.
Do not set environment variables with env global variable. While you can edit some settings in the env global variable, you should use the withEnv syntax instead. This is because the env variable is global, changing it directly is discouraged as it changes the environment globally, so the withEnv syntax is recommended.
So, in the Initialization stage, we are cloning the source code.
In the Maven stage, we are interested in running mvn clean verify command which will run all the testing tools and generate the reports along with the code quality plugins (checkstyle, PMD, findbugs).
So that was it. I hope it was of some help. 🙂
You can find the complete implementation here.