mirror of
https://github.com/akitaonrails/ai-memory.git
synced 2026-11-05 14:52:30 +00:00
ci: run the Linux/macOS suite under nextest, cancel superseded PR runs
nextest's per-test processes cut the test step from 381s to 242s on Linux and from 977s to 427s on macOS. A `ci` profile keeps it a full gate: every tier, no retries, a hang kill at 10 minutes. Doctests still run through `cargo test --doc`, which nextest does not cover. Windows stays on `cargo test`. nextest (732s vs 665s), a Dev Drive (1161s warm) and a two-way nextest partition (841s wall vs 820s) were each measured there and none beat it. ci, nix and macos-app now cancel an in-progress run when a newer commit lands on the same pull request; pushes and dispatches are never cancelled. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MDbhmszrjG9s5MrPrTuNtm
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
f296bab558
commit
d1da58982a
+14
-9
@@ -7,8 +7,7 @@
|
||||
# needs more than ~1s alone either gets fixed or moves into a `slow`/`stress`
|
||||
# module, and the 5s slow-timeout below surfaces new offenders in every run's
|
||||
# summary. Two independent things run the skipped tier anyway: the pre-push
|
||||
# hook (`scripts/install-git-hooks.sh`) and CI, which uses `cargo test` and
|
||||
# never reads this file.
|
||||
# hook (`scripts/install-git-hooks.sh`) and CI, which runs `-P ci` below.
|
||||
|
||||
[profile.default]
|
||||
default-filter = "not test(/(^|::)(slow|stress)[a-z0-9_]*::/)"
|
||||
@@ -31,15 +30,21 @@ failure-output = "immediate-final"
|
||||
status-level = "fail"
|
||||
# The slow tier legitimately sits in the 10-20s range.
|
||||
slow-timeout = { period = "30s", terminate-after = 8 }
|
||||
# No retries: no genuinely flaky test has been found in this suite, and a
|
||||
# local gate should tell the truth. Retries belong in profile.ci.
|
||||
# No retries: a gate should tell the truth (profile.ci follows the same rule).
|
||||
|
||||
[profile.ci]
|
||||
# CI runs every tier, like `cargo tf`: `all()` overrides the everyday skip it
|
||||
# would otherwise inherit from profile.default.
|
||||
default-filter = "all()"
|
||||
# Runner contention is real and separate from flakiness.
|
||||
retries = 2
|
||||
# No retries: a retry turns a flaky test green, and the suite's real flakes
|
||||
# were found because CI showed them failing.
|
||||
retries = 0
|
||||
failure-output = "immediate-final"
|
||||
fail-fast = false
|
||||
|
||||
[profile.ci.junit]
|
||||
path = "junit.xml"
|
||||
status-level = "fail"
|
||||
final-status-level = "slow"
|
||||
# Hosted runners (Windows especially) are several times slower than a
|
||||
# workstation, so the everyday 5s marker would flag most of the suite. Kill a
|
||||
# test only after 10 minutes: long enough for a slow runner, short enough that
|
||||
# a hang fails the job instead of eating its whole timeout.
|
||||
slow-timeout = { period = "60s", terminate-after = 10 }
|
||||
|
||||
@@ -16,6 +16,13 @@ env:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# A newer push to a pull request supersedes its in-flight run, so cancel it.
|
||||
# Pushes to main and manual dispatches are never cancelled: each is the record
|
||||
# for its commit (a dispatch is the pre-release matrix on an exact SHA).
|
||||
concurrency:
|
||||
group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
fmt:
|
||||
name: rustfmt
|
||||
@@ -70,7 +77,14 @@ jobs:
|
||||
- name: Regenerate the Tailwind bundle
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: echo "TAILWIND_BUILD=1" >> "$GITHUB_ENV"
|
||||
- run: cargo test --workspace --all-targets
|
||||
# nextest runs every test binary's tests in parallel across the runner's
|
||||
# cores; `cargo test` ran the binaries one after another, which was most
|
||||
# of this job's wall clock. Profile `ci` (.config/nextest.toml) runs every
|
||||
# tier, including slow::/stress::, with no retries.
|
||||
- uses: taiki-e/install-action@f7e5d7c961414b23f5b25b2da9294395d08513ad # v2.87.26
|
||||
with:
|
||||
tool: cargo-nextest
|
||||
- run: cargo nextest run --workspace --all-targets --profile ci
|
||||
# `--all-targets` deliberately excludes doctests, so a doc-comment code
|
||||
# block that fails to compile (e.g. an indented shell example rustdoc
|
||||
# reads as Rust) shipped unnoticed. Run them explicitly.
|
||||
|
||||
@@ -8,6 +8,12 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# Same rule as ci.yml: a newer push to a pull request cancels its in-flight
|
||||
# run; pushes, schedules and dispatches each run to completion.
|
||||
concurrency:
|
||||
group: macos-app-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
swift-test:
|
||||
name: swift test (ai-memory-macos)
|
||||
|
||||
@@ -51,6 +51,12 @@ on:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
# Same rule as ci.yml: a newer push to a pull request cancels its in-flight
|
||||
# run; pushes, schedules and dispatches each run to completion.
|
||||
concurrency:
|
||||
group: nix-${{ github.event.pull_request.number || github.sha }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
build-linux:
|
||||
name: nix build (x86_64-linux)
|
||||
|
||||
@@ -243,9 +243,10 @@ cargo deny check # dependency policy (if installed)
|
||||
`.config/nextest.toml`. Run them from the repo root. `cargo t` builds the
|
||||
workspace's default members, which is every shipped crate; the evals harness
|
||||
is two more test binaries that only `cargo tf`, the pre-push hook, and CI
|
||||
build (`--workspace`). Without nextest,
|
||||
`cargo test --workspace --all-targets` is what CI runs: everything, slower,
|
||||
no tiers.
|
||||
build (`--workspace`). Linux and macOS CI run `cargo nextest run --workspace
|
||||
--all-targets --profile ci`: every tier like `cargo tf`, no retries, a
|
||||
10-minute hang kill. Without nextest, `cargo test --workspace --all-targets`
|
||||
covers the same tests, slower, no tiers.
|
||||
|
||||
- **Slow tier.** A test whose module path has a segment starting with `slow`
|
||||
or `stress` (`packaging::slow::*`, `stress_autoscope::*`) runs only under
|
||||
@@ -332,7 +333,9 @@ no tiers.
|
||||
locking, git plumbing, or the hook bundle, so the corresponding Windows
|
||||
jobs run before the merge rather than only on the nightly schedule. Both
|
||||
the Rust test job and the hook-bundle job use this label gate on pull
|
||||
requests; they also run on manual dispatch.
|
||||
requests; they also run on manual dispatch. That job stays on plain
|
||||
`cargo test`: nextest, partitioning across runners, and a Dev Drive were
|
||||
each measured there and none beat it.
|
||||
|
||||
## Code style guidelines
|
||||
|
||||
@@ -484,9 +487,11 @@ Additional boundary rules:
|
||||
- New disk+SQL mutations need recovery/rollback tests.
|
||||
- The recall-eval framework lives at
|
||||
`crates/ai-memory-consolidate/tests/recall_eval.rs`.
|
||||
- Tests run with `cargo t` locally and `cargo test --workspace --all-targets`
|
||||
in CI (plus `cargo test --workspace --doc`, which `--all-targets` excludes,
|
||||
for doc-comment code blocks).
|
||||
- Tests run with `cargo t` locally,
|
||||
`cargo nextest run --workspace --all-targets --profile ci` in Linux/macOS
|
||||
CI, and `cargo test --workspace --all-targets` on Windows (plus
|
||||
`cargo test --workspace --doc`, since neither runs doctests, for
|
||||
doc-comment code blocks).
|
||||
|
||||
## Security considerations
|
||||
|
||||
|
||||
+2
-1
@@ -53,7 +53,8 @@ cargo deny check # dependency policy
|
||||
```
|
||||
|
||||
`cargo tf` needs nextest (`cargo install cargo-nextest --locked`); without it,
|
||||
`cargo test --workspace --all-targets` is the equivalent and is what CI runs.
|
||||
`cargo test --workspace --all-targets` is the equivalent. Linux and macOS CI run the
|
||||
same tests with `cargo nextest run --workspace --all-targets --profile ci`.
|
||||
If `cargo-deny` or `cargo-audit` are not installed:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -759,7 +759,23 @@ fn workflows_keep_fixed_rust_jobs_on_the_fixed_toolchain() {
|
||||
fn dev_loop_is_wired_consistently() {
|
||||
// One gate, written down in four places; keep them from drifting apart.
|
||||
let ci = read_repo(".github/workflows/ci.yml");
|
||||
assert!(ci.contains("cargo test --workspace --all-targets"));
|
||||
assert!(ci.contains("cargo nextest run --workspace --all-targets --profile ci"));
|
||||
// nextest does not run doctests.
|
||||
assert!(ci.contains("cargo test --workspace --doc"));
|
||||
// Windows stays on plain `cargo test`: nextest's per-test processes cost
|
||||
// more there than its parallelism saves.
|
||||
let windows = read_repo(".github/workflows/windows.yml");
|
||||
assert!(windows.contains("cargo test --workspace --all-targets"));
|
||||
// The `ci` profile is what makes CI a full gate: every tier, nothing
|
||||
// turned green by a retry.
|
||||
let nextest = read_repo(".config/nextest.toml");
|
||||
let ci_profile = nextest
|
||||
.split("[profile.ci]")
|
||||
.nth(1)
|
||||
.expect("nextest.toml defines [profile.ci]");
|
||||
let ci_profile = ci_profile.split("\n[").next().unwrap_or(ci_profile);
|
||||
assert!(ci_profile.contains("default-filter = \"all()\""));
|
||||
assert!(ci_profile.contains("retries = 0"));
|
||||
assert!(
|
||||
ci.contains("TAILWIND_BUILD=1"),
|
||||
"CI must regenerate the stylesheet somewhere"
|
||||
|
||||
Reference in New Issue
Block a user