fix(graphql): refresh the schema snapshot as part of SDK generation - #157
Merged
Conversation
The snapshot that tests/test_graphql_queries.py validates against was refreshed only by an explicit `just refresh-schema`, disconnected from generation. Nothing would have kept it current, and #155 described the risk incorrectly: it claimed a stale snapshot could only cause a false failure. It can cause a false pass, in the direction that matters. If the backend removes a field the snapshot still lists, a query using it validates clean here and fails at runtime — precisely the library-query breakage the test exists to catch. Adding a field is the safe direction; removing one is not. `just generate-sdk` now refreshes the snapshot after generating the REST client, so both halves of the SDK come from the same running backend in one command. This mirrors the TypeScript client, whose codegen introspects the live GraphQL endpoint on every generate — which is the structural reason its query documents never went stale-invalid while Python's did. refresh-schema now introspects the GraphQL endpoint rather than importing the backend package, so it needs a running backend instead of a sibling checkout — the same dependency generate-sdk already has. It fails loudly when the backend is unreachable rather than leaving a stale file looking fresh. The snapshot is rewritten in introspection order, which reorders ~1700 lines on this first pass. Verified semantically identical: 116 types before and after, none added or removed, and all 51 documents still validate.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
Answering "does the schema get downloaded every generation run?" — it didn't, and that was a hole in #155.
The snapshot
tests/test_graphql_queries.pyvalidates against was refreshed only by an explicitjust refresh-schema, entirely disconnected from generation. Nothing kept it current.Correcting #155
That PR claimed a stale snapshot "can only cause a false failure, never a false pass." That's wrong in the direction that matters.
The second row is exactly the library-query breakage the test exists to catch. A stale snapshot doesn't just weaken the gate, it can reproduce the original bug with the gate reporting green.
Change
just generate-sdknow refreshes the snapshot after generating the REST client, so both halves of the SDK come from the same running backend in one command. Drift is bounded by the regen cycle instead of by whether someone remembered.This mirrors the TypeScript client, whose
codegen.tsintrospects the live GraphQL endpoint on everynpm run generate. That's the structural reason its 42 documents never went stale-invalid while Python's five did — not a difference in diligence.refresh-schemanow introspects the GraphQL endpoint rather than importing the backend package, so it depends on a running backend instead of a sibling checkout — the same dependencygenerate-sdkalready has. It fails loudly when the backend is unreachable rather than leaving a stale file looking freshly written.The large diff is reordering, verified
Introspection emits types in a different order than the previous direct SDL export, so this rewrites ~1700 lines on the first pass. Confirmed semantically identical before committing: 116 types before and after, none added, none removed, and all 51 documents still validate. Subsequent refreshes will be stable since they always come from introspection.
Testing
just test-allgreen — 490 passed / 17 skipped, ruff, basedpyright 0 errors. Verifiedjust refresh-schemaagainst the live backend and confirmed the round trip.Note
The unreachable-backend path returns a clear error and exits non-zero rather than writing a partial file, so a failed refresh can't silently leave a snapshot that looks current.