|
12 | 12 | import subprocess as sp |
13 | 13 | import sys |
14 | 14 | from dataclasses import dataclass |
| 15 | +from functools import cache |
15 | 16 | from glob import glob |
16 | 17 | from inspect import cleandoc |
17 | 18 | from os import getenv |
|
62 | 63 |
|
63 | 64 | # libm PR CI takes a long time and doesn't need to run unless relevant files have been |
64 | 65 | # changed. Anything matching this regex pattern will trigger a run. |
65 | | -TRIGGER_LIBM_PR_CI = ".*(libm|musl).*" |
| 66 | +TRIGGER_LIBM_CI_FILE_PAT = ".*(libm|musl).*" |
66 | 67 |
|
67 | 68 | TYPES = ["f16", "f32", "f64", "f128"] |
68 | 69 |
|
@@ -125,8 +126,18 @@ class PrInfo: |
125 | 126 | cfg: PrCfg |
126 | 127 |
|
127 | 128 | @classmethod |
128 | | - def load(cls, pr_number: int | str) -> Self: |
129 | | - """For a given PR number, query the body and commit list""" |
| 129 | + def from_env(cls) -> Self | None: |
| 130 | + """Create a PR object from the PR_NUMBER environment if set, `None` otherwise.""" |
| 131 | + pr_env = os.environ.get("PR_NUMBER") |
| 132 | + if pr_env is not None and len(pr_env) > 0: |
| 133 | + return cls.from_pr(pr_env) |
| 134 | + |
| 135 | + return None |
| 136 | + |
| 137 | + @classmethod |
| 138 | + @cache # Cache so we don't print info messages multiple times |
| 139 | + def from_pr(cls, pr_number: int | str) -> Self: |
| 140 | + """For a given PR number, query the body and commit list.""" |
130 | 141 | pr_info = sp.check_output( |
131 | 142 | [ |
132 | 143 | "gh", |
@@ -238,22 +249,23 @@ def may_skip_libm_ci(self) -> bool: |
238 | 249 | """If this is a PR and no libm files were changed, allow skipping libm |
239 | 250 | jobs.""" |
240 | 251 |
|
241 | | - if self.is_pr(): |
242 | | - return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed) |
| 252 | + # Always run on merge CI |
| 253 | + if not self.is_pr(): |
| 254 | + return False |
243 | 255 |
|
244 | | - return False |
| 256 | + # By default, run if there are any changed files matching the pattern |
| 257 | + return all(not re.match(TRIGGER_LIBM_CI_FILE_PAT, str(f)) for f in self.changed) |
245 | 258 |
|
246 | 259 | def emit_workflow_output(self): |
247 | 260 | """Create a JSON object a list items for each type's changed files, if any |
248 | 261 | did change, and the routines that were affected by the change. |
249 | 262 | """ |
250 | 263 |
|
251 | | - pr_number = os.environ.get("PR_NUMBER") |
252 | 264 | skip_tests = False |
253 | 265 | error_on_many_tests = False |
254 | 266 |
|
255 | | - if pr_number is not None and len(pr_number) > 0: |
256 | | - pr = PrInfo.load(pr_number) |
| 267 | + pr = PrInfo.from_env() |
| 268 | + if pr is not None: |
257 | 269 | skip_tests = pr.cfg.skip_extensive |
258 | 270 | error_on_many_tests = not pr.cfg.allow_many_extensive |
259 | 271 |
|
@@ -398,7 +410,7 @@ def handle_bench_regressions(args: list[str]): |
398 | 410 | eprint(USAGE) |
399 | 411 | exit(1) |
400 | 412 |
|
401 | | - pr = PrInfo.load(pr_number) |
| 413 | + pr = PrInfo.from_pr(pr_number) |
402 | 414 | if pr.cfg.allow_regressions: |
403 | 415 | eprint("PR allows regressions") |
404 | 416 | return |
|
0 commit comments