feat(hitl): add createHITLRequest — paired SDK release for ADK plugin v1 #56
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: Wire-Shape Contract | |
| # QF-14 Java arm: blocks drift between Java @JsonProperty-annotated | |
| # classes and the OpenAPI specs that are the authoritative wire | |
| # contract. Runs on every PR and push to main. Drift NOT covered by | |
| # the baseline fails the check. | |
| # | |
| # Specs are fetched from the getaxonflow/axonflow community mirror at | |
| # the SHA recorded in tests/fixtures/wire-shape-baseline.json so the | |
| # gate is deterministic. A 'spec-pin-bump' label is required on PRs | |
| # that change the SHA, preserving review integrity (a PR that both | |
| # moved the SHA and the Java classes could otherwise silence drift). | |
| # | |
| # To regenerate the baseline: | |
| # python3 scripts/wire_shape/refresh.py <specs_dir> | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'src/main/java/**/*.java' | |
| - 'tests/fixtures/wire-shape-baseline.json' | |
| - 'scripts/wire_shape/**' | |
| - '.github/workflows/wire-shape-contract.yml' | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'src/main/java/**/*.java' | |
| - 'tests/fixtures/wire-shape-baseline.json' | |
| - 'scripts/wire_shape/**' | |
| - '.github/workflows/wire-shape-contract.yml' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| jobs: | |
| wire-shape: | |
| name: Validate Wire Shape | |
| runs-on: ubuntu-latest | |
| env: | |
| AXONFLOW_TELEMETRY: 'off' | |
| 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", "") or "").strip() | |
| if not sha: | |
| print( | |
| f"::error::{path} is missing openapi_specs_sha. " | |
| "Regenerate via scripts/wire_shape/refresh.py.", | |
| file=sys.stderr, | |
| ) | |
| sys.exit(1) | |
| print(f"sha={sha}") | |
| PY | |
| - 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_FILE=$(mktemp) | |
| if git show "origin/${BASE_REF}:tests/fixtures/wire-shape-baseline.json" > "$BASE_FILE" 2>/dev/null; then | |
| # File exists on the base branch. It MUST parse — a malformed | |
| # baseline file would otherwise let `BASE_SHA` come back empty | |
| # and route this PR through the "first pin introduction" | |
| # bypass below, silently authorizing a SHA bump. | |
| BASE_SHA=$(python3 -c "import json, sys; print(json.load(open(sys.argv[1])).get('openapi_specs_sha','') or '')" "$BASE_FILE") | |
| else | |
| # File genuinely absent on the base branch (first-time | |
| # introduction). Distinguishing this from "file present but | |
| # unparseable" is what guards the bypass. | |
| BASE_SHA="" | |
| fi | |
| rm -f "$BASE_FILE" | |
| if [ -z "$BASE_SHA" ]; then | |
| if git cat-file -e "origin/${BASE_REF}:tests/fixtures/wire-shape-baseline.json" 2>/dev/null; then | |
| echo "::error::tests/fixtures/wire-shape-baseline.json on origin/${BASE_REF} parsed with empty openapi_specs_sha." | |
| echo "::error::This is unrecoverable from inside the gate. Re-run scripts/wire_shape/refresh.py on main." | |
| exit 1 | |
| fi | |
| echo "::notice::Base branch has no wire-shape-baseline.json yet; treating this PR as 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 into a dedicated SHA-bump PR, or" | |
| echo "::error::apply the 'spec-pin-bump' label to this PR." | |
| 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' | |
| - name: Install PyYAML | |
| run: pip install 'pyyaml>=6,<7' | |
| - name: Run wire-shape contract validator | |
| env: | |
| AXONFLOW_OPENAPI_SPECS_DIR: ${{ github.workspace }}/axonflow-community/docs/api | |
| run: python3 scripts/wire_shape/validate.py |