Skip to content

Commit

Permalink
Support dry run in the CLI (#29626)
Browse files Browse the repository at this point in the history
GitOrigin-RevId: f57d35b0884aedae8c9ecce70de53e1bb92ea985
  • Loading branch information
sujayakar authored and Convex, Inc. committed Sep 6, 2024
1 parent dc49dba commit fd90418
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 36 deletions.
32 changes: 13 additions & 19 deletions src/cli/lib/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ async function startComponentsPushAndCodegen(
writePushRequest?: string;
},
): Promise<StartPushResponse | null> {
const verbose = options.verbose || options.dryRun;
const convexDir = await getFunctionsDirectoryPath(ctx);

// '.' means use the process current working directory, it's the default behavior.
Expand All @@ -157,7 +156,7 @@ async function startComponentsPushAndCodegen(
// This produces a bundle in memory as a side effect but it's thrown away.
const { components, dependencyGraph } = await parentSpan.enterAsync(
"componentGraph",
() => componentGraph(ctx, absWorkingDir, rootComponent, verbose),
() => componentGraph(ctx, absWorkingDir, rootComponent, options.verbose),
);

changeSpinner(ctx, "Generating server code...");
Expand Down Expand Up @@ -194,15 +193,15 @@ async function startComponentsPushAndCodegen(
rootComponent,
[...components.values()],
projectConfig.node.externalPackages,
verbose,
options.verbose,
),
);
if (options.debugBundlePath) {
const { config: localConfig } = await configFromProjectConfig(
ctx,
projectConfig,
configPath,
verbose,
options.verbose,
);
// TODO(ENG-6972): Actually write the bundles for components.
await handleDebugBundlePath(ctx, options.debugBundlePath, localConfig);
Expand Down Expand Up @@ -246,7 +245,7 @@ async function startComponentsPushAndCodegen(
}
const startPushRequest = {
adminKey: options.adminKey,
dryRun: false,
dryRun: options.dryRun,
functions: projectConfig.functions,
appDefinition,
componentDefinitions,
Expand All @@ -264,11 +263,12 @@ async function startComponentsPushAndCodegen(

changeSpinner(ctx, "Uploading functions to Convex...");
const startPushResponse = await parentSpan.enterAsync("startPush", (span) =>
startPush(ctx, span, options.url, startPushRequest, verbose),
startPush(ctx, span, startPushRequest, options),
);

verbose && console.log("startPush:");
verbose && console.dir(startPushResponse, { depth: null });
if (options.verbose) {
logMessage(ctx, "startPush: " + JSON.stringify(startPushResponse, null, 2));
}

changeSpinner(ctx, "Generating TypeScript bindings...");
await parentSpan.enterAsync("doFinalComponentCodegen", () =>
Expand Down Expand Up @@ -340,14 +340,6 @@ export async function runComponentsPush(

await ensureHasConvexDependency(ctx, "push");

if (options.dryRun) {
return await ctx.crash({
exitCode: 1,
errorType: "fatal",
printedMessage: "dryRun not allowed yet",
});
}

const startPushResponse = await pushSpan.enterAsync(
"startComponentsPushAndCodegen",
(span) =>
Expand All @@ -364,17 +356,19 @@ export async function runComponentsPush(
}

await pushSpan.enterAsync("waitForSchema", (span) =>
waitForSchema(ctx, span, options.adminKey, options.url, startPushResponse),
waitForSchema(ctx, span, startPushResponse, options),
);

const finishPushResponse = await pushSpan.enterAsync("finishPush", (span) =>
finishPush(ctx, span, options.adminKey, options.url, startPushResponse),
finishPush(ctx, span, startPushResponse, options),
);
printDiff(ctx, finishPushResponse, options);
pushSpan.end();

// Asynchronously report that the push completed.
void reportPushCompleted(ctx, options.adminKey, options.url, reporter);
if (!options.dryRun) {
void reportPushCompleted(ctx, options.adminKey, options.url, reporter);
}
}

function printDiff(
Expand Down
46 changes: 29 additions & 17 deletions src/cli/lib/deploy2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,26 @@ import { Reporter, Span } from "./tracing.js";
export async function startPush(
ctx: Context,
span: Span,
url: string,
request: StartPushRequest,
verbose?: boolean,
options: {
url: string;
verbose?: boolean;
},
): Promise<StartPushResponse> {
if (verbose) {
if (options.verbose) {
const custom = (_k: string | number, s: any) =>
typeof s === "string" ? s.slice(0, 40) + (s.length > 40 ? "..." : "") : s;
console.log(JSON.stringify(request, custom, 2));
}
const onError = (err: any) => {
if (err.toString() === "TypeError: fetch failed") {
changeSpinner(ctx, `Fetch failed, is ${url} correct? Retrying...`);
changeSpinner(
ctx,
`Fetch failed, is ${options.url} correct? Retrying...`,
);
}
};
const fetch = deploymentFetch(url, request.adminKey, onError);
const fetch = deploymentFetch(options.url, request.adminKey, onError);
changeSpinner(ctx, "Analyzing and deploying source code...");
try {
const response = await fetch("/api/deploy2/start_push", {
Expand Down Expand Up @@ -85,7 +90,7 @@ export async function startPush(
printedMessage: message,
});
}
logFailure(ctx, "Error: Unable to start push to " + url);
logFailure(ctx, "Error: Unable to start push to " + options.url);
return await logAndHandleFetchError(ctx, error);
}
}
Expand All @@ -96,11 +101,14 @@ const SCHEMA_TIMEOUT_MS = 10_000;
export async function waitForSchema(
ctx: Context,
span: Span,
adminKey: string,
url: string,
startPush: StartPushResponse,
options: {
adminKey: string;
url: string;
dryRun: boolean;
},
) {
const fetch = deploymentFetch(url, adminKey);
const fetch = deploymentFetch(options.url, options.adminKey);

changeSpinner(
ctx,
Expand All @@ -112,9 +120,10 @@ export async function waitForSchema(
try {
const response = await fetch("/api/deploy2/wait_for_schema", {
body: JSON.stringify({
adminKey,
adminKey: options.adminKey,
schemaChange: startPush.schemaChange,
timeoutMs: SCHEMA_TIMEOUT_MS,
dryRun: options.dryRun,
}),
method: "POST",
headers: {
Expand All @@ -123,7 +132,7 @@ export async function waitForSchema(
});
currentStatus = schemaStatus.parse(await response.json());
} catch (error: unknown) {
logFailure(ctx, "Error: Unable to wait for schema from " + url);
logFailure(ctx, "Error: Unable to wait for schema from " + options.url);
return await logAndHandleFetchError(ctx, error);
}
switch (currentStatus.type) {
Expand Down Expand Up @@ -192,18 +201,21 @@ export async function waitForSchema(
export async function finishPush(
ctx: Context,
span: Span,
adminKey: string,
url: string,
startPush: StartPushResponse,
options: {
adminKey: string;
url: string;
dryRun: boolean;
},
): Promise<FinishPushDiff> {
changeSpinner(ctx, "Finalizing push...");
const fetch = deploymentFetch(url, adminKey);
const fetch = deploymentFetch(options.url, options.adminKey);
try {
const response = await fetch("/api/deploy2/finish_push", {
body: JSON.stringify({
adminKey,
adminKey: options.adminKey,
startPush,
dryRun: false,
dryRun: options.dryRun,
}),
method: "POST",
headers: {
Expand All @@ -212,7 +224,7 @@ export async function finishPush(
});
return finishPushDiff.parse(await response.json());
} catch (error: unknown) {
logFailure(ctx, "Error: Unable to finish push to " + url);
logFailure(ctx, "Error: Unable to finish push to " + options.url);
return await logAndHandleFetchError(ctx, error);
}
}
Expand Down

0 comments on commit fd90418

Please sign in to comment.