|
59 | 59 | # accidentally spending huge amounts of CI time.
|
60 | 60 | ALLOW_MANY_EXTENSIVE_DIRECTIVE = "ci: allow-many-extensive"
|
61 | 61 | MANY_EXTENSIVE_THRESHOLD = 20
|
| 62 | +# Require tests for `libm` |
| 63 | +TEST_LIBM_DIRECTIVE = "ci: test-libm" |
62 | 64 |
|
63 | 65 | # Don't run exhaustive tests if these files change, even if they contaiin a function
|
64 | 66 | # definition.
|
@@ -89,9 +91,25 @@ class PrInfo:
|
89 | 91 | created_at: str
|
90 | 92 | number: int
|
91 | 93 |
|
| 94 | + @classmethod |
| 95 | + def from_env(cls, gh_ref: str | None = None) -> Self | None: |
| 96 | + """Create a PR object from the PR_NUMBER environment if set, using a ref |
| 97 | + as a fallback. Returns `None` is there is no PR found. |
| 98 | + """ |
| 99 | + pr_env = os.environ.get("PR_NUMBER") |
| 100 | + if pr_env is not None and len(pr_env) > 0: |
| 101 | + return cls(*PrInfo.load(pr_env)) |
| 102 | + |
| 103 | + if gh_ref is None: |
| 104 | + return None |
| 105 | + |
| 106 | + # Split `refs/pull/1234/merge` |
| 107 | + pr_number = int(gh_ref.split("/")[2]) |
| 108 | + return cls(*PrInfo.load(pr_number)) |
| 109 | + |
92 | 110 | @classmethod
|
93 | 111 | def load(cls, pr_number: int | str) -> Self:
|
94 |
| - """For a given PR number, query the body and commit list""" |
| 112 | + """For a given PR number, query the body and commit list.""" |
95 | 113 | pr_info = sp.check_output(
|
96 | 114 | [
|
97 | 115 | "gh",
|
@@ -207,22 +225,31 @@ def may_skip_libm_ci(self) -> bool:
|
207 | 225 | """If this is a PR and no libm files were changed, allow skipping libm
|
208 | 226 | jobs."""
|
209 | 227 |
|
210 |
| - if self.is_pr(): |
211 |
| - return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed) |
| 228 | + # Always run on merge CI |
| 229 | + if not self.is_pr(): |
| 230 | + return False |
| 231 | + |
| 232 | + pr = PrInfo.from_env() |
| 233 | + if pr is None: |
| 234 | + eprint("Is a PR but couldn't load PrInfo") |
| 235 | + exit(1) |
| 236 | + |
| 237 | + # Allow opting in to libm tests |
| 238 | + if pr.contains_directive(TEST_LIBM_DIRECTIVE): |
| 239 | + return True |
212 | 240 |
|
213 |
| - return False |
| 241 | + return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed) |
214 | 242 |
|
215 | 243 | def emit_workflow_output(self):
|
216 | 244 | """Create a JSON object a list items for each type's changed files, if any
|
217 | 245 | did change, and the routines that were affected by the change.
|
218 | 246 | """
|
219 | 247 |
|
220 |
| - pr_number = os.environ.get("PR_NUMBER") |
221 | 248 | skip_tests = False
|
222 | 249 | error_on_many_tests = False
|
223 | 250 |
|
224 |
| - if pr_number is not None and len(pr_number) > 0: |
225 |
| - pr = PrInfo.load(pr_number) |
| 251 | + pr = PrInfo.from_env() |
| 252 | + if pr is not None: |
226 | 253 | skip_tests = pr.contains_directive(SKIP_EXTENSIVE_DIRECTIVE)
|
227 | 254 | error_on_many_tests = not pr.contains_directive(
|
228 | 255 | ALLOW_MANY_EXTENSIVE_DIRECTIVE
|
|
0 commit comments