-
Notifications
You must be signed in to change notification settings - Fork 6
Send notifications to Slack
A good practice in DevOps is to integrate your tools with each other. In our case, one step can be to integrate Jenkins with Slack and have your builds sending notifications to Slack. The notification could contain the build progress and its final status: passed or failed.
Slack Notification is the plugin you'll have to install. Here you can find the steps to install a Jenkins plugin.
Before start using the plugin, we need to do some Slack configurations:
- create a Slack channel (eg. jenkins-pipeline-workshop)
- go to
Customize Slack
- go to
Configure Apps
->Apps
- select
Jenkins CI
app - click
Add to Slack
- choose the newly created channel and click
Add Jenkins CI integration
- copy the generated token
You'll have to use the generated token when configuring the Slack Notification
plugin. From security point of view, it's not a good idea to specify the token as clear text. The recommended approach is to use store it using the Jenkins credentials
and refer to that credential when configuring the plugin. Here you can find how to create Jenkins credentials
.
Let's configure the Slack notification
plugin:
- go to
Jenkins
->Manage Jenkins
->Configure System
- go to ->
Slack
section - complete your Slack workspace
- select the previously created
Slack integration
credential - test the connection
- if success, save the configuration
You send have each one of the stages you configured in the Jenkins pipeline sending notifications to slack. This will keep track of the build progress.
Most probably, your Build
stage currently looks like this:
stage('Build') {
steps {
withMaven(maven: MAVEN_INSTALLATION, mavenSettingsConfig: MAVEN_SETTINGS_CONFIG) {
sh 'mvn -DskipTests clean package'
}
}
}
You'll have to call the slackSend
method to whenever you want to send a notification to Slack. You can pass the message as parameter, but also some additional details, such as a color for that message. This is a valid code to fulfil this purpose.
slackSend message: 'Build stage', color: '#0000ff'
However, in most cases, you'll want to send more details in the notification, such as the build number, the job name, the branch for which the build was executed, the failure reason etc.
The available Jenkins environment variables can cover most of these details. If you want to have a look at all available environment variable, just add the following line in one of the stages from the Jenkins pipeline:
sh 'printenv'
One example of more detailed notification for your Build
stage could be the following code snippet. Notice that you'll have to use the script
directive because there is a variable defined inside it.
stage('Build') {
steps {
withMaven(maven: MAVEN_INSTALLATION, mavenSettingsConfig: MAVEN_SETTINGS_CONFIG) {
sh 'mvn -DskipTests clean package'
}
script {
statusComment = "[${env.JOB_NAME}] <${env.BUILD_URL}|#${env.BUILD_NUMBER}> ${env.STAGE_NAME} stage completed succesfully for ${env.GIT_BRANCH}"
slackSend message: statusComment, color: '#0000ff'
}
}
}
You can use exactly the same script
directive and it's content for the Test
stage.
Because Deploy
is an interactive stage you would like to know who was that approved or not the stage. To do this, you'll have to change a bit the way you use the input
step and specify a value for submitterParameter
. This way after someone approves or declines the inout step, the submitter name will be filled into the specified value for submitterParameter
.
The Deploy
stage will look like this:
stage('Deploy') {
input{
message 'Do you want to deploy?'
submitterParameter 'responder'
}
steps {
echo "Deploying application..."
script {
statusComment = "[${env.JOB_NAME}] <${env.BUILD_URL}|#${env.BUILD_NUMBER}> ${env.STAGE_NAME} stage was approved by ${responder} for ${env.GIT_BRANCH}"
slackSend color: '#0000ff', message: statusComment
}
}
}
If you want to notify Slack when the build ended, you can rely on post
section. It has blocks for all possible reasons why a build can end. For example, you can have the following clock next to all the defined stages in the Jenkins pipeline. Have a look here for more details.
post {
success {
...
}
failure {
...
}
aborted {
...
}
...
}
Let's suppose we want to send a notification when the build ended successfully. The syntax is pretty straight-forward based on what we know already:
success {
script {
statusComment = "[${env.JOB_NAME}] <${env.BUILD_URL}|#${env.BUILD_NUMBER}> completed succesfully for ${env.GIT_BRANCH} :tada:"
slackSend color: 'good', message: statusComment
}
}
If someone declines to proceed with the interactive Deploy
stage, the build will be marked as aborted. You would like to know who was that approved or not the stage. To do this, you'll define a Groovy function in your Jenkinsfile
. Pay attention to put your new function outside the pipeline
definition.
String getBuildUser() {
return currentBuild.rawBuild.getCause(Cause.UserIdCause).getUserId()
}
aborted {
script {
statusComment = "[${env.JOB_NAME}] <${env.BUILD_URL}|#${env.BUILD_NUMBER}> for ${env.GIT_BRANCH} was aborted by ${getBuildUser()}"
slackSend message: statusComment
}
}
The build can fail because of various reasons, but most probably it will fail because of some failing tests. In this case, it would be useful for the notification to contain how many tests failed ad made the build to fail as well. This information can be retrieved by defining a new Groovy function:
String getTestResultsMessage() {
AbstractTestResultAction testResultAction = currentBuild.rawBuild.getAction(AbstractTestResultAction.class)
if (testResultAction != null) {
def total = testResultAction.totalCount
def failed = testResultAction.failCount
def skipped = testResultAction.skipCount
return "[${env.JOB_NAME}] <${env.BUILD_URL}|#${env.BUILD_NUMBER}> had test failures for ${env.GIT_BRANCH}.\n Total: ${total}, Failed: ${failed}, Skipped: ${skipped}"
} else {
return "[${env.JOB_NAME}] <${env.BUILD_URL}|#${env.BUILD_NUMBER}> failed for ${env.GIT_BRANCH}"
}
}
You can now use the result of this function in the snippet below:
failure {
script {
statusComment = getTestResultsMessage()
slackSend color: 'danger', message: statusComment
}
}
If everything went well and the build ended successfully, the generated notifications will look like this:
If you have at least 1 test failing, the generated notifications will look like this:
You can have a look here to see the final form of the Jenkinsfile.