|
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