Estimated reading time: 11 minutes
As a DevOps engineer, I provide the latest build on different environments as and when a code/feature occurs.
In our development team we have a CI/CD pipelines in place. This process triggers each time code is merged into its respective branch. For e.g. every time a feature branch merges with the development, the CI/CD pipeline for Dev branch triggers automatically. Or, every time the development branch merges into the Staging branch the CI/CD process for the staging branch triggers.
For both pipelines, there exist dedicated Jobs pre-configured in Jenkins.
Apart from the common branches, there may exist specific feature branches for which there are no jobs/pipelines. Manually creating a Jenkins job for such branches is cumbersome, especially during release periods as developers frequently request builds.
To automate the creation of a job for such branches, I broke down this problem in the following stages:
- Build a generic Jenkins job which can dynamically accept the branch name
- Integrate this with Slack such that developers can see notifications on the progress of their build in Slack
- Modify slash command to accept parameters such as branch name and docker image name. This gives developers more granular control on the branches to be built and the docker image name of their output.
In this blog, I will show how to integrate Jenkins with Slack Notifications and trigger a job from Slack. I will also walk you through the process of triggering a parameterized build from Slack.
As is obvious from its popularity, Slack is one of the most widely used open-source communication and collaboration tools. Slack provides more than forty custom apps and we will use Slash Commands and Jenkins CI for this integration.
What is Jenkins?
Jenkins is a popular open-source continuous integration (CI) tool. Written entirely in Java, Jenkins is a self-contained, open-source automation server. It can be used to automate software building, testing, and deployment.
Jenkins supports the automation process of continuous integration and continuous delivery (CI/CD). Moreover, it also supports version control tools such as git and source code management tools like GitHub that allows building, testing and deploying code on remote repositories.
Section 1 – Integrate Jenkins tools With Slack Notifications
Go to Jenkins > Manage Jenkins > Plugin Manager > Search for the “Slack Notification Plugin” and install it.
Create a Slack account (if you do not have one) and then create a private/public channel. In my Scenario, I have created a channel named “sample”.
Then Go to settings > Click on ‘Add an app’.
Click on View App Directory. Search for “Jenkins CI” and click add configuration.
Set the channel name that you wish to integrate with Jenkins and click on “Add Jenkins CI Integration”.You will get a Team Domain name and Integration Token Credential ID after adding Jenkins CI Integration.
After a successful installation, go to Jenkins > Click on ‘Manage Jenkins’ > Click on ‘Configure System’.
Find the ‘Global Slack Notifier Settings’ section and add the following values:
- Team Subdomain:
DomainName
DomainName
- Integration Token Credential ID:
secret text
secret text
- Channel or Slack Id and other fields are optional
Then save these settings
Note: Exposing Integration Token is not secure. Please remember to replace the Integration Token with appropriate credentials (secret text).
Go to Jenkins job > Go to the post-build section > Select Slack Notifications. In the Slack Notifications section, choose the events you would like to be notified about.
Now Build the Jenkins job. Based on the build result you will receive a Slack notification on the Slack channel as shown below.
Section 2:- Trigger Jenkins Job From Slack
Go to Jenkins > Manage Jenkins > Plugin Manager and search for ‘Build Authorization Token Root’ and install that plugin.
After installing the plugin, go to Dashboard > Click on Job name > Click on Job configure > On Build Triggers Click
On ‘Trigger builds remotely’ (e.g., from scripts) add Authentication token (you can generate a random token from here) for eg. “57464576646654”.
Use the following URL to trigger the build:
JENKINS_URL/job/SampleJob/build?token=TOKEN_NAME
OR
JENKINS_URL/job/SampleJob/buildWithParameters?token=TOKEN_NAME
Optionally append ‘&cause=Cause+Text’ to provide text that will be included in the recorded build cause.
For e.g:
Now, login to Slack, add a channel and ‘Add an app.
’Click on ‘View App Directory’, search for “Slash Commands” and click add configuration.
Click on Add Configuration and, in my scenario, I have set my command name as “/build”. However, you can give custom name to your command. Click on the “Add Slash Command Integration” button.
Provide a request URL that is needed when the slash command runs and performs a Post and Get method to the URL.
Shown below is a sample
slash
command configuration,
Hint – For your understanding select Autocomplete help text. This would help the user see suggestions for your command.
Save your Integration. Now run the /build command from your Slack channel. This will start your Jenkins job from Slack.
Section 3 – Trigger a build for a specific branch or a parameterized Jenkins Job From Slack
In the Above section, I showed how we can trigger a Jenkins Job from within Slack. In this section, I will show how we can trigger a build for a specific branch or pass a parameter through Slack for a Jenkins Job.
For this, We need three plugins:
- Pre SCM BuildStep Plugin
- EnvInject Plugin
- Build Authorization Token Root Plugin
In the above section, we installed and used the Build Authorization Token Root Plugin which will be useful now.
Go to Slack > Slash command configuration
I have configured my Slack slash command to call:
https://Jenkins_URL/job/Job_name/buildWithParameters?token=Your_Authentication_token
When I type
/build parameter1 parameter2
, the
text
I type after the slash command gets sent with the URL as a parameter (branch_name, dockertag in this case).
-
/build
/build
– this is the command, the part that tells Slack to treat it as a Slash Command and has specific routing instructions. -
feature/2348757 cicd-01
feature/2348757 cicd-01
– this is the text portion, it includes everything after the first space following the command. It is treated as a single parameter that is passed to the app that owns the command.
The text contains a whole string (i.e text = branch_name dockertag).
Hence we need to split this ‘text’ parameter into multiple environment variables that Jenkins can use for the build process.
To achieve this we need to add two pre-SCM build steps and install the Pre-SCM Build Step plugin.
To do this, go to Jenkins > Manage Jenkins > Plugin Manager and search for the “Pre SCM BuildStep” plugin and install it.
After installation,
Go to the Jenkins job and click on run BuildStep before SCM runs under ‘On Build Environment’. Now click on Add Build Step > Execute shell command which consists of the following script:
build_parameters=($text) echo BRANCH=${build_parameters[0]} > env.properties echo param2=${build_parameters[1]} >> env.properties
‘env.properties’ is a file used to store the parsed strings. This script stores the environment variables in a key-value pair. This script stores a parameter in a string array where the parameters are split by the ‘space’ character. Parameters are read and stored in a variable.
Pre-SCM build step 2 is ‘Inject Environment Variables’. For this, we need to install the “Inject Environment Variables” plugin.
Go to Jenkins > Manage Jenkins > Plugin Manager and search for “Environment Injector” plugin and install it.
In the Run build step before SCM runs section, click on Add Build Step then on Inject Environment Variables and in the Properties File Path > Specify path as $WORKSPACE/env.properties.
I have created the properties file in a Workspace to read the file with my parsed environment variables and inject them in the job environment.
Set the Flag as parameterized > Create a String parameter.
Now, Specify the git repository (note that we’re specifying the branch as $BRANCH, hence it will read the properties file and return a value of Branch (in this case, develop, master or feature). Also specify the docker tag as $PARAM2, to return the value of PARAM2.
The command
/build feature/2348757 cicd-01
in Slack starts the Jenkins job and triggers the build for specific branch and sets docker image tag.
References
- Haahr, Mads. “True Random Number Service.” RANDOM.ORG – String Generator. Accessed August 09, 2019. https://www.random.org/strings/?source=post_page—————————.
- “EnvInject Plugin – Jenkins.” Jenkins Wiki. Accessed August 09, 2019. Plugin.
- “Pre-scm-buildstep – Jenkins.” Jenkins Wiki. Accessed August 09, 2019. https://wiki.jenkins.io/display/JENKINS/pre-scm-buildstep.
- Slack. “Slash Commands.” Slack. Accessed August 09, 2019. .
If you enjoyed this post, here are a few more that may interest you,