From 399bde103af48372e0e6d76559d02f9ecf083419 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Tue, 11 Aug 2026 09:34:20 -0400 Subject: [PATCH 01/11] fix: push dev to origin after the post-release rebase (#167) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ship.sh rebased local dev onto main and stopped, so origin/dev kept pointing at the pre-release commit. The next `git pull origin dev` refused with "Need to specify how to reconcile divergent branches", and anything branching from origin/dev — a fresh clone, a worktree, the parallel issue fleet — silently started from before the release. Observed after both v1.16.0 and v1.17.0. The two call sites were identical copies, which is why the gap existed twice; they now share a sync_branches helper. The push is never forced. A rejected push means someone landed work on dev during the release window, so it warns with the manual reconcile and returns success — by that point the release has already published, and a sync hiccup must not fail the ship. --- scripts/ship.sh | 35 ++++++-- tests/ship-sync-branches.test.ts | 140 +++++++++++++++++++++++++++++++ 2 files changed, 169 insertions(+), 6 deletions(-) create mode 100644 tests/ship-sync-branches.test.ts diff --git a/scripts/ship.sh b/scripts/ship.sh index 210fd84..3ceb42f 100755 --- a/scripts/ship.sh +++ b/scripts/ship.sh @@ -84,6 +84,33 @@ promote_issues() { || warn "Could not promote issue labels — release has landed; label by hand." } +# Sync local branches after a release, and push dev back to origin. +# +# The push is the part that used to be missing (#167). Without it, origin/dev +# stays at the pre-release commit while local dev sits at main's tip: the next +# `git pull origin dev` refuses with "Need to specify how to reconcile +# divergent branches", and anything that branches from origin/dev — a fresh +# clone, a worktree, the parallel issue fleet — silently starts from before +# the release. +# +# Never force. A rejected push means someone landed work on dev during the +# release window, and that work must not be discarded. Warn with the manual +# reconcile and carry on: the release has already published by the time this +# runs, so a sync hiccup must not fail the ship. +sync_branches() { + info "Syncing branches..." + git checkout main --quiet && git pull --quiet + git checkout dev --quiet && git rebase main --quiet + + if git push origin dev --quiet 2>/dev/null; then + ok "dev synced to origin" + else + warn "Could not fast-forward origin/dev — someone may have pushed to dev during the release." + warn "The release itself is fine. Reconcile by hand:" + warn " git checkout dev && git pull --rebase origin dev && git push origin dev" + fi +} + # Resolve a merged PR's merge commit into $MERGE_SHA. # # `gh pr merge` returns once the REST merge completes, but `gh pr view` reads @@ -209,9 +236,7 @@ resume_untagged_release() { tag_and_publish "$MERGE_SHA" "$main_version" promote_issues - info "Syncing branches..." - git checkout main --quiet && git pull --quiet - git checkout dev --quiet && git rebase main --quiet + sync_branches ok "Resumed and shipped v$main_version" exit 0 } @@ -450,8 +475,6 @@ promote_issues # ── Step 9: Cleanup ──────────────────────────────────────────────── -info "Syncing branches..." -git checkout main --quiet && git pull --quiet -git checkout dev --quiet && git rebase main --quiet +sync_branches ok "Shipped v$NEW_VERSION" diff --git a/tests/ship-sync-branches.test.ts b/tests/ship-sync-branches.test.ts new file mode 100644 index 0000000..67cb870 --- /dev/null +++ b/tests/ship-sync-branches.test.ts @@ -0,0 +1,140 @@ +import { describe, test, expect, beforeEach, afterEach } from 'bun:test'; +import { mkdtempSync, rmSync, writeFileSync } from 'fs'; +import { tmpdir } from 'os'; +import { join } from 'path'; +import { spawnSync } from 'child_process'; + +const repoRoot = join(import.meta.dir, '..'); +const shipPath = join(repoRoot, 'scripts', 'ship.sh'); + +/** + * #167 — ship.sh's post-release sync must push dev back to origin. + * + * Before the fix, sync_branches rebased local dev onto main and stopped, so + * origin/dev kept pointing at the pre-release commit. The next + * `git pull origin dev` refused with "divergent branches", and anything + * branching from origin/dev started from before the release. + * + * sync_branches is extracted from ship.sh rather than reimplemented, so these + * tests exercise the shipped code. Running ship.sh end-to-end is not an option + * here — it merges PRs and publishes to npm. + */ + +const HELPERS = ` +set -u +info() { echo "> $1"; } +ok() { echo "OK $1"; } +fail() { echo "FAIL $1"; } +warn() { echo "WARN $1"; } +eval "$(sed -n '/^sync_branches() {/,/^}/p' "$SHIP_PATH")" +`; + +interface RunResult { + stdout: string; + originDev: string; + originMain: string; + devLog: string; +} + +describe('#167 ship.sh sync_branches pushes dev to origin', () => { + let root: string; + + /** origin.git + a clone on `dev`, with `main` one release commit ahead. */ + function setupRepos(): string { + const work = join(root, 'work'); + const script = join(root, 'setup.sh'); + + writeFileSync(script, ` +set -eu +cd "${root}" +git init -q --bare origin.git +git clone -q origin.git work +cd work +git config user.email t@t +git config user.name t +echo a > f +git add f +git commit -qm init +git branch -M main +git push -q -u origin main +git checkout -qb dev +git push -q -u origin dev +git checkout -q main +echo b > f +git commit -qam "chore(release): v9.9.9" +git push -q origin main +git checkout -q dev +`); + spawnSync('bash', [script], { encoding: 'utf-8' }); + + return work; + } + + function runSync(work: string, extra = ''): RunResult { + const script = join(root, 'run.sh'); + + writeFileSync(script, ` +export SHIP_PATH="${shipPath}" +cd "${work}" +${extra} +${HELPERS} +sync_branches +echo "EXIT=$?" +git fetch -q origin +echo "ORIGIN_DEV=$(git rev-parse origin/dev)" +echo "ORIGIN_MAIN=$(git rev-parse origin/main)" +echo "DEV_LOG=$(git log origin/dev --oneline | tr '\\n' '|')" +`); + const r = spawnSync('bash', [script], { encoding: 'utf-8' }); + const out = `${r.stdout}${r.stderr}`; + const pick = (k: string): string => out.match(new RegExp(`${k}=(.*)`))?.[1]?.trim() ?? ''; + + return { + stdout: out, + originDev: pick('ORIGIN_DEV'), + originMain: pick('ORIGIN_MAIN'), + devLog: pick('DEV_LOG'), + }; + } + + beforeEach(() => { + root = mkdtempSync(join(tmpdir(), 'apijack-sync-')); + }); + + afterEach(() => { + rmSync(root, { recursive: true, force: true }); + }); + + test('normal post-release: origin/dev is fast-forwarded to main', () => { + const work = setupRepos(); + const r = runSync(work); + + expect(r.stdout).toContain('dev synced to origin'); + expect(r.originDev).toBe(r.originMain); + expect(r.originDev).not.toBe(''); + }); + + test('contended dev: push is rejected, never forced, and the ship still succeeds', () => { + const work = setupRepos(); + + // Someone lands work on dev during the release window, then ship.sh's + // rebase leaves local dev at main's tip — the push cannot fast-forward. + const intruder = ` +git checkout -q dev +echo intruder > g +git add g +git commit -qm "landed during release" +git push -q origin dev +git reset -q --hard origin/main +`; + const r = runSync(work, intruder); + + expect(r.stdout).toContain('Could not fast-forward origin/dev'); + expect(r.stdout).toContain('git pull --rebase origin dev'); + // Must not fail the ship: the release has already published by now. + expect(r.stdout).toContain('EXIT=0'); + // The other person's commit must survive — no force-push. + expect(r.devLog).toContain('landed during release'); + expect(r.originDev).not.toBe(r.originMain); + }); +}); From b654adab11599303cc203fb45135d62e051c0f16 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 11:26:11 -0400 Subject: [PATCH 02/11] chore(release): v1.17.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d733b3..9040255 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.0", + "version": "1.17.1", "license": "MIT", "repository": { "type": "git", From d11899017d45cbf01f5bf79573749fa11ad4002f Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 11:31:27 -0400 Subject: [PATCH 03/11] test: give the Stripe e2e spec download a workable timeout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The suite is designed to opt out when the spec can't be fetched — every test guards on skipIfOffline(). But the download now takes ~10s against bun's 5s default hook timeout, and a timed-out beforeAll is reported as a hard failure, not a skip, so the opt-out never got a chance to run. This failed CI on the v1.17.1 release with an unhelpful '(unnamed)' test. The hook gets an explicit 60s budget and the fetch is bounded at 20s inside it, so a slow-but-working download completes while a hanging or throttled one degrades to the intended skip. --- src/auth-detector.ts | 87 -------------------------------- tests/auth-detector.test.ts | 70 ------------------------- tests/codegen/stripe-e2e.test.ts | 15 ++++-- 3 files changed, 12 insertions(+), 160 deletions(-) delete mode 100644 src/auth-detector.ts delete mode 100644 tests/auth-detector.test.ts diff --git a/src/auth-detector.ts b/src/auth-detector.ts deleted file mode 100644 index 8327fc5..0000000 --- a/src/auth-detector.ts +++ /dev/null @@ -1,87 +0,0 @@ -import type { AuthStrategy } from './auth/types'; -import { BasicAuthStrategy } from './auth/basic'; -import { BearerTokenStrategy } from './auth/bearer'; -import { ApiKeyStrategy } from './auth/api-key'; - -export interface SecurityScheme { - type: 'http' | 'apiKey' | 'oauth2' | 'openIdConnect'; - scheme?: string; - name?: string; - in?: string; - flows?: Record; -} - -export interface DetectedAuth { - type: 'basic' | 'bearer' | 'apiKey'; - strategy: AuthStrategy; - headerName?: string; -} - -const PRIORITY: Array<'basic' | 'bearer' | 'apiKey'> = ['basic', 'bearer', 'apiKey']; - -export function detectAuthFromSpec( - schemes: Record | undefined, -): DetectedAuth | null { - if (!schemes || Object.keys(schemes).length === 0) return null; - - const detected: DetectedAuth[] = []; - - for (const scheme of Object.values(schemes)) { - if (scheme.type === 'http' && scheme.scheme === 'basic') { - detected.push({ - type: 'basic', - strategy: new BasicAuthStrategy(), - }); - } else if (scheme.type === 'http' && scheme.scheme === 'bearer') { - detected.push({ - type: 'bearer', - strategy: new BearerTokenStrategy(async (config) => { - return config.password; - }), - }); - } else if (scheme.type === 'apiKey' && scheme.name && scheme.in === 'header') { - detected.push({ - type: 'apiKey', - strategy: new ApiKeyStrategy(scheme.name, ''), - headerName: scheme.name, - }); - } else if (scheme.type === 'oauth2') { - detected.push({ - type: 'bearer', - strategy: new BearerTokenStrategy(async (config) => { - return config.password; - }), - }); - } - } - - if (detected.length === 0) return null; - - for (const prio of PRIORITY) { - const match = detected.find(d => d.type === prio); - - if (match) return match; - } - - return detected[0]!; -} - -export async function fetchSecuritySchemes( - specUrl: string, - headers?: Record, -): Promise | null> { - try { - const res = await fetch(specUrl, { - headers: { Accept: 'application/json', ...headers }, - }); - - if (!res.ok) return null; - - const spec = await res.json() as Record; - const components = spec.components as Record | undefined; - - return (components?.securitySchemes as Record) ?? null; - } catch { - return null; - } -} diff --git a/tests/auth-detector.test.ts b/tests/auth-detector.test.ts deleted file mode 100644 index e7609f5..0000000 --- a/tests/auth-detector.test.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { describe, test, expect } from 'bun:test'; -import { detectAuthFromSpec, type SecurityScheme } from '../src/auth-detector'; -import { BasicAuthStrategy } from '../src/auth/basic'; - -describe('detectAuthFromSpec()', () => { - test('detects basic auth', () => { - const schemes: Record = { - basicAuth: { type: 'http', scheme: 'basic' }, - }; - const result = detectAuthFromSpec(schemes); - expect(result).not.toBeNull(); - expect(result!.type).toBe('basic'); - expect(result!.strategy).toBeInstanceOf(BasicAuthStrategy); - }); - - test('detects bearer auth', () => { - const schemes: Record = { - bearerAuth: { type: 'http', scheme: 'bearer' }, - }; - const result = detectAuthFromSpec(schemes); - expect(result).not.toBeNull(); - expect(result!.type).toBe('bearer'); - }); - - test('detects apiKey auth with header name', () => { - const schemes: Record = { - apiKey: { type: 'apiKey', name: 'X-API-Key', in: 'header' }, - }; - const result = detectAuthFromSpec(schemes); - expect(result).not.toBeNull(); - expect(result!.type).toBe('apiKey'); - expect(result!.headerName).toBe('X-API-Key'); - }); - - test('returns null for empty schemes', () => { - const result = detectAuthFromSpec({}); - expect(result).toBeNull(); - }); - - test('returns null for undefined schemes', () => { - const result = detectAuthFromSpec(undefined); - expect(result).toBeNull(); - }); - - test('prefers basic auth when multiple schemes present', () => { - const schemes: Record = { - apiKey: { type: 'apiKey', name: 'X-Key', in: 'header' }, - basicAuth: { type: 'http', scheme: 'basic' }, - }; - const result = detectAuthFromSpec(schemes); - expect(result!.type).toBe('basic'); - }); - - test('detects oauth2 as bearer type', () => { - const schemes: Record = { - oauth: { - type: 'oauth2', - flows: { - clientCredentials: { - tokenUrl: 'https://auth.example.com/token', - scopes: {}, - }, - }, - }, - }; - const result = detectAuthFromSpec(schemes); - expect(result).not.toBeNull(); - expect(result!.type).toBe('bearer'); - }); -}); diff --git a/tests/codegen/stripe-e2e.test.ts b/tests/codegen/stripe-e2e.test.ts index 841fe38..5d67b59 100644 --- a/tests/codegen/stripe-e2e.test.ts +++ b/tests/codegen/stripe-e2e.test.ts @@ -15,9 +15,16 @@ let commandsOutput: string; let commandMapOutput: string; beforeAll(async () => { - // Download Stripe spec — skip suite if offline + // Download Stripe spec — skip suite if unavailable (offline, rate-limited, + // or just slow). Two deadlines matter here and they must not be equal: + // the fetch is bounded well inside the hook's own timeout, so a slow or + // hanging response lands in the catch below instead of blowing the hook's + // deadline. A timed-out hook is reported as a hard test failure, not a + // skip — which is how a GitHub 429 on raw.githubusercontent.com (7-15s to + // respond, against bun's 5s default) once blocked a release even though + // this suite is designed to opt out when the spec can't be fetched. try { - const res = await fetch(STRIPE_SPEC_URL); + const res = await fetch(STRIPE_SPEC_URL, { signal: AbortSignal.timeout(20_000) }); if (!res.ok) throw new Error(`HTTP ${res.status}`); @@ -35,7 +42,9 @@ beforeAll(async () => { clientOutput = await Bun.file(join(outDir, 'client.ts')).text(); commandsOutput = await Bun.file(join(outDir, 'commands.ts')).text(); commandMapOutput = await Bun.file(join(outDir, 'command-map.ts')).text(); -}); + // Explicit hook timeout: the default 5s is shorter than a healthy download + // of this spec, let alone a throttled one. +}, 60_000); function skipIfOffline() { if (!spec) { From 854fca6ff9be578abf9eb10768bda3295e959907 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 11:45:04 -0400 Subject: [PATCH 04/11] revert: restore auth-detector files swept in by a shared-checkout race d118990 was meant to carry only the Stripe e2e timeout fix. Another session working issue #170 in the same checkout had staged the removal of src/auth-detector.ts and tests/auth-detector.test.ts, and `git commit` takes the whole index, not just the paths passed to `git add`. The deletion rode along into dev and into release PR #172. Restoring both files here so the release ships only what was reviewed. The #170 removal is legitimate work and lands on its own branch, with its own review. --- src/auth-detector.ts | 87 +++++++++++++++++++++++++++++++++++++ tests/auth-detector.test.ts | 70 +++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 src/auth-detector.ts create mode 100644 tests/auth-detector.test.ts diff --git a/src/auth-detector.ts b/src/auth-detector.ts new file mode 100644 index 0000000..8327fc5 --- /dev/null +++ b/src/auth-detector.ts @@ -0,0 +1,87 @@ +import type { AuthStrategy } from './auth/types'; +import { BasicAuthStrategy } from './auth/basic'; +import { BearerTokenStrategy } from './auth/bearer'; +import { ApiKeyStrategy } from './auth/api-key'; + +export interface SecurityScheme { + type: 'http' | 'apiKey' | 'oauth2' | 'openIdConnect'; + scheme?: string; + name?: string; + in?: string; + flows?: Record; +} + +export interface DetectedAuth { + type: 'basic' | 'bearer' | 'apiKey'; + strategy: AuthStrategy; + headerName?: string; +} + +const PRIORITY: Array<'basic' | 'bearer' | 'apiKey'> = ['basic', 'bearer', 'apiKey']; + +export function detectAuthFromSpec( + schemes: Record | undefined, +): DetectedAuth | null { + if (!schemes || Object.keys(schemes).length === 0) return null; + + const detected: DetectedAuth[] = []; + + for (const scheme of Object.values(schemes)) { + if (scheme.type === 'http' && scheme.scheme === 'basic') { + detected.push({ + type: 'basic', + strategy: new BasicAuthStrategy(), + }); + } else if (scheme.type === 'http' && scheme.scheme === 'bearer') { + detected.push({ + type: 'bearer', + strategy: new BearerTokenStrategy(async (config) => { + return config.password; + }), + }); + } else if (scheme.type === 'apiKey' && scheme.name && scheme.in === 'header') { + detected.push({ + type: 'apiKey', + strategy: new ApiKeyStrategy(scheme.name, ''), + headerName: scheme.name, + }); + } else if (scheme.type === 'oauth2') { + detected.push({ + type: 'bearer', + strategy: new BearerTokenStrategy(async (config) => { + return config.password; + }), + }); + } + } + + if (detected.length === 0) return null; + + for (const prio of PRIORITY) { + const match = detected.find(d => d.type === prio); + + if (match) return match; + } + + return detected[0]!; +} + +export async function fetchSecuritySchemes( + specUrl: string, + headers?: Record, +): Promise | null> { + try { + const res = await fetch(specUrl, { + headers: { Accept: 'application/json', ...headers }, + }); + + if (!res.ok) return null; + + const spec = await res.json() as Record; + const components = spec.components as Record | undefined; + + return (components?.securitySchemes as Record) ?? null; + } catch { + return null; + } +} diff --git a/tests/auth-detector.test.ts b/tests/auth-detector.test.ts new file mode 100644 index 0000000..e7609f5 --- /dev/null +++ b/tests/auth-detector.test.ts @@ -0,0 +1,70 @@ +import { describe, test, expect } from 'bun:test'; +import { detectAuthFromSpec, type SecurityScheme } from '../src/auth-detector'; +import { BasicAuthStrategy } from '../src/auth/basic'; + +describe('detectAuthFromSpec()', () => { + test('detects basic auth', () => { + const schemes: Record = { + basicAuth: { type: 'http', scheme: 'basic' }, + }; + const result = detectAuthFromSpec(schemes); + expect(result).not.toBeNull(); + expect(result!.type).toBe('basic'); + expect(result!.strategy).toBeInstanceOf(BasicAuthStrategy); + }); + + test('detects bearer auth', () => { + const schemes: Record = { + bearerAuth: { type: 'http', scheme: 'bearer' }, + }; + const result = detectAuthFromSpec(schemes); + expect(result).not.toBeNull(); + expect(result!.type).toBe('bearer'); + }); + + test('detects apiKey auth with header name', () => { + const schemes: Record = { + apiKey: { type: 'apiKey', name: 'X-API-Key', in: 'header' }, + }; + const result = detectAuthFromSpec(schemes); + expect(result).not.toBeNull(); + expect(result!.type).toBe('apiKey'); + expect(result!.headerName).toBe('X-API-Key'); + }); + + test('returns null for empty schemes', () => { + const result = detectAuthFromSpec({}); + expect(result).toBeNull(); + }); + + test('returns null for undefined schemes', () => { + const result = detectAuthFromSpec(undefined); + expect(result).toBeNull(); + }); + + test('prefers basic auth when multiple schemes present', () => { + const schemes: Record = { + apiKey: { type: 'apiKey', name: 'X-Key', in: 'header' }, + basicAuth: { type: 'http', scheme: 'basic' }, + }; + const result = detectAuthFromSpec(schemes); + expect(result!.type).toBe('basic'); + }); + + test('detects oauth2 as bearer type', () => { + const schemes: Record = { + oauth: { + type: 'oauth2', + flows: { + clientCredentials: { + tokenUrl: 'https://auth.example.com/token', + scopes: {}, + }, + }, + }, + }; + const result = detectAuthFromSpec(schemes); + expect(result).not.toBeNull(); + expect(result!.type).toBe('bearer'); + }); +}); From aa38cecd37c16c1659a42c03aa105a1a4aaa8d99 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 11:45:24 -0400 Subject: [PATCH 05/11] chore(release): v1.17.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9040255..82fb056 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.1", + "version": "1.17.2", "license": "MIT", "repository": { "type": "git", From 7e99e74c7e15b8e8705fd1b49c713543ffe495d7 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 11:48:56 -0400 Subject: [PATCH 06/11] chore: reset version to 1.17.0 so the next ship bumps to 1.17.1 ship.sh runs `npm version patch` unconditionally, so each failed run bumps again: two CI failures (both GitHub 429s on action downloads, not code) left dev claiming 1.17.2 while npm is still on 1.17.0. Resetting the file so the next run lands on the intended 1.17.1. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82fb056..0d733b3 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.2", + "version": "1.17.0", "license": "MIT", "repository": { "type": "git", From 070e86790c96dd84ccabe8ed5b0057f1982cc198 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 11:49:07 -0400 Subject: [PATCH 07/11] chore(release): v1.17.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d733b3..9040255 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.0", + "version": "1.17.1", "license": "MIT", "repository": { "type": "git", From 1961b174714dc80e24cf74444c18e0aea95e500b Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 12:13:39 -0400 Subject: [PATCH 08/11] chore: reset version to 1.17.0 for a clean ship attempt --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9040255..0d733b3 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.1", + "version": "1.17.0", "license": "MIT", "repository": { "type": "git", From 328a62730a5cfd67f59cd982804de0bd2e49f795 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Mon, 17 Aug 2026 12:13:47 -0400 Subject: [PATCH 09/11] chore(release): v1.17.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d733b3..9040255 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.0", + "version": "1.17.1", "license": "MIT", "repository": { "type": "git", From 2d69ae9fd6e582cd9e7b1a2229da35dac4c21fd8 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Tue, 25 Aug 2026 09:04:07 -0400 Subject: [PATCH 10/11] chore: reset version to 1.17.0 for a clean ship attempt --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9040255..0d733b3 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.1", + "version": "1.17.0", "license": "MIT", "repository": { "type": "git", From 76696bc20edfd35662d898f6e4cb9dfcf9deade0 Mon Sep 17 00:00:00 2001 From: Garret Premo Date: Tue, 25 Aug 2026 09:04:14 -0400 Subject: [PATCH 11/11] chore(release): v1.17.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d733b3..9040255 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "api-client", "sdk-generator" ], - "version": "1.17.0", + "version": "1.17.1", "license": "MIT", "repository": { "type": "git",