Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(35)

Unified Diff: git_cl.py

Issue 1063103002: git cl try uses buildbucket via OAuth2 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: fix Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | third_party/google_api_python_client/apiclient/__init__.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: git_cl.py
diff --git a/git_cl.py b/git_cl.py
index d4486e5b10abd24e0667f0b6509695950029660d..8bbb303e9033a1a857f6682c4052a5d8f104cfca 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -11,6 +11,7 @@ from distutils.version import LooseVersion
from multiprocessing.pool import ThreadPool
import base64
import glob
+import httplib
import json
import logging
import optparse
@@ -21,6 +22,8 @@ import stat
import sys
import tempfile
import textwrap
+import time
+import traceback
import urllib2
import urlparse
import webbrowser
@@ -31,9 +34,15 @@ try:
except ImportError:
pass
-
from third_party import colorama
+from third_party import httplib2
from third_party import upload
+
+ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
+sys.path.insert(
+ 0, os.path.join(ROOT_DIR, 'third_party', 'google_api_python_client'))
+
+import apiclient
import auth
import breakpad # pylint: disable=W0611
import clang_format
@@ -62,6 +71,12 @@ REFS_THAT_ALIAS_TO_OTHER_REFS = {
'refs/remotes/origin/lkcr': 'refs/remotes/origin/master',
}
+# Buildbucket-related constants
+DISCOVERY_URL = (
+ 'https://cr-buildbucket.appspot.com/_ah/api/discovery/v1/apis/'
+ '{api}/{apiVersion}/rest')
nodir 2015/04/14 16:12:48 Rename to BUILDBUCKET_DISCOVERY_URL
sheyang 2015/04/14 17:29:57 Done.
+BUILDSET_STR = 'patch/rietveld/{hostname}/{issue}/{patch}'
+
# Valid extensions for files we want to lint.
DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
DEFAULT_LINT_IGNORE_REGEX = r"$^"
@@ -202,6 +217,92 @@ def add_git_similarity(parser):
parser.parse_args = Parse
+def _prefix_master(master):
+ prefix = 'master.'
+ if master.startswith(prefix):
+ return master
+ else:
+ return '%s%s' % (prefix, master)
+
+
+def _get_buildbucket(rietveld_host, auth_config):
+ authenticator = auth.get_authenticator_for_host(rietveld_host, auth_config)
+ http = httplib2.Http()
+ return apiclient.discovery.build(
+ 'buildbucket', 'v1',
+ http=authenticator.authorize(http),
+ discoveryServiceUrl=DISCOVERY_URL,
+ )
+
+
+def trigger_distributed_try_jobs(
+ auth_config, changelist, options, masters, category):
+ rietveld_host = urlparse.urlparse(changelist.GetRietveldServer()).hostname
nodir 2015/04/14 16:12:48 We will need to make sure that all branches on all
sheyang 2015/04/14 17:29:57 As a fallback, rietveld_server will be fetched fro
+ buildbucket = _get_buildbucket(rietveld_host, auth_config)
+ issue_props = changelist.GetIssueProperties()
+ issue = changelist.GetIssue()
+ patchset = changelist.GetMostRecentPatchset()
+ buildset = BUILDSET_STR.format(
+ hostname=rietveld_host,
+ issue=str(issue),
+ patch=str(patchset))
nodir 2015/04/14 16:12:48 You don't need str calls here
sheyang 2015/04/14 17:29:57 Done.
+ print 'Tried jobs on:'
nodir 2015/04/14 16:12:48 "Trying", as they were not tried yet
sheyang 2015/04/14 17:29:57 This is from the old code... Updated.
+ for (master, builders_and_tests) in masters.iteritems():
nodir 2015/04/14 16:12:48 Parens are unnecessary
sheyang 2015/04/14 17:29:57 Done.
+ print 'Master: %s' % master
+ bucket = _prefix_master(master)
+ for builder, tests in builders_and_tests.iteritems():
+ req = buildbucket.put(body={
nodir 2015/04/14 16:12:48 In https://codereview.chromium.org/1058893004/ esp
sheyang 2015/04/14 17:29:57 Acknowledged.
+ 'bucket': bucket,
+ 'parameters_json': json.dumps({
+ 'builder_name': builder,
+ 'changes':[
+ {'author': {'email': issue_props['owner_email']}},
+ ],
+ 'properties': {
+ 'category': category,
+ 'clobber': options.clobber,
+ 'issue': issue,
+ 'master': master,
+ 'patch_project': issue_props['project'],
+ 'patch_storage': 'rietveld',
+ 'patchset': patchset,
+ 'reason': options.name,
+ 'revision': options.revision,
+ 'rietveld': changelist.GetRietveldServer(),
nodir 2015/04/14 16:12:48 why not rietveld_host ?
sheyang 2015/04/14 17:29:57 I think it needs 'https' prefix... adding rietveld
+ 'testfilter': tests,
+ },
+ }),
+ 'tags': ['buildset:%s' % buildset,
+ 'master:%s' % master,
+ 'builder:%s' % builder,
+ 'user_agent:git-cl-try']
+ })
+ wait = 1
+ try_count = 3
+ while try_count > 0:
+ try:
+ try_count -= 1
+ response = req.execute()
+ if response.get('error'):
+ msg = 'Error in response. Reason: %s. Message: %s.' % (
+ response['error'].get('reason', ''),
+ response['error'].get('message', ''))
+ raise BuildbucketResponseException(msg)
+ break
+ except apiclient.errors.HttpError as ex:
+ status = ex.resp.status if ex.resp else None
+ if status >= 500:
nodir 2015/04/14 16:12:48 Inverse this condition so you can unindent the ">=
sheyang 2015/04/14 17:29:57 Done.
sheyang 2015/04/14 17:29:57 Done.
+ logging.debug('Transient errors when triggering tryjobs. '
+ 'Will retry in %d seconds.', wait)
+ time.sleep(wait)
+ wait *= 2
+ if try_count <= 0:
+ raise
nodir 2015/04/14 16:12:48 Move these two lines before logging about transien
sheyang 2015/04/14 17:29:57 Done.
sheyang 2015/04/14 17:29:57 Done.
+ else:
+ raise
+ print ' %s: %s' % (builder, tests)
+
+
def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards):
"""Return the corresponding git ref if |base_url| together with |glob_spec|
matches the full |url|.
@@ -269,6 +370,10 @@ def print_stats(similarity, find_copies, args):
stdout=stdout, env=env)
+class BuildbucketResponseException(Exception):
+ pass
+
+
class Settings(object):
def __init__(self):
self.default_server = None
@@ -2860,22 +2965,23 @@ def CMDtry(parser, args):
'upload fail?\ngit-cl try always uses latest patchset from rietveld. '
'Continuing using\npatchset %s.\n' % patchset)
try:
- cl.RpcServer().trigger_distributed_try_jobs(
- cl.GetIssue(), patchset, options.name, options.clobber,
- options.revision, masters)
- except urllib2.HTTPError, e:
- if e.code == 404:
- print('404 from rietveld; '
- 'did you mean to use "git try" instead of "git cl try"?')
- return 1
- print('Tried jobs on:')
-
- for (master, builders) in masters.iteritems():
- if master:
- print 'Master: %s' % master
- length = max(len(builder) for builder in builders)
- for builder in sorted(builders):
- print ' %*s: %s' % (length, builder, ','.join(builders[builder]))
+ trigger_distributed_try_jobs(
+ auth_config, cl, options, masters, 'git cl try')
+ except apiclient.errors.HttpError as ex:
+ status = ex.resp.status if ex.resp else None
+ if status == httplib.FORBIDDEN:
+ print 'ERROR: Access denied. Please verify you have tryjob access.'
+ else:
+ print 'ERROR: Tryjob request failed: %s.' % ex
+ return 1
+ except BuildbucketResponseException as ex:
+ print ex
+ return 1
+ except Exception as e:
+ stacktrace = (''.join(traceback.format_stack()) + traceback.format_exc())
+ print 'ERROR: unexpected error when trying to trigger tryjobs: %s\n%s' % (
+ e, stacktrace)
nodir 2015/04/14 16:12:48 doesn't logging.exception do the same with current
sheyang 2015/04/14 17:29:57 logging.exception only has traceback.format_exc().
+ return 1
return 0
« no previous file with comments | « no previous file | third_party/google_api_python_client/apiclient/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698