def test_recent_failing_chromium_exports_all_pages(self):
     self.wpt_github = WPTGitHub(MockHost(),
                                 user='******',
                                 token='decafbad',
                                 pr_history_window=1)
     self.wpt_github.host.web.responses = [
         {
             'status_code':
             200,
             'headers': {
                 'Link':
                 '<https://api.github.com/resources?page=2>; rel="next"'
             },
             'body':
             json.dumps({
                 'incomplete_results': False,
                 'items': [self.generate_pr_item(1)]
             })
         },
         {
             'status_code':
             200,
             'headers': {
                 'Link': ''
             },
             'body':
             json.dumps({
                 'incomplete_results': False,
                 'items': [self.generate_pr_item(2)]
             })
         },
     ]
     self.assertEqual(
         len(self.wpt_github.recent_failing_chromium_exports()), 2)
    def test_branch_check_runs_all_pages(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=1)
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200,
                'headers': {
                    'Link':
                    '<https://api.github.com/resources?page=2>; rel="next"'
                },
                'body': json.dumps({'check_runs': [{
                    'conclusion': 'success'
                }]})
            },
            {
                'status_code': 200,
                'headers': {
                    'Link': ''
                },
                'body': json.dumps({'check_runs': [{
                    'conclusion': 'failure'
                }]})
            },
        ]

        check_runs = self.wpt_github.get_branch_check_runs('1')
        self.assertEqual(check_runs[0]['conclusion'], 'success')
        self.assertEqual(check_runs[1]['conclusion'], 'failure')
 def test_constructor_throws_on_pr_history_window_too_large(self):
     with self.assertRaises(ValueError):
         self.wpt_github = WPTGitHub(
             MockHost(),
             user='******',
             token='decafbad',
             pr_history_window=MAX_PR_HISTORY_WINDOW + 1)
Exemple #4
0
 def test_all_pull_requests_throws_github_error_when_incomplete(self):
     self.wpt_github = WPTGitHub(MockHost(), user='******', token='decafbad', pr_history_window=1)
     self.wpt_github.host.web.responses = [
         {'status_code': 200,
          'body': json.dumps({'incomplete_results': True, 'items': [self.generate_pr_item(1)]})},
     ]
     with self.assertRaises(GitHubError):
         self.wpt_github.all_pull_requests()
Exemple #5
0
 def test_all_pull_requests_single_page(self):
     self.wpt_github = WPTGitHub(MockHost(), user='******', token='decafbad', pr_history_window=1)
     self.wpt_github.host.web.responses = [
         {'status_code': 200,
          'headers': {'Link': ''},
          'body': json.dumps({'incomplete_results': False, 'items': [self.generate_pr_item(1)]})},
     ]
     self.assertEqual(len(self.wpt_github.all_pull_requests()), 1)
Exemple #6
0
    def main(self, argv=None):
        """Creates PRs for in-flight CLs and merges changes that land on master.

        Returns:
            A boolean: True if success, False if there were any patch failures.
        """
        options = self.parse_args(argv)

        self.dry_run = options.dry_run
        log_level = logging.DEBUG if options.verbose else logging.INFO
        configure_logging(logging_level=log_level, include_time=True)
        if options.verbose:
            # Print out the full output when executive.run_command fails.
            self.host.executive.error_output_limit = None

        credentials = read_credentials(self.host, options.credentials_json)
        if not (credentials.get('GH_USER') and credentials.get('GH_TOKEN')):
            _log.error('You must provide your GitHub credentials for this '
                       'script to work.')
            _log.error('See https://chromium.googlesource.com/chromium/src'
                       '/+/master/docs/testing/web_platform_tests.md'
                       '#GitHub-credentials for instructions on how to set '
                       'your credentials up.')
            return False

        self.wpt_github = self.wpt_github or WPTGitHub(
            self.host, credentials['GH_USER'], credentials['GH_TOKEN'])
        self.gerrit = self.gerrit or GerritAPI(
            self.host, credentials['GERRIT_USER'], credentials['GERRIT_TOKEN'])
        self.local_wpt = self.local_wpt or LocalWPT(self.host,
                                                    credentials['GH_TOKEN'])
        self.local_wpt.fetch()

        _log.info('Searching for exportable in-flight CLs.')
        # The Gerrit search API is slow and easy to fail, so we wrap it in a try
        # statement to continue exporting landed commits when it fails.
        try:
            open_gerrit_cls = self.gerrit.query_exportable_open_cls()
        except GerritError as e:
            _log.info(
                'In-flight CLs cannot be exported due to the following error:')
            _log.error(str(e))
            gerrit_error = True
        else:
            self.process_gerrit_cls(open_gerrit_cls)
            gerrit_error = False

        _log.info('Searching for exportable Chromium commits.')
        exportable_commits, git_errors = self.get_exportable_commits()
        self.process_chromium_commits(exportable_commits)
        if git_errors:
            _log.info(
                'Attention: The following errors have prevented some commits from being '
                'exported:')
            for error in git_errors:
                _log.error(error)

        return not (gerrit_error or git_errors)
    def main(self, argv=None):
        """Closes all PRs that are abandoned in Gerrit."""
        options = self.parse_args(argv)
        log_level = logging.DEBUG if options.verbose else logging.INFO
        configure_logging(logging_level=log_level, include_time=True)
        credentials = read_credentials(self.host, options.credentials_json)
        gh_user = credentials.get('GH_USER')
        gh_token = credentials.get('GH_TOKEN')
        if not gh_user or not gh_token:
            _log.error('You have not set your GitHub credentials. This '
                       'script may fail with a network error when making '
                       'an API request to GitHub.')
            _log.error('See https://chromium.googlesource.com/chromium/src'
                       '/+/master/docs/testing/web_platform_tests.md'
                       '#GitHub-credentials for instructions on how to set '
                       'your credentials up.')
            return False

        gr_user = credentials['GERRIT_USER']
        gr_token = credentials['GERRIT_TOKEN']
        if not gr_user or not gr_token:
            _log.warning('You have not set your Gerrit credentials. This '
                         'script may fail with a network error when making '
                         'an API request to Gerrit.')

        self.wpt_github = self.wpt_github or WPTGitHub(self.host, gh_user,
                                                       gh_token)
        self.gerrit = self.gerrit or GerritAPI(self.host, gr_user, gr_token)
        pull_requests = self.retrieve_all_prs()
        for pull_request in pull_requests:
            if pull_request.state != 'open':
                continue
            change_id = self.wpt_github.extract_metadata(
                'Change-Id: ', pull_request.body)

            if not change_id:
                continue

            try:
                cl = self.gerrit.query_cl(change_id)
            except GerritError as e:
                _log.error('Could not query change_id %s: %s', change_id,
                           str(e))
                continue

            cl_status = cl.status
            if cl_status == 'ABANDONED':
                comment = 'Close this PR because the Chromium CL has been abandoned.'
                self.log_affected_pr_details(pull_request, comment)
                self.close_pr_and_delete_branch(pull_request.number, comment)
            elif cl_status == 'MERGED' and (not cl.is_exportable()):
                comment = 'Close this PR because the Chromium CL does not have exportable changes.'
                self.log_affected_pr_details(pull_request, comment)
                self.close_pr_and_delete_branch(pull_request.number, comment)

        return True
 def test_branch_check_runs_single_page(self):
     self.wpt_github = WPTGitHub(MockHost(),
                                 user='******',
                                 token='decafbad',
                                 pr_history_window=1)
     self.wpt_github.host.web.responses = [
         {
             'status_code': 200,
             'headers': {
                 'Link': ''
             },
             'body': json.dumps({'check_runs': [{
                 'conclusion': 'success'
             }]})
         },
     ]
     self.assertEqual(
         self.wpt_github.get_branch_check_runs('1')[0]['conclusion'],
         'success')
Exemple #9
0
    def main(self, argv=None):
        """Closes all PRs that are abandoned in Gerrit."""
        options = self.parse_args(argv)
        log_level = logging.DEBUG if options.verbose else logging.INFO
        configure_logging(logging_level=log_level, include_time=True)
        credentials = read_credentials(self.host, options.credentials_json)
        gh_user = credentials.get('GH_USER')
        gh_token = credentials.get('GH_TOKEN')
        if not gh_user or not gh_token:
            _log.error('You have not set your GitHub credentials. This '
                       'script may fail with a network error when making '
                       'an API request to GitHub.')
            _log.error('See https://chromium.googlesource.com/chromium/src'
                       '/+/master/docs/testing/web_platform_tests.md'
                       '#GitHub-credentials for instructions on how to set '
                       'your credentials up.')
            return False

        gr_user = credentials['GERRIT_USER']
        gr_token = credentials['GERRIT_TOKEN']
        if not gr_user or not gr_token:
            _log.warning('You have not set your Gerrit credentials. This '
                         'script may fail with a network error when making '
                         'an API request to Gerrit.')

        self.wpt_github = self.wpt_github or WPTGitHub(self.host, gh_user, gh_token)
        self.gerrit = self.gerrit or GerritAPI(self.host, gr_user, gr_token)
        pull_requests = self.retrieve_all_prs()
        for pull_request in pull_requests:
            if pull_request.state != 'open':
                continue
            change_id = self.wpt_github.extract_metadata('Change-Id: ', pull_request.body)
            if not change_id:
                continue
            cl_status = self.gerrit.query_cl(change_id).status
            if cl_status == 'ABANDONED':
                _log.info('https://github.com/web-platform-tests/wpt/pull/%s', pull_request.number)
                _log.info(self.wpt_github.extract_metadata('Reviewed-on: ', pull_request.body))
                self.close_abandoned_pr(pull_request)
        return True
 def extract_metadata(self, tag, commit_body, all_matches=False):
     return WPTGitHub.extract_metadata(tag, commit_body, all_matches)
 def setUp(self):
     self.wpt_github = WPTGitHub(MockHost(),
                                 user='******',
                                 token='decafbad')
class WPTGitHubTest(unittest.TestCase):
    def generate_pr_item(self, pr_number, state='closed'):
        return {
            'title': 'Foobar',
            'number': pr_number,
            'body': 'description',
            'state': state,
            'labels': [{
                'name': EXPORT_PR_LABEL
            }]
        }

    def setUp(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad')

    def test_init(self):
        self.assertEqual(self.wpt_github.user, 'rutabaga')
        self.assertEqual(self.wpt_github.token, 'decafbad')

    def test_constructor_throws_on_pr_history_window_too_large(self):
        with self.assertRaises(ValueError):
            self.wpt_github = WPTGitHub(
                MockHost(),
                user='******',
                token='decafbad',
                pr_history_window=MAX_PR_HISTORY_WINDOW + 1)

    def test_auth_token(self):
        self.assertEqual(self.wpt_github.auth_token(),
                         base64.encodestring('rutabaga:decafbad').strip())

    def test_extract_link_next(self):
        link_header = (
            '<https://api.github.com/user/repos?page=1&per_page=100>; rel="first", '
            '<https://api.github.com/user/repos?page=2&per_page=100>; rel="prev", '
            '<https://api.github.com/user/repos?page=4&per_page=100>; rel="next", '
            '<https://api.github.com/user/repos?page=50&per_page=100>; rel="last"'
        )
        self.assertEqual(self.wpt_github.extract_link_next(link_header),
                         '/user/repos?page=4&per_page=100')

    def test_extract_link_next_not_found(self):
        self.assertIsNone(self.wpt_github.extract_link_next(''))

    def test_recent_failing_chromium_exports_single_page(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=1)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'headers': {
                    'Link': ''
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(1)]
                })
            },
        ]

        self.assertEqual(
            len(self.wpt_github.recent_failing_chromium_exports()), 1)

    def test_recent_failing_chromium_exports_all_pages(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=1)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'headers': {
                    'Link':
                    '<https://api.github.com/resources?page=2>; rel="next"'
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(1)]
                })
            },
            {
                'status_code':
                200,
                'headers': {
                    'Link': ''
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(2)]
                })
            },
        ]
        self.assertEqual(
            len(self.wpt_github.recent_failing_chromium_exports()), 2)

    def test_recent_failing_chromium_exports_throws_github_error(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 204
            },
        ]
        with self.assertRaises(GitHubError):
            self.wpt_github.recent_failing_chromium_exports()

    def test_all_pull_requests_single_page(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=1)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'headers': {
                    'Link': ''
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(1)]
                })
            },
        ]
        self.assertEqual(len(self.wpt_github.all_pull_requests()), 1)

    def test_all_pull_requests_all_pages(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=2)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'headers': {
                    'Link':
                    '<https://api.github.com/resources?page=2>; rel="next"'
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(1)]
                })
            },
            {
                'status_code':
                200,
                'headers': {
                    'Link': ''
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(2)]
                })
            },
        ]
        self.assertEqual(len(self.wpt_github.all_pull_requests()), 2)

    def test_all_pull_requests_reaches_pr_history_window(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=2)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'headers': {
                    'Link':
                    '<https://api.github.com/resources?page=2>; rel="next"'
                },
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(1)]
                })
            },
            {
                'status_code':
                200,
                'headers': {
                    'Link': ''
                },
                'body':
                json.dumps({
                    'incomplete_results':
                    False,
                    'items':
                    [self.generate_pr_item(2),
                     self.generate_pr_item(3)]
                })
            },
        ]
        self.assertEqual(len(self.wpt_github.all_pull_requests()), 2)

    def test_all_pull_requests_throws_github_error_on_non_200(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 204
            },
        ]
        with self.assertRaises(GitHubError):
            self.wpt_github.all_pull_requests()

    def test_all_pull_requests_throws_github_error_when_incomplete(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=1)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'body':
                json.dumps({
                    'incomplete_results': True,
                    'items': [self.generate_pr_item(1)]
                })
            },
        ]
        with self.assertRaises(GitHubError):
            self.wpt_github.all_pull_requests()

    def test_all_pull_requests_throws_github_error_when_too_few_prs(self):
        self.wpt_github = WPTGitHub(MockHost(),
                                    user='******',
                                    token='decafbad',
                                    pr_history_window=2)
        self.wpt_github.host.web.responses = [
            {
                'status_code':
                200,
                'body':
                json.dumps({
                    'incomplete_results': False,
                    'items': [self.generate_pr_item(1)]
                })
            },
        ]
        with self.assertRaises(GitHubError):
            self.wpt_github.all_pull_requests()

    def test_create_pr_success(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 201,
                'body': json.dumps({'number': 1234})
            },
        ]
        self.assertEqual(self.wpt_github.create_pr('branch', 'title', 'body'),
                         1234)

    def test_create_pr_throws_github_error_on_non_201(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200
            },
        ]
        with self.assertRaises(GitHubError):
            self.wpt_github.create_pr('branch', 'title', 'body')

    def test_get_branch_statuses(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200,
                'body': json.dumps({'statuses': [{
                    'description': 'abc'
                }]})
            },
        ]
        self.assertEqual(
            self.wpt_github.get_branch_statuses('1234')[0]['description'],
            'abc')

    def test_get_pr_branch(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200,
                'body': json.dumps({'head': {
                    'ref': 'fake_branch'
                }})
            },
        ]
        self.assertEqual(self.wpt_github.get_pr_branch(1234), 'fake_branch')

    def test_is_pr_merged_receives_204(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 204
            },
        ]
        self.assertTrue(self.wpt_github.is_pr_merged(1234))

    def test_is_pr_merged_receives_404(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 404
            },
        ]
        self.assertFalse(self.wpt_github.is_pr_merged(1234))

    def test_merge_pr_success(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200
            },
        ]
        self.wpt_github.merge_pr(1234)

    def test_merge_pr_throws_merge_error_on_405(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 405
            },
        ]

        with self.assertRaises(MergeError):
            self.wpt_github.merge_pr(5678)

    def test_remove_label_throws_github_error_on_non_200_or_204(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 201
            },
        ]

        with self.assertRaises(GitHubError):
            self.wpt_github.remove_label(1234, 'rutabaga')

    def test_delete_remote_branch_throws_github_error_on_non_204(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200
            },
        ]

        with self.assertRaises(GitHubError):
            self.wpt_github.delete_remote_branch('rutabaga')

    def test_add_comment_throws_github_error_on_non_201(self):
        self.wpt_github.host.web.responses = [
            {
                'status_code': 200
            },
        ]

        with self.assertRaises(GitHubError):
            self.wpt_github.add_comment(123, 'rutabaga')

    def test_pr_for_chromium_commit_change_id_only(self):
        self.wpt_github.all_pull_requests = lambda: [
            PullRequest('PR1', 1, 'body\nChange-Id: I00c0ffee', 'open', []),
            PullRequest('PR2', 2, 'body\nChange-Id: I00decade', 'open', []),
        ]
        chromium_commit = MockChromiumCommit(
            MockHost(),
            change_id='I00decade',
            position='refs/heads/master@{#10}')
        pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit)
        self.assertEqual(pull_request.number, 2)

    def test_pr_for_chromium_commit_prefers_change_id(self):
        self.wpt_github.all_pull_requests = lambda: [
            PullRequest(
                'PR1', 1,
                'body\nChange-Id: I00c0ffee\nCr-Commit-Position: refs/heads/master@{#10}',
                'open', []),
            PullRequest(
                'PR2', 2,
                'body\nChange-Id: I00decade\nCr-Commit-Position: refs/heads/master@{#33}',
                'open', []),
        ]
        chromium_commit = MockChromiumCommit(
            MockHost(),
            change_id='I00decade',
            position='refs/heads/master@{#10}')
        pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit)
        self.assertEqual(pull_request.number, 2)

    def test_pr_for_chromium_commit_multiple_change_ids(self):
        self.wpt_github.all_pull_requests = lambda: [
            PullRequest('PR1', 1,
                        'body\nChange-Id: I00c0ffee\nChange-Id: I00decade',
                        'open', []),
        ]

        chromium_commit = MockChromiumCommit(
            MockHost(),
            change_id='I00c0ffee',
            position='refs/heads/master@{#10}')
        pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit)
        self.assertEqual(pull_request.number, 1)

        chromium_commit = MockChromiumCommit(
            MockHost(),
            change_id='I00decade',
            position='refs/heads/master@{#33}')
        pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit)
        self.assertEqual(pull_request.number, 1)
    def main(self, argv=None):
        # TODO(robertma): Test this method! Split it to make it easier to test
        # if necessary.

        options = self.parse_args(argv)

        self.verbose = options.verbose
        log_level = logging.DEBUG if self.verbose else logging.INFO
        configure_logging(logging_level=log_level, include_time=True)

        # Having the full output when executive.run_command fails is useful when
        # investigating a failed import, as all we have are logs.
        self.executive.error_output_limit = None

        if options.auto_update and options.auto_upload:
            _log.error(
                '--auto-upload and --auto-update cannot be used together.')
            return 1

        if not self.checkout_is_okay():
            return 1

        credentials = read_credentials(self.host, options.credentials_json)
        gh_user = credentials.get('GH_USER')
        gh_token = credentials.get('GH_TOKEN')
        if not gh_user or not gh_token:
            _log.warning('You have not set your GitHub credentials. This '
                         'script may fail with a network error when making '
                         'an API request to GitHub.')
            _log.warning('See https://chromium.googlesource.com/chromium/src'
                         '/+/master/docs/testing/web_platform_tests.md'
                         '#GitHub-credentials for instructions on how to set '
                         'your credentials up.')
        self.wpt_github = self.wpt_github or WPTGitHub(self.host, gh_user,
                                                       gh_token)
        self.git_cl = GitCL(
            self.host, auth_refresh_token_json=options.auth_refresh_token_json)

        _log.debug('Noting the current Chromium revision.')
        chromium_revision = self.chromium_git.latest_git_commit()

        # Instantiate Git after local_wpt.fetch() to make sure the path exists.
        local_wpt = LocalWPT(self.host, gh_token=gh_token)
        local_wpt.fetch()
        self.wpt_git = self.host.git(local_wpt.path)

        if options.revision is not None:
            _log.info('Checking out %s', options.revision)
            self.wpt_git.run(['checkout', options.revision])

        _log.debug('Noting the revision we are importing.')
        self.wpt_revision = self.wpt_git.latest_git_commit()
        self.last_wpt_revision = self._get_last_imported_wpt_revision()
        import_commit = 'wpt@%s' % self.wpt_revision

        _log.info('Importing %s to Chromium %s', import_commit,
                  chromium_revision)

        if options.ignore_exportable_commits:
            commit_message = self._commit_message(chromium_revision,
                                                  import_commit)
        else:
            commits = self.apply_exportable_commits_locally(local_wpt)
            if commits is None:
                _log.error('Could not apply some exportable commits cleanly.')
                _log.error('Aborting import to prevent clobbering commits.')
                return 1
            commit_message = self._commit_message(
                chromium_revision,
                import_commit,
                locally_applied_commits=commits)

        self._clear_out_dest_path()

        _log.info('Copying the tests from the temp repo to the destination.')
        test_copier = TestCopier(self.host, local_wpt.path)
        test_copier.do_import()

        # TODO(robertma): Implement `add --all` in Git (it is different from `commit --all`).
        self.chromium_git.run(['add', '--all', self.dest_path])

        # Remove expectations for tests that were deleted and rename tests
        # in expectations for renamed tests.
        self._expectations_updater.cleanup_test_expectations_files()

        self._generate_manifest()

        # TODO(crbug.com/800570 robertma): Re-enable it once we fix the bug.
        # self._delete_orphaned_baselines()


        if not self.chromium_git.has_working_directory_changes():
            _log.info('Done: no changes to import.')
            return 0

        if self._only_wpt_manifest_changed():
            _log.info('Only manifest was updated; skipping the import.')
            return 0

        self._commit_changes(commit_message)
        _log.info('Changes imported and committed.')

        if not options.auto_upload and not options.auto_update:
            return 0

        self._upload_cl()
        _log.info('Issue: %s', self.git_cl.run(['issue']).strip())

        if not self.update_expectations_for_cl():
            return 1

        if not options.auto_update:
            return 0

        if not self.run_commit_queue_for_cl():
            return 1

        if not self.send_notifications(local_wpt, options.auto_file_bugs,
                                       options.monorail_auth_json):
            return 1

        return 0