Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins : Sending success email only once a day (though the job is running @hourly)

I have a jenkins job configured to run hourly. I want the success build mail to be sent as email only once a day. Email-Ext gives me the option to send emails for all success , failures etc. But what i wanted is the ability to send success email only once.

like image 917
Rajesh Avatar asked Mar 02 '13 10:03

Rajesh


3 Answers

This is an old question and you have probably found your own workaround already, but I had a similar need and I thought I'd share my solution anyway. What I was trying to do was generate a once-daily summary email of jobs in a failed state. This is fundamentally very similar to sending a once-daily success report for a single job.

My solution uses a Groovy build step coupled with the Email-Ext plugin's pre-send script feature. I got the idea from the Nabble thread referenced in the comments above. See also Email-Ext Recipes on the Jenkins site.

Here's the initial groovy script that determines which builds are failed, configured under Execute System Groovy Script. You could do something similar to determine whether your build succeeded or failed:

// List the names of jobs you want to ignore for this check
ignore = [ ]

// Find all failed and unstable jobs
failed = hudson.model.Hudson.instance.getView("All").items.findAll{ job ->
  job.getDisplayName() != "Daily Jenkins Job Nag" &&
  !ignore.contains(job.getDisplayName()) &&
  job.isBuildable() &&
  job.lastCompletedBuild &&
  (job.lastCompletedBuild.result == hudson.model.Result.FAILURE ||
   job.lastCompletedBuild.result == hudson.model.Result.UNSTABLE)
}

// Log the job names so the build results are legible
failed.each { job ->
  println(job.getDisplayName() +
          " " + job.lastCompletedBuild.result +
          " at build " + job.lastCompletedBuild.number +
          " (" + job.lastCompletedBuild.timestamp.format("yyyy-MM-dd'T'HH:mm ZZZZ") + ")");
}

// Return failure if there are any failed jobs
return failed.size 

Then, down in the Editable Email Notification section, I set the Email-Ext plugin to notify on failure. I set Content Type to Plain Text (text/plain), left Default Content empty, and set the following as the Pre-send Script:

failed = hudson.model.Hudson.instance.getView("All").items.findAll{ job ->
  job.getDisplayName() != "Daily Jenkins Job Nag" &&
  job.isBuildable() &&
  job.lastCompletedBuild &&
  (job.lastCompletedBuild.result == hudson.model.Result.FAILURE ||
   job.lastCompletedBuild.result == hudson.model.Result.UNSTABLE)
}

def output = StringBuilder.newInstance()

output << "<html>\n"
output << " <body>\n"
output << "<p>Jenkins reports the following failed jobs:</p>"
output << "  <ul>\n"

failed.each { job ->
  url = hudson.model.Hudson.instance.rootUrl + job.url + "/" + job.lastCompletedBuild.number + "/"
  output << "   <li>"
  output << "<a href=\"" + url  + "\">" + job.displayName + "</a>"
  output << " " + job.lastCompletedBuild.result 
  output << " at build " + job.lastCompletedBuild.number
  output << " (" + job.lastCompletedBuild.timestamp.format("yyyy-MM-dd'T'HH:mm ZZZZ") + ")"
  output << "</li>\n"
}

output << "  </ul>\n"
output << " </body>\n"
output << "</html>"

msg.setContent(output.toString(), "text/html")

The key is that you have access to the msg object, which is a MimeMessage. You can set the content of the MIME message to whatever you want.

In this case, I'm generating a list of failed jobs, but in your case it would be whatever message you want to receive for your once-daily success report. Depending on what you need, you could have Email-Ext send a result for every build rather than just for failed builds.

like image 123
Ken Pronovici Avatar answered Oct 19 '22 05:10

Ken Pronovici


How about suppressing e-mails if insufficient time has lapsed since the previous e-mail? Although not precisely what was requested, a pre-send script like this might be worth considering for its simplicity?

if (build.result != hudson.model.Result.SUCCESS) {
    cancel = true;
}
else {
  try {
    long minEmailGap = 1000 * 60 * 60 * 16; // 16 hours in milliseconds

    File file = new File("/TimestampForMyJob.txt");

    if (file.exists() == false) {
      file.createNewFile();
    }
    else {
      long currentTime = (new Date()).getTime();

      if (file.lastModified() + minEmailGap > currentTime) {
        cancel = true;
      }
      else {
        file.setLastModified(currentTime);
      }
    }
  }
  catch(IOException e) {
    // We can't tell whether the e-mail should be sent out or not, so we do nothing
    // and it just gets sent anyway - probably the best we can do with this exception.
  }
}
like image 21
Antony Avatar answered Oct 19 '22 05:10

Antony


Well, there is no plugin that can do that for you. The default email feature in Jenkins is very simple and it works fine. There is Email-ext plugin though, and this one can do lot more for you.

First of all, with Email-ext, you can configure a specific trigger to send the email notification - it can be on success or failure, which is similar to the default behaviour of Jenkins. But then you have the more refined one, like First failure and Still failing. This will give you a great deal of control on when and to whom (Recipients list, Commiter or Requester) your Jenkins will send an email. In my case a good configuration here will help a lot with email traffic generated by Jenkins. And you can send specific emails in specific situation to specific list of people - great!

The other option, if you really do not need that level of control and want to just to limit the email traffic to one summary per day is to set up a mailing list. Most mailing list engines will let you send a daily digest of all email traffic to the list. It should be enough, although I really do not feel like it is actually a good option on the long term. I would definitely give a try to Email-ext plugin.

like image 2
Łukasz Rżanek Avatar answered Oct 19 '22 05:10

Łukasz Rżanek