From 52db0646f8bc0f303a3a81397f810e4fcb79ed95 Mon Sep 17 00:00:00 2001 From: Saurabh Jain Date: Sun, 10 May 2026 21:13:49 +0200 Subject: [PATCH 1/2] chore(ci): cancel orphaned PR runs + prune Python matrix on PR Same patterns as axonflow-sdk-java#176, axonflow-enterprise#2140/#2146: 1. **Concurrency**: cancel orphaned PR runs; push-to-main keys on SHA so main runs never queue. Applied to ci, integration (existing block reshaped), heartbeat-real-stack, definition-of-done, validate-version-alignment. 2. **Matrix prune on PR** for ci.yml `test` job + integration.yml `contract-tests` job: PR: python-version: ['3.11'] else: python-version: ['3.10', '3.11', '3.12'] Cuts ci.yml `test` job from 3 parallel python legs to 1 on PR. Drift catch on push:main and the existing weekly Tuesday cron. 3. **heartbeat-real-stack.yml**: add `cache: 'pip'` to setup-python (cold pip install on every 3-OS run today). 4. **definition-of-done.yml**: drop `edited` PR event type. No app code change. Signed-off-by: Saurabh Jain --- .github/workflows/ci.yml | 8 +++++++- .github/workflows/definition-of-done.yml | 7 ++++++- .github/workflows/heartbeat-real-stack.yml | 6 ++++++ .github/workflows/integration.yml | 11 +++++++---- .github/workflows/validate-version-alignment.yml | 4 ++++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0187a76..0a93be2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,6 +9,10 @@ on: permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + env: AXONFLOW_TELEMETRY: 'off' @@ -43,8 +47,10 @@ jobs: test: runs-on: ubuntu-latest strategy: + # PR runs only Python 3.11 (current release toolchain). Push to main and + # workflow_dispatch run the full matrix to catch version-specific drift. matrix: - python-version: ['3.10', '3.11', '3.12'] + python-version: ${{ fromJson(github.event_name == 'pull_request' && '["3.11"]' || '["3.10", "3.11", "3.12"]') }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/definition-of-done.yml b/.github/workflows/definition-of-done.yml index 279e56c..b973142 100644 --- a/.github/workflows/definition-of-done.yml +++ b/.github/workflows/definition-of-done.yml @@ -6,12 +6,17 @@ name: Definition of Done on: pull_request: - types: [opened, synchronize, reopened, edited] + # Drop `edited` — re-runs the gate on title/body edits without any code change. + types: [opened, synchronize, reopened] permissions: contents: read pull-requests: read +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: lint-no-mocks-in-runtime-e2e: name: Lint — no mocks in runtime-e2e/ diff --git a/.github/workflows/heartbeat-real-stack.yml b/.github/workflows/heartbeat-real-stack.yml index 634d433..e75f5f7 100644 --- a/.github/workflows/heartbeat-real-stack.yml +++ b/.github/workflows/heartbeat-real-stack.yml @@ -12,6 +12,10 @@ on: pull_request: branches: [main] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + env: AXONFLOW_TELEMETRY: 'off' @@ -34,6 +38,8 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.11' + cache: 'pip' + cache-dependency-path: 'pyproject.toml' - name: Install SDK (editable) run: pip install -e . diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index 3dfb404..4a2a3f5 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -15,10 +15,11 @@ permissions: contents: read # Avoid spawning parallel docker-compose stacks for back-to-back pushes; -# also cancels stale PR runs when a new commit lands. +# also cancels stale PR runs when a new commit lands. Push to main keys on SHA +# so main runs never queue or cancel each other. concurrency: - group: integration-${{ github.ref }} - cancel-in-progress: true + group: integration-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} env: AXONFLOW_TELEMETRY: 'off' @@ -33,8 +34,10 @@ jobs: timeout-minutes: 10 strategy: fail-fast: false + # PR runs only Python 3.11. Push, dispatch, and weekly Tuesday cron run + # the full matrix to catch version-specific drift before tagging. matrix: - python-version: ['3.10', '3.11', '3.12'] + python-version: ${{ fromJson(github.event_name == 'pull_request' && '["3.11"]' || '["3.10", "3.11", "3.12"]') }} steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/validate-version-alignment.yml b/.github/workflows/validate-version-alignment.yml index 1c786c1..a372d8b 100644 --- a/.github/workflows/validate-version-alignment.yml +++ b/.github/workflows/validate-version-alignment.yml @@ -34,6 +34,10 @@ on: permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: validate-versions: name: Validate Version Alignment From 1d76bbaa7ca9d2f27c17112eefb80e9d25635876 Mon Sep 17 00:00:00 2001 From: Saurabh Jain Date: Sun, 10 May 2026 21:34:56 +0200 Subject: [PATCH 2/2] ci: add Test Summary aggregator job MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same pattern as the sdk-java summary fix. Matrix prune means `test (3.10)` and `test (3.12)` don't report on PR runs; branch protection requires those names → permanent block. Aggregator reports a stable `Test Summary` check that branch protection should require instead. Signed-off-by: Saurabh Jain --- .github/workflows/ci.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0a93be2..1012f43 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,6 +75,26 @@ jobs: flags: python-sdk fail_ci_if_error: false + # Aggregator that always reports a single check name regardless of the + # matrix shape (PR-time matrix is `['3.11']`; push/dispatch is full). + # Branch protection requires `Test Summary`, not the per-version names, + # so matrix changes don't strand required checks. + test-summary: + name: Test Summary + needs: [test] + if: always() + runs-on: ubuntu-latest + steps: + - name: Aggregate test matrix result + run: | + result="${{ needs.test.result }}" + echo "test matrix result: $result" + if [ "$result" != "success" ] && [ "$result" != "skipped" ]; then + echo "::error::test matrix did not all pass (result: $result)" + exit 1 + fi + echo "Test matrix OK" + # QF-15: wire-shape contract CI. Blocks drift between Python SDK pydantic # models and the OpenAPI specs that are the authoritative wire contract. # Runs on every PR. Drift the baseline does not cover fails the check.