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