Continuous Integration with Jenkins: More about Free-style Jobs steps.
In the first article of “Continuous Integration with Jenkins: How? and Why?”, we have discussed about Continuous Integration, its benefits, the wide catalog of plugins and tools, and also, about Jenkins, a powerful Continuous integration server that we can use to get all those benefits that I have mentioned. This time, I would like to explain more about the “Free-style” jobs, focusing in how we can scheduling Jobs and execute Scripts as steps.
Scheduling Jenkins Free-Style Jobs:
As soon as possible we should integrate and test our code in order to detect issues immediately, this action can help us at saving time and effort. Jenkins allows us to execute our “free-style” jobs in many ways. We can do it by implementing WebHooks, Polling the Source code Management or building periodically.
A. Webhooks: Depending of the job’s purpose, you may need a method for building instead of another, however I highly recommend you the webhooks in order to achieve continuous integration. After an event is triggered inside of your branch or entire repository, if you configure a WebHook, this will send an HTTP Post payload to the URL that was added to it. In this case, this HTTP Post payload will execute automatically the job.

On the image above, we can see a GitLab webhook that triggers an automated build on Jenkins.
1. Create an event: At least one event must be configured on a Webhook, on GitLab exist several types, some of them are “Push Events”, “Tag Push Events”, “Comments”, “Merge Request Events”… they will be discussed later.
2. A HTTP POST payload is sent to [http://jenkinsurl/job/jobsname]: After an event is triggered, GitLab or another Source Code Manager, will send an HTTP POST payload to any service that you have configured on the WebHook, in this case, this HTTP Post payload will be send to Jenkins. The URL structure is [http:jenkinsurl/job/jobsname] as example: http://jenkinsurl.com/job/AdminJavaDev.
3.Creates an automated build: At the moment when Jenkins receives the payload, the job will be executed automatically.
4.Notifies the result: Jenkins will notifies the team if the build failed.
A.1 Integrating Jenkins with WebHooks: For this exercise, we will implement a WebHook by using GitLab. I have created my own GitLab server.
Environment:
1. Windows 10.
2. GitLab Community Edition 9.4.5.
3. Jenkins 2.60.2.
4. Git plugin 3.3.1. (Jenkins).
5. GitLab plugin 1.4.2.
Pre-requirements:
1. GitLab and Jenkins must be running under the same network or Jenkins must be exposed if you don’t have your own GitLab server.
2. A Job successfully configured.
3. The following plugins installed on Jenkins:
4. Git plugin.
5. GitLab plugin.
A.1.1 Creating the Webhook on GitLab:
- Go to your GitLab project home page.
- Click on “Settings” -> “Integrations”.
3. The following form will be displayed:
4. Complete the following blanks and check the options.
4.1 URL: Write the url of the jenkins server/jobname. Example: http://jenkinsurl/project/Webhooktest.
4.2 Secret Token: You can generate a secret token, following the next steps:
a- Go to Jenkins server -> your project -> configure.
b- Click on the “Build Triggers” tab.
c- Check the option “Build when a change is pushed to GitLab. GitLab CI Service URL: http://jenkinsurl:80/project/job_name” -> Advanced.
d- On “Secret token” button, click on “Generate” button.
e- Copy the alphanumeric code that was generated on the “Secret token” blank on GitLab.
5. Trigger. Check one or more options according to your needs
5.1. Events:
Push Events: This URL will be triggered by a push to the repository.
Tag Push Events: This URL will be triggered when a new tag is pushed to the repository.
Comments: This URL will be triggered when someone adds a comment.
Issues Events: This URL will be triggered when an issue is created/updated/merged.
Confidential Issues events: This URL will be triggered when a confidential issue is created/updated/merged.
Merge Request events: This URL will be triggered when a merge request is created/updated/merged.
***Job Events: This URL will be triggered when the job status changes.
***Pipeline Events: This URL will be triggered when the pipeline status changes.
Wikipage Events: This URL will be triggered when a wiki page is created/updated.
*** = These options apply only for GitLab CI.
6. For this exercise, please,check the “Push Event” option.
7. Uncheck “Enable SSL” option. (We are not using any security protocol).
8. Click on “Add webhook” button.
9. Finally, try your new “WebHook” by clicking on “Test” button next to your webhook url.

10. If everything was set correctly, a “Hook executed successfully” alert will be displayed:
11. Finally, push a change or edit your files directly. This action will trigger the webhook event.
12. Immediately, you will notice that a new build was executed.
13. Click on the build number.
14. The information about the GitLab event is displayed:
B. Polling from SCM: There is another option for scheduling jobs; polling from SCM. In this case, Jenkins will be looking for changes on the repository, if they exist, it will execute a build, if not, the job won’t be executed. This polling could be scheduled for a specific time. You will not need a special plugin to start using it. However, this method has a delay action, because the job won’t be triggered immediately after a change has being committed I recommend you this feature when you are using Subversion as Source Code Manager.
B.1 Enable Polling from SCM on a Jenkins Job:
Before getting into the jobs configuration, it’s really important to understand how this polling is scheduled. Jenkins will use Cron Expressions to do it. This expression will represent a set of time in which Jenkins will request the repository for changes. The fields of a Cron Expression on Jenkins are the following:
A Cron expression in Jenkins is comprising by 5 fields separated by white spaces.
As you can see on figure 11, there are different allowed values that we can use, for example:
i. * specifies all possible valid values.
ii. M-N specifies a range of values.
iii. M-N/X or */X steps by intervals of X through the specified range or whole valid range.
iv. A,B,…,Z enumerates multiple values.
How can I schedule a job that runs every 5 minutes, every hour, every day of week and every month? According to the previous image, the slot for minutes is the first one, so an expression could be the following:
H/5 * * * *
There are two things that could blow your mind. (Understanding how the Cron Expressions work could be challenging).
What is the “H” at the beginning?
The “H” (Hash) can help us to improve the load and also a better using of limited resources. When I use H instead 0, the server will execute the jobs with a minimum difference of time, just to avoid a large spike of executions.
And what about the H/?
Take a look about this expression and compared it with the above one:
5 * * * *
Which are the differences between them?:
The first one is indicating that Jenkins will be looking for changes each 5 minutes, because is using a / (slash) that creates steps. It means it will “jump” each 5 steps: 5, 10 , 15… each step is a execution.
The second expression indicates that Jenkins will be looking for changes at the first 5 minutes of each hour. So, It will request for changes at 12:05, 1:05, 2:05…
There is a tricky example:
H(0–29)/10 * * * *
This expression means that Jenkins will request for changes every 10 minutes on the first half of every hour. Remember, the( — )between 2 values indicates that the expression includes a range.
Now, we will schedule a job by using Polling from SCM.
a. On your “Free-style” job configuration go to Build Triggers and check “Poll SCM” option.
b. Then a textarea is displayed, there you must add your cron expression. For this example, Jenkins will looking for changes every fifteen minutes.
c. Finally, save the changes.
C. Build Periodically:
Finally, we have the last one of the methods for scheduling jobs. “Building Periodically” follows the same structure as “Polling from SCM” with the main difference that a Job configured with “Build Periodically” method will be triggered whether there are or not changes.
- To Enable this feature go to your Jenkins Job.
- Build Triggers -> Build Periodically.
3. You can see that a textarea is displayed. As I mentioned before, this feature also needs to be configured with “Cron Format”. So, in this area you must specify a schedule. Remember, the job will be triggered independently of the changes.
4. Finally save the changes.
There are different methods of scheduling a job that can help you throughout your process of continuous integration. I highly recommend you reading and practicing in order to identify which benefits you can get from one or another.
Trigger a job as a Post-Build step:
As you can see through this and the past article, the Free-style jobs are comprising of steps. These steps can be classified into some categories such as “Source Code Management”, here are listed all the methods to connect and create integrations with the Source Code Managers. “Build”, on this tag we can add the different ways of building the project, and finally “Post-Build” steps, where the actions that must be executed after a build is created take place. This time I will explain how to Trigger a job as a Post-Build step.
Pre-requirements:
a. 2 jobs running successfully, one of them will act as a “Father” and will trigger the other job.
Steps:
- Go to “Configure” section of you “Father” free-style job.
- Select the “Post-Build Actions” tab.
3. Click on “Add a Post-Build action” button and then select “Build other projects” option.
4. The next form will be displayed.
5. There is a blank for the Projects to build. You can separate with a comma each project.
6. This project(s) will be executed depending of the option you choose.
a. Trigger only if build is stable.
b. Trigger even if the build is unstable.
c. Trigger even if the build fails.
7. The job will trigger a job called “Concepts” only is build is stable:
8. Click on “Build Now” option.
9. Then, you can see the “Father” job was successfully executed and then ,the “Concepts” jobs is being executed.
This feature can help us when we need to create an automated build on certain circumstances. So, it will be triggered when any scenario that was set, happens.
Executing Scripts on a Free-style job:
We can see that Jenkins jobs offer a wide variety of customizable tasks inside every of them, also, they could be complemented with any plugin to extends its functionality. But, what happens when we can’t find any plugin or we need and specific task that Jenkins can’t provide us?
One of the possible solutions is using Shell Scripts as Jenkins steps.
A Script is a set of commands that will help in building the project. On Jenkins, this scripts will be run within the job’s workspace. Jenkins allow us to run this script on different Operative Systems:
On Windows, we must set the commands inside the the textarea that is displayed when we selected. Configure -> Build -> Add Build step -> Execute Windows batch command.
On Unix based, Configure -> Build -> Add Build step -> Execute Shell.
This option works as a terminal of every operating system.The commands will be the same. Also we can create a .sh file on Unix or the equivalent .bat file on Windows, in order to avoid to write a long script on the Shell Script area on Jenkins. It could be difficult to handle it.
I will explain how we can integrate them by examples:
Environment:
a. CentOS 7.
b. Jenkins 2.71
Prerequirements:
a. Maven 3.0.5 in PATH.
b. A Freestyle Java Job.
Writing a Shell Script on Linux:
For this exercise, we will build a Java project, by using Maven, but instead use the Maven plugin, we will use commands to do it.
1. Go to the Job configuration.
2. Click on “Build” tab.
3. Under “Build” label, click on “Add Build Step” button -> Execute.
4. Now a textarea will be displayed, we can treat it as a “terminal”.
Write the commands in order to build a java app with maven.
5. Click on save button.
6. Finally, build the job.
7. Select the previous build and click on “Console log”.
8. The “+” symbol before the expression, indicates that a script was run.
Remember, the scripts will be executed at the root of every workspace of each job. But, if we need to move between folders, we can do it by using “cd” command.
There is another basic example. I will list the contents of a folder that is not on the workspace root.
i. Add to the last shell step,“cd folder” + “ls”.
ii. Save the changes and build the project.
iii. Verify the output.
If you understand and know the commands that you can run on each Operating System, you can achieve a lot of functionalities and features in order to extend Jenkins.
Environment Variables.
Jenkins also help us by providing “Environment Variables” that we can use in our scripts, some of them are, you can verify them by clicking on the “See the list of available environment variables” under the Shell Script textarea:
Some of them are:
In order to use one or more of this environment variables, we must write a “$” before any of them. For example:
We will move a file that is inside a folder to the root of the WORKSPACE. In Linux, we must specify the path where the file is located to the new one. To avoid write a long path, we can use the $WORKSPACE variable, it provides the absolute path of the directory assigned to the build as a workspace.
- The file .jar will be moved from “target” folder to the root of the “Workspace”.
- Save the changes and run the job.
- Verify the logs.
4. As you can see, the absolute path is displayed on the logs, however by using the $WORKSPACE variable, we can save time and avoid human error, because it provides the right path.
5. Also, we can check the file is where we have just move it.
Executing a Script File by using “Execute Shell” step:
As I mentioned, we can use the execute scripts inside the textarea that the “Execute Shell” provides. However, If we need to run a lot of commands and statements, could be a mess. So, we can write a Script file we the necessary instructions in order to execute anything we need in our job.
- We are going to execute the same maven build, however, this will be inside a .sh file. This file will be on the repo. -> This is optional, because you can add this file at any place, just make sure Jenkins can find it.
- The content of my simple script.
3. The content of my “Execute Shell” step:
4. I’ve added a “chmod +x” to the script file in order to add executions permissions.
5. Then I will execute the script.
6. Save the changes and run the job.
7. Verify the output.
As you can see, the step started with the permissions assignation, then the script execution, where different mvn goals are being executed.
8. Finally you can check that the build was successfully executed.
The Jenkins Free-style jobs are part of the core of Continuous Integration, so, understanding and learning more about them and the different tasks that they can do, can help us at improve our CI processes and also, more complex steps.
Scheduling the jobs is a really nice feature that we MUST implement, why? If we run a job each 2 weeks, there is not Continuous Integration, because, each push must be evaluated it immediately.
On the other hand, the “Execute Shell” step on Jenkins could help us at implementing tasks that the plugins don’t offer. Remember, we could add scripts files that can be included on our continuous integration process.
Sources: