• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env lucicfg
2#
3# Copyright 2021 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# main.star: lucicfg configuration for ANGLE's standalone builders.
8
9lucicfg.check_version(min = "1.31.3", message = "Update depot_tools")
10
11# Use LUCI Scheduler BBv2 names and add Scheduler realms configs.
12lucicfg.enable_experiment("crbug.com/1182002")
13
14# Fail build when merge script fails.
15build_experiments = {"chromium_swarming.expose_merge_script_failures": 100}
16
17lucicfg.config(
18    fail_on_warnings = True,
19    lint_checks = [
20        "default",
21        "-module-docstring",
22        "-function-docstring",
23    ],
24)
25
26luci.project(
27    name = "angle",
28    buildbucket = "cr-buildbucket.appspot.com",
29    logdog = "luci-logdog.appspot.com",
30    milo = "luci-milo.appspot.com",
31    notify = "luci-notify.appspot.com",
32    scheduler = "luci-scheduler.appspot.com",
33    swarming = "chromium-swarm.appspot.com",
34    acls = [
35        acl.entry(
36            roles = [
37                acl.PROJECT_CONFIGS_READER,
38                acl.LOGDOG_READER,
39                acl.BUILDBUCKET_READER,
40                acl.SCHEDULER_READER,
41            ],
42            groups = "all",
43        ),
44        acl.entry(
45            roles = [
46                acl.SCHEDULER_OWNER,
47            ],
48            groups = "project-angle-admins",
49        ),
50        acl.entry(
51            roles = [
52                acl.LOGDOG_WRITER,
53            ],
54            groups = "luci-logdog-angle-writers",
55        ),
56    ],
57    bindings = [
58        luci.binding(
59            roles = "role/configs.validator",
60            users = "angle-try-builder@chops-service-accounts.iam.gserviceaccount.com",
61        ),
62        luci.binding(
63            roles = "role/swarming.poolOwner",
64            groups = ["project-angle-owners", "mdb/chrome-troopers"],
65        ),
66        luci.binding(
67            roles = "role/swarming.poolViewer",
68            groups = "all",
69        ),
70        # Allow any Angle build to trigger a test ran under testing accounts
71        # used on shared chromium tester pools.
72        luci.binding(
73            roles = "role/swarming.taskServiceAccount",
74            users = [
75                "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
76                "chrome-gpu-gold@chops-service-accounts.iam.gserviceaccount.com",
77            ],
78        ),
79    ],
80)
81
82# Swarming permissions
83luci.realm(name = "pools/ci")
84luci.realm(name = "pools/try")
85
86# Allow Angle owners and Chrome troopers to run tasks directly for testing and
87# development on all Angle bots. E.g. via `led` tool or "Debug" button in Swarming Web UI.
88luci.binding(
89    realm = "@root",
90    roles = "role/swarming.poolUser",
91    groups = ["project-angle-owners", "mdb/chrome-troopers"],
92)
93luci.binding(
94    realm = "@root",
95    roles = "role/swarming.taskTriggerer",
96    groups = ["project-angle-owners", "mdb/chrome-troopers"],
97)
98
99def _generate_project_pyl(ctx):
100    ctx.output["project.pyl"] = "\n".join([
101        "# This is a non-LUCI generated file",
102        "# This is consumed by presubmit checks that need to validate the config",
103        repr(dict(
104            # We don't validate matching source-side configs for simplicity.
105            validate_source_side_specs_have_builder = False,
106        )),
107        "",
108    ])
109
110lucicfg.generator(_generate_project_pyl)
111
112luci.milo(
113    logo = "https://storage.googleapis.com/chrome-infra/OpenGL%20ES_RGB_June16.svg",
114    bug_url_template = "https://bugs.chromium.org/p/angleproject/issues/entry?components=Infra",
115)
116
117luci.logdog(gs_bucket = "chromium-luci-logdog")
118
119# The category for an os: a more generic grouping than specific OS versions that
120# can be used for computing defaults
121os_category = struct(
122    ANDROID = "Android",
123    LINUX = "Linux",
124    MAC = "Mac",
125    WINDOWS = "Windows",
126)
127
128def os_enum(dimension, category, console_name):
129    return struct(dimension = dimension, category = category, console_name = console_name)
130
131os = struct(
132    ANDROID = os_enum("Ubuntu", os_category.ANDROID, "android"),
133    LINUX = os_enum("Ubuntu", os_category.LINUX, "linux"),
134    MAC = os_enum("Mac", os_category.MAC, "mac"),
135    WINDOWS = os_enum("Windows", os_category.WINDOWS, "win"),
136)
137
138# Recipes
139
140_RECIPE_NAME_PREFIX = "recipe:"
141_DEFAULT_BUILDERLESS_OS_CATEGORIES = [os_category.LINUX, os_category.WINDOWS]
142
143def _recipe_for_package(cipd_package):
144    def recipe(*, name, cipd_version = None, recipe = None, use_python3 = False):
145        # Force the caller to put the recipe prefix rather than adding it
146        # programatically to make the string greppable
147        if not name.startswith(_RECIPE_NAME_PREFIX):
148            fail("Recipe name {!r} does not start with {!r}"
149                .format(name, _RECIPE_NAME_PREFIX))
150        if recipe == None:
151            recipe = name[len(_RECIPE_NAME_PREFIX):]
152        return luci.recipe(
153            name = name,
154            cipd_package = cipd_package,
155            cipd_version = cipd_version,
156            recipe = recipe,
157            use_bbagent = True,
158            use_python3 = use_python3,
159        )
160
161    return recipe
162
163build_recipe = _recipe_for_package(
164    "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",
165)
166
167build_recipe(
168    name = "recipe:angle",
169    use_python3 = True,
170)
171
172build_recipe(
173    name = "recipe:run_presubmit",
174    use_python3 = True,
175)
176
177def get_os_from_name(name):
178    if name.startswith("android"):
179        return os.ANDROID
180    if name.startswith("linux"):
181        return os.LINUX
182    if name.startswith("win"):
183        return os.WINDOWS
184    if name.startswith("mac"):
185        return os.MAC
186    return os.MAC
187
188def get_gpu_type_from_builder_name(name):
189    return name.split("-")[1]
190
191# Adds both the CI and Try standalone builders.
192def angle_builder(name, cpu):
193    config_os = get_os_from_name(name)
194    dimensions = {}
195    dimensions["os"] = config_os.dimension
196
197    if config_os.category in _DEFAULT_BUILDERLESS_OS_CATEGORIES:
198        dimensions["builderless"] = "1"
199
200    is_asan = "-asan" in name
201    is_tsan = "-tsan" in name
202    is_debug = "-dbg" in name
203    is_exp = "-exp" in name
204    is_perf = name.endswith("-perf")
205    is_s22 = "s22" in name
206    is_trace = name.endswith("-trace")
207    is_uwp = "winuwp" in name
208    is_msvc = is_uwp or "-msvc" in name
209
210    location_filters = None
211
212    if name.endswith("-compile"):
213        test_mode = "compile_only"
214        category = "compile"
215    elif name.endswith("-test"):
216        test_mode = "compile_and_test"
217        category = "test"
218    elif is_trace:
219        test_mode = "trace_tests"
220        category = "trace"
221
222        # Trace tests are only run on CQ if files in the capture folders change.
223        location_filters = [
224            cq.location_filter(path_regexp = "DEPS"),
225            cq.location_filter(path_regexp = "src/libANGLE/capture/.+"),
226            cq.location_filter(path_regexp = "src/tests/angle_end2end_tests_expectations.txt"),
227            cq.location_filter(path_regexp = "src/tests/capture.+"),
228            cq.location_filter(path_regexp = "src/tests/egl_tests/.+"),
229            cq.location_filter(path_regexp = "src/tests/gl_tests/.+"),
230        ]
231    elif is_perf:
232        test_mode = "compile_and_test"
233        category = "perf"
234    else:
235        print("Test mode unknown for %s" % name)
236
237    if is_msvc:
238        toolchain = "msvc"
239    else:
240        toolchain = "clang"
241
242    if is_uwp:
243        os_toolchain_name = "win-uwp"
244    elif is_msvc:
245        os_toolchain_name = "win-msvc"
246    else:
247        os_toolchain_name = config_os.console_name
248
249    if is_perf:
250        short_name = get_gpu_type_from_builder_name(name)
251    elif is_asan:
252        short_name = "asan"
253        if is_exp:
254            short_name = "asan-exp"
255    elif is_tsan:
256        short_name = "tsan"
257        if is_exp:
258            short_name = "tsan-exp"
259    elif is_debug:
260        short_name = "dbg"
261    elif is_exp:
262        short_name = "exp"
263        if is_s22:
264            # This is a little clunky, but we'd like this to be cleanly "s22" rather than "s22-exp"
265            short_name = "s22"
266    else:
267        short_name = "rel"
268
269    properties = {
270        "builder_group": "angle",
271        "$build/reclient": {
272            "instance": "rbe-chromium-untrusted",
273            "metrics_project": "chromium-reclient-metrics",
274            "scandeps_server": True,
275        },
276        "platform": config_os.console_name,
277        "toolchain": toolchain,
278        "test_mode": test_mode,
279    }
280
281    ci_properties = {
282        "builder_group": "angle",
283        "$build/reclient": {
284            "instance": "rbe-chromium-trusted",
285            "metrics_project": "chromium-reclient-metrics",
286            "scandeps_server": True,
287        },
288        "platform": config_os.console_name,
289        "toolchain": toolchain,
290        "test_mode": test_mode,
291    }
292
293    # TODO(343503161): Remove sheriff_rotations after SoM is updated.
294    ci_properties["gardener_rotations"] = ["angle"]
295    ci_properties["sheriff_rotations"] = ["angle"]
296
297    if is_perf:
298        timeout_hours = 5
299    else:
300        timeout_hours = 3
301
302    luci.builder(
303        name = name,
304        bucket = "ci",
305        triggered_by = ["main-poller"],
306        executable = "recipe:angle",
307        experiments = build_experiments,
308        service_account = "angle-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
309        properties = ci_properties,
310        dimensions = dimensions,
311        build_numbers = True,
312        resultdb_settings = resultdb.settings(enable = True),
313        test_presentation = resultdb.test_presentation(
314            column_keys = ["v.gpu"],
315            grouping_keys = ["status", "v.test_suite"],
316        ),
317        triggering_policy = scheduler.policy(
318            kind = scheduler.LOGARITHMIC_BATCHING_KIND,
319            log_base = 2,
320        ),
321        execution_timeout = timeout_hours * time.hour,
322    )
323
324    active_experimental_builders = [
325        "android-arm64-exp-test",
326        "android-arm64-exp-s22-test",
327        "linux-exp-test",
328    ]
329
330    if (not is_exp) or (name in active_experimental_builders):
331        luci.console_view_entry(
332            console_view = "ci",
333            builder = "ci/" + name,
334            category = category + "|" + os_toolchain_name + "|" + cpu,
335            short_name = short_name,
336        )
337    else:
338        luci.list_view_entry(
339            list_view = "exp",
340            builder = "ci/" + name,
341        )
342
343    # Do not include perf tests in "try".
344    if not is_perf:
345        luci.list_view_entry(
346            list_view = "try",
347            builder = "try/" + name,
348        )
349
350        luci.builder(
351            name = name,
352            bucket = "try",
353            executable = "recipe:angle",
354            experiments = build_experiments,
355            service_account = "angle-try-builder@chops-service-accounts.iam.gserviceaccount.com",
356            properties = properties,
357            dimensions = dimensions,
358            build_numbers = True,
359            resultdb_settings = resultdb.settings(enable = True),
360            test_presentation = resultdb.test_presentation(
361                column_keys = ["v.gpu"],
362                grouping_keys = ["status", "v.test_suite"],
363            ),
364        )
365
366        # Don't add experimental bots to CQ.
367        if not is_exp:
368            luci.cq_tryjob_verifier(
369                cq_group = "main",
370                builder = "angle:try/" + name,
371                location_filters = location_filters,
372            )
373
374luci.bucket(
375    name = "ci",
376    acls = [
377        acl.entry(
378            acl.BUILDBUCKET_TRIGGERER,
379            users = [
380                "angle-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
381            ],
382        ),
383    ],
384)
385
386luci.bucket(
387    name = "try",
388    acls = [
389        acl.entry(
390            acl.BUILDBUCKET_TRIGGERER,
391            groups = [
392                "project-angle-tryjob-access",
393                "service-account-cq",
394            ],
395        ),
396    ],
397)
398
399luci.builder(
400    name = "presubmit",
401    bucket = "try",
402    executable = "recipe:run_presubmit",
403    experiments = build_experiments,
404    service_account = "angle-try-builder@chops-service-accounts.iam.gserviceaccount.com",
405    build_numbers = True,
406    dimensions = {
407        "os": os.LINUX.dimension,
408    },
409    properties = {
410        "repo_name": "angle",
411        "runhooks": True,
412    },
413    resultdb_settings = resultdb.settings(enable = True),
414    test_presentation = resultdb.test_presentation(
415        column_keys = ["v.gpu"],
416        grouping_keys = ["status", "v.test_suite"],
417    ),
418)
419
420luci.gitiles_poller(
421    name = "main-poller",
422    bucket = "ci",
423    repo = "https://chromium.googlesource.com/angle/angle",
424    refs = [
425        "refs/heads/main",
426    ],
427    schedule = "with 10s interval",
428)
429
430# name, clang, debug, cpu, uwp, trace_tests
431angle_builder("android-arm-compile", cpu = "arm")
432angle_builder("android-arm-dbg-compile", cpu = "arm")
433angle_builder("android-arm64-dbg-compile", cpu = "arm64")
434angle_builder("android-arm64-exp-s22-test", cpu = "arm64")
435angle_builder("android-arm64-exp-test", cpu = "arm64")
436angle_builder("android-arm64-test", cpu = "arm64")
437angle_builder("linux-asan-test", cpu = "x64")
438angle_builder("linux-exp-asan-test", cpu = "x64")
439angle_builder("linux-exp-test", cpu = "x64")
440angle_builder("linux-exp-tsan-test", cpu = "x64")
441angle_builder("linux-tsan-test", cpu = "x64")
442angle_builder("linux-dbg-compile", cpu = "x64")
443angle_builder("linux-test", cpu = "x64")
444angle_builder("mac-dbg-compile", cpu = "x64")
445angle_builder("mac-exp-test", cpu = "x64")
446angle_builder("mac-test", cpu = "x64")
447angle_builder("win-asan-test", cpu = "x64")
448angle_builder("win-dbg-compile", cpu = "x64")
449angle_builder("win-exp-test", cpu = "x64")
450angle_builder("win-msvc-compile", cpu = "x64")
451angle_builder("win-msvc-dbg-compile", cpu = "x64")
452angle_builder("win-msvc-x86-compile", cpu = "x86")
453angle_builder("win-msvc-x86-dbg-compile", cpu = "x86")
454angle_builder("win-test", cpu = "x64")
455angle_builder("win-x86-dbg-compile", cpu = "x86")
456angle_builder("win-x86-test", cpu = "x86")
457angle_builder("winuwp-compile", cpu = "x64")
458angle_builder("winuwp-dbg-compile", cpu = "x64")
459
460angle_builder("linux-trace", cpu = "x64")
461angle_builder("win-trace", cpu = "x64")
462
463angle_builder("android-pixel4-perf", cpu = "arm64")
464angle_builder("android-pixel6-perf", cpu = "arm64")
465angle_builder("linux-intel-uhd630-perf", cpu = "x64")
466angle_builder("linux-nvidia-gtx1660-perf", cpu = "x64")
467angle_builder("win10-intel-uhd630-perf", cpu = "x64")
468angle_builder("win10-nvidia-gtx1660-perf", cpu = "x64")
469
470# Views
471
472luci.console_view(
473    name = "ci",
474    title = "ANGLE CI Builders",
475    repo = "https://chromium.googlesource.com/angle/angle",
476)
477
478luci.list_view(
479    name = "exp",
480    title = "ANGLE Experimental CI Builders",
481)
482
483luci.list_view(
484    name = "try",
485    title = "ANGLE Try Builders",
486)
487
488luci.list_view_entry(
489    list_view = "try",
490    builder = "try/presubmit",
491)
492
493# CQ
494
495luci.cq(
496    status_host = "chromium-cq-status.appspot.com",
497    submit_max_burst = 4,
498    submit_burst_delay = 480 * time.second,
499)
500
501luci.cq_group(
502    name = "main",
503    watch = cq.refset(
504        "https://chromium.googlesource.com/angle/angle",
505        refs = [r"refs/heads/main"],
506    ),
507    acls = [
508        acl.entry(
509            acl.CQ_COMMITTER,
510            groups = "project-angle-committers",
511        ),
512        acl.entry(
513            acl.CQ_DRY_RUNNER,
514            groups = "project-angle-tryjob-access",
515        ),
516    ],
517    verifiers = [
518        luci.cq_tryjob_verifier(
519            builder = "angle:try/presubmit",
520            disable_reuse = True,
521        ),
522        luci.cq_tryjob_verifier(
523            builder = "chromium:try/android-angle-chromium-try",
524        ),
525        luci.cq_tryjob_verifier(
526            builder = "chromium:try/fuchsia-angle-try",
527        ),
528        luci.cq_tryjob_verifier(
529            builder = "chromium:try/linux-angle-chromium-try",
530        ),
531        luci.cq_tryjob_verifier(
532            builder = "chromium:try/mac-angle-chromium-try",
533        ),
534        luci.cq_tryjob_verifier(
535            builder = "chromium:try/win-angle-chromium-x64-try",
536        ),
537        luci.cq_tryjob_verifier(
538            builder = "chromium:try/win-angle-chromium-x86-try",
539        ),
540    ],
541)
542