[HOLD-for-9.0.0][skip-runtime-e2e] docs(decisions): canonical /decisions verdict values #840
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| 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' | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: pip install -e ".[dev]" | |
| - name: Run Ruff linter | |
| run: ruff check . | |
| - name: Run Ruff formatter check | |
| run: ruff format --check . | |
| - name: Run MyPy | |
| run: mypy axonflow | |
| - name: Run falsey-clobber check (no `data.get(...) or X` against pre-existing baseline) | |
| run: python3 scripts/lint_no_falsey_clobber.py axonflow/ --baseline .lint_baselines/falsey_clobber.json | |
| 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: ${{ fromJson(github.event_name == 'pull_request' && '["3.11"]' || '["3.10", "3.11", "3.12"]') }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: pip install -e ".[dev,all]" | |
| - name: Run tests | |
| run: pytest --cov-report=xml | |
| - name: Upload coverage | |
| if: matrix.python-version == '3.11' | |
| uses: codecov/codecov-action@v4 | |
| with: | |
| files: ./coverage.xml | |
| 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. | |
| # | |
| # The specs are fetched from the getaxonflow/axonflow community mirror | |
| # pinned to the SHA recorded in tests/fixtures/wire_shape_baseline.json | |
| # so the gate is deterministic — a given SDK commit always diffs against | |
| # the same spec revision, independent of upstream activity. Changing the | |
| # pinned SHA from the same PR that changes SDK models would bypass the | |
| # gate, so the workflow also runs a SHA-bump guard that requires a | |
| # 'spec-pin-bump' label on PRs that move the SHA. | |
| # | |
| # To pick up new spec changes, regenerate the baseline via | |
| # scripts/refresh_wire_shape_baseline.py (ideally in a dedicated PR). | |
| wire-shape-contract: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout SDK (full history for SHA-bump guard) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Read pinned OpenAPI specs SHA from baseline | |
| id: specs_sha | |
| run: | | |
| python3 - <<'PY' >> "$GITHUB_OUTPUT" | |
| import json | |
| import sys | |
| path = "tests/fixtures/wire_shape_baseline.json" | |
| data = json.load(open(path)) | |
| sha = data.get("openapi_specs_sha", "").strip() | |
| if not sha: | |
| print( | |
| f"::error::{path} is missing openapi_specs_sha. " | |
| "Regenerate via scripts/refresh_wire_shape_baseline.py.", | |
| file=sys.stderr, | |
| ) | |
| sys.exit(1) | |
| print(f"sha={sha}") | |
| PY | |
| # SHA-bump guard: the pinned SHA is the contract's source of truth. | |
| # A PR that both changes the SHA and the SDK models can silently | |
| # retarget the gate away from the drift it should have caught. Require | |
| # explicit 'spec-pin-bump' label to acknowledge the bump. First-time | |
| # introductions (base branch has no pin yet) bypass the guard. | |
| - name: Guard against unauthorized OpenAPI specs SHA bump | |
| if: github.event_name == 'pull_request' | |
| env: | |
| PR_LABELS: ${{ toJSON(github.event.pull_request.labels.*.name) }} | |
| BASE_REF: ${{ github.base_ref }} | |
| PR_SHA: ${{ steps.specs_sha.outputs.sha }} | |
| run: | | |
| set -e | |
| BASE_SHA=$( | |
| git show "origin/${BASE_REF}:tests/fixtures/wire_shape_baseline.json" 2>/dev/null \ | |
| | python3 -c "import json, sys; print(json.load(sys.stdin).get('openapi_specs_sha','') or '')" \ | |
| || true | |
| ) | |
| if [ -z "$BASE_SHA" ]; then | |
| echo "::notice::Base branch has no openapi_specs_sha yet; treating this PR as the first pin introduction." | |
| exit 0 | |
| fi | |
| if [ "$BASE_SHA" = "$PR_SHA" ]; then | |
| echo "openapi_specs_sha unchanged (${PR_SHA})." | |
| exit 0 | |
| fi | |
| echo "SHA change detected: ${BASE_SHA} -> ${PR_SHA}" | |
| HAS_LABEL=$(printf '%s' "$PR_LABELS" | python3 -c "import json, sys; print('spec-pin-bump' in json.load(sys.stdin))") | |
| if [ "$HAS_LABEL" = "True" ]; then | |
| echo "::notice::'spec-pin-bump' label present — SHA bump authorized." | |
| exit 0 | |
| fi | |
| echo "::error::openapi_specs_sha changed from ${BASE_SHA} to ${PR_SHA}." | |
| echo "::error::The wire-shape contract's spec revision is pinned to preserve" | |
| echo "::error::review integrity: a SHA change in the same PR as SDK changes" | |
| echo "::error::can silence drift by retargeting the contract to a friendlier" | |
| echo "::error::revision. Either split this into a dedicated SHA-bump PR, or" | |
| echo "::error::apply the 'spec-pin-bump' label to this PR to acknowledge that" | |
| echo "::error::the bump is intentional and has been reviewed independently." | |
| exit 1 | |
| - name: Checkout OpenAPI specs (pinned to baseline SHA) | |
| uses: actions/checkout@v4 | |
| with: | |
| repository: getaxonflow/axonflow | |
| ref: ${{ steps.specs_sha.outputs.sha }} | |
| path: axonflow-community | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install dependencies | |
| run: pip install -e ".[dev]" | |
| - name: Run wire-shape contract tests | |
| env: | |
| AXONFLOW_OPENAPI_SPECS_DIR: ${{ github.workspace }}/axonflow-community/docs/api | |
| run: pytest tests/test_wire_shape.py -m wire_shape -v --no-cov | |
| build: | |
| runs-on: ubuntu-latest | |
| needs: [lint, test, wire-shape-contract] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| cache: 'pip' | |
| cache-dependency-path: 'pyproject.toml' | |
| - name: Install build tools | |
| run: pip install build twine | |
| - name: Build package | |
| run: python -m build | |
| - name: Check package | |
| run: twine check dist/* | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ |