ci: Skip testing libm in PRs if it did not change
Many contributions to compiler-builtins don't have any need to touch libm, and could get by with the few minutes of CI for compiler-builtins rather than the ~30 minutes for libm. We already have some scripts that handle changed file detection, so expand its use to skip libm CI if it doesn't need to run.
This commit is contained in:
parent
a829d916b5
commit
8902f740da
4 changed files with 66 additions and 37 deletions
|
|
@ -16,6 +16,27 @@ env:
|
|||
BENCHMARK_RUSTC: nightly-2025-01-16 # Pin the toolchain for reproducable results
|
||||
|
||||
jobs:
|
||||
# Determine which tests should be run based on changed files.
|
||||
calculate_vars:
|
||||
name: Calculate workflow variables
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
outputs:
|
||||
extensive_matrix: ${{ steps.script.outputs.extensive_matrix }}
|
||||
may_skip_libm_ci: ${{ steps.script.outputs.may_skip_libm_ci }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 500
|
||||
- name: Fetch pull request ref
|
||||
run: git fetch origin "$GITHUB_REF:$GITHUB_REF"
|
||||
if: github.event_name == 'pull_request'
|
||||
- run: python3 ci/ci-util.py generate-matrix >> "$GITHUB_OUTPUT"
|
||||
id: script
|
||||
|
||||
test:
|
||||
name: Build and test
|
||||
timeout-minutes: 60
|
||||
|
|
@ -78,9 +99,11 @@ jobs:
|
|||
os: windows-2025
|
||||
channel: nightly-x86_64-gnu
|
||||
runs-on: ${{ matrix.os }}
|
||||
needs: [calculate_vars]
|
||||
env:
|
||||
BUILD_ONLY: ${{ matrix.build_only }}
|
||||
TEST_VERBATIM: ${{ matrix.test_verbatim }}
|
||||
MAY_SKIP_LIBM_CI: ${{ needs.calculate_vars.outputs.may_skip_libm_ci }}
|
||||
steps:
|
||||
- name: Print runner information
|
||||
run: uname -a
|
||||
|
|
@ -267,41 +290,21 @@ jobs:
|
|||
run: rustup set profile minimal && rustup default stable && rustup component add rustfmt
|
||||
- run: cargo fmt -- --check
|
||||
|
||||
# Determine which extensive tests should be run based on changed files.
|
||||
calculate_extensive_matrix:
|
||||
name: Calculate job matrix
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
outputs:
|
||||
matrix: ${{ steps.script.outputs.matrix }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 100
|
||||
- name: Fetch pull request ref
|
||||
run: git fetch origin "$GITHUB_REF:$GITHUB_REF"
|
||||
if: github.event_name == 'pull_request'
|
||||
- run: python3 ci/ci-util.py generate-matrix >> "$GITHUB_OUTPUT"
|
||||
id: script
|
||||
|
||||
extensive:
|
||||
name: Extensive tests for ${{ matrix.ty }}
|
||||
needs:
|
||||
# Wait on `clippy` so we have some confidence that the crate will build
|
||||
- clippy
|
||||
- calculate_extensive_matrix
|
||||
- calculate_vars
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 240 # 4 hours
|
||||
strategy:
|
||||
matrix:
|
||||
# Use the output from `calculate_extensive_matrix` to calculate the matrix
|
||||
# Use the output from `calculate_vars` to create the matrix
|
||||
# FIXME: it would be better to run all jobs (i.e. all types) but mark those that
|
||||
# didn't change as skipped, rather than completely excluding the job. However,
|
||||
# this is not currently possible https://github.com/actions/runner/issues/1985.
|
||||
include: ${{ fromJSON(needs.calculate_extensive_matrix.outputs.matrix).matrix }}
|
||||
include: ${{ fromJSON(needs.calculate_vars.outputs.extensive_matrix).extensive_matrix }}
|
||||
env:
|
||||
TO_TEST: ${{ matrix.to_test }}
|
||||
steps:
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ git history.
|
|||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess as sp
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
|
|
@ -68,6 +69,10 @@ IGNORE_FILES = [
|
|||
"libm/src/math/arch/intrinsics.rs",
|
||||
]
|
||||
|
||||
# libm PR CI takes a long time and doesn't need to run unless relevant files have been
|
||||
# changed. Anything matching this regex pattern will trigger a run.
|
||||
TRIGGER_LIBM_PR_CI = ".*(libm|musl).*"
|
||||
|
||||
TYPES = ["f16", "f32", "f64", "f128"]
|
||||
|
||||
|
||||
|
|
@ -116,7 +121,6 @@ class FunctionDef(TypedDict):
|
|||
type: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class Context:
|
||||
gh_ref: str | None
|
||||
changed: list[Path]
|
||||
|
|
@ -142,7 +146,7 @@ class Context:
|
|||
# the PR number), and sets this as `GITHUB_REF`.
|
||||
ref = self.gh_ref
|
||||
eprint(f"using ref `{ref}`")
|
||||
if ref is None or "merge" not in ref:
|
||||
if not self.is_pr():
|
||||
# If the ref is not for `merge` then we are not in PR CI
|
||||
eprint("No diff available for ref")
|
||||
return
|
||||
|
|
@ -170,6 +174,10 @@ class Context:
|
|||
)
|
||||
self.changed = [Path(p) for p in textlist.splitlines()]
|
||||
|
||||
def is_pr(self) -> bool:
|
||||
"""Check if we are looking at a PR rather than a push."""
|
||||
return self.gh_ref is not None and "merge" in self.gh_ref
|
||||
|
||||
@staticmethod
|
||||
def _ignore_file(fname: str) -> bool:
|
||||
return any(fname.startswith(pfx) for pfx in IGNORE_FILES)
|
||||
|
|
@ -196,7 +204,16 @@ class Context:
|
|||
|
||||
return ret
|
||||
|
||||
def make_workflow_output(self) -> str:
|
||||
def may_skip_libm_ci(self) -> bool:
|
||||
"""If this is a PR and no libm files were changed, allow skipping libm
|
||||
jobs."""
|
||||
|
||||
if self.is_pr():
|
||||
return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed)
|
||||
|
||||
return False
|
||||
|
||||
def emit_workflow_output(self):
|
||||
"""Create a JSON object a list items for each type's changed files, if any
|
||||
did change, and the routines that were affected by the change.
|
||||
"""
|
||||
|
|
@ -216,9 +233,10 @@ class Context:
|
|||
eprint("Skipping all extensive tests")
|
||||
|
||||
changed = self.changed_routines()
|
||||
ret = []
|
||||
matrix = []
|
||||
total_to_test = 0
|
||||
|
||||
# Figure out which extensive tests need to run
|
||||
for ty in TYPES:
|
||||
ty_changed = changed.get(ty, [])
|
||||
ty_to_test = [] if skip_tests else ty_changed
|
||||
|
|
@ -230,9 +248,14 @@ class Context:
|
|||
"to_test": ",".join(ty_to_test),
|
||||
}
|
||||
|
||||
ret.append(item)
|
||||
output = json.dumps({"matrix": ret}, separators=(",", ":"))
|
||||
eprint(f"output: {output}")
|
||||
matrix.append(item)
|
||||
|
||||
ext_matrix = json.dumps({"extensive_matrix": matrix}, separators=(",", ":"))
|
||||
may_skip = str(self.may_skip_libm_ci()).lower()
|
||||
print(f"extensive_matrix={ext_matrix}")
|
||||
print(f"may_skip_libm_ci={may_skip}")
|
||||
eprint(f"extensive_matrix={ext_matrix}")
|
||||
eprint(f"may_skip_libm_ci={may_skip}")
|
||||
eprint(f"total extensive tests: {total_to_test}")
|
||||
|
||||
if error_on_many_tests and total_to_test > MANY_EXTENSIVE_THRESHOLD:
|
||||
|
|
@ -242,8 +265,6 @@ class Context:
|
|||
)
|
||||
exit(1)
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def locate_baseline(flags: list[str]) -> None:
|
||||
"""Find the most recent baseline from CI, download it if specified.
|
||||
|
|
@ -398,8 +419,7 @@ def main():
|
|||
match sys.argv[1:]:
|
||||
case ["generate-matrix"]:
|
||||
ctx = Context()
|
||||
output = ctx.make_workflow_output()
|
||||
print(f"matrix={output}")
|
||||
ctx.emit_workflow_output()
|
||||
case ["locate-baseline", *flags]:
|
||||
locate_baseline(flags)
|
||||
case ["check-regressions", *args]:
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ run() {
|
|||
-e CI \
|
||||
-e CARGO_TARGET_DIR=/builtins-target \
|
||||
-e CARGO_TERM_COLOR \
|
||||
-e MAY_SKIP_LIBM_CI \
|
||||
-e RUSTFLAGS \
|
||||
-e RUST_BACKTRACE \
|
||||
-e RUST_COMPILER_RT_ROOT \
|
||||
|
|
|
|||
|
|
@ -174,6 +174,14 @@ done
|
|||
|
||||
# Test libm
|
||||
|
||||
# Make sure a simple build works
|
||||
cargo check -p libm --no-default-features --target "$target"
|
||||
|
||||
if [ "${MAY_SKIP_LIBM_CI:-}" = "true" ]; then
|
||||
echo "skipping libm PR CI"
|
||||
exit
|
||||
fi
|
||||
|
||||
mflags=()
|
||||
|
||||
# We enumerate features manually.
|
||||
|
|
@ -226,9 +234,6 @@ case "$target" in
|
|||
*windows-gnu) mflags+=(--exclude libm-macros) ;;
|
||||
esac
|
||||
|
||||
# Make sure a simple build works
|
||||
cargo check -p libm --no-default-features --target "$target"
|
||||
|
||||
if [ "${BUILD_ONLY:-}" = "1" ]; then
|
||||
# If we are on targets that can't run tests, verify that we can build.
|
||||
cmd=(cargo build --target "$target" --package libm)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue