diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0187a76..1012f43 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 @@ -69,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. 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