|  | #!/usr/bin/env python3 | 
|  | # Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file | 
|  | # for details. All rights reserved. Use of this source code is governed by a | 
|  | # BSD-style license that can be found in the LICENSE file. | 
|  |  | 
|  | # Convenience script for triggering bots on specific commits. | 
|  |  | 
|  | import json | 
|  | import git_utils | 
|  | import optparse | 
|  | import os | 
|  | import re | 
|  | import subprocess | 
|  | import sys | 
|  | import urllib | 
|  | from urllib.request import urlopen | 
|  | import utils | 
|  |  | 
|  | LUCI_SCHEDULE = os.path.join(utils.REPO_ROOT, 'infra', 'config', 'global', | 
|  | 'generated', 'luci-scheduler.cfg') | 
|  | # Trigger lines have the format: | 
|  | #   triggers: "BUILDER_NAME" | 
|  | TRIGGERS_RE = r'^  triggers: "(\w.*)"' | 
|  |  | 
|  | DESUGAR_JDK11_BOT = 'lib_desugar-archive-jdk11' | 
|  | DESUGAR_JDK11_LEGACY_BOT = 'lib_desugar-archive-jdk11-legacy' | 
|  | DESUGAR_JDK8_BOT = 'lib_desugar-archive-jdk8' | 
|  | SMALI_BOT = 'smali' | 
|  |  | 
|  |  | 
|  | def ParseOptions(): | 
|  | result = optparse.OptionParser() | 
|  | result.add_option('--release', | 
|  | help='Run on the release branch builders.', | 
|  | default=False, | 
|  | action='store_true') | 
|  | result.add_option('--cl', | 
|  | metavar=('<url>'), | 
|  | help='Run the specified cl on the bots. This should be ' | 
|  | 'the full url, e.g., ' | 
|  | 'https://r8-review.googlesource.com/c/r8/+/37420/1, ' | 
|  | 'or the CL and patch number, e.g., 37420/1') | 
|  | result.add_option('--desugar-jdk11', | 
|  | help='Run the jdk11 library desugar and archiving bot.', | 
|  | default=False, | 
|  | action='store_true') | 
|  | result.add_option( | 
|  | '--desugar-jdk11-legacy', | 
|  | help='Run the jdk11 legacy library desugar and archiving bot.', | 
|  | default=False, | 
|  | action='store_true') | 
|  | result.add_option('--desugar-jdk8', | 
|  | help='Run the jdk8 library desugar and archiving bot.', | 
|  | default=False, | 
|  | action='store_true') | 
|  | result.add_option('--smali', | 
|  | metavar=('<version>'), | 
|  | help='Build smali version <version>.') | 
|  | result.add_option('--builder', help='Trigger specific builder') | 
|  | (options, args) = result.parse_args() | 
|  | if not options.cl.startswith('http'): | 
|  | [cl_number, patch_number] = [int(x) for x in options.cl.split('/')] | 
|  | options.cl = 'https://r8-review.googlesource.com/c/r8/+/%s/%s' % ( | 
|  | cl_number, patch_number) | 
|  | return (options, args) | 
|  |  | 
|  |  | 
|  | def get_builders(): | 
|  | is_release = False | 
|  | main_builders = [] | 
|  | release_builders = [] | 
|  | with open(LUCI_SCHEDULE, 'r') as fp: | 
|  | lines = fp.readlines() | 
|  | for line in lines: | 
|  | if 'branch-gitiles' in line: | 
|  | is_release = True | 
|  | if 'main-gitiles-trigger' in line: | 
|  | is_release = False | 
|  | match = re.match(TRIGGERS_RE, line) | 
|  | if match: | 
|  | builder = match.group(1) | 
|  | if is_release: | 
|  | assert 'release' in builder, builder | 
|  | release_builders.append(builder) | 
|  | else: | 
|  | assert 'release' not in builder, builder | 
|  | main_builders.append(builder) | 
|  | print('Desugar jdk11 builder:\n  ' + DESUGAR_JDK11_BOT) | 
|  | print('Desugar jdk11 legacy builder:\n  ' + DESUGAR_JDK11_LEGACY_BOT) | 
|  | print('Desugar jdk8 builder:\n  ' + DESUGAR_JDK8_BOT) | 
|  | print('Smali builder:\n  ' + SMALI_BOT) | 
|  | print('Main builders:\n  ' + '\n  '.join(main_builders)) | 
|  | print('Release builders:\n  ' + '\n  '.join(release_builders)) | 
|  | return (main_builders, release_builders) | 
|  |  | 
|  |  | 
|  | def sanity_check_url(url): | 
|  | a = urlopen(url) | 
|  | if a.getcode() != 200: | 
|  | raise Exception('Url: %s \n returned %s' % (url, a.getcode())) | 
|  |  | 
|  |  | 
|  | def trigger_builders(builders, commit): | 
|  | commit_url = 'https://r8.googlesource.com/r8/+/%s' % commit | 
|  | sanity_check_url(commit_url) | 
|  | for builder in builders: | 
|  | cmd = ['bb', 'add', 'r8/ci/%s' % builder, '-commit', commit_url] | 
|  | subprocess.check_call(cmd) | 
|  |  | 
|  |  | 
|  | def trigger_smali_builder(version): | 
|  | utils.check_basic_semver_version( | 
|  | version, | 
|  | 'use semantic version of the smali version to built (pre-releases are not supported)', | 
|  | allowPrerelease=False) | 
|  | print( | 
|  | "Check that tag %s is created and pushed to the remote (e.g by running" | 
|  | % version) | 
|  | print() | 
|  | print("  git ls-remote origin refs/tags/%s in a smali checkout)" % version) | 
|  | print() | 
|  | print("in a smali checkout)") | 
|  | print() | 
|  | answer = input("Is tag %s present? [y/N]:" % version) | 
|  | if answer != 'y': | 
|  | print('Aborting smali release build') | 
|  | sys.exit(1) | 
|  | cmd = [ | 
|  | 'bb', 'add', | 
|  | 'r8/ci/%s' % SMALI_BOT, '-p', | 
|  | 'test_options=["--version", "%s"]' % version | 
|  | ] | 
|  | subprocess.check_call(cmd) | 
|  |  | 
|  |  | 
|  | def trigger_cl(builders, cl_url): | 
|  | # Fixup internal urls to make bb happy. | 
|  | fixed_url = cl_url.replace('r8-review.git.corp.google.com', | 
|  | 'r8-review.googlesource.com') | 
|  | for builder in builders: | 
|  | cmd = ['bb', 'add', 'r8/ci/%s' % builder, '-cl', fixed_url] | 
|  | subprocess.check_call(cmd) | 
|  |  | 
|  |  | 
|  | def Main(): | 
|  | (options, args) = ParseOptions() | 
|  | desugar = options.desugar_jdk11 or options.desugar_jdk11_legacy or options.desugar_jdk8 | 
|  | requires_commit = not options.cl and not desugar and not options.smali | 
|  | if len(args) != 1 and requires_commit: | 
|  | print('Takes exactly one argument, the commit to run') | 
|  | return 1 | 
|  |  | 
|  | if options.cl and options.release: | 
|  | print('You can\'t run cls on the release bots') | 
|  | return 1 | 
|  |  | 
|  | if options.cl and desugar: | 
|  | print('You can\'t run cls on the desugar bot') | 
|  | return 1 | 
|  |  | 
|  | if options.cl and options.smali: | 
|  | print('You can\'t run cls on the smali bot') | 
|  | return 1 | 
|  |  | 
|  | if options.smali: | 
|  | if not options.release: | 
|  | print('Only release versions of smali can be built') | 
|  | return 1 | 
|  |  | 
|  | trigger_smali_builder(options.smali) | 
|  | return | 
|  |  | 
|  | commit = None if not requires_commit else args[0] | 
|  | (main_builders, release_builders) = get_builders() | 
|  | builders = release_builders if options.release else main_builders | 
|  | if options.builder: | 
|  | builder = options.builder | 
|  | assert builder in main_builders or builder in release_builders | 
|  | builders = [options.builder] | 
|  | if desugar: | 
|  | assert options.desugar_jdk11 or options.desugar_jdk11_legacy or options.desugar_jdk8 | 
|  | if options.desugar_jdk11: | 
|  | builders = [DESUGAR_JDK11_BOT] | 
|  | elif options.desugar_jdk11_legacy: | 
|  | builders = [DESUGAR_JDK11_LEGACY_BOT] | 
|  | else: | 
|  | builders = [DESUGAR_JDK8_BOT] | 
|  | commit = git_utils.GetHeadRevision(utils.REPO_ROOT, use_main=True) | 
|  | if options.cl: | 
|  | trigger_cl(builders, options.cl) | 
|  | else: | 
|  | assert commit | 
|  | trigger_builders(builders, commit) | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | sys.exit(Main()) |