Skip to content

Commit d15bb11

Browse files
authored
Include diff in spec-drift issue body (#39)
* Include diff in spec-drift issue body Pretty-print both specs with --sort-keys so unrelated key reordering doesn't trip the check, then attach a unified diff (truncated at 60 KB) to the issue body inside a <details> block. Update the existing open issue on subsequent runs so the diff stays current instead of pinning to whatever week the drift first appeared. * Simplify spec-drift body construction - Capture the diff directly in the existing `if ! diff …` (errexit is already exempt inside `if`), removing the separate `-q` pre-check, the intermediate pretty-printed tempfiles, and the `|| true` workaround. - Replace the multi-echo body wrapper with two `printf`s and a 1-line bash `&&` truncation marker. - Pass `--label vendored --label upstream` to `diff` so the issue body shows meaningful headers instead of `/dev/fd/63`. * Refresh openapi.json from upstream Only `info.description` changed ("Last updated: April 23, 2026" → "April 30, 2026"); the field is OpenAPI metadata that does not surface in any generated Python, so re-running the regen pipeline produces no changes under `ionq_core/`. The upstream-sorted diff matches the preview posted on this PR. Resolves #38. * Collapse openapi.json diffs in GitHub PR views `linguist-vendored=true` only excludes a file from repo language statistics; it does not suppress diffs in PRs (see github-linguist's `generated.rb` and github-linguist/linguist#3234). Add `linguist-generated=true` so reviewers see openapi.json collapsed by default — the spec is fetched from upstream by the regen pipeline and isn't intended for line-by-line review (the actual semantic diff lives in the spec-drift issue body now). * Remove unnecessary comment * Derive spec URL from openapi.json in spec-drift workflow * Drop redundant spec-drift URL extraction test
1 parent c468c31 commit d15bb11

4 files changed

Lines changed: 21 additions & 11 deletions

File tree

.gitattributes

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ ionq_core/api/** linguist-generated=true
77
ionq_core/models/** linguist-generated=true
88

99
# Vendored upstream OpenAPI spec.
10-
openapi.json linguist-vendored=true
10+
openapi.json linguist-vendored=true linguist-generated=true
1111

1212
# Lockfile.
1313
uv.lock linguist-generated=true

.github/workflows/spec-drift.yml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,34 @@ jobs:
1818
with:
1919
persist-credentials: false
2020
- name: Fetch latest spec
21-
run: curl -sf https://api.ionq.co/v0.4/api-docs -o /tmp/latest-spec.json
21+
run: |
22+
BASE_URL=$(jq -r '.servers[0].url' openapi.json)
23+
echo "BASE_URL=${BASE_URL}" >> "$GITHUB_ENV"
24+
curl -sf "${BASE_URL}/api-docs" -o /tmp/latest-spec.json
2225
- name: Check for drift
2326
id: drift
2427
run: |
25-
if ! diff -q <(python3 -m json.tool openapi.json) <(python3 -m json.tool /tmp/latest-spec.json) > /dev/null 2>&1; then
28+
if ! diff -u --label vendored --label upstream <(python3 -m json.tool --sort-keys openapi.json) <(python3 -m json.tool --sort-keys /tmp/latest-spec.json) > /tmp/spec.diff; then
2629
echo "drifted=true" >> "$GITHUB_OUTPUT"
2730
fi
28-
- name: Open issue
31+
- name: Open or update issue
2932
if: steps.drift.outputs.drifted == 'true'
3033
env:
3134
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3235
run: |
33-
existing=$(gh issue list --label spec-drift --state open --json number --jq length)
34-
if [[ "$existing" == "0" ]]; then
36+
{
37+
echo "The spec at ${BASE_URL}/api-docs has diverged from the vendored openapi.json. Fetch the new spec and regenerate the client."
38+
printf '\n<details><summary>Diff (sorted, pretty-printed JSON)</summary>\n\n```diff\n'
39+
head -c 60000 /tmp/spec.diff
40+
[[ $(wc -c < /tmp/spec.diff) -gt 60000 ]] && printf '\n... (truncated)\n'
41+
printf '```\n</details>\n'
42+
} > /tmp/body.md
43+
existing=$(gh issue list --label spec-drift --state open --json number --jq '.[0].number // empty')
44+
if [[ -z "$existing" ]]; then
3545
gh issue create \
3646
--title "OpenAPI spec has changed upstream" \
37-
--body "The spec at api.ionq.co/v0.4/api-docs has diverged from the vendored openapi.json. Fetch the new spec and regenerate the client." \
47+
--body-file /tmp/body.md \
3848
--label spec-drift
49+
else
50+
gh issue edit "$existing" --body-file /tmp/body.md
3951
fi

openapi.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/test_docs_consistency.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,18 +127,16 @@ def test_oas_patch_versions_match():
127127

128128

129129
def test_spec_path_matches_default_base_url():
130-
# Without this, a DEFAULT_BASE_URL bump leaves spec-drift.yml curling the stale endpoint.
130+
# Without this, a DEFAULT_BASE_URL bump leaves CONTRIBUTING.md pointing at a stale endpoint.
131131
spec_path = f"{urlparse(DEFAULT_BASE_URL).path}/api-docs"
132132
assert spec_path in CONTRIB
133-
assert spec_path in SPEC_DRIFT_WF
134133

135134

136135
def test_spec_servers_path_in_docs():
137136
# Catches a stale openapi.json: code/docs bumped without regen, or fetched from the wrong version.
138137
spec = json.loads((ROOT / "openapi.json").read_text())
139138
spec_path = urlparse(spec["servers"][0]["url"]).path
140139
assert f"{spec_path}/api-docs" in CONTRIB
141-
assert f"{spec_path}/api-docs" in SPEC_DRIFT_WF
142140

143141

144142
def test_single_spdx_year_across_package():

0 commit comments

Comments
 (0)