blob: 75df8bc2b2937837fcac77313757a54aaa0ef0a2 [file] [log] [blame]
[email protected]5f0788b2015-06-09 00:04:511#!/usr/bin/env python
2# Copyright (c) 2015 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Tool for interacting with Buildbucket.
7
8Usage:
9 $ depot-tools-auth login https://cr-buildbucket.appspot.com
10 $ buildbucket.py \
11 put \
12 --bucket master.tryserver.chromium.linux \
13 --builder my-builder \
14
15 Puts a build into buildbucket for my-builder on tryserver.chromium.linux.
16"""
17
18import argparse
19import json
20import urlparse
21import os
22import sys
23
24from third_party import httplib2
25
26import auth
27
28
29BUILDBUCKET_URL = 'https://cr-buildbucket.appspot.com'
[email protected]8e6e1e62015-08-07 21:52:1830BUILDBUCKET_API_URL = urlparse.urljoin(
[email protected]5f0788b2015-06-09 00:04:5131 BUILDBUCKET_URL,
32 '_ah/api/buildbucket/v1/builds',
33)
34
35
36def main(argv):
37 parser = argparse.ArgumentParser()
38 parser.add_argument(
39 '-v',
40 '--verbose',
41 action='store_true',
42 )
43 subparsers = parser.add_subparsers(dest='command')
[email protected]8e6e1e62015-08-07 21:52:1844 get_parser = subparsers.add_parser('get')
45 get_parser.add_argument(
46 '--id',
47 help='The ID of the build to get the status of.',
48 required=True,
49 )
[email protected]5f0788b2015-06-09 00:04:5150 put_parser = subparsers.add_parser('put')
51 put_parser.add_argument(
[email protected]1da6b032015-06-09 00:16:0352 '-b',
[email protected]5f0788b2015-06-09 00:04:5153 '--bucket',
54 help=(
55 'The bucket to schedule the build on. Typically the master name, e.g.'
56 ' master.tryserver.chromium.linux.'
57 ),
58 required=True,
59 )
60 put_parser.add_argument(
[email protected]c1ae89e2015-06-22 23:06:4461 '-c',
62 '--changes',
63 help='A flie to load a JSON list of changes dicts from.',
64 )
65 put_parser.add_argument(
[email protected]5f0788b2015-06-09 00:04:5166 '-n',
67 '--builder-name',
68 help='The builder to schedule the build on.',
69 required=True,
70 )
71 put_parser.add_argument(
72 '-p',
73 '--properties',
Sergiy Byelozyorovc3975e52018-07-09 22:30:0974 help=(
75 'A file to load a JSON dict of properties from. Use "-" to pipe JSON '
76 'from another command.'
77 ),
[email protected]5f0788b2015-06-09 00:04:5178 )
79 args = parser.parse_args()
[email protected]5f0788b2015-06-09 00:04:5180
[email protected]8e6e1e62015-08-07 21:52:1881 body = None
[email protected]c1ae89e2015-06-22 23:06:4482
[email protected]8e6e1e62015-08-07 21:52:1883 if args.command == 'get':
84 method = 'GET'
85 url = '%s/%s' % (BUILDBUCKET_API_URL, args.id)
86 elif args.command == 'put':
87 changes = []
88 if args.changes:
89 try:
90 with open(args.changes) as fp:
91 changes.extend(json.load(fp))
92 except (TypeError, ValueError):
93 sys.stderr.write('%s contained invalid JSON list.\n' % args.changes)
94 raise
95
96 properties = {}
97 if args.properties:
98 try:
Sergiy Byelozyorovc3975e52018-07-09 22:30:0999 # Allow using pipes to stream properties from another command, e.g.
100 # echo '{"foo": "bar", "baz": 42}' | buildbucket.py -p -
101 if args.properties == '-':
102 properties.update(json.load(sys.stdin))
103 else:
104 with open(args.properties) as fp:
105 properties.update(json.load(fp))
[email protected]8e6e1e62015-08-07 21:52:18106 except (TypeError, ValueError):
107 sys.stderr.write('%s contained invalid JSON dict.\n' % args.properties)
108 raise
109
110 body = json.dumps({
111 'bucket': args.bucket,
112 'parameters_json': json.dumps({
113 'builder_name': args.builder_name,
114 'changes': changes,
115 'properties': properties,
116 }),
117 })
118 method = 'PUT'
119 url = BUILDBUCKET_API_URL
[email protected]5f0788b2015-06-09 00:04:51120
121 authenticator = auth.get_authenticator_for_host(
122 BUILDBUCKET_URL,
123 auth.make_auth_config(use_oauth2=True),
124 )
125 http = authenticator.authorize(httplib2.Http())
126 http.force_exception_to_status_code = True
127 response, content = http.request(
[email protected]8e6e1e62015-08-07 21:52:18128 url,
129 method,
130 body=body,
[email protected]5f0788b2015-06-09 00:04:51131 headers={'Content-Type': 'application/json'},
132 )
133
134 if args.verbose:
135 print content
136
Michael Achenbach69f640e2018-09-19 07:01:38137 build_url = json.loads(content).get('build', {}).get('url')
Michael Achenbach0639cbc2018-09-18 11:33:14138 if build_url:
139 print 'Build triggered on: %s' % build_url
140
[email protected]5f0788b2015-06-09 00:04:51141 return response.status != 200
142
143
144if __name__ == '__main__':
145 sys.exit(main(sys.argv))