blob: e8fa7bc2e9ff21a9dee7e3dfe2e7ed40f95e3f4c [file] [log] [blame]
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import logging
from webkitpy.w3c.local_wpt import LocalWPT
from webkitpy.w3c.common import exportable_commits_since
from webkitpy.w3c.wpt_github import WPTGitHub
_log = logging.getLogger(__name__)
class TestExporter(object):
def __init__(self, host, gh_user, gh_token, dry_run=False):
self.host = host
self.wpt_github = WPTGitHub(host, gh_user, gh_token)
self.dry_run = dry_run
self.local_wpt = LocalWPT(self.host, gh_token)
self.local_wpt.fetch()
def run(self):
"""Query in-flight pull requests, then merge PR or create one.
This script assumes it will be run on a regular interval. On
each invocation, it will either attempt to merge or attempt to
create a PR, never both.
"""
pull_requests = self.wpt_github.in_flight_pull_requests()
if len(pull_requests) == 1:
self.merge_in_flight_pull_request(pull_requests.pop())
elif len(pull_requests) > 1:
_log.error(pull_requests)
# TODO(jeffcarp): Print links to PRs
raise Exception('More than two in-flight PRs!')
else:
self.export_first_exportable_commit()
def merge_in_flight_pull_request(self, pull_request):
"""Attempt to merge an in-flight PR.
Args:
pull_request: a PR object returned from the GitHub API.
"""
_log.info('In-flight PR found: #%d', pull_request['number'])
_log.info(pull_request['title'])
# TODO(jeffcarp): Check the PR status here (for Travis CI, etc.)
if self.dry_run:
_log.info('[dry_run] Would have attempted to merge PR')
return
_log.info('Merging...')
self.wpt_github.merge_pull_request(pull_request['number'])
_log.info('PR merged! Deleting branch.')
self.wpt_github.delete_remote_branch('chromium-export-try')
_log.info('Branch deleted!')
def export_first_exportable_commit(self):
"""Looks for exportable commits in Chromium, creates PR if found."""
wpt_commit, chromium_commit = self.local_wpt.most_recent_chromium_commit()
assert chromium_commit, 'No Chromium commit found, this is impossible'
wpt_behind_master = self.local_wpt.commits_behind_master(wpt_commit)
_log.info('\nLast Chromium export commit in web-platform-tests:')
_log.info('web-platform-tests@%s', wpt_commit)
_log.info('(%d behind web-platform-tests@origin/master)', wpt_behind_master)
_log.info('\nThe above WPT commit points to the following Chromium commit:')
_log.info('chromium@%s', chromium_commit.sha)
_log.info('(%d behind chromium@origin/master)', chromium_commit.num_behind_master())
exportable_commits = exportable_commits_since(chromium_commit.sha, self.host, self.local_wpt)
if not exportable_commits:
_log.info('No exportable commits found in Chromium, stopping.')
return
_log.info('Found %d exportable commits in Chromium:', len(exportable_commits))
for commit in exportable_commits:
_log.info('- %s %s', commit, commit.subject())
outbound_commit = exportable_commits[0]
_log.info('Picking the earliest commit and creating a PR')
_log.info('- %s %s', outbound_commit.sha, outbound_commit.subject())
patch = outbound_commit.format_patch()
message = outbound_commit.message()
author = outbound_commit.author()
if self.dry_run:
_log.info('[dry_run] Stopping before creating PR')
_log.info('\n\n[dry_run] message:')
_log.info(message)
_log.info('\n\n[dry_run] patch:')
_log.info(patch)
return
remote_branch_name = self.local_wpt.create_branch_with_patch(message, patch, author)
response_data = self.wpt_github.create_pr(
remote_branch_name=remote_branch_name,
desc_title=outbound_commit.subject(),
body=outbound_commit.body())
_log.info('Create PR response: %s', response_data)
if response_data:
data, status_code = self.wpt_github.add_label(response_data['number'])
_log.info('Add label response (status %s): %s', status_code, data)