| #!/usr/bin/env lucicfg | 
 |  | 
 | lucicfg.check_version("1.30.9", "Please use newer `lucicfg` binary") | 
 |  | 
 | # Use LUCI Scheduler BBv2 names and add Scheduler realms configs. | 
 | lucicfg.enable_experiment("crbug.com/1182002") | 
 |  | 
 | luci.builder.defaults.experiments.set({ | 
 |     "luci.recipes.use_python3": 100, | 
 | }) | 
 |  | 
 | luci.project( | 
 |     name = "r8", | 
 |     buildbucket = "cr-buildbucket.appspot.com", | 
 |     logdog = "luci-logdog.appspot.com", | 
 |     milo = "luci-milo.appspot.com", | 
 |     notify = "luci-notify.appspot.com", | 
 |     scheduler = "luci-scheduler.appspot.com", | 
 |     swarming = "chrome-swarming.appspot.com", | 
 |     acls = [ | 
 |         acl.entry( | 
 |             [ | 
 |                 acl.BUILDBUCKET_READER, | 
 |                 acl.LOGDOG_READER, | 
 |                 acl.PROJECT_CONFIGS_READER, | 
 |                 acl.SCHEDULER_READER, | 
 |             ], | 
 |             groups = ["all"], | 
 |         ), | 
 |         acl.entry( | 
 |             [ | 
 |                 acl.BUILDBUCKET_TRIGGERER, | 
 |                 acl.SCHEDULER_OWNER, | 
 |             ], | 
 |             groups = [ | 
 |                 "project-r8-committers", | 
 |             ], | 
 |             users = [ | 
 |                 "luci-scheduler@appspot.gserviceaccount.com", | 
 |             ], | 
 |         ), | 
 |         acl.entry( | 
 |             [ | 
 |                 acl.LOGDOG_WRITER, | 
 |             ], | 
 |             groups = [ | 
 |                 "luci-logdog-r8-writers", | 
 |             ], | 
 |         ), | 
 |     ], | 
 |     bindings = [ | 
 |         luci.binding( | 
 |             roles = "role/swarming.poolOwner", | 
 |             groups = "mdb/r8-team", | 
 |         ), | 
 |         luci.binding( | 
 |             roles = "role/swarming.poolViewer", | 
 |             groups = "googlers", | 
 |         ), | 
 |     ], | 
 | ) | 
 |  | 
 | luci.logdog(gs_bucket = "logdog-r8-archive") | 
 |  | 
 | # Allow the given users to use LUCI `led` tool and "Debug" button | 
 | # inside the given bucket & pool security realms. | 
 | def led_users(*, pool_realm, builder_realm, groups): | 
 |     luci.realm( | 
 |         name = pool_realm, | 
 |         bindings = [ | 
 |             luci.binding( | 
 |                 roles = "role/swarming.poolUser", | 
 |                 groups = groups, | 
 |             ), | 
 |         ], | 
 |     ) | 
 |     luci.binding( | 
 |         realm = builder_realm, | 
 |         roles = "role/swarming.taskTriggerer", | 
 |         groups = groups, | 
 |     ) | 
 |  | 
 | led_users( | 
 |     pool_realm = "pools/ci", | 
 |     builder_realm = "ci", | 
 |     groups = [ | 
 |         "mdb/r8-team", | 
 |         "mdb/chrome-troopers", | 
 |     ], | 
 | ) | 
 |  | 
 | luci.bucket(name = "ci") | 
 |  | 
 | luci.milo() | 
 |  | 
 | luci.notifier( | 
 |     name = "r8-failures", | 
 |     on_failure = True, | 
 |     on_new_failure = True, | 
 |     notify_blamelist = True, | 
 | ) | 
 |  | 
 | luci.gitiles_poller( | 
 |     name = "main-gitiles-trigger", | 
 |     bucket = "ci", | 
 |     repo = "https://r8.googlesource.com/r8", | 
 | ) | 
 |  | 
 | luci.gitiles_poller( | 
 |     name = "branch-gitiles-8.9-forward", | 
 |     bucket = "ci", | 
 |     repo = "https://r8.googlesource.com/r8", | 
 |     refs = ["refs/heads/([8]\\.([9]|[1-9][0-9])+(\\.[0-9]+)?|[9]\\.[0-9]+(\\.[0-9]+)?)"], | 
 |     path_regexps = ["src/main/java/com/android/tools/r8/Version.java"], | 
 | ) | 
 |  | 
 | luci.gitiles_poller( | 
 |     name = "branch-gitiles-8.11-forward", | 
 |     bucket = "ci", | 
 |     repo = "https://r8.googlesource.com/r8", | 
 |     refs = ["refs/heads/([8]\\.[1-9][1-9]|[9]\\.[0-9]+)"], | 
 |     path_regexps = ["src/main/java/com/android/tools/r8/Version.java"], | 
 | ) | 
 |  | 
 | luci.gitiles_poller( | 
 |     name = "branch-gitiles-8.5-forward", | 
 |     bucket = "ci", | 
 |     repo = "https://r8.googlesource.com/r8", | 
 |     refs = ["refs/heads/([8]\\.([5-9]|[1-9][0-9])+(\\.[0-9]+)?|[9]\\.[0-9]+(\\.[0-9]+)?)"], | 
 |     path_regexps = ["src/main/java/com/android/tools/r8/Version.java"], | 
 | ) | 
 |  | 
 | luci.gitiles_poller( | 
 |     name = "branch-gitiles-trigger", | 
 |     bucket = "ci", | 
 |     repo = "https://r8.googlesource.com/r8", | 
 |     refs = ["refs/heads/[0-9]+\\.[0-9]+(\\.[0-9]+)?"], | 
 |     path_regexps = ["src/main/java/com/android/tools/r8/Version.java"], | 
 | ) | 
 |  | 
 | luci.console_view( | 
 |     name = "main", | 
 |     title = "R8 Main Console", | 
 |     repo = "https://r8.googlesource.com/r8", | 
 |     refs = ["refs/heads/.*"], | 
 | ) | 
 |  | 
 | view_builders = [] | 
 |  | 
 | def builder_view(name, category, short_name): | 
 |     view_builders.append((name, category, short_name)) | 
 |  | 
 | luci.recipe( | 
 |     name = "rex", | 
 |     cipd_package = "infra_internal/recipe_bundles/" + | 
 |                    "chrome-internal.googlesource.com/chrome/tools/build", | 
 |     cipd_version = "refs/heads/main", | 
 |     use_bbagent = True, | 
 | ) | 
 |  | 
 | common_test_options = [ | 
 |     "--tool=r8", | 
 |     "--print-times", | 
 |     "--no_internal", | 
 |     "--one_line_per_test", | 
 |     "--archive_failures", | 
 | ] | 
 |  | 
 | default_timeout = time.hour * 6 | 
 |  | 
 | def get_dimensions(windows = False, internal = False, archive = False, jammy=True): | 
 |     # We use the following setup: | 
 |     #   windows -> always windows machine | 
 |     #   internal -> always internal, single small, machine | 
 |     #   archie -> archive or normal machines (normal machines set archive) | 
 |     #   all_other -> normal linux machines | 
 |     dimensions = { | 
 |         "cpu": "x86-64", | 
 |         "pool": "luci.r8.ci", | 
 |     } | 
 |     if windows: | 
 |         dimensions["os"] = "Windows-11" | 
 |     else: | 
 |         if jammy: | 
 |             dimensions["os"] = "Ubuntu-22.04" | 
 |         else: | 
 |             dimensions["os"] = "Ubuntu-20.04" | 
 |     if internal: | 
 |         dimensions["internal"] = "true" | 
 |     elif archive: | 
 |         dimensions["archive"] = "true" | 
 |     else: | 
 |         dimensions["normal"] = "true" | 
 |     return dimensions | 
 |  | 
 | def r8_builder( | 
 |         name, | 
 |         priority = 26, | 
 |         trigger = True, | 
 |         category = None, | 
 |         triggering_policy = None, | 
 |         release_trigger = None, | 
 |         max_concurrent_invocations = 1, | 
 |         **kwargs): | 
 |     release = name.endswith("release") | 
 |     triggered = None | 
 |     if trigger: | 
 |         if release: | 
 |             triggered = release_trigger if release_trigger else ["branch-gitiles-trigger"] | 
 |         else: | 
 |             triggered = ["main-gitiles-trigger"] | 
 |     triggering_policy = triggering_policy or scheduler.policy( | 
 |         kind = scheduler.GREEDY_BATCHING_KIND, | 
 |         max_batch_size = 1 if release else None, | 
 |         max_concurrent_invocations = max_concurrent_invocations, | 
 |     ) | 
 |  | 
 |     luci.builder( | 
 |         name = name, | 
 |         bucket = "ci", | 
 |         service_account = "r8-ci-builder@chops-service-accounts." + | 
 |                           "iam.gserviceaccount.com", | 
 |         build_numbers = True, | 
 |         swarming_tags = ["vpython:native-python-wrapper"], | 
 |         notifies = ["r8-failures"] if trigger else None, | 
 |         priority = priority, | 
 |         triggered_by = triggered, | 
 |         triggering_policy = triggering_policy, | 
 |         executable = "rex", | 
 |         **kwargs | 
 |     ) | 
 |     category = category if category else "R8" | 
 |     category = "Release|" + category if release else category | 
 |     builder_view(name, category, name.split("-")[-1].replace("_release", "")) | 
 |  | 
 | def r8_tester( | 
 |         name, | 
 |         test_options, | 
 |         dimensions = None, | 
 |         execution_timeout = default_timeout, | 
 |         expiration_timeout = time.hour * 35, | 
 |         max_concurrent_invocations = 1, | 
 |         category = None, | 
 |         release_trigger = None): | 
 |     dimensions = dimensions if dimensions else get_dimensions() | 
 |     for name in [name, name + "_release"]: | 
 |         r8_builder( | 
 |             name = name, | 
 |             category = category, | 
 |             execution_timeout = execution_timeout, | 
 |             expiration_timeout = expiration_timeout, | 
 |             dimensions = dimensions, | 
 |             release_trigger = release_trigger, | 
 |             max_concurrent_invocations = max_concurrent_invocations, | 
 |             properties = { | 
 |                 "test_options": test_options, | 
 |                 "builder_group": "internal.client.r8", | 
 |             }, | 
 |         ) | 
 |  | 
 | def r8_tester_with_default( | 
 |         name, | 
 |         test_options, | 
 |         dimensions = None, | 
 |         category = None, | 
 |         release_trigger = None, | 
 |         max_concurrent_invocations = 1, | 
 |         execution_timeout = default_timeout): | 
 |     r8_tester( | 
 |         name, | 
 |         test_options + common_test_options, | 
 |         dimensions = dimensions, | 
 |         category = category, | 
 |         release_trigger = release_trigger, | 
 |         max_concurrent_invocations = max_concurrent_invocations, | 
 |         execution_timeout = execution_timeout, | 
 |     ) | 
 |  | 
 | def archivers(): | 
 |     for name in [ | 
 |         "archive", | 
 |         "archive_release", | 
 |         "lib_desugar-archive-jdk11", | 
 |         "lib_desugar-archive-jdk11-legacy", | 
 |         "lib_desugar-archive-jdk8", | 
 |     ]: | 
 |         desugar = "desugar" in name | 
 |         properties = { | 
 |             "test_wrapper": "tools/archive_desugar_jdk_libs.py" if desugar else "tools/archive.py", | 
 |             "builder_group": "internal.client.r8", | 
 |         } | 
 |         if desugar: | 
 |             if name.endswith("jdk11"): | 
 |                 properties["test_options"] = ["--variant=jdk11_minimal", "--variant=jdk11", "--variant=jdk11_nio"] | 
 |             elif name.endswith("jdk11-legacy"): | 
 |                 properties["test_options"] = ["--variant=jdk11_legacy"] | 
 |             else: | 
 |                 properties["test_options"] = ["--variant=jdk8"] | 
 |  | 
 |         r8_builder( | 
 |             name, | 
 |             category = "library_desugar" if desugar else "archive", | 
 |             dimensions = get_dimensions(archive = True), | 
 |             triggering_policy = scheduler.policy( | 
 |                 kind = scheduler.GREEDY_BATCHING_KIND, | 
 |                 max_batch_size = 1, | 
 |                 max_concurrent_invocations = 1, | 
 |             ), | 
 |             priority = 25, | 
 |             trigger = not desugar, | 
 |             properties = properties, | 
 |             execution_timeout = time.hour * 1, | 
 |             expiration_timeout = time.hour * 35, | 
 |         ) | 
 |  | 
 | archivers() | 
 |  | 
 | r8_builder( | 
 |     "check", | 
 |     category = "archive", | 
 |     dimensions = get_dimensions(), | 
 |     triggering_policy = scheduler.policy( | 
 |         kind = scheduler.GREEDY_BATCHING_KIND, | 
 |         max_batch_size = 1, | 
 |         max_concurrent_invocations = 1, | 
 |     ), | 
 |     priority = 25, | 
 |     properties = { | 
 |         "test_wrapper": "tools/check-cherry-picks.py", | 
 |         "builder_group": "internal.client.r8", | 
 |     }, | 
 |     execution_timeout = time.minute * 30, | 
 |     expiration_timeout = time.hour * 35, | 
 | ) | 
 |  | 
 | def perf(): | 
 |     for name in ["perf", "perf_release"]: | 
 |         properties = { | 
 |             "test_wrapper": "tools/perf.py", | 
 |             "builder_group": "internal.client.r8", | 
 |         } | 
 |         if name.endswith("release"): | 
 |             properties["test_options"] = ["--no-upload-benchmark-data-to-google-storage"] | 
 |         r8_builder( | 
 |             name, | 
 |             category = "perf", | 
 |             dimensions = get_dimensions(), | 
 |             triggering_policy = scheduler.policy( | 
 |                 kind = scheduler.GREEDY_BATCHING_KIND, | 
 |                 max_batch_size = 1, | 
 |                 max_concurrent_invocations = 3, | 
 |             ), | 
 |             release_trigger = ["branch-gitiles-8.9-forward"], | 
 |             priority = 25, | 
 |             properties = properties, | 
 |             execution_timeout = time.hour * 6, | 
 |             expiration_timeout = time.hour * 35, | 
 |         ) | 
 |  | 
 | perf() | 
 |  | 
 | r8_tester_with_default( | 
 |     "linux-default", | 
 |     ["--runtimes=dex-default", "--command_cache_dir=/tmp/ccache"], | 
 |     max_concurrent_invocations = 2, | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-none", | 
 |     ["--runtimes=none", "--command_cache_dir=/tmp/ccache"], | 
 |     max_concurrent_invocations = 2, | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-jdk8", | 
 |     ["--runtimes=jdk8", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-jdk11", | 
 |     ["--runtimes=jdk11", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-jdk17", | 
 |     ["--runtimes=jdk17", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-jdk21", | 
 |     ["--runtimes=jdk21", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-jdk24", | 
 |     ["--runtimes=jdk24", "--command_cache_dir=/tmp/ccache"], | 
 |     release_trigger = ["branch-gitiles-8.11-forward"], | 
 | ) | 
 |  | 
 | r8_tester_with_default( | 
 |     "linux-android-4.0", | 
 |     ["--dex_vm=4.0.4", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 |     max_concurrent_invocations = 2, | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-4.4", | 
 |     ["--dex_vm=4.4.4", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 |  | 
 | r8_tester_with_default( | 
 |     "linux-android-5", | 
 |     ["--dex_vm=5.1.1", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 |     dimensions = get_dimensions(jammy=True), | 
 | ) | 
 |  | 
 | r8_tester_with_default( | 
 |     "linux-android-6", | 
 |     ["--dex_vm=6.0.1", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-7", | 
 |     ["--dex_vm=7.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 |  | 
 | r8_tester_with_default( | 
 |     "linux-android-8", | 
 |     ["--dex_vm=8.1.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-9", | 
 |     ["--dex_vm=9.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-10", | 
 |     ["--dex_vm=10.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-12", | 
 |     ["--dex_vm=12.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-13", | 
 |     ["--dex_vm=13.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-14", | 
 |     ["--dex_vm=14.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 | ) | 
 | r8_tester_with_default( | 
 |     "linux-android-15", | 
 |     ["--dex_vm=15.0.0", "--all_tests", "--command_cache_dir=/tmp/ccache"], | 
 |     release_trigger = ["branch-gitiles-8.5-forward"], | 
 | ) | 
 |  | 
 | r8_tester_with_default( | 
 |     "win", | 
 |     ["--all_tests"], | 
 |     dimensions = get_dimensions(windows = True), | 
 |     execution_timeout = time.hour * 8, | 
 |     max_concurrent_invocations = 2, | 
 | ) | 
 |  | 
 | def internal(): | 
 |     for name in ["linux-internal", "linux-internal_release"]: | 
 |         r8_builder( | 
 |             name, | 
 |             dimensions = get_dimensions(internal = True), | 
 |             triggering_policy = scheduler.policy( | 
 |                 kind = scheduler.GREEDY_BATCHING_KIND, | 
 |                 max_concurrent_invocations = 1, | 
 |                 max_batch_size = 1 if "release" in name else 20, | 
 |             ), | 
 |             priority = 25, | 
 |             properties = { | 
 |                 "test_options": ["--bot"], | 
 |                 "test_wrapper": "tools/internal_test.py", | 
 |                 "builder_group": "internal.client.r8", | 
 |             }, | 
 |             execution_timeout = time.hour * 12, | 
 |             expiration_timeout = time.hour * 35, | 
 |         ) | 
 |  | 
 | internal() | 
 |  | 
 | def app_dump(): | 
 |     for release in ["", "_release"]: | 
 |         properties = { | 
 |             "builder_group": "internal.client.r8", | 
 |             "test_options": ["--bot", "--workers", "4"], | 
 |             "test_wrapper": "tools/run_on_app_dump.py", | 
 |         } | 
 |         name = "linux-run-on-app-dump" + release | 
 |         r8_builder( | 
 |             name, | 
 |             dimensions = get_dimensions(), | 
 |             execution_timeout = time.hour * 12, | 
 |             expiration_timeout = time.hour * 35, | 
 |             properties = properties, | 
 |         ) | 
 |  | 
 | app_dump() | 
 |  | 
 | def desugared_library(): | 
 |     test_options = [ | 
 |         "--one_line_per_test", | 
 |         "--archive_failures", | 
 |         "--no_internal", | 
 |         "--no_arttests", | 
 |         "--desugared-library", | 
 |         "HEAD", | 
 |         "--desugared-library-configuration", | 
 |         "jdk11", | 
 |     ] | 
 |     properties = { | 
 |         "builder_group": "internal.client.r8", | 
 |         "test_options": test_options, | 
 |     } | 
 |     r8_builder( | 
 |         "desugared_library-jdk11_head", | 
 |         category = "library_desugar", | 
 |         dimensions = get_dimensions(), | 
 |         execution_timeout = time.hour * 12, | 
 |         expiration_timeout = time.hour * 35, | 
 |         properties = properties, | 
 |     ) | 
 |  | 
 | desugared_library() | 
 |  | 
 | r8_builder( | 
 |     "linux-dev", | 
 |     category = "Kotlin", | 
 |     dimensions = get_dimensions(), | 
 |     execution_timeout = time.hour * 12, | 
 |     expiration_timeout = time.hour * 35, | 
 |     properties = { | 
 |         "builder_group": "internal.client.r8", | 
 |         "test_options": ["--runtimes=dex-default:jdk11", "--kotlin-compiler-dev", "--one_line_per_test", "--archive_failures", "--no-internal", "*kotlin*", "*debug*"], | 
 |     }, | 
 | ) | 
 |  | 
 | r8_builder( | 
 |     "linux-old", | 
 |     category = "Kotlin", | 
 |     dimensions = get_dimensions(), | 
 |     execution_timeout = time.hour * 12, | 
 |     expiration_timeout = time.hour * 35, | 
 |     properties = { | 
 |         "builder_group": "internal.client.r8", | 
 |         "test_options": ["--runtimes=dex-default:jdk11", "--kotlin-compiler-old", "--one_line_per_test", "--archive_failures", "--no-internal", "*kotlin*", "*debug*"], | 
 |     }, | 
 | ) | 
 |  | 
 | r8_builder( | 
 |     "smali", | 
 |     category = "aux", | 
 |     trigger = False, | 
 |     dimensions = get_dimensions(), | 
 |     triggering_policy = scheduler.policy( | 
 |         kind = scheduler.GREEDY_BATCHING_KIND, | 
 |         max_concurrent_invocations = 1, | 
 |         max_batch_size = 1, | 
 |     ), | 
 |     properties = { | 
 |         "test_wrapper": "tools/archive_smali.py", | 
 |         "builder_group": "internal.client.smali", | 
 |     }, | 
 |     execution_timeout = time.hour * 12, | 
 |     expiration_timeout = time.hour * 35, | 
 | ) | 
 |  | 
 | order_of_categories = [ | 
 |     "archive", | 
 |     "R8", | 
 |     "Kotlin", | 
 |     "library_desugar", | 
 |     "perf", | 
 |     "Release|archive", | 
 |     "Release|perf", | 
 |     "Release|R8", | 
 | ] | 
 |  | 
 | categories_with_no_console = [ | 
 |     "aux", | 
 | ] | 
 |  | 
 | def add_view_entries(): | 
 |     # Ensure that all categories are ordered | 
 |     for v in view_builders: | 
 |         if v[1] in categories_with_no_console: | 
 |             continue | 
 |         if not v[1] in order_of_categories: | 
 |             fail() | 
 |     for category in order_of_categories: | 
 |         for v in [x for x in view_builders if x[1] == category]: | 
 |             luci.console_view_entry( | 
 |                 console_view = "main", | 
 |                 builder = v[0], | 
 |                 category = v[1], | 
 |                 short_name = v[2], | 
 |             ) | 
 |  | 
 | add_view_entries() |