3 A script for reporting the results of an invirtibuild. Supports any
4 combination of the following reporting mechanisms.
6 Note that all strings are interpolated with a dictionary containing
9 build_id, commit, failed_stage, inserted_at, package,
10 pocket, principal, result, short_commit, traceback, version
14 To configure zephyr, add something like the following to your invirt config:
19 zephyr: &post_build_zepyhr
20 class: myclass [required]
21 instance: myinstance [optional]
22 zsig: myzsig [optional]
24 zephyr: *post_build_zephyr
28 To configure email notifications, add something like the following to your invirt config:
33 mail: &post_build_mail
34 to: myemail@example.com [required]
35 from: myemail@example.com [required]
36 subject: My Subject [optional]
38 mail: *post_build_mail
40 post_build values will be used when this script is invoked as
41 post-build, while failed_build values will be used when it is invoked
51 from email.mime import text
53 from invirt import common, database, builder
54 from invirt.config import structs as config
56 def make_msg(build, values, verbose=True, success=lambda x: x, failure=lambda x: x):
58 if not verbose and values['traceback'] is not None:
59 values['traceback'] = textwrap.fill('\n'.join(values['traceback'].split('\n')[-2:]))
62 values['result'] = success(values['result'])
63 msg = """Build of %(package)s v%(version)s in %(pocket)s %(result)s.
65 Branch %(pocket)s has been advanced to %(short_commit)s.
67 (Build %(build_id)s was submitted by %(principal)s at %(inserted_at)s.)""" % values
69 values['result'] = failure(values['result'])
70 msg = """Build of %(package)s v%(version)s in %(pocket)s %(result)s while %(failed_stage)s.
74 (Build %(build_id)s was submitted by %(principal)s at %(inserted_at)s.)""" % values
78 m = re.sub('@', '@@', m)
79 m = re.sub('}', '@(})', m)
82 def zephyr_success(m):
83 return '}@{@color(green)%s}@{' % zephyr_escape(m)
85 def zephyr_failure(m):
86 return '}@{@color(red)%s}@{' % zephyr_escape(m)
89 parser = optparse.OptionParser('Usage: %prog build_id')
90 opts, args = parser.parse_args()
94 prog = os.path.basename(sys.argv[0])
97 build = database.Build.query().get(args[0])
98 short_commit = builder.canonicalize_commit(build.package, build.commit, shorten=True)
99 values = { 'build_id' : build.build_id,
100 'commit' : build.commit,
101 'failed_stage' : build.failed_stage,
102 'inserted_at' : build.inserted_at,
103 'package' : build.package,
104 'pocket' : build.pocket,
105 'principal' : build.principal,
106 'short_commit' : short_commit,
107 'traceback' : build.traceback,
108 'version' : build.version }
110 values['result'] = 'succeeded'
112 values['result'] = 'failed'
115 if prog == 'post-build':
116 hook_config = config.build.hooks.post_build
117 elif prog == 'failed-build':
118 hook_config = config.build.hooks.failed_build
120 print >>sys.stderr, '{post,failed}-build invoke with unrecognized name %s' % prog
122 except common.InvirtConfigError:
123 print >>sys.stderr, 'No hook configuration found for %s.' % prog
127 zephyr_config = hook_config.zephyr
128 klass = zephyr_config['class'] % values
129 except common.InvirtConfigError:
130 print >>sys.stderr, 'No zephyr configuration specified for %s.' % prog
132 msg = '@{%s}' % make_msg(build, values, verbose=False,
133 success=zephyr_success, failure=zephyr_failure)
134 instance = zephyr_config.get('instance', 'build_%(build_id)s') % values
135 zsig = zephyr_config.get('zsig', 'XVM Buildbot') % values
136 common.captureOutput(['zwrite', '-c', klass, '-i', instance, '-s',
137 zsig, '-d', '-m', msg],
138 stdout=None, stderr=None)
141 mail_config = hook_config.mail
142 to = mail_config.to % values
143 sender = mail_config['from'] % values
144 except common.InvirtConfigError:
145 print >>sys.stderr, 'No email configuration specified for %s.' % prog
147 msg = make_msg(build, values)
148 email = text.MIMEText(msg)
149 email['To'] = to % values
150 email['From'] = sender % values
151 email['Subject'] = mail_config.get('subject', 'XVM build %(build_id)s has %(result)s') % values
152 common.captureOutput(['sendmail', '-t'], email.as_string(),
153 stdout=None, stderr=None)
155 if __name__ == '__main__':