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 builers.
8
9lucicfg.config(
10    fail_on_warnings = True,
11    lint_checks = [
12        "default",
13        "-module-docstring",
14        "-function-docstring",
15    ],
16)
17
18# Enable LUCI Realms support.
19lucicfg.enable_experiment("crbug.com/1085650")
20# Launch 0% of Swarming tasks for builds in "realms-aware mode"
21# TODO(https://crbug.com/1204972): ramp up to 100%.
22# luci.builder.defaults.experiments.set({"luci.use_realms": 0})
23
24# Enable LUCI Realms support.
25lucicfg.enable_experiment("crbug.com/1085650")
26
27# Launch all builds and tasks in Angle in realms mode.
28luci.builder.defaults.experiments.set({"luci.use_realms": 100})
29
30luci.project(
31    name = "angle",
32    buildbucket = "cr-buildbucket.appspot.com",
33    logdog = "luci-logdog.appspot.com",
34    milo = "luci-milo.appspot.com",
35    notify = "luci-notify.appspot.com",
36    scheduler = "luci-scheduler.appspot.com",
37    swarming = "chromium-swarm.appspot.com",
38    acls = [
39        acl.entry(
40            roles = [
41                acl.PROJECT_CONFIGS_READER,
42                acl.LOGDOG_READER,
43                acl.BUILDBUCKET_READER,
44                acl.SCHEDULER_READER,
45            ],
46            groups = "all",
47        ),
48        acl.entry(
49            roles = [
50                acl.SCHEDULER_OWNER,
51            ],
52            groups = "project-angle-admins",
53        ),
54        acl.entry(
55            roles = [
56                acl.LOGDOG_WRITER,
57            ],
58            groups = "luci-logdog-angle-writers",
59        ),
60    ],
61    bindings = [
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    monorail_project = "angleproject",
115    monorail_components = ["Infra"],
116)
117
118luci.logdog(gs_bucket = "chromium-luci-logdog")
119
120# The category for an os: a more generic grouping than specific OS versions that
121# can be used for computing defaults
122os_category = struct(
123    ANDROID = "Android",
124    LINUX = "Linux",
125    MAC = "Mac",
126    WINDOWS = "Windows",
127)
128
129def os_enum(dimension, category, console_name):
130    return struct(dimension = dimension, category = category, console_name = console_name)
131
132os = struct(
133    ANDROID = os_enum("Ubuntu", os_category.ANDROID, "android"),
134    LINUX = os_enum("Ubuntu", os_category.LINUX, "linux"),
135    MAC = os_enum("Mac", os_category.MAC, "mac"),
136    WINDOWS = os_enum("Windows", os_category.WINDOWS, "win"),
137)
138
139# Recipes
140
141_RECIPE_NAME_PREFIX = "recipe:"
142_DEFAULT_BUILDERLESS_OS_CATEGORIES = [os_category.LINUX, os_category.WINDOWS]
143_GOMA_RBE_PROD = {
144    "server_host": "goma.chromium.org",
145    "rpc_extra_params": "?prod",
146}
147
148def _recipe_for_package(cipd_package):
149    def recipe(*, name, cipd_version = None, recipe = None, use_bbagent = False):
150        # Force the caller to put the recipe prefix rather than adding it
151        # programatically to make the string greppable
152        if not name.startswith(_RECIPE_NAME_PREFIX):
153            fail("Recipe name {!r} does not start with {!r}"
154                .format(name, _RECIPE_NAME_PREFIX))
155        if recipe == None:
156            recipe = name[len(_RECIPE_NAME_PREFIX):]
157        return luci.recipe(
158            name = name,
159            cipd_package = cipd_package,
160            cipd_version = cipd_version,
161            recipe = recipe,
162            use_bbagent = use_bbagent,
163        )
164
165    return recipe
166
167build_recipe = _recipe_for_package(
168    "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",
169)
170
171build_recipe(
172    name = "recipe:angle",
173)
174
175build_recipe(
176    name = "recipe:run_presubmit",
177)
178
179def get_os_from_name(name):
180    if name.startswith("android"):
181        return os.ANDROID
182    if name.startswith("linux"):
183        return os.LINUX
184    if name.startswith("win"):
185        return os.WINDOWS
186    if name.startswith("mac"):
187        return os.MAC
188    return os.MAC
189
190# Adds both the CI and Try standalone builders.
191def angle_builder(name, debug, cpu, toolchain = "clang", uwp = False, test_mode = "compile_and_test"):
192    properties = {
193        "builder_group": "angle",
194    }
195    config_os = get_os_from_name(name)
196    dimensions = {}
197    dimensions["os"] = config_os.dimension
198
199    goma_props = {}
200    goma_props.update(_GOMA_RBE_PROD)
201
202    if config_os.category in _DEFAULT_BUILDERLESS_OS_CATEGORIES:
203        dimensions["builderless"] = "1"
204        goma_props["enable_ats"] = True
205
206    properties["$build/goma"] = goma_props
207    properties["platform"] = config_os.console_name
208    properties["toolchain"] = toolchain
209
210    if toolchain == "gcc":
211        properties["test_mode"] = "checkout_only"
212    elif debug or toolchain == "msvc" or (config_os.category == os_category.ANDROID and cpu == "arm"):
213        properties["test_mode"] = "compile_only"
214    else:
215        properties["test_mode"] = test_mode
216
217    luci.builder(
218        name = name,
219        bucket = "ci",
220        triggered_by = ["master-poller"],
221        executable = "recipe:angle",
222        service_account = "angle-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
223        properties = properties,
224        dimensions = dimensions,
225        build_numbers = True,
226    )
227
228    is_perf = "-perf" in name
229
230    # Trace tests are only included automatically if files in the capture folder change.
231    if test_mode == "trace_tests":
232        config = "trace"
233        location_regexp = [
234            ".+/[+]/src/libANGLE/capture/.+",
235            ".+/[+]/src/tests/capture.+",
236        ]
237    elif is_perf:
238        config = "perf"
239    else:
240        config = "angle"
241        location_regexp = None
242
243    if uwp:
244        os_name = "winuwp"
245    else:
246        os_name = config_os.console_name
247
248    short_name = "dbg" if debug else "rel"
249
250    luci.console_view_entry(
251        console_view = "ci",
252        builder = "ci/" + name,
253        category = config + "|" + os_name + "|" + toolchain + "|" + cpu,
254        short_name = short_name,
255    )
256
257    # Do not include perf tests in "try".
258    if not is_perf:
259        luci.list_view_entry(
260            list_view = "try",
261            builder = "try/" + name,
262        )
263
264        luci.builder(
265            name = name,
266            bucket = "try",
267            executable = "recipe:angle",
268            service_account = "angle-try-builder@chops-service-accounts.iam.gserviceaccount.com",
269            properties = properties,
270            dimensions = dimensions,
271            build_numbers = True,
272        )
273
274        # Include all other bots in the CQ by default except the placeholder GCC configs.
275        if toolchain != "gcc":
276            luci.cq_tryjob_verifier(
277                cq_group = "master",
278                builder = "angle:try/" + name,
279                location_regexp = location_regexp,
280            )
281
282luci.bucket(
283    name = "ci",
284    acls = [
285        acl.entry(
286            acl.BUILDBUCKET_TRIGGERER,
287            users = [
288                "angle-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
289            ],
290        ),
291    ],
292)
293
294luci.bucket(
295    name = "try",
296    acls = [
297        acl.entry(
298            acl.BUILDBUCKET_TRIGGERER,
299            groups = [
300                "project-angle-tryjob-access",
301                "service-account-cq",
302            ],
303        ),
304    ],
305)
306
307luci.builder(
308    name = "presubmit",
309    bucket = "try",
310    executable = "recipe:run_presubmit",
311    service_account = "angle-try-builder@chops-service-accounts.iam.gserviceaccount.com",
312    build_numbers = True,
313    dimensions = {
314        "os": os.LINUX.dimension,
315    },
316    properties = {
317        "repo_name": "angle",
318        "runhooks": True,
319    },
320)
321
322luci.gitiles_poller(
323    name = "master-poller",
324    bucket = "ci",
325    repo = "https://chromium.googlesource.com/angle/angle",
326    refs = [
327        "refs/heads/master",
328    ],
329    schedule = "with 10s interval",
330)
331
332# name, clang, debug, cpu, uwp, trace_tests
333angle_builder("android-arm-dbg", debug = True, cpu = "arm")
334angle_builder("android-arm-rel", debug = False, cpu = "arm")
335angle_builder("android-arm64-dbg", debug = True, cpu = "arm64")
336angle_builder("android-arm64-rel", debug = False, cpu = "arm64")
337angle_builder("linux-clang-dbg", debug = True, cpu = "x64")
338angle_builder("linux-clang-rel", debug = False, cpu = "x64")
339angle_builder("linux-gcc-dbg", debug = True, cpu = "x64", toolchain = "gcc")
340angle_builder("linux-gcc-rel", debug = False, cpu = "x64", toolchain = "gcc")
341angle_builder("mac-dbg", debug = True, cpu = "x64")
342angle_builder("mac-rel", debug = False, cpu = "x64")
343angle_builder("win-clang-x86-dbg", debug = True, cpu = "x86")
344angle_builder("win-clang-x86-rel", debug = False, cpu = "x86")
345angle_builder("win-clang-x64-dbg", debug = True, cpu = "x64")
346angle_builder("win-clang-x64-rel", debug = False, cpu = "x64")
347angle_builder("win-msvc-x86-dbg", debug = True, cpu = "x86", toolchain = "msvc")
348angle_builder("win-msvc-x86-rel", debug = False, cpu = "x86", toolchain = "msvc")
349angle_builder("win-msvc-x64-dbg", debug = True, cpu = "x64", toolchain = "msvc")
350angle_builder("win-msvc-x64-rel", debug = False, cpu = "x64", toolchain = "msvc")
351angle_builder("winuwp-x64-dbg", debug = True, cpu = "x64", toolchain = "msvc", uwp = True)
352angle_builder("winuwp-x64-rel", debug = False, cpu = "x64", toolchain = "msvc", uwp = True)
353
354angle_builder("linux-trace-rel", debug = False, cpu = "x64", test_mode = "trace_tests")
355angle_builder("win-trace-rel", debug = False, cpu = "x64", test_mode = "trace_tests")
356
357angle_builder("android-perf", debug = False, cpu = "arm64")
358angle_builder("linux-perf", debug = False, cpu = "x64")
359angle_builder("win-perf", debug = False, cpu = "x64")
360
361# Views
362
363luci.console_view(
364    name = "ci",
365    title = "ANGLE CI Builders",
366    repo = "https://chromium.googlesource.com/angle/angle",
367    refs = ["refs/heads/master"],
368)
369
370luci.list_view(
371    name = "try",
372    title = "ANGLE Try Builders",
373)
374
375luci.list_view_entry(
376    list_view = "try",
377    builder = "try/presubmit",
378)
379
380# CQ
381
382luci.cq(
383    status_host = "chromium-cq-status.appspot.com",
384    submit_max_burst = 4,
385    submit_burst_delay = 480 * time.second,
386)
387
388luci.cq_group(
389    name = "master",
390    watch = cq.refset(
391        "https://chromium.googlesource.com/angle/angle",
392        refs = [r"refs/heads/master", r"refs/heads/main"],
393    ),
394    acls = [
395        acl.entry(
396            acl.CQ_COMMITTER,
397            groups = "project-angle-committers",
398        ),
399        acl.entry(
400            acl.CQ_DRY_RUNNER,
401            groups = "project-angle-tryjob-access",
402        ),
403    ],
404    verifiers = [
405        luci.cq_tryjob_verifier(
406            builder = "angle:try/presubmit",
407            disable_reuse = True,
408        ),
409        luci.cq_tryjob_verifier(
410            builder = "chromium:try/android-angle-chromium-try",
411        ),
412        luci.cq_tryjob_verifier(
413            builder = "chromium:try/android-angle-try",
414        ),
415        luci.cq_tryjob_verifier(
416            builder = "chromium:try/fuchsia-angle-try",
417        ),
418        luci.cq_tryjob_verifier(
419            builder = "chromium:try/linux-angle-chromium-try",
420        ),
421        luci.cq_tryjob_verifier(
422            builder = "chromium:try/linux-swangle-try-tot-angle-x64",
423        ),
424        luci.cq_tryjob_verifier(
425            builder = "chromium:try/mac-angle-chromium-try",
426        ),
427        luci.cq_tryjob_verifier(
428            builder = "chromium:try/win-angle-chromium-x64-try",
429        ),
430        luci.cq_tryjob_verifier(
431            builder = "chromium:try/win-angle-chromium-x86-try",
432        ),
433        luci.cq_tryjob_verifier(
434            builder = "chromium:try/win-swangle-try-tot-angle-x86",
435        ),
436    ],
437)
438