-
Notifications
You must be signed in to change notification settings - Fork 167
feat: spec-sync pipeline (Problem 3) #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
068287e
chore(spec-sync): add fetch/normalize script and V1 spec snapshot bas…
yzld2002 92ee58b
chore(spec-sync): add drift detector
yzld2002 ee48f45
chore(spec-sync): add reference-model codegen (datamodel-code-generator)
yzld2002 0d98f60
chore(spec-sync): add griffe surface-lock gate (baseline=last release…
yzld2002 9ce063a
test(spec-sync): add staging contract-test scaffold (contract marker)
yzld2002 af14062
ci(spec-sync): add two-phase spec-sync workflow (mechanical + AI)
yzld2002 abddece
ci(spec-sync): add PR gates (surface-lock + staging contract tests)
yzld2002 40d8efe
ci(spec-sync): add production-spec release gate (staging-in, producti…
yzld2002 c30c495
docs(spec-sync): document the spec-sync pipeline and TS-port follow-up
yzld2002 2afbbb6
fix(spec-sync): exclude generated specs from linters; lock deps; stag…
yzld2002 98e7bb8
fix(spec-sync): pin codegen/griffe to validated versions; regen model…
yzld2002 93666d5
ci(spec-sync): use fine-grained PAT (SPEC_SYNC_TOKEN) instead of a Gi…
yzld2002 e94036c
fix(spec-sync): method-granular release gate; mkdir -p snapshot parent
yzld2002 0ad5bea
chore(spec-sync): re-baseline V1 snapshot to the SDK's implemented su…
yzld2002 dfce66d
ci(spec-sync): deterministic AI push, no duplicate PRs, injection har…
yzld2002 513fb06
ci(spec-sync): scope live-staging gate, exact codegen pins, opt-in co…
yzld2002 5942ca6
fix(spec-sync): close staging client in fixture; align docs to hourly…
yzld2002 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| name: PR Gates | ||
| on: | ||
| pull_request: | ||
| branches: [main] | ||
|
|
||
| jobs: | ||
| surface-lock: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 # tags for the release-tag baseline | ||
| - name: Install Rye | ||
| run: | | ||
| curl -sSf https://rye.astral.sh/get | bash | ||
| echo "$HOME/.rye/shims" >> "$GITHUB_PATH" | ||
| env: | ||
| RYE_VERSION: '0.44.0' | ||
| RYE_INSTALL_OPTION: '--yes' | ||
| - name: Install dependencies | ||
| run: rye sync --all-features | ||
| - name: Surface lock (no breaking change to released API) | ||
| run: ./scripts/spec-sync/surface-lock.sh | ||
|
|
||
| contract-tests: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| - name: Install Rye | ||
| run: | | ||
| curl -sSf https://rye.astral.sh/get | bash | ||
| echo "$HOME/.rye/shims" >> "$GITHUB_PATH" | ||
| env: | ||
| RYE_VERSION: '0.44.0' | ||
| RYE_INSTALL_OPTION: '--yes' | ||
| - name: Install dependencies | ||
| run: rye sync --all-features | ||
| - name: Contract tests vs staging | ||
| env: | ||
| LANDINGAI_ADE_STAGING_APIKEY: ${{ secrets.LANDINGAI_ADE_STAGING_APIKEY }} | ||
| run: rye run pytest tests/contract -m contract -v | ||
|
yzld2002 marked this conversation as resolved.
Outdated
yzld2002 marked this conversation as resolved.
Outdated
|
||
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| name: Spec Sync | ||
| on: | ||
| schedule: | ||
| - cron: '0 */6 * * *' # every ~6h; cron covers correctness, dispatch cuts latency | ||
|
yzld2002 marked this conversation as resolved.
Outdated
|
||
| workflow_dispatch: {} | ||
|
|
||
| permissions: | ||
| contents: read # writes happen via the app token, not GITHUB_TOKEN | ||
|
|
||
| jobs: | ||
| spec-sync: | ||
| if: github.repository == 'landing-ai/ade-python' | ||
|
yzld2002 marked this conversation as resolved.
|
||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 30 | ||
| env: | ||
| V1_SPEC_URL: https://api.va.staging.landing.ai/v1/ade/openapi.json # staging drives the loop | ||
| steps: | ||
| - uses: actions/checkout@v6 | ||
| with: | ||
| # SPEC_SYNC_TOKEN is a fine-grained PAT (Contents: RW, Pull requests: RW) | ||
| # scoped to this repo. It must NOT be the default GITHUB_TOKEN: pushes/PRs | ||
| # authored by GITHUB_TOKEN do not trigger the gate workflows (anti-recursion). | ||
| token: ${{ secrets.SPEC_SYNC_TOKEN }} | ||
| fetch-depth: 0 # tags needed for surface-lock baseline | ||
|
|
||
| - name: Install Rye | ||
| run: | | ||
| curl -sSf https://rye.astral.sh/get | bash | ||
| echo "$HOME/.rye/shims" >> "$GITHUB_PATH" | ||
| env: | ||
| RYE_VERSION: '0.44.0' | ||
| RYE_INSTALL_OPTION: '--yes' | ||
|
|
||
| - name: Install dependencies | ||
| run: rye sync --all-features | ||
|
|
||
| - name: Detect drift | ||
| id: drift | ||
| run: | | ||
| set +e | ||
| ./scripts/spec-sync/check-drift.sh "$V1_SPEC_URL" specs/v1-ade.json | ||
| echo "code=$?" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: No drift | ||
| if: steps.drift.outputs.code == '0' | ||
| run: echo "specs in sync; nothing to do." | ||
|
|
||
| - name: Fail on fetch error | ||
| if: steps.drift.outputs.code != '0' && steps.drift.outputs.code != '10' | ||
| run: | | ||
| echo "spec fetch/normalize failed (exit ${{ steps.drift.outputs.code }})" | ||
| exit 1 | ||
|
|
||
| # ---- Phase 1: mechanical ---- | ||
| - name: Mechanical commit (snapshot + reference models) | ||
| if: steps.drift.outputs.code == '10' | ||
| id: mech | ||
| run: | | ||
| git config user.name "spec-sync[bot]" | ||
| git config user.email "spec-sync@users.noreply.github.com" | ||
| branch="spec-sync/v1-$(date -u +%Y%m%dT%H%M%SZ)" | ||
|
yzld2002 marked this conversation as resolved.
Outdated
|
||
| git checkout -b "$branch" | ||
| ./scripts/spec-sync/gen-models.sh specs/v1-ade.json specs/_generated/v1_models.py | ||
| git add specs/v1-ade.json specs/_generated/v1_models.py | ||
| git commit -m "chore(spec-sync): update V1 spec snapshot + regenerated reference models" | ||
| git push -u origin "$branch" | ||
| echo "branch=$branch" >> "$GITHUB_OUTPUT" | ||
|
|
||
| # ---- Phase 2: AI wiring (same checkout/branch) ---- | ||
| - name: AI wiring commit | ||
| if: steps.drift.outputs.code == '10' | ||
| uses: anthropics/claude-code-action@v1 | ||
| with: | ||
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| github_token: ${{ secrets.SPEC_SYNC_TOKEN }} | ||
| prompt: | | ||
| The previous commit updated specs/v1-ade.json and regenerated reference | ||
| models in specs/_generated/v1_models.py. Update the SDK to match the spec | ||
| diff: add or adjust resource classes, method signatures, param TypedDicts, | ||
| response models, tests, api.md, and README examples, mirroring the existing | ||
| conventions in src/landingai_ade/resources/parse_jobs.py. | ||
| Rules: PURELY ADDITIVE — never modify or remove an existing public signature | ||
| (the surface-lock CI job will fail the PR); follow existing code style; | ||
| run ./scripts/format; commit to the current branch. | ||
|
yzld2002 marked this conversation as resolved.
Outdated
|
||
| claude_args: | | ||
| --max-turns 40 | ||
| --allowedTools "Edit,Write,Read,Bash(git *),Bash(rye *),Bash(./scripts/*)" | ||
|
yzld2002 marked this conversation as resolved.
Outdated
|
||
|
|
||
| - name: Open sync PR | ||
|
yzld2002 marked this conversation as resolved.
Outdated
|
||
| if: steps.drift.outputs.code == '10' | ||
| env: | ||
| GH_TOKEN: ${{ secrets.SPEC_SYNC_TOKEN }} | ||
| run: | | ||
| gh pr create \ | ||
| --base main \ | ||
| --head "${{ steps.mech.outputs.branch }}" \ | ||
| --title "spec-sync: track V1 spec drift" \ | ||
| --body $'Automated spec-sync PR.\n\n- **Commit 1 (mechanical):** normalized spec snapshot + regenerated reference models.\n- **Commit 2 (AI):** resources/methods/tests/docs wired from the spec diff.\n\nGates (surface-lock, contract tests, lint/test/typecheck) must pass. **Human review required before merge.**' | ||
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #!/usr/bin/env bash | ||
| # Compare a live spec against its committed snapshot. | ||
| # exit 0 -> no drift | ||
| # exit 10 -> drift detected; <committed-path> updated in place with the live spec | ||
| # other -> operational error (e.g. fetch failure) | ||
| set -euo pipefail | ||
|
|
||
| if [ "$#" -ne 2 ]; then | ||
| echo "usage: check-drift.sh <spec-url> <committed-path>" >&2 | ||
| exit 2 | ||
| fi | ||
|
|
||
| url="$1" | ||
| committed="$2" | ||
| here="$(cd "$(dirname "$0")" && pwd)" | ||
| tmp="$(mktemp)" | ||
| trap 'rm -f "$tmp"' EXIT | ||
|
|
||
| "$here/fetch-normalize.sh" "$url" > "$tmp" | ||
|
|
||
| if [ -f "$committed" ] && diff -q "$committed" "$tmp" >/dev/null; then | ||
| echo "no drift: $committed" | ||
| exit 0 | ||
| fi | ||
|
|
||
| mkdir -p "$(dirname "$committed")" | ||
| cp "$tmp" "$committed" | ||
|
Copilot marked this conversation as resolved.
|
||
| echo "drift detected -> updated $committed" | ||
| exit 10 | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.