Skip to content

Commit 96fbbe3

Browse files
thomasballingerConvex, Inc.
authored andcommitted
Don't fail because can't contact GitHub for latest (#40229)
Quick fix to avoid crashing if GitHub releases can't be contacted. This is ripe for a better solution, ideally - there's a flag to avoid checking GitHub for an update at all (besides the current flag for specifying an exact version - failing during binary download is also protected We do want to prompt users to upgrade when using downloaded binaries (vs self-hosting) but this should never stop developers from working offline. GitOrigin-RevId: f2cc66326fffb5bb4b73333a433a7180f4104e5c
1 parent d4c1caa commit 96fbbe3

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

src/cli/lib/localDeployment/download.ts

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
startLogProgress,
66
logVerbose,
77
logMessage,
8+
logError,
9+
logWarning,
810
} from "../../../bundler/log.js";
911
import {
1012
dashboardZip,
@@ -38,12 +40,27 @@ type GitHubRelease = components["schemas"]["release"];
3840

3941
export async function ensureBackendBinaryDownloaded(
4042
ctx: Context,
41-
version: { kind: "latest" } | { kind: "version"; version: string },
43+
version:
44+
| { kind: "latest"; allowedVersion?: string }
45+
| { kind: "version"; version: string },
4246
): Promise<{ binaryPath: string; version: string }> {
4347
if (version.kind === "version") {
4448
return _ensureBackendBinaryDownloaded(ctx, version.version);
4549
}
46-
const latestVersionWithBinary = await findLatestVersionWithBinary(ctx);
50+
if (version.allowedVersion) {
51+
const latestVersionWithBinary = await findLatestVersionWithBinary(
52+
ctx,
53+
false,
54+
);
55+
if (latestVersionWithBinary === null) {
56+
logWarning(
57+
`Failed to get latest version from GitHub, using downloaded version ${version.allowedVersion}`,
58+
);
59+
return _ensureBackendBinaryDownloaded(ctx, version.allowedVersion);
60+
}
61+
return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);
62+
}
63+
const latestVersionWithBinary = await findLatestVersionWithBinary(ctx, true);
4764
return _ensureBackendBinaryDownloaded(ctx, latestVersionWithBinary);
4865
}
4966

@@ -94,9 +111,27 @@ function parseLinkHeader(header: string): {
94111
* Finds the latest version of the convex backend that has a binary that works
95112
* on this platform.
96113
*/
97-
export async function findLatestVersionWithBinary(
114+
export async function findLatestVersionWithBinary<
115+
RequireSuccess extends boolean,
116+
>(
98117
ctx: Context,
99-
): Promise<string> {
118+
requireSuccess: RequireSuccess,
119+
): Promise<RequireSuccess extends true ? string : string | null> {
120+
// These shouldn't crash when there's a perfectly good binary already available.
121+
async function maybeCrash(
122+
...args: Parameters<typeof ctx.crash>
123+
): Promise<RequireSuccess extends true ? never : null> {
124+
if (requireSuccess) {
125+
return await ctx.crash(...args);
126+
}
127+
if (args[0].printedMessage) {
128+
logError(args[0].printedMessage);
129+
} else {
130+
logError("Error downloading latest binary");
131+
}
132+
return null as RequireSuccess extends true ? never : null;
133+
}
134+
100135
const targetName = getDownloadPath();
101136
logVerbose(
102137
`Finding latest stable release containing binary named ${targetName}`,
@@ -111,7 +146,7 @@ export async function findLatestVersionWithBinary(
111146

112147
if (!response.ok) {
113148
const text = await response.text();
114-
return await ctx.crash({
149+
return await maybeCrash({
115150
exitCode: 1,
116151
errorType: "fatal",
117152
printedMessage: `GitHub API returned ${response.status}: ${text}`,
@@ -161,7 +196,7 @@ export async function findLatestVersionWithBinary(
161196

162197
// If we get here, we didn't find any suitable releases
163198
if (!latestVersion) {
164-
return await ctx.crash({
199+
return await maybeCrash({
165200
exitCode: 1,
166201
errorType: "fatal",
167202
printedMessage:
@@ -174,14 +209,14 @@ export async function findLatestVersionWithBinary(
174209

175210
// If we found stable releases but none had our binary
176211
const message = `Failed to find a convex backend release that contained ${targetName}.`;
177-
return await ctx.crash({
212+
return await maybeCrash({
178213
exitCode: 1,
179214
errorType: "fatal",
180215
printedMessage: message,
181216
errForSentry: new LocalDeploymentError(message),
182217
});
183218
} catch (e) {
184-
return await ctx.crash({
219+
return maybeCrash({
185220
exitCode: 1,
186221
errorType: "fatal",
187222
printedMessage: "Failed to get latest convex backend releases",

src/cli/lib/localDeployment/localDeployment.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export async function handleLocalDeployment(
8484
options.backendVersion === undefined
8585
? {
8686
kind: "latest",
87+
allowedVersion: existingDeploymentForProject?.config.backendVersion,
8788
}
8889
: { kind: "version", version: options.backendVersion },
8990
);

src/cli/lib/localDeployment/run.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ test("findLatestVersionWithBinary", async () => {
3838
} as Response),
3939
);
4040

41-
const expected = await findLatestVersionWithBinary(ctx);
41+
const expected = await findLatestVersionWithBinary(ctx, true);
4242
expect(fetchSpy).toHaveBeenCalledTimes(1);
4343
expect(fetchSpy).toHaveBeenCalledWith(
4444
"https://api.github.com/repos/get-convex/convex-backend/releases?per_page=30",
@@ -56,7 +56,7 @@ test("findLatestVersionWithBinary", async () => {
5656
);
5757
stderrSpy.mockClear();
5858

59-
await expect(findLatestVersionWithBinary(ctx)).rejects.toThrow();
59+
await expect(findLatestVersionWithBinary(ctx, true)).rejects.toThrow();
6060
expect(fetchSpy).toHaveBeenCalledTimes(1);
6161
expect(fetchSpy).toHaveBeenCalledWith(
6262
"https://api.github.com/repos/get-convex/convex-backend/releases?per_page=30",

0 commit comments

Comments
 (0)