Grep Jenkins output and email user - jenkins

How do I grep the Jenkin's output and email the user if the word "Fail" shows up in the output? I want to use Jenkin's pipeline system.
I am running an ssh command using Jenkins. I want at the end of the job to grep the Jenkin's output and send an email to the admin if there are any failures (if the word "Fail" shows up in the output). How can I do that with Pipeline?

You can use the pipeline step httpRequest to send a http request to the build console url: BUILD_URL/consoleText
You can get the current BUILD_URL via global variable: currentBuild.absoluteUrl or env.BUILD_URL
pipeline {
agent any
stages {
stage('test') {
steps {
script {
def response = httpRequest([
// if your jenkins need login,
// add your jenkins account or a common accout
// to jenkins credentials, below authentication value is
// the credential Id
authentication: 'ba2e4f46-56f1-4467-ae97-17b356d7f854',
url: currentBuild.absoluteUrl + 'consoleText'])
if(response.status == 200) {
if(response.content =~ /Fail/) {
sh 'echo Build fail'
// add step to send mail
}
else {
sh 'echo Build successfully'
}
}
else {
echo 'Fail to fetch the build console log'
}
}
}
}
}
}

Related

Can't attach the allure report to the Jenkins email

The Allure report is not attaching to the Jenkins email. I am using the Jenkins pipeline script and this is my script however this is the error i get in my email:
Groovy Template file [allure-report.groovy] was not found in $JENKINS_HOME/email-templates.
Also I am not able to find allure-report.groovy in my computer
Here is my Jenkins pipeline, I am not sure how to include the template:
pipeline {
agent {
label {
label ""
customWorkspace "/john/qa-end-to-end"
}
}
tools {nodejs "node"}
stages {
stage('Checkout App') {
steps {
dir("${env.HOME}/app") {
echo "Building.."
sh 'git reset --hard HEAD'
sh 'git clean -f -d'
sh 'git pull'
}
}
}
stage('Starting Tests') {
steps {
echo "Starting End to End Tests"
dir("${env.HOME}/qa-end-to-end/") {
sh './tests.sh'
}
}
}
}
post('Publish Report') {
always {
script {
allure([
includeProperties: false,
jdk: '',
properties: [],
reportBuildPolicy: 'ALWAYS',
results: [[path: '$WORKSPACE/${env.HOME}/app/target/allure-results']]
])
}
}
failure {
emailext(
attachmentsPattern: "$WORKSPACE/${env.HOME}/qa-end-to-end/allure-report/index.html",
body: '''${SCRIPT, template="allure-report.groovy"}''',
subject: "Failure in End to End Tests -> Build Number: ${env.BUILD_NUMBER}",
from: "john#gmail.com",
to: "mike#gmail.com"
)
}
}
}
$JENKINS_HOME/email-templates is used to place email body template, generally when you install Jenkins plugin like email, it which includes some pre-defined templates and those templates will be extracted into $JENKINS_HOME/email-templates after plugin installed.
And when you use send email in job's Post Action, you can choose to use one of template of plugin and Jenkins will try to get the template from folder $JENKINS_HOME/email-templates
If you want to use self template, you need to put it into $JENKINS_HOME/email-templates too.
Using custom scripts (those not packaged with email-ext) requires the cooperation of your Jenkins administrator. The steps are relatively simple:
Create the script/template. The name of the script end in the standard extension for the language (.groovy). The template can be named anything
Have your Jenkins administrator place the script inside $JENKINS_HOME\email-templates.
Use the script token with the template parameter equal to your template filename, or in addition the script parameter equal to the custom script name. For example, if the template filename is foobar.template, the email content would look like this ${SCRIPT, template="foobar.template"}.
More detail

Notify slack user from Jenkins pipeline when build fails

I am sending slack notification to a channel from Jenkins pipeline, I have installed Jenkins slack plugin https://plugins.jenkins.io/slack and configured Jenkins slack app to send notification to the channel whenever the build fails or succeeds. Instead of sending just a failure message to slack channel I want to notify the user saying that the build failed.
eg: #user error in deploying following project
I referred this steps from jenkins slack plugin
def userIds = slackUserIdsFromCommitters()
def userIdsString = userIds.collect { "<#$it>" }.join(' ')
post {
// Send the build result to slack channel
success {
slackSend (color:'good', message: "<#$userIds>Successfully deployed")
}
failure {
slackSend (color:'danger', message: "<#$userIds>Error in build ${env.JOB_NAME}")
}
}
I am getting null value for $userIds variable.
If it is still relevant for someone, I did so:
........
}
post {
always {
script {
env.GIT_COMMIT_MSG = sh (script: 'git log -1 --pretty=%B ${GIT_COMMIT} | head -n1', returnStdout: true).stripIndent().trim()
env.GIT_AUTHOR = sh (script: 'git log -1 --pretty=%ae ${GIT_COMMIT} | awk -F "#" \'{print $1}\' | grep -Po "[a-z]{1,}" | head -n1', returnStdout: true).trim()
slackSend(
color: color_slack_msg(),
message: """
*${currentBuild.currentResult}:* Job `${env.JOB_NAME}` build `${env.BUILD_DISPLAY_NAME}` by <#${env.GIT_AUTHOR}>
Build commit: ${GIT_COMMIT}
Last commit message: '${env.GIT_COMMIT_MSG}'
More info at: ${env.BUILD_URL}
Time: ${currentBuild.durationString.minus(' and counting')}
""".stripIndent().trim(),
channel: 'slack-channel',
tokenCredentialId: 'SlackToken'
)
}
cleanWs()
}
}
}
def color_slack_msg() {
switch(currentBuild.currentResult) {
case "SUCCESS":
return "good"
break
case "FAILURE":
case "UNSTABLE":
return "danger"
break
default:
return "warning"
break
}
}
this will work if mail = login in slack
This feature is only available for a bot user in slack, not for a Jenkins bot app.
The bot user which you create should have access to read and write message to the channel.

How to read log file from within pipeline?

I have a pipeline job that runs a maven build. In the "post" section of the pipeline, I want to get the log file so that I can perform some failure analysis on it using some regexes. I have tried the following:
def logContent = Jenkins.getInstance()
.getItemByFullName(JOB_NAME)
.getBuildByNumber(
Integer.parseInt(BUILD_NUMBER))
.logFile.text
Error for the above code
Scripts not permitted to use staticMethod jenkins.model.Jenkins
getInstance
currentBuild.rawBuild.getLogFile()
Error for the above code
Scripts not permitted to use method hudson.model.Run getLogFile
From my research, when I encounter these, I should be able to go to the scriptApproval page and see a prompt to approve these scripts, but when I go to that page, there are no new prompts.
I've also tried loading the script in from a separate file and running it on a different node with no luck.
I'm not sure what else to try at this point, so that's why I'm here. Any help is greatly appreciated.
P.S. I'm aware of the BFA tool, and I've tried manually triggering the analysis early, but in order to do that, I need to be able to access the log file, so I run into the same issue.
You can use pipeline step httpRequest from here
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Test fetch build log'
}
post {
always {
script {
def logUrl = env.BUILD_URL + 'consoleText'
def response = httpRequest(
url: logUrl,
authentication: '<credentialsId of jenkins user>',
ignoreSslErrors: true
)
def log = response.content
echo 'Build log: ' + log
}
}
}
}
}
}
If your jenkins job can run on linux machine, you can use curl to archive same goal.
pipeline {
agent any
stages {
stage('Build') {
environment {
JENKINS_AUTH = credentials('< credentialsId of jenkins user')
}
steps {
sh 'pwd'
}
post {
always {
script {
def logUrl = env.BUILD_URL + 'consoleText'
def cmd = 'curl -u ${JENKINS_AUTH} -k ' + logUrl
def log = sh(returnStdout: true, script: cmd).trim()
echo 'Build log: ' +
echo log
}
}
}
}
}
}
Above two approaches both require the credentials is Username and password format. More detail about what is it and how to add in Jenkins, please look at here
Currently this is not possible via the RunWrapper object that is made available. See https://issues.jenkins.io/browse/JENKINS-46376 for a request to add this.
So the only options are:
explicitly whitelisting the methods
read the log via the URL as described in the other answer, but this requires either anonymous read access or using proper credentials.

How do i suppress shell command output in jenkins pipeline stage view?

I'm running a series of jenkins pipeline commands. I can't seem to suppress a sensitive command from both the console logs and the jenkins stage Let's assume my jenkinsfile is something like this:
def silentShell(java.lang.String cmd) {
sh('#!/bin/sh -e\n' + cmd)
}
pipeline {
agent any
stages {
stage('Write Secret Thing') {
steps {
silentShell 'echo "password here" > secretfile.txt'
}
}
}
}
The silentShell function successfully hides it from the console log output, but not from the stage view on the main build job page. Is there a way to do so?
This is the bit I mean (non-redacted snippet from my testing):

How to restrict the users that can run jenkinsfile tests in pull requests?

I have deployed the pipeline-as-code docker demo with multibranch.
It works alright. I added my github username as the organization and when I make a pull request, the tests are run.
However, when some other user makes a pull request, their tests are also run. I would like to manually approve which pull requests from external contributors are good to run in my jenkins server. Is there a way to do that?
I can do it with ghprb, but it is not compatible with pipelines, and I want to migrate my jobs to pipelines.
please try adding these lines in your pipeline script:
node('slaveName') {
properties([
parameters([
string(
defaultValue: 'whitelisted1#gmail.com,whitelisted2#gmail.com',
description: 'comma separated whitelisted emails',
name: 'WHITELIST'
)
])
])
def authorEmail
stage('Git') {
authorEmail = sh([
// git log format docs here: https://git-scm.com/docs/pretty-formats
script : "git log -1 --format='%aE'",
returnStdout: true
]).trim()
boolean allowRun = isWhitelisted(env.WHITELIST, authorEmail)
if (allowRun) {
echo "email ${authorEmail} is whitelisted, proceed execution"
} else {
echo "email ${authorEmail} is not in whitelist ${env.WHITELIST}, proceed jenkins job?"
input message: 'Proceed?'
// or just abort build with non-zero shell exit
// currentBuild.result = 'FAILURE'
// sh "exit 10"
}
}
}
}
#NonCPS
boolean isWhitelisted(whitelist, email) {
def res = whitelist.tokenize(" ,;").find { white -> white == email }
return null != res
}

Resources