Skip to content

Commit 1d102d4

Browse files
committed
store and expose base schema sdl + hash
1 parent 3e59605 commit 1d102d4

10 files changed

Lines changed: 83 additions & 2 deletions

File tree

integration-tests/testkit/flow.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,8 @@ export function checkSchema(input: SchemaCheckInput, token: string) {
12761276
schemaCheck {
12771277
__typename
12781278
id
1279+
previousSchemaSDL
1280+
baseSchemaHash
12791281
schemaVersion {
12801282
id
12811283
}
@@ -1299,6 +1301,8 @@ export function checkSchema(input: SchemaCheckInput, token: string) {
12991301
}
13001302
schemaCheck {
13011303
id
1304+
previousSchemaSDL
1305+
baseSchemaHash
13021306
}
13031307
}
13041308
}

integration-tests/tests/api/schema/check.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,6 +2070,7 @@ describe.concurrent('schema check with a base service schema', () => {
20702070
const result = await checkSchema(
20712071
{
20722072
service: 'products',
2073+
baseSchemaHash: 'base-commit-sha',
20732074
baseSdl: /* GraphQL */ `
20742075
extend schema
20752076
@link(url: "https://specs.apollo.dev/link/v1.0")
@@ -2107,6 +2108,10 @@ describe.concurrent('schema check with a base service schema', () => {
21072108
expect(result.schemaCheck).toMatchObject({
21082109
__typename: 'SchemaCheckError',
21092110
valid: false,
2111+
schemaCheck: {
2112+
previousSchemaSDL: expect.stringContaining('baseOnly: String'),
2113+
baseSchemaHash: 'base-commit-sha',
2114+
},
21102115
changes: {
21112116
nodes: [
21122117
{

packages/libraries/cli/src/commands/schema/check.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,12 @@ export default class SchemaCheck extends Command<typeof SchemaCheck> {
238238
}
239239

240240
let minifiedBaseSdl: string | null = null;
241+
let baseSchemaHash: string | null = null;
241242

242243
if (flags.base) {
243244
const basePointer = flags.base;
244245
const gitResult = parseBaseGitFileReference(basePointer);
246+
baseSchemaHash = gitResult.status === 'ok' ? gitResult.commit : null;
245247
const result =
246248
gitResult.status === 'error'
247249
? await loadSchema('first-federation-then-graphql-introspection', basePointer, {
@@ -346,6 +348,7 @@ export default class SchemaCheck extends Command<typeof SchemaCheck> {
346348
url: flags.url,
347349
schemaProposalId: flags.schemaProposalId,
348350
baseSdl: minifiedBaseSdl,
351+
baseSchemaHash,
349352
},
350353
},
351354
/** Gateway timeout is 60 seconds. */

packages/migrations/src/run-pg-migrations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,6 @@ export const runPGMigrations = async (args: { slonik: PostgresDatabasePool; runT
130130
import('./actions/2026.06.11T00-00-00.oidc-integration-user-id-claim'),
131131
import('./actions/2026.08.06T00-00-00.scim-provisioning-status'),
132132
import('./actions/2026.08.07T00-00-00.scim-pending-confirmation-index'),
133+
import('./actions/2026.08.11T00-00-00.schema-check-base-sdl'),
133134
]),
134135
});

packages/services/api/src/modules/schema/module.graphql.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,11 @@ export default gql`
901901
"""
902902
baseSdl: String
903903
904+
"""
905+
An identifier for the schema supplied through 'baseSdl', such as its Git commit SHA.
906+
"""
907+
baseSchemaHash: String
908+
904909
github: GitHubSchemaCheckInput
905910
meta: SchemaCheckMetaInput
906911
"""
@@ -1446,6 +1451,10 @@ export default gql`
14461451
"""
14471452
previousSchemaSDL: String @tag(name: "public")
14481453
"""
1454+
The caller-supplied identifier for an explicit comparison baseline, such as a Git commit SHA.
1455+
"""
1456+
baseSchemaHash: String @tag(name: "public")
1457+
"""
14491458
The name of the service that owns the schema. Is null for non composite project types.
14501459
"""
14511460
serviceName: String @tag(name: "public")
@@ -1603,6 +1612,10 @@ export default gql`
16031612
"""
16041613
previousSchemaSDL: String @tag(name: "public")
16051614
"""
1615+
The caller-supplied identifier for an explicit comparison baseline, such as a Git commit SHA.
1616+
"""
1617+
baseSchemaHash: String @tag(name: "public")
1618+
"""
16061619
The name of the service that owns the schema. Is null for non composite project types.
16071620
"""
16081621
serviceName: String @tag(name: "public")
@@ -1704,6 +1717,10 @@ export default gql`
17041717
"""
17051718
previousSchemaSDL: String @tag(name: "public")
17061719
"""
1720+
The caller-supplied identifier for an explicit comparison baseline, such as a Git commit SHA.
1721+
"""
1722+
baseSchemaHash: String @tag(name: "public")
1723+
"""
17071724
The name of the service that owns the schema. Is null for non composite project types.
17081725
"""
17091726
serviceName: String @tag(name: "public")

packages/services/api/src/modules/schema/providers/schema-check-manager.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ export class SchemaCheckManager {
7272
}
7373

7474
async getPreviousSchemaSDL(schemaCheck: SchemaCheck) {
75+
if (schemaCheck.baseSchemaSDL !== null) {
76+
return schemaCheck.baseSchemaSDL;
77+
}
78+
7579
if (schemaCheck.serviceName === null || schemaCheck.schemaVersionId === null) {
7680
return null;
7781
}

packages/services/api/src/modules/schema/providers/schema-publisher.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ export class SchemaPublisher {
580580

581581
const sdl = tryPrettifySDL(input.sdl);
582582
const baseSdl = input.baseSdl ? tryPrettifySDL(input.baseSdl) : null;
583+
const baseSchemaHash = baseSdl ? (input.baseSchemaHash ?? null) : null;
583584

584585
const activeContracts =
585586
project.type === ProjectType.FEDERATION
@@ -775,6 +776,8 @@ export class SchemaPublisher {
775776
if (checkResult.conclusion === SchemaCheckConclusion.Failure) {
776777
schemaCheck = await this.storage.createSchemaCheck({
777778
schemaSDL: sdl,
779+
baseSchemaSDL: baseSdl,
780+
baseSchemaHash,
778781
serviceName: input.service ?? null,
779782
serviceUrl: input.url ?? null,
780783
meta: input.meta ?? null,
@@ -831,6 +834,8 @@ export class SchemaPublisher {
831834
} else if (checkResult.conclusion === SchemaCheckConclusion.Success) {
832835
schemaCheck = await this.storage.createSchemaCheck({
833836
schemaSDL: sdl,
837+
baseSchemaSDL: baseSdl,
838+
baseSchemaHash,
834839
serviceName: input.service ?? null,
835840
serviceUrl: input.url ?? null,
836841
meta: input.meta ?? null,
@@ -889,6 +894,8 @@ export class SchemaPublisher {
889894

890895
schemaCheck = await this.storage.createSchemaCheck({
891896
schemaSDL: sdl,
897+
baseSchemaSDL: baseSdl,
898+
baseSchemaHash,
892899
serviceName: input.service ?? null,
893900
serviceUrl: input.url ?? null,
894901
meta: input.meta ?? null,

packages/services/storage/src/db/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ export interface schema_change_approvals {
402402
}
403403

404404
export interface schema_checks {
405+
base_schema_hash: string | null;
406+
base_schema_sdl_store_id: string | null;
405407
breaking_schema_changes: any | null;
406408
composite_schema_sdl: string | null;
407409
composite_schema_sdl_store_id: string | null;

packages/services/storage/src/index.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3092,11 +3092,16 @@ export async function createStorage(
30923092
}
30933093

30943094
const schemaSDLHash = createSDLHash(args.schemaSDL);
3095+
const baseSchemaSDLHash = args.baseSchemaSDL ? createSDLHash(args.baseSchemaSDL) : null;
30953096
let compositeSchemaSDLHash: string | null = null;
30963097
let supergraphSDLHash: string | null = null;
30973098

30983099
sdlStoreInserts.push(insertSdl(schemaSDLHash, args.schemaSDL));
30993100

3101+
if (args.baseSchemaSDL && baseSchemaSDLHash) {
3102+
sdlStoreInserts.push(insertSdl(baseSchemaSDLHash, args.baseSchemaSDL));
3103+
}
3104+
31003105
if (args.compositeSchemaSDL) {
31013106
compositeSchemaSDLHash = createSDLHash(args.compositeSchemaSDL);
31023107
sdlStoreInserts.push(insertSdl(compositeSchemaSDLHash, args.compositeSchemaSDL));
@@ -3114,6 +3119,8 @@ export async function createStorage(
31143119
psql`/* createSchemaCheck */
31153120
INSERT INTO "schema_checks" (
31163121
"schema_sdl_store_id"
3122+
, "base_schema_sdl_store_id"
3123+
, "base_schema_hash"
31173124
, "service_name"
31183125
, "service_url"
31193126
, "meta"
@@ -3141,6 +3148,8 @@ export async function createStorage(
31413148
)
31423149
VALUES (
31433150
${schemaSDLHash}
3151+
, ${baseSchemaSDLHash}
3152+
, ${args.baseSchemaHash}
31443153
, ${args.serviceName}
31453154
, ${args.serviceUrl}
31463155
, ${psql.jsonbOrNull(args.meta)}
@@ -3239,6 +3248,7 @@ export async function createStorage(
32393248
FROM
32403249
"schema_checks" as c
32413250
LEFT JOIN "sdl_store" as s_schema ON s_schema."id" = c."schema_sdl_store_id"
3251+
LEFT JOIN "sdl_store" as s_base_schema ON s_base_schema."id" = c."base_schema_sdl_store_id"
32423252
LEFT JOIN "sdl_store" as s_composite_schema ON s_composite_schema."id" = c."composite_schema_sdl_store_id"
32433253
LEFT JOIN "sdl_store" as s_supergraph ON s_supergraph."id" = c."supergraph_sdl_store_id"
32443254
WHERE
@@ -3374,6 +3384,7 @@ export async function createStorage(
33743384
FROM
33753385
"schema_checks" as c
33763386
LEFT JOIN "sdl_store" as s_schema ON s_schema."id" = c."schema_sdl_store_id"
3387+
LEFT JOIN "sdl_store" as s_base_schema ON s_base_schema."id" = c."base_schema_sdl_store_id"
33773388
LEFT JOIN "sdl_store" as s_composite_schema ON s_composite_schema."id" = c."composite_schema_sdl_store_id"
33783389
LEFT JOIN "sdl_store" as s_supergraph ON s_supergraph."id" = c."supergraph_sdl_store_id"
33793390
WHERE
@@ -3426,6 +3437,7 @@ export async function createStorage(
34263437
args.withSDL
34273438
? psql`
34283439
LEFT JOIN "sdl_store" as s_schema ON s_schema."id" = c."schema_sdl_store_id"
3440+
LEFT JOIN "sdl_store" as s_base_schema ON s_base_schema."id" = c."base_schema_sdl_store_id"
34293441
LEFT JOIN "sdl_store" as s_composite_schema ON s_composite_schema."id" = c."composite_schema_sdl_store_id"
34303442
LEFT JOIN "sdl_store" as s_supergraph ON s_supergraph."id" = c."supergraph_sdl_store_id"
34313443
`
@@ -3554,6 +3566,8 @@ export async function createStorage(
35543566
}
35553567
LEFT JOIN "sdl_store" as s_schema
35563568
ON s_schema."id" = c."schema_sdl_store_id"
3569+
LEFT JOIN "sdl_store" as s_base_schema
3570+
ON s_base_schema."id" = c."base_schema_sdl_store_id"
35573571
LEFT JOIN "sdl_store" as s_composite_schema
35583572
ON s_composite_schema."id" = c."composite_schema_sdl_store_id"
35593573
LEFT JOIN "sdl_store" as s_supergraph
@@ -3707,6 +3721,10 @@ export async function createStorage(
37073721
FROM "filtered_schema_checks"
37083722
WHERE "filtered_schema_checks"."schema_sdl_store_id" IS NOT NULL
37093723
3724+
UNION SELECT DISTINCT "filtered_schema_checks"."base_schema_sdl_store_id"
3725+
FROM "filtered_schema_checks"
3726+
WHERE "filtered_schema_checks"."base_schema_sdl_store_id" IS NOT NULL
3727+
37103728
UNION SELECT DISTINCT "filtered_schema_checks"."composite_schema_sdl_store_id"
37113729
FROM "filtered_schema_checks"
37123730
WHERE "filtered_schema_checks"."composite_schema_sdl_store_id" IS NOT NULL
@@ -3777,6 +3795,7 @@ export async function createStorage(
37773795
"schema_checks"
37783796
WHERE
37793797
"schema_checks"."schema_sdl_store_id" = "sdl_store"."id"
3798+
OR "schema_checks"."base_schema_sdl_store_id" = "sdl_store"."id"
37803799
OR "schema_checks"."composite_schema_sdl_store_id" = "sdl_store"."id"
37813800
OR "schema_checks"."supergraph_sdl_store_id" = "sdl_store"."id"
37823801
)
@@ -4212,16 +4231,19 @@ const schemaCheckSQLFields = (include?: { sdl?: boolean; changes?: boolean }) =>
42124231
(include?.sdl ?? true)
42134232
? psql`
42144233
, coalesce(c."schema_sdl", s_schema."sdl") as "schemaSDL"
4234+
, s_base_schema."sdl" as "baseSchemaSDL"
42154235
, coalesce(c."composite_schema_sdl", s_composite_schema."sdl") as "compositeSchemaSDL"
42164236
, coalesce(c."supergraph_sdl", s_supergraph."sdl") as "supergraphSDL"
42174237
`
42184238
: psql`
42194239
, '' as "schemaSDL"
4240+
, null as "baseSchemaSDL"
42204241
, null as "compositeSchemaSDL"
42214242
, null as "supergraphSDL"
42224243
`
42234244
}
42244245
, c."service_name" as "serviceName"
4246+
, c."base_schema_hash" as "baseSchemaHash"
42254247
, c."service_url" as "serviceUrl"
42264248
, c."meta"
42274249
, c."target_id" as "targetId"

packages/services/storage/src/schema-change-model.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,7 +1448,7 @@ const SchemaProposalOutputFields = {
14481448
schemaProposalChanges: z.array(HiveSchemaChangeModel).nullable(),
14491449
};
14501450

1451-
const SchemaCheckSharedOutputFields = {
1451+
const SchemaCheckCommonFields = {
14521452
schemaSDL: z.string(),
14531453
serviceName: z.string().nullable(),
14541454
serviceUrl: z.string().nullable(),
@@ -1470,8 +1470,24 @@ const SchemaCheckSharedOutputFields = {
14701470
...SchemaProposalOutputFields,
14711471
};
14721472

1473+
const SchemaCheckSharedOutputFields = {
1474+
...SchemaCheckCommonFields,
1475+
baseSchemaSDL: z.string().nullable(),
1476+
baseSchemaHash: z.string().nullable(),
1477+
};
1478+
14731479
const SchemaCheckSharedInputFields = {
1474-
...SchemaCheckSharedOutputFields,
1480+
...SchemaCheckCommonFields,
1481+
baseSchemaSDL: z
1482+
.string()
1483+
.nullable()
1484+
.optional()
1485+
.transform(value => value ?? null),
1486+
baseSchemaHash: z
1487+
.string()
1488+
.nullable()
1489+
.optional()
1490+
.transform(value => value ?? null),
14751491
};
14761492

14771493
const ContractCheckInput = z.object({

0 commit comments

Comments
 (0)