diff --git a/.changeset/strong-pandas-brake.md b/.changeset/strong-pandas-brake.md new file mode 100644 index 000000000..c1b161fec --- /dev/null +++ b/.changeset/strong-pandas-brake.md @@ -0,0 +1,5 @@ +--- +'@graphql-hive/cli': minor +--- + +Support SchemaPublishMissingUrlError type diff --git a/integration-tests/tests/cli/schema.spec.ts b/integration-tests/tests/cli/schema.spec.ts index e62ba1e19..dff8a4468 100644 --- a/integration-tests/tests/cli/schema.spec.ts +++ b/integration-tests/tests/cli/schema.spec.ts @@ -137,3 +137,61 @@ test('service url should be available in supergraph', async () => { expect(supergraph.body).toMatch('(name: "users" url: "https://api.com/users-subgraph")'); }); + +test('service url should be required in Federation', async () => { + const { access_token: owner_access_token } = await authenticate('main'); + const orgResult = await createOrganization( + { + name: 'foo', + }, + owner_access_token + ); + const org = orgResult.body.data!.createOrganization.ok!.createdOrganizationPayload.organization; + const code = org.inviteCode; + + // Join + const { access_token: member_access_token } = await authenticate('extra'); + await joinOrganization(code, member_access_token); + + const projectResult = await createProject( + { + organization: org.cleanId, + type: ProjectType.Federation, + name: 'foo', + }, + owner_access_token + ); + + const project = projectResult.body.data!.createProject.ok!.createdProject; + const target = projectResult.body.data!.createProject.ok!.createdTarget; + + // Create a token with write rights + const writeTokenResult = await createToken( + { + name: 'test', + organization: org.cleanId, + project: project.cleanId, + target: target.cleanId, + organizationScopes: [], + projectScopes: [], + targetScopes: [TargetAccessScope.RegistryRead, TargetAccessScope.RegistryWrite], + }, + owner_access_token + ); + expect(writeTokenResult.body.errors).not.toBeDefined(); + const writeToken = writeTokenResult.body.data!.createToken.ok!.secret; + + await expect( + schemaPublish([ + '--token', + writeToken, + '--author', + 'Kamil', + '--commit', + 'abc123', + '--service', + 'users', + 'fixtures/federation-init.graphql', + ]) + ).rejects.toThrowError('EXIT: 1'); +}); diff --git a/packages/libraries/cli/src/commands/schema/publish.graphql b/packages/libraries/cli/src/commands/schema/publish.graphql index 1d59509e5..128d20a49 100644 --- a/packages/libraries/cli/src/commands/schema/publish.graphql +++ b/packages/libraries/cli/src/commands/schema/publish.graphql @@ -32,6 +32,9 @@ mutation schemaPublish($input: SchemaPublishInput!, $usesGitHubApp: Boolean!) { ... on SchemaPublishMissingServiceError @skip(if: $usesGitHubApp) { missingServiceError: message } + ... on SchemaPublishMissingUrlError @skip(if: $usesGitHubApp) { + missingUrlError: message + } ... on GitHubSchemaPublishSuccess @include(if: $usesGitHubApp) { message } diff --git a/packages/libraries/cli/src/commands/schema/publish.ts b/packages/libraries/cli/src/commands/schema/publish.ts index e30560bb8..608d40b03 100644 --- a/packages/libraries/cli/src/commands/schema/publish.ts +++ b/packages/libraries/cli/src/commands/schema/publish.ts @@ -175,6 +175,9 @@ export default class SchemaPublish extends Command { } else if (result.schemaPublish.__typename === 'SchemaPublishMissingServiceError') { this.fail(`${result.schemaPublish.missingServiceError} Please use the '--service ' parameter.`); this.exit(1); + } else if (result.schemaPublish.__typename === 'SchemaPublishMissingUrlError') { + this.fail(`${result.schemaPublish.missingUrlError} Please use the '--url ' parameter.`); + this.exit(1); } else if (result.schemaPublish.__typename === 'SchemaPublishError') { const changes = result.schemaPublish.changes; const errors = result.schemaPublish.errors;