From f5d62b6102cd0f68e1d1ef2df4858b9fc2d9310e Mon Sep 17 00:00:00 2001 From: Alexander Nachtmann Date: Wed, 14 Oct 2026 15:00:54 +0200 Subject: [PATCH] Cancel superseded PR runs and drop macOS from the integration matrices A push to a PR now cancels that PR's running checks; pushes to main and tags still always finish. badge-action, consumer-coverage and readme-badge-coverage run on Linux and Windows only: macOS adds no path handling of its own, and BadgeActionTests run badge.sh under macOS's bash 3.2 in local runs. macOS runners remain for the release-only osx-arm64 pack. Co-Authored-By: Claude Opus 5.5 --- .agents/skills/dotcov-ci-workflows/SKILL.md | 4 ++-- .github/tests/README.md | 8 ++++---- .github/workflows/nuget-publish.yml | 15 ++++++++++++--- README.md | 9 +++++---- tests/AGENTS.md | 4 ++-- 5 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.agents/skills/dotcov-ci-workflows/SKILL.md b/.agents/skills/dotcov-ci-workflows/SKILL.md index 9e93660..d4d76f1 100644 --- a/.agents/skills/dotcov-ci-workflows/SKILL.md +++ b/.agents/skills/dotcov-ci-workflows/SKILL.md @@ -23,14 +23,14 @@ description: >- the distinction between PR/main validation and release-triggered packing and publication. DotCov's Linux/Windows test matrix applies to ordinary CI; Fallout upstream's release-only cross-platform policy does not apply here. - The `badge-action` Linux/Windows/macOS matrix invokes the composite action with + The `badge-action` Linux/Windows matrix invokes the composite action with its default tool installation against a local bare origin; preserve that isolation and its publication dependency so validation never recreates GitHub's `badges` branch. The `readme-badge-coverage` matrix additionally compares pinned README badge evidence with fresh measurements of the exact upstream commits. Preserve its evidence files, local badge origins, and release dependency. The `consumer-coverage` matrix runs pinned TypeScript/Python upstream suites - on all three hosts, compares native JSON and DotCov counts, and publishes only + on Linux and Windows, compares native JSON and DotCov counts, and publishes only to a local origin. Keep the report comparisons and release dependency intact. 3. Preserve the observable contracts: - Publication depends on build, tests, and both package groups. Keep the diff --git a/.github/tests/README.md b/.github/tests/README.md index bddd85c..b732407 100644 --- a/.github/tests/README.md +++ b/.github/tests/README.md @@ -2,7 +2,7 @@ `consumer_coverage.py` is an integration test used by the `consumer-coverage` job in [CI](../workflows/nuget-publish.yml). It invokes the current DotCov CLI and the actual -composite badge action. Every PR runs both languages on Linux, Windows, and macOS. +composite badge action. Every PR runs both languages on Linux and Windows. The upstream projects already have coverage configuration. Their sources and tests are unchanged: the TypeScript project declares a 100% Jest threshold, and the Python project @@ -129,7 +129,7 @@ DotCov's own 100% line/branch gate and the other targets' gates are unchanged. Pydash uses Python 3.12 and the coverage.py 7.16.0 / pytest 9.1.1 / pytest-cov 7.1.0 versions recorded in its published [Python 3.12 CI job](https://github.com/dgilland/pydash/actions/runs/33272967265/job/99154667022). That upstream job ran Python 3.12.14. CI selects the available Python 3.12 patch release on -each host (setup-python does not distribute 3.12.14 on Windows or macOS); exact count +each host (setup-python does not distribute 3.12.14 on Windows); exact count comparisons remain mandatory. Its 2,274 unit tests and doctests run with upstream's targets, source configuration, exclusions, and 100% gate. CI installs the package editable so per-file paths refer to the checkout. A local pytest plugin supplies a virtual clock and timer queue only to @@ -140,14 +140,14 @@ The plugin replaces module references for those two tests and restores them afte test; other tests and the Python standard library keep real time. Timers execute pydash's actual callbacks in deadline order, including cancellation and max-wait behavior. -CI first runs `test_pydash_clock.py` on all three hosts. It repeats both unchanged upstream +CI first runs `test_pydash_clock.py` on both hosts. It repeats both unchanged upstream tests with real 30 ms scheduling stalls, verifies clock isolation and JUnit evidence, and proves that deliberately early or late timers still fail upstream assertions. The full measurement then requires all 2,274 tests to pass with zero skips or errors, evidence that exactly the two intended tests used the clock, and the same exact coverage counts. There are no retries, merged partial measurements, extra exclusions, or relaxed thresholds. -A separate `test_pydash_threads.py` suite runs on Linux, Windows, and macOS using pydash's +A separate `test_pydash_threads.py` suite runs on Linux and Windows using pydash's real clock, `threading.Timer`, and locks, without loading the virtual-clock plugin. Five scenarios each run three times: background delivery and last-result reuse; cancellation after a timer has fired; a caller arriving during a blocked callback; eight concurrent diff --git a/.github/workflows/nuget-publish.yml b/.github/workflows/nuget-publish.yml index d6fd8d1..fcfdfbf 100644 --- a/.github/workflows/nuget-publish.yml +++ b/.github/workflows/nuget-publish.yml @@ -16,6 +16,12 @@ permissions: contents: read id-token: write +# A new push to a PR supersedes its running checks. Pushes to main and tags never cancel: +# every merge is validated and a release run always finishes. +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + env: DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 DOTNET_NOLOGO: true @@ -104,6 +110,9 @@ jobs: dotnet tool restore dotnet fallout Coverage --reports TestResults + # The integration matrices run on Linux and Windows. macOS adds no coverage path of its own + # (POSIX paths like Linux); BadgeActionTests run badge.sh under macOS's bash 3.2 locally. + # macOS runners stay for the release-only osx-arm64 Native AOT pack. # Exercise the composite action and its default installer against this checkout's portable # package. A release candidate is not on NuGet yet. Native packages are packed separately; # the local-only feed prevents an already-published version from masking this checkout. @@ -112,7 +121,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest] runs-on: ${{ matrix.os }} defaults: run: @@ -195,7 +204,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest] language: [typescript, python] include: - language: typescript @@ -296,7 +305,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, windows-latest, macos-latest] + os: [ubuntu-latest, windows-latest] target: [compare-versions, pydash, peek-readable] include: - target: compare-versions diff --git a/README.md b/README.md index 5249c0b..d3127f9 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,7 @@ root, warns, and its gates answer `NODATA`. Where the sources are checked out, a `--probe-sources` to resolve each file against the root that holds it on disk; anywhere else, `--source-root ` names the root. -CI runs the full suites of two pinned upstream projects on Linux, Windows, and macOS: +CI runs the full suites of two pinned upstream projects on Linux and Windows: | Language | Real project | Coverage producer | Checks | |---|---|---|---| @@ -92,11 +92,11 @@ out the commit recorded by Coveralls and compares fresh coverage with that publi | TypeScript async | [peek-readable 5.4.2](https://github.com/Borewit/peek-readable/blob/9cef754de7baad45e43195bbb35bd9bbf30abbc9/README.md) | [Coveralls build 71980502](https://coveralls.io/builds/71980502) | 205/209 lines, 54/57 branches; all 29 tests, real timers | | Python | [pydash 8.1.0](https://github.com/dgilland/pydash/blob/f46de3669742c075e5379c1e193c86c1c2c70dc2/README.rst) | [Coveralls build 81442862](https://coveralls.io/builds/81442862) | 100%; 2,607/2,607 lines in the published Python 3.12 run; 2,274 tests | -These checks also run on Linux, Windows, and macOS and publish a matching DotCov badge to a +These checks also run on Linux and Windows and publish a matching DotCov badge to a local test origin. The saved service records bind the reference percentages to the source commits, so later changes to a moving upstream badge cannot change the expected result. Pydash collects line coverage only; the existing consumer matrix separately verifies Python -branch coverage and failing gates. Pydash also runs separate real-thread tests on all three +branch coverage and failing gates. Pydash also runs separate real-thread tests on both hosts for timer cancellation, callback locking, concurrent callers, and maximum wait. @@ -194,7 +194,8 @@ falls short of its threshold. A branch rate below its minimum turns the badge re This repository enforces 100% line and branch coverage in CI without publishing a badge branch. The badge action below is optional for consumers who want to publish coverage in their own repository. It runs on Linux, Windows (Git Bash), and macOS runners with .NET installed; CI exercises -installation, publishing, and a failing gate on all three. It creates a `badges` branch on first use: +installation, publishing, and a failing gate on Linux and Windows, and the test suite runs +`badge.sh` under macOS's bash 3.2. It creates a `badges` branch on first use: ```yaml permissions: diff --git a/tests/AGENTS.md b/tests/AGENTS.md index b2a1e0e..3d4d62d 100644 --- a/tests/AGENTS.md +++ b/tests/AGENTS.md @@ -81,8 +81,8 @@ den Repository-Wrapper ebenfalls als echten Prozess: Parameter, Eingaben und Exi - Temp-Verzeichnisse über `TempWorkspace`, Kindprozesse über `ChildProcess`. - `BadgeActionTests` laufen auch unter Windows und wählen dort explizit Git for Windows' Bash statt eines möglichen WSL-Bash auf PATH. Die `badge-action`-CI-Matrix prüft zusätzlich die - Composite Action mit dem lokal gepackten Kandidaten und ihrem Standard-Installer auf Linux, - Windows und macOS; Pushes gehen ausschließlich an ein lokales Bare-Repository. + Composite Action mit dem lokal gepackten Kandidaten und ihrem Standard-Installer auf Linux + und Windows; Pushes gehen ausschließlich an ein lokales Bare-Repository. ## Isolation messen