builders.star (18817B)
1 #!/usr/bin/env lucicfg 2 3 # Copyright (c) 2025 The WebRTC project authors. All Rights Reserved. 4 # 5 # Use of this source code is governed by a BSD-style license 6 # that can be found in the LICENSE file in the root of the source 7 # tree. An additional intellectual property rights grant can be found 8 # in the file PATENTS. All contributing project authors may 9 # be found in the AUTHORS file in the root of the source tree. 10 11 """ CQ and CI bots """ 12 13 load("@chromium-luci//xcode.star", "xcode") 14 15 WEBRTC_XCODE = "17a5305k" 16 DEFAULT_CPU = "x86-64" 17 WEBRTC_GIT = "https://webrtc.googlesource.com/src" 18 19 # Add names of builders to remove from LKGR finder to this list. This is 20 # useful when a failure can be safely ignored while fixing it without 21 # blocking the LKGR finder on it. 22 skipped_lkgr_bots = [ 23 ] 24 25 lkgr_builders = [] 26 27 def os_from_name(name): 28 """Returns the 'os' dimension based on a builder name. 29 30 Args: 31 name: name of the builder. 32 Returns: 33 The os dimension to use for the provided builder. 34 """ 35 if "ios" in name.lower() or "mac" in name.lower(): 36 return "Mac" 37 if "win" in name.lower(): 38 return "Windows" 39 return "Linux" 40 41 def make_siso_properties(instance, jobs = None): 42 """Makes a default RBE property with the specified argument. 43 44 Args: 45 instance: RBE insatnce name. 46 jobs: Number of jobs to be used by the builder. 47 Returns: 48 A dictonary with the siso properties. 49 """ 50 siso_props = { 51 "project": instance, 52 "configs": ["builder"], 53 "enable_cloud_profiler": True, 54 "enable_cloud_trace": True, 55 "enable_monitoring": True, 56 } 57 if jobs: 58 siso_props["remote_jobs"] = jobs 59 props = { 60 "$build/siso": siso_props, 61 } 62 return props 63 64 def add_milo(builder, views): 65 """Add Milo console entries for the builder. 66 67 Args: 68 builder: builder name (str). 69 views: dict where keys are names of consoles and values are either a 70 category for the console (str, pipe-separated) or True, which means 71 adding to a list view rather than a console. 72 """ 73 for view_name, category in views.items(): 74 if category == None: 75 continue 76 elif type(category) == "string": 77 category, _, short_name = category.rpartition("|") 78 luci.console_view_entry( 79 console_view = view_name, 80 builder = builder, 81 category = category or None, 82 short_name = short_name or None, 83 ) 84 elif category == True: 85 luci.list_view_entry( 86 list_view = view_name, 87 builder = builder, 88 ) 89 else: 90 fail("Unexpected value for category: %r" % category) 91 92 def webrtc_builder( 93 name, 94 bucket, 95 dimensions, 96 properties = None, 97 recipe = "standalone", 98 priority = 30, 99 execution_timeout = 2 * time.hour, 100 **kwargs): 101 """WebRTC specific wrapper around luci.builder. 102 103 Args: 104 name: builder name (str). 105 bucket: The name of the bucket the builder belongs to. 106 dimensions: dict of Swarming dimensions (strings) to search machines by. 107 properties: dict of properties to pass to the recipe (on top of the default ones). 108 recipe: string with the name of the recipe to run. 109 priority: int [1-255] or None, indicating swarming task priority, lower is 110 more important. If None, defer the decision to Buildbucket service. 111 execution_timeout: int or None, how long to wait for a running build to finish before 112 forcefully aborting it and marking the build as timed out. If None, 113 defer the decision to Buildbucket service. 114 **kwargs: Pass on to webrtc_builder / luci.builder. 115 Returns: 116 A luci.builder. 117 """ 118 properties = properties or {} 119 resultdb_bq_table = "webrtc-ci.resultdb." + bucket + "_test_results" 120 return luci.builder( 121 name = name, 122 bucket = bucket, 123 executable = recipe, 124 dimensions = dimensions, 125 properties = properties, 126 execution_timeout = execution_timeout, 127 priority = priority, 128 build_numbers = True, 129 swarming_tags = ["vpython:native-python-wrapper"], 130 resultdb_settings = resultdb.settings( 131 enable = True, 132 bq_exports = [ 133 resultdb.export_test_results(bq_table = resultdb_bq_table), 134 ], 135 ), 136 **kwargs 137 ) 138 139 def ci_builder( 140 name, 141 ci_cat, 142 properties = None, 143 perf_cat = None, 144 prioritized = False, 145 **kwargs): 146 """Add a post-submit builder. 147 148 Args: 149 name: builder name (str). 150 ci_cat: the category + name for the /ci/ console, or None to omit from the console. 151 properties: dict of properties to pass to the recipe (on top of the default ones). 152 perf_cat: the category + name for the /perf/ console, or None to omit from the console. 153 prioritized: True to make this builder have a higher priority and never batch builds. 154 **kwargs: Pass on to webrtc_builder / luci.builder. 155 Returns: 156 A luci.builder. 157 158 Notifications are also disabled if a builder is not on either of /ci/ or /perf/ consoles. 159 """ 160 if prioritized: 161 kwargs["triggering_policy"] = scheduler.greedy_batching( 162 max_batch_size = 1, 163 max_concurrent_invocations = 3, 164 ) 165 kwargs["priority"] = 29 166 167 add_milo(name, {"ci": ci_cat, "perf": perf_cat}) 168 if ci_cat and not perf_cat: 169 lkgr_builders.append(name) 170 dimensions = ({"os": os_from_name(name), "pool": "luci.webrtc.ci", "cpu": kwargs.pop("cpu", DEFAULT_CPU)}) 171 dimensions["builderless"] = "1" 172 properties = properties or {} 173 properties["builder_group"] = "client.webrtc" 174 properties.update(make_siso_properties("rbe-webrtc-trusted")) 175 176 notifies = ["post_submit_failure_notifier", "infra_failure_notifier"] 177 notifies += ["webrtc_tree_closer"] if name not in skipped_lkgr_bots else [] 178 return webrtc_builder( 179 name = name, 180 dimensions = dimensions, 181 properties = properties, 182 bucket = "perf" if perf_cat else "ci", 183 service_account = "webrtc-ci-builder@chops-service-accounts.iam.gserviceaccount.com", 184 triggered_by = ["webrtc-gitiles-trigger-main"], 185 repo = WEBRTC_GIT, 186 notifies = notifies, 187 **kwargs 188 ) 189 190 def try_builder( 191 name, 192 properties = None, 193 try_cat = True, 194 cq = {}, 195 branch_cq = True, 196 builder = None, 197 **kwargs): 198 """Add a pre-submit builder. 199 200 Args: 201 name: builder name (str). 202 properties: dict of properties to pass to the recipe (on top of the default ones). 203 try_cat: boolean, whether to include this builder in the /try/ console. See also: `add_milo`. 204 cq: None to exclude this from all commit queues, or a dict of kwargs for cq_tryjob_verifier. 205 branch_cq: False to exclude this builder just from the release-branch CQ. 206 builder: builder to set in the dimensions, if None, builderless:1 is used. 207 **kwargs: Pass on to webrtc_builder / luci.builder. 208 Returns: 209 A luci.builder. 210 """ 211 add_milo(name, {"try": try_cat}) 212 dimensions = ({"os": os_from_name(name), "pool": "luci.webrtc.try", "cpu": DEFAULT_CPU}) 213 if builder != None: 214 dimensions["builder"] = builder 215 else: 216 dimensions["builderless"] = "1" 217 properties = properties or {} 218 properties["builder_group"] = "tryserver.webrtc" 219 properties.update(make_siso_properties("rbe-webrtc-untrusted")) 220 if cq != None: 221 luci.cq_tryjob_verifier(name, cq_group = "cq", **cq) 222 if branch_cq: 223 luci.cq_tryjob_verifier(name, cq_group = "cq_branch", **cq) 224 225 return webrtc_builder( 226 name = name, 227 dimensions = dimensions, 228 properties = properties, 229 bucket = "try", 230 service_account = "webrtc-try-builder@chops-service-accounts.iam.gserviceaccount.com", 231 notifies = ["infra_failure_notifier"], 232 **kwargs 233 ) 234 235 def perf_builder(name, perf_cat, **kwargs): 236 """Add a perf builder. 237 238 Args: 239 name: builder name (str). 240 perf_cat: the category + name for the /perf/ console, or None to omit from the console. 241 **kwargs: Pass on to webrtc_builder / luci.builder. 242 Returns: 243 A luci.builder. 244 245 Notifications are also disabled. 246 """ 247 add_milo(name, {"perf": perf_cat}) 248 properties = make_siso_properties("rbe-webrtc-trusted") 249 properties["builder_group"] = "client.webrtc.perf" 250 dimensions = {"pool": "luci.webrtc.perf", "os": "Linux"} 251 return webrtc_builder( 252 name = name, 253 dimensions = dimensions, 254 properties = properties, 255 bucket = "perf", 256 service_account = "webrtc-ci-builder@chops-service-accounts.iam.gserviceaccount.com", 257 # log_base of 1.7 means: 258 # when there are P pending builds, LUCI will batch the first B builds. 259 # P: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... 260 # B: 1 1 2 2 3 3 3 3 4 4 4 4 4 4 5 ... 261 triggering_policy = scheduler.logarithmic_batching(log_base = 1.7), 262 repo = WEBRTC_GIT, 263 execution_timeout = 3 * time.hour, 264 notifies = ["post_submit_failure_notifier", "infra_failure_notifier"], 265 **kwargs 266 ) 267 268 def cron_builder(name, service_account = None, **kwargs): 269 if service_account == None: 270 service_account = "chromium-webrtc-autoroll@webrtc-ci.iam.gserviceaccount.com" 271 add_milo(name, {"cron": True}) 272 return webrtc_builder( 273 name = name, 274 dimensions = {"pool": "luci.webrtc.cron", "os": "Linux", "cpu": DEFAULT_CPU}, 275 bucket = "cron", 276 service_account = service_account, 277 notifies = ["cron_notifier"], 278 **kwargs 279 ) 280 281 def chromium_try_builder(name, **kwargs): 282 return try_builder( 283 name, 284 builder = "chromium-compile", 285 recipe = "chromium_trybot", 286 branch_cq = False, 287 execution_timeout = 3 * time.hour, 288 **kwargs 289 ) 290 291 def normal_builder_factory(**common_kwargs): 292 def builder(*args, **kwargs): 293 kwargs.update(common_kwargs) 294 return ci_builder(*args, **kwargs) 295 296 def try_job(name, **kwargs): 297 kwargs.update(common_kwargs) 298 return try_builder(name, **kwargs) 299 300 return builder, try_job 301 302 # Mixins: 303 304 ios_builder, ios_try_job = normal_builder_factory( 305 properties = {"xcode_build_version": xcode.for_ios(WEBRTC_XCODE).version}, 306 caches = [xcode.for_ios(WEBRTC_XCODE).cache], 307 ) 308 309 # Actual builder configuration: 310 311 ci_builder("Android32 (dbg)", "Android|arm|dbg") 312 try_builder("android_compile_arm_dbg", cq = {"experiment_percentage": 100}) 313 try_builder("android_arm_dbg") 314 ci_builder("Android32", "Android|arm|rel") 315 try_builder("android_arm_rel") 316 ci_builder("Android32 Builder arm", "Android|arm|size", perf_cat = "Android|arm|Builder|", prioritized = True) 317 try_builder("android_compile_arm_rel") 318 perf_builder("Perf Android32 (R Pixel5)", "Android|arm|Tester|R Pixel5", triggered_by = ["Android32 Builder arm"]) 319 try_builder("android_compile_arm64_dbg", cq = None) 320 try_builder("android_arm64_dbg", cq = None) 321 ci_builder("Android64", "Android|arm64|rel") 322 try_builder("android_arm64_rel") 323 ci_builder("Android64 Builder arm64", "Android|arm64|size", perf_cat = "Android|arm64|Builder|", prioritized = True) 324 perf_builder("Perf Android64 (R Pixel5)", "Android|arm64|Tester|R Pixel5", triggered_by = ["Android64 Builder arm64"]) 325 try_builder("android_compile_arm64_rel") 326 ci_builder("Android64 Builder x64 (dbg)", "Android|x64|dbg") 327 try_builder("android_compile_x64_dbg") 328 try_builder("android_compile_x64_rel", cq = None) 329 ci_builder("Android32 Builder x86 (dbg)", "Android|x86|dbg") 330 try_builder("android_compile_x86_dbg") 331 ci_builder("Android32 Builder x86", "Android|x86|rel") 332 try_builder("android_compile_x86_rel") 333 ci_builder("Android32 (more configs)", "Android|arm|more") 334 try_builder("android_arm_more_configs") 335 chromium_try_builder("android_chromium_compile") 336 337 ios_builder("iOS64 Debug", "iOS|arm64|dbg") 338 ios_try_job("ios_compile_arm64_dbg") 339 ios_builder("iOS64 Release", "iOS|arm64|rel") 340 ios_try_job("ios_compile_arm64_rel") 341 ios_builder("iOS Debug (simulator)", "iOS|x64|sim") 342 343 ios_try_job("ios_dbg_simulator") 344 ios_builder("iOS API Framework Builder", "iOS|fat|size", recipe = "ios_api_framework", prioritized = True) 345 ios_try_job("ios_api_framework", recipe = "ios_api_framework") 346 347 ci_builder("Linux32 Debug", "Linux|x86|dbg") 348 try_builder("linux_x86_dbg") 349 ci_builder("Linux32 Release", "Linux|x86|rel") 350 try_builder("linux_x86_rel") 351 ci_builder("Linux64 Debug", "Linux|x64|dbg") 352 try_builder("linux_dbg", cq = None) 353 try_builder("linux_compile_dbg") 354 ci_builder("Linux64 Release", "Linux|x64|rel") 355 try_builder("linux_rel") 356 ci_builder("Linux64 Builder", "Linux|x64|size", perf_cat = "Linux|x64|Builder|", prioritized = True) 357 try_builder("linux_compile_rel") 358 perf_builder("Perf Linux", "Linux|x64|Tester", triggered_by = ["Linux64 Builder"]) 359 ci_builder("Linux32 Debug (ARM)", "Linux|arm|dbg") 360 try_builder("linux_compile_arm_dbg") 361 ci_builder("Linux32 Release (ARM)", "Linux|arm|rel") 362 try_builder("linux_compile_arm_rel") 363 ci_builder("Linux64 Debug (ARM)", "Linux|arm64|dbg") 364 try_builder("linux_compile_arm64_dbg") 365 ci_builder("Linux64 Release (ARM)", "Linux|arm64|rel") 366 try_builder("linux_compile_arm64_rel") 367 ci_builder("Linux Asan", "Linux|x64|asan") 368 try_builder("linux_asan") 369 ci_builder("Linux MSan", "Linux|x64|msan") 370 try_builder("linux_msan") 371 ci_builder("Linux Tsan v2", "Linux|x64|tsan") 372 try_builder("linux_tsan2") 373 ci_builder("Linux UBSan", "Linux|x64|ubsan") 374 try_builder("linux_ubsan") 375 ci_builder("Linux UBSan vptr", "Linux|x64|ubsan") 376 try_builder("linux_ubsan_vptr") 377 ci_builder("Linux64 Release (Libfuzzer)", "Linux|x64|fuzz", recipe = "libfuzzer") 378 try_builder("linux_libfuzzer_rel", recipe = "libfuzzer") 379 ci_builder("Linux (more configs)", "Linux|x64|more") 380 try_builder("linux_more_configs") 381 try_builder("linux_coverage") 382 chromium_try_builder("webrtc_linux_chromium") 383 chromium_try_builder("linux_chromium_compile", cq = None) 384 chromium_try_builder("linux_chromium_compile_dbg") 385 386 ci_builder("Fuchsia Builder", ci_cat = None, perf_cat = "Fuchsia|x64|Builder|", prioritized = True) 387 ci_builder("Fuchsia Release", "Fuchsia|x64|rel") 388 try_builder("fuchsia_rel") 389 perf_builder("Perf Fuchsia", "Fuchsia|x64|Tester|", triggered_by = ["Fuchsia Builder"]) 390 391 ci_builder("Mac64 Debug", "Mac|x64|dbg") 392 try_builder("mac_dbg", cq = None) 393 try_builder("mac_compile_dbg") 394 ci_builder("Mac64 Release", "Mac|x64|rel") 395 try_builder("mac_rel") 396 try_builder("mac_compile_rel", cq = None) 397 ci_builder("Mac64 Builder", ci_cat = None, perf_cat = "Mac|x64|Builder|") 398 ci_builder("MacArm64 Builder", ci_cat = None, perf_cat = "Mac|arm64|Builder|") 399 perf_builder("Perf Mac 11", "Mac|x64|Tester|11", triggered_by = ["Mac64 Builder"]) 400 perf_builder("Perf Mac M1 Arm64 12", "Mac|arm64|Tester|12", triggered_by = ["MacArm64 Builder"]) 401 ci_builder("Mac Asan", "Mac|x64|asan") 402 try_builder("mac_asan") 403 ci_builder("MacARM64 M1 Release", "Mac|arm64M1|rel", cpu = "arm64-64-Apple_M1") 404 try_builder("mac_rel_m1") 405 try_builder("mac_dbg_m1") 406 407 # TODO: b/427073823 - Re-enable once the slow compilation issue is fixed. 408 chromium_try_builder("mac_chromium_compile", cq = None) 409 410 ci_builder("Win32 Debug (Clang)", "Win Clang|x86|dbg") 411 try_builder("win_x86_clang_dbg", cq = None) 412 try_builder("win_compile_x86_clang_dbg") 413 ci_builder("Win32 Release (Clang)", "Win Clang|x86|rel") 414 try_builder("win_x86_clang_rel") 415 try_builder("win_compile_x86_clang_rel", cq = None) 416 ci_builder("Win64 Builder (Clang)", ci_cat = None, perf_cat = "Win|x64|Builder|") 417 perf_builder("Perf Win 10", "Win|x64|Tester|10", triggered_by = ["Win64 Builder (Clang)"]) 418 ci_builder("Win64 Debug (Clang)", "Win Clang|x64|dbg") 419 try_builder("win_x64_clang_dbg") 420 try_builder("win_compile_x64_clang_dbg") 421 ci_builder("Win64 Release (Clang)", "Win Clang|x64|rel") 422 try_builder("win_x64_clang_rel") 423 try_builder("win_compile_x64_clang_rel") 424 ci_builder("Win64 ASan", "Win Clang|x64|asan") 425 try_builder("win_asan") 426 ci_builder("Win (more configs)", "Win Clang|x86|more") 427 try_builder("win_x86_more_configs") 428 try_builder("win11_release", cq = None) 429 try_builder("win11_debug", cq = None) 430 chromium_try_builder("win_chromium_compile") 431 chromium_try_builder("win_chromium_compile_dbg") 432 433 try_builder("iwyu_verifier") 434 435 try_builder( 436 "presubmit", 437 recipe = "run_presubmit", 438 properties = {"repo_name": "webrtc", "runhooks": True}, 439 priority = 28, 440 cq = {"disable_reuse": True}, 441 ) 442 443 cron_builder( 444 "Auto-roll - WebRTC DEPS", 445 recipe = "auto_roll_webrtc_deps", 446 schedule = "0 */2 * * *", # Every 2 hours. 447 ) 448 449 cron_builder( 450 "WebRTC version update", 451 recipe = "update_webrtc_binary_version", 452 schedule = "0 4 * * *", # Every day at 4am. 453 service_account = "webrtc-version-updater@webrtc-ci.iam.gserviceaccount.com", 454 ) 455 456 lkgr_config = { 457 "project": "webrtc", 458 "source_url": WEBRTC_GIT, 459 "status_url": "https://webrtc-status.appspot.com", 460 "allowed_lag": 9, # hours (up to 10x during low commit volume periods) 461 "allowed_gap": 150, # commits behind 462 "buckets": { 463 "webrtc/ci": { 464 # bucket alias: luci.webrtc.ci 465 "builders": [ 466 b 467 for b in sorted(lkgr_builders) 468 if b not in skipped_lkgr_bots 469 ], 470 }, 471 "chromium/webrtc.fyi": { 472 # bucket alias: luci.chromium.webrtc.fyi 473 "builders": [ 474 "WebRTC Chromium FYI Android Builder (dbg)", 475 "WebRTC Chromium FYI Android Builder", 476 "WebRTC Chromium FYI Android Tester", 477 "WebRTC Chromium FYI Linux Builder (dbg)", 478 "WebRTC Chromium FYI Linux Builder", 479 "WebRTC Chromium FYI Linux Tester", 480 "WebRTC Chromium FYI Mac Builder (dbg)", 481 "WebRTC Chromium FYI Mac Builder", 482 "WebRTC Chromium FYI Mac Tester", 483 "WebRTC Chromium FYI Win Builder (dbg)", 484 "WebRTC Chromium FYI Win Builder", 485 "WebRTC Chromium FYI Win10 Tester", 486 # TODO: b/441273941 - Re-enable once the ios infra issue is resolved 487 #"WebRTC Chromium FYI ios-device", 488 #"WebRTC Chromium FYI ios-simulator", 489 ], 490 }, 491 }, 492 } 493 494 cron_builder( 495 "WebRTC lkgr finder", 496 recipe = "lkgr_finder", 497 properties = { 498 "project": "webrtc", 499 "repo": WEBRTC_GIT, 500 "ref": "refs/heads/lkgr", 501 "src_ref": "refs/heads/main", 502 "lkgr_status_gs_path": "chromium-webrtc/lkgr-status", 503 "config": lkgr_config, 504 }, 505 schedule = "*/10 * * * *", # Every 10 minutes. 506 )