Skip to content
75 changes: 73 additions & 2 deletions cli/src/commands/subgraph/commands/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,44 @@ import {
parseGraphQLWebsocketSubprotocol,
splitLabel,
} from '@wundergraph/cosmo-shared';
import { SubgraphType } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb';
import { SubgraphType, SubgraphPublishStats } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb';
import { BaseCommandOptions } from '../../../core/types/types.js';
import { getBaseHeaders } from '../../../core/config.js';
import { validateSubscriptionProtocols } from '../../../utils.js';
import { websocketSubprotocolDescription } from '../../../constants.js';
import { websocketSubprotocolDescription, limitMaxValue } from '../../../constants.js';

const printTruncationWarning = (
counts: SubgraphPublishStats | undefined,
displayedCounts: {
compositionErrors: number;
compositionWarnings: number;
deploymentErrors: number;
},
) => {
if (!counts) {
return;
}

const truncatedItems: string[] = [];

if (counts.compositionErrors > displayedCounts.compositionErrors) {
truncatedItems.push(
`composition errors (${displayedCounts.compositionErrors} of ${counts.compositionErrors} shown)`,
);
}
if (counts.compositionWarnings > displayedCounts.compositionWarnings) {
truncatedItems.push(
`composition warnings (${displayedCounts.compositionWarnings} of ${counts.compositionWarnings} shown)`,
);
}
if (counts.deploymentErrors > displayedCounts.deploymentErrors) {
truncatedItems.push(`deployment errors (${displayedCounts.deploymentErrors} of ${counts.deploymentErrors} shown)`);
}

if (truncatedItems.length > 0) {
console.log(pc.yellow(`\nNote: Some results were truncated: ${truncatedItems.join(', ')}.`));
}
};

export default (opts: BaseCommandOptions) => {
const command = new Command('publish');
Expand Down Expand Up @@ -74,6 +107,11 @@ export default (opts: BaseCommandOptions) => {
'--disable-resolvability-validation',
'This flag will disable the validation for whether all nodes of the federated graph are resolvable. Do NOT use unless troubleshooting.',
);
command.option(
'-l, --limit <number>',
'The maximum number of composition errors, warnings, and deployment errors to display.',
'50',
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.

command.action(async (name, options) => {
const schemaFile = resolve(options.schema);
Expand All @@ -98,6 +136,13 @@ export default (opts: BaseCommandOptions) => {
websocketSubprotocol: options.websocketSubprotocol,
});

const limit = Number(options.limit);
if (!Number.isInteger(limit) || limit <= 0 || limit > limitMaxValue) {
program.error(
pc.red(`The limit must be a valid number between 1 and ${limitMaxValue}. Received: '${options.limit}'`),
);
}

const spinner = ora('Subgraph is being published...').start();

const resp = await opts.client.platform.publishFederatedSubgraph(
Expand All @@ -118,6 +163,7 @@ export default (opts: BaseCommandOptions) => {
: undefined,
labels: options.label.map((label: string) => splitLabel(label)),
type: SubgraphType.STANDARD,
limit,
},
{
headers: getBaseHeaders(),
Expand Down Expand Up @@ -177,6 +223,12 @@ export default (opts: BaseCommandOptions) => {
console.log(compositionErrorsTable.toString());

if (options.failOnCompositionError) {
// Only composition errors were displayed at this point, warnings come after switch
printTruncationWarning(resp.counts, {
compositionErrors: resp.compositionErrors.length,
compositionWarnings: 0,
deploymentErrors: 0,
});
Comment thread
coderabbitai[bot] marked this conversation as resolved.
program.error(pc.red(pc.bold('The command failed due to composition errors.')));
}

Expand Down Expand Up @@ -208,6 +260,12 @@ export default (opts: BaseCommandOptions) => {
console.log(deploymentErrorsTable.toString());

if (options.failOnAdmissionWebhookError) {
// Only deployment errors were displayed at this point, warnings come after switch
printTruncationWarning(resp.counts, {
compositionErrors: 0,
compositionWarnings: 0,
deploymentErrors: resp.deploymentErrors.length,
});
program.error(pc.red(pc.bold('The command failed due to admission webhook errors.')));
}

Expand All @@ -223,6 +281,9 @@ export default (opts: BaseCommandOptions) => {
}
}

// Track what was actually displayed
const displayedWarnings = options.suppressWarnings ? 0 : resp.compositionWarnings.length;

if (!options.suppressWarnings && resp.compositionWarnings.length > 0) {
const compositionWarningsTable = new Table({
head: [
Expand All @@ -246,6 +307,16 @@ export default (opts: BaseCommandOptions) => {
}
console.log(compositionWarningsTable.toString());
}

// Determine what was actually displayed based on the response code
const displayedCounts = {
compositionErrors:
resp.response?.code === EnumStatusCode.ERR_SUBGRAPH_COMPOSITION_FAILED ? resp.compositionErrors.length : 0,
compositionWarnings: displayedWarnings,
deploymentErrors: resp.response?.code === EnumStatusCode.ERR_DEPLOYMENT_FAILED ? resp.deploymentErrors.length : 0,
};

printTruncationWarning(resp.counts, displayedCounts);
});

return command;
Expand Down
6 changes: 0 additions & 6 deletions cli/test/check-schema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@ describe('stdout', () => {
});

afterEach(() => {
logSpy.mockRestore();
stderrSpy.mockRestore();
exitSpy.mockRestore();
process.exitCode = undefined;
resetVcsConfig();
});
Expand Down Expand Up @@ -667,9 +664,6 @@ describe('json output', () => {
});

afterEach(() => {
logSpy.mockRestore();
stderrSpy.mockRestore();
exitSpy.mockRestore();
process.exitCode = undefined;
resetVcsConfig();
});
Expand Down
Loading
Loading