1
0
mirror of https://github.com/golang/go synced 2024-11-22 00:54:43 -07:00

dashboard: send notification emails when the build breaks

R=bradfitz, rsc
CC=golang-dev
https://golang.org/cl/4530061
This commit is contained in:
Andrew Gerrand 2011-05-30 11:27:31 +10:00
parent 55dd63bb4e
commit 5784dcfd19
2 changed files with 86 additions and 7 deletions

View File

@ -1,5 +1,5 @@
application: godashboard application: godashboard
version: 6 version: 7
runtime: python runtime: python
api_version: 1 api_version: 1

View File

@ -12,15 +12,12 @@ from google.appengine.ext import db
from google.appengine.ext import webapp from google.appengine.ext import webapp
from google.appengine.ext.webapp import template from google.appengine.ext.webapp import template
from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext.webapp.util import run_wsgi_app
import binascii
import datetime import datetime
import hashlib import hashlib
import hmac import hmac
import logging import logging
import os import os
import re import re
import struct
import time
import bz2 import bz2
# local imports # local imports
@ -346,16 +343,98 @@ class Build(webapp.RequestHandler):
key = 'todo-%s' % builder key = 'todo-%s' % builder
memcache.delete(key) memcache.delete(key)
# TODO: Send mail for build breakage. c = getBrokenCommit(node, builder)
if c is not None and not c.fail_notification_sent:
notifyBroken(c, builder)
self.response.set_status(200) self.response.set_status(200)
def failed(c, builder):
def getBrokenCommit(node, builder):
"""
getBrokenCommit returns a Commit that breaks the build.
The Commit will be either the one specified by node or the one after.
"""
# Squelch mail if already fixed.
head = firstResult(builder)
if broken(head, builder) == False:
return
# Get current node and node before, after.
cur = nodeByHash(node)
if cur is None:
return
before = nodeBefore(cur)
after = nodeAfter(cur)
if broken(before, builder) == False and broken(cur, builder):
return cur
if broken(cur, builder) == False and broken(after, builder):
return after
return
def firstResult(builder):
q = Commit.all().order('-__key__').limit(20)
for c in q:
for i, b in enumerate(c.builds):
p = b.split('`', 1)
if p[0] == builder:
return c
return None
def nodeBefore(c):
return nodeByHash(c.parentnode)
def nodeAfter(c):
return Commit.all().filter('parenthash', c.node).get()
def notifyBroken(c, builder):
def send():
n = Commit.get_by_key_name('%08x-%s' % (c.num, c.node))
if n.fail_notification_sent:
return False
n.fail_notification_sent = True
return n.put()
if not db.run_in_transaction(send):
return
subject = const.mail_fail_subject % (builder, c.desc.split('\n')[0])
path = os.path.join(os.path.dirname(__file__), 'fail-notify.txt')
body = template.render(path, {
"builder": builder,
"node": c.node,
"user": c.user,
"desc": c.desc,
"loghash": logHash(c, builder)
})
mail.send_mail(
sender=const.mail_from,
to=const.mail_fail_to,
subject=subject,
body=body
)
def logHash(c, builder):
for i, b in enumerate(c.builds):
p = b.split('`', 1)
if p[0] == builder:
return p[1]
return ""
def broken(c, builder):
"""
broken returns True if commit c breaks the build for the specified builder,
False if it is a good build, and None if no results exist for this builder.
"""
if c is None:
return None
for i, b in enumerate(c.builds): for i, b in enumerate(c.builds):
p = b.split('`', 1) p = b.split('`', 1)
if p[0] == builder: if p[0] == builder:
return len(p[1]) > 0 return len(p[1]) > 0
return False return None
def node(num): def node(num):
q = Commit.all() q = Commit.all()