From 63074a5e8ca81ea695664a296a805388d2a99bb2 Mon Sep 17 00:00:00 2001 From: Brandon Corbett Date: Fri, 16 Oct 2026 20:55:35 -0400 Subject: [PATCH] ci: keep openapi.json and the adapter manifest versioned with the package Regenerate both in the Changesets version step and fail the contract test when either drifts from the routes or from package.json. Closes #395 --- .changeset/openapi-version-in-step.md | 5 +++++ adapter-manifest.json | 2 +- openapi.json | 2 +- package.json | 2 +- tests/unit/openapi/generatedContract.spec.ts | 19 ++++++++++++++++--- 5 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 .changeset/openapi-version-in-step.md diff --git a/.changeset/openapi-version-in-step.md b/.changeset/openapi-version-in-step.md new file mode 100644 index 00000000..25a2d44d --- /dev/null +++ b/.changeset/openapi-version-in-step.md @@ -0,0 +1,5 @@ +--- +'seamless-auth-api': patch +--- + +`openapi.json` and `adapter-manifest.json` now carry the package version. The release version step regenerates both, and the contract test fails when either file drifts from the route definitions or from `package.json`. Both said 0.17.0 through the 0.18.0 release. diff --git a/adapter-manifest.json b/adapter-manifest.json index 8971c138..29e0240f 100644 --- a/adapter-manifest.json +++ b/adapter-manifest.json @@ -1,6 +1,6 @@ { "schemaVersion": 1, - "apiVersion": "0.17.0", + "apiVersion": "0.18.0", "session": { "subject": "sub", "token": "token", diff --git a/openapi.json b/openapi.json index 5740e16c..acd42f63 100644 --- a/openapi.json +++ b/openapi.json @@ -1,6 +1,6 @@ { "openapi": "3.0.3", - "info": { "title": "Seamless Auth API", "version": "0.17.0" }, + "info": { "title": "Seamless Auth API", "version": "0.18.0" }, "components": { "schemas": {}, "parameters": {}, diff --git a/package.json b/package.json index f6e326a1..e983fb69 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "format:check": "prettier --check .", "changeset": "changeset", "check:changeset-bump": "node ./src/scripts/checkChangesetBump.mjs", - "version-packages": "changeset version", + "version-packages": "changeset version && npm run generate:api", "db:create": "env-cmd -f .env sequelize-cli db:create || sequelize-cli db:create", "db:drop": "env-cmd -f .env sequelize-cli db:drop || sequelize-cli db:drop", "db:refresh": "env-cmd -f .env sequelize-cli db:drop && sequelize-cli db:create", diff --git a/tests/unit/openapi/generatedContract.spec.ts b/tests/unit/openapi/generatedContract.spec.ts index d44e5ed7..51ded094 100644 --- a/tests/unit/openapi/generatedContract.spec.ts +++ b/tests/unit/openapi/generatedContract.spec.ts @@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url'; import { describe, expect, it } from 'vitest'; +import { getAdapterManifest } from '../../../src/lib/adapterManifest.js'; import { buildOpenApiDocument } from '../../../src/scripts/generateApiTypes.js'; const repoRoot = join(dirname(fileURLToPath(import.meta.url)), '../../..'); @@ -12,14 +13,26 @@ function readCommitted(relativePath: string) { return readFileSync(join(repoRoot, relativePath), 'utf8'); } +const packageVersion = JSON.parse(readCommitted('package.json')).version; + describe('generated API contract', () => { it('keeps openapi.json in step with the route definitions', async () => { const generated = await buildOpenApiDocument(); const committed = JSON.parse(readCommitted('openapi.json')); - // The version tracks package.json, which Changesets bumps on release without - // regenerating. Everything else must match. - expect({ ...generated, info: undefined }).toEqual({ ...committed, info: undefined }); + expect(committed).toEqual(generated); + }); + + it('versions openapi.json with the package', () => { + expect(JSON.parse(readCommitted('openapi.json')).info.version).toBe(packageVersion); + }); + + it('keeps adapter-manifest.json in step with the route definitions', async () => { + await buildOpenApiDocument(); + const committed = JSON.parse(readCommitted('adapter-manifest.json')); + + expect(committed).toEqual(JSON.parse(JSON.stringify(getAdapterManifest()))); + expect(committed.apiVersion).toBe(packageVersion); }); it('ships non-empty generated types', () => {