Skip to content

Commit 023c3fd

Browse files
author
Deploy Bot
committed
fix(cli-v3): ignore engine checks during deployment install to prevent build server failures (#2913)
1 parent 1ccb8c1 commit 023c3fd

File tree

4 files changed

+173
-53
lines changed

4 files changed

+173
-53
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/cli-v3": patch
3+
---
4+
5+
Fix: Ignore engine checks during deployment install phase to prevent failure on build server when Node version mismatch exists. (#2913)

packages/cli-v3/src/commands/deploy.ts

Lines changed: 36 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
252252
}
253253

254254
if (!options.skipUpdateCheck) {
255-
await updateTriggerPackages(dir, { ...options }, true, true);
255+
await updateTriggerPackages(dir, { ...options, ignoreEngines: true }, true, true);
256256
}
257257

258258
const cwd = process.cwd();
@@ -489,9 +489,8 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
489489
const version = deployment.version;
490490

491491
const rawDeploymentLink = `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`;
492-
const rawTestLink = `${authorization.dashboardUrl}/projects/v3/${
493-
resolvedConfig.project
494-
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`;
492+
const rawTestLink = `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
493+
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`;
495494

496495
const deploymentLink = cliLink("View deployment", rawDeploymentLink);
497496
const testLink = cliLink("Test tasks", rawTestLink);
@@ -708,8 +707,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
708707
}
709708
} else {
710709
outro(
711-
`Version ${version} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${
712-
isLinksSupported ? `| ${deploymentLink} | ${testLink}` : ""
710+
`Version ${version} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${isLinksSupported ? `| ${deploymentLink} | ${testLink}` : ""
713711
}`
714712
);
715713

@@ -733,18 +731,16 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
733731
TRIGGER_VERSION: version,
734732
TRIGGER_DEPLOYMENT_SHORT_CODE: deployment.shortCode,
735733
TRIGGER_DEPLOYMENT_URL: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`,
736-
TRIGGER_TEST_URL: `${authorization.dashboardUrl}/projects/v3/${
737-
resolvedConfig.project
738-
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
734+
TRIGGER_TEST_URL: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
735+
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
739736
},
740737
outputs: {
741738
deploymentVersion: version,
742739
workerVersion: version,
743740
deploymentShortCode: deployment.shortCode,
744741
deploymentUrl: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`,
745-
testUrl: `${authorization.dashboardUrl}/projects/v3/${
746-
resolvedConfig.project
747-
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
742+
testUrl: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
743+
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
748744
needsPromotion: options.skipPromotion ? "true" : "false",
749745
},
750746
});
@@ -787,8 +783,7 @@ async function failDeploy(
787783
checkLogsForErrors(logs);
788784

789785
outro(
790-
`${chalkError(`${prefix}:`)} ${
791-
error.message
786+
`${chalkError(`${prefix}:`)} ${error.message
792787
}. Full build logs have been saved to ${logPath}`
793788
);
794789

@@ -1088,9 +1083,8 @@ async function handleNativeBuildServerDeploy({
10881083
const deployment = initializeDeploymentResult.data;
10891084

10901085
const rawDeploymentLink = `${dashboardUrl}/projects/v3/${config.project}/deployments/${deployment.shortCode}`;
1091-
const rawTestLink = `${dashboardUrl}/projects/v3/${config.project}/test?environment=${
1092-
options.env === "prod" ? "prod" : "stg"
1093-
}`;
1086+
const rawTestLink = `${dashboardUrl}/projects/v3/${config.project}/test?environment=${options.env === "prod" ? "prod" : "stg"
1087+
}`;
10941088

10951089
const exposedDeploymentLink = isLinksSupported
10961090
? cliLink(chalk.bold(rawDeploymentLink), rawDeploymentLink)
@@ -1156,8 +1150,7 @@ async function handleNativeBuildServerDeploy({
11561150
log.warn(`Failed streaming build logs, open the deployment in the dashboard to view the logs`);
11571151

11581152
outro(
1159-
`Version ${deployment.version} is being deployed ${
1160-
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
1153+
`Version ${deployment.version} is being deployed ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
11611154
}`
11621155
);
11631156

@@ -1204,10 +1197,10 @@ async function handleNativeBuildServerDeploy({
12041197
level === "error"
12051198
? chalk.bold(chalkError(message))
12061199
: level === "warn"
1207-
? chalkWarning(message)
1208-
: level === "debug"
1209-
? chalkGrey(message)
1210-
: message;
1200+
? chalkWarning(message)
1201+
: level === "debug"
1202+
? chalkGrey(message)
1203+
: message;
12111204

12121205
// We use console.log here instead of clack's logger as the current version does not support changing the line spacing.
12131206
// And the logs look verbose with the default spacing.
@@ -1240,8 +1233,7 @@ async function handleNativeBuildServerDeploy({
12401233
log.error("Failed dequeueing build, please try again shortly");
12411234

12421235
throw new OutroCommandError(
1243-
`Version ${deployment.version} ${
1244-
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
1236+
`Version ${deployment.version} ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
12451237
}`
12461238
);
12471239
}
@@ -1256,8 +1248,7 @@ async function handleNativeBuildServerDeploy({
12561248
}
12571249

12581250
throw new OutroCommandError(
1259-
`Version ${deployment.version} ${
1260-
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
1251+
`Version ${deployment.version} ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
12611252
}`
12621253
);
12631254
}
@@ -1283,13 +1274,12 @@ async function handleNativeBuildServerDeploy({
12831274
}
12841275

12851276
outro(
1286-
`Version ${deployment.version} was deployed ${
1287-
isLinksSupported
1288-
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
1289-
"View deployment",
1290-
rawDeploymentLink
1291-
)}`
1292-
: ""
1277+
`Version ${deployment.version} was deployed ${isLinksSupported
1278+
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
1279+
"View deployment",
1280+
rawDeploymentLink
1281+
)}`
1282+
: ""
12931283
}`
12941284
);
12951285
return process.exit(0);
@@ -1303,14 +1293,13 @@ async function handleNativeBuildServerDeploy({
13031293
chalk.bold(
13041294
chalkError(
13051295
"Deployment failed" +
1306-
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
1296+
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
13071297
)
13081298
)
13091299
);
13101300

13111301
throw new OutroCommandError(
1312-
`Version ${deployment.version} deployment failed ${
1313-
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
1302+
`Version ${deployment.version} deployment failed ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
13141303
}`
13151304
);
13161305
}
@@ -1323,14 +1312,13 @@ async function handleNativeBuildServerDeploy({
13231312
chalk.bold(
13241313
chalkError(
13251314
"Deployment timed out" +
1326-
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
1315+
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
13271316
)
13281317
)
13291318
);
13301319

13311320
throw new OutroCommandError(
1332-
`Version ${deployment.version} deployment timed out ${
1333-
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
1321+
`Version ${deployment.version} deployment timed out ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
13341322
}`
13351323
);
13361324
}
@@ -1343,14 +1331,13 @@ async function handleNativeBuildServerDeploy({
13431331
chalk.bold(
13441332
chalkError(
13451333
"Deployment was canceled" +
1346-
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
1334+
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
13471335
)
13481336
)
13491337
);
13501338

13511339
throw new OutroCommandError(
1352-
`Version ${deployment.version} deployment canceled ${
1353-
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
1340+
`Version ${deployment.version} deployment canceled ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
13541341
}`
13551342
);
13561343
}
@@ -1369,13 +1356,12 @@ async function handleNativeBuildServerDeploy({
13691356
}
13701357

13711358
outro(
1372-
`Version ${deployment.version} ${
1373-
isLinksSupported
1374-
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
1375-
"View deployment",
1376-
rawDeploymentLink
1377-
)}`
1378-
: ""
1359+
`Version ${deployment.version} ${isLinksSupported
1360+
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
1361+
"View deployment",
1362+
rawDeploymentLink
1363+
)}`
1364+
: ""
13791365
}`
13801366
);
13811367
return process.exit(0);
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
2+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3+
import { updateTriggerPackages } from "./update.js";
4+
import * as nypm from "nypm";
5+
import * as pkgTypes from "pkg-types";
6+
import * as fs from "node:fs/promises";
7+
import * as clack from "@clack/prompts";
8+
import path from "node:path";
9+
10+
// Mock dependencies
11+
vi.mock("nypm");
12+
vi.mock("pkg-types");
13+
vi.mock("node:fs/promises");
14+
vi.mock("@clack/prompts");
15+
vi.mock("std-env", () => ({
16+
hasTTY: true,
17+
isCI: false,
18+
}));
19+
vi.mock("../utilities/initialBanner.js", () => ({
20+
updateCheck: vi.fn().mockResolvedValue(undefined),
21+
printStandloneInitialBanner: vi.fn(),
22+
}));
23+
vi.mock("../version.js", () => ({
24+
VERSION: "3.0.0",
25+
}));
26+
vi.mock("../cli/common.js", () => ({
27+
CommonCommandOptions: { pick: () => ({}) },
28+
}));
29+
vi.mock("../utilities/cliOutput.js", () => ({
30+
chalkError: vi.fn(),
31+
prettyError: vi.fn(),
32+
prettyWarning: vi.fn(),
33+
}));
34+
vi.mock("../utilities/fileSystem.js", () => ({
35+
removeFile: vi.fn(),
36+
writeJSONFilePreserveOrder: vi.fn(),
37+
}));
38+
vi.mock("../utilities/logger.js", () => ({
39+
logger: {
40+
debug: vi.fn(),
41+
log: vi.fn(),
42+
table: vi.fn(),
43+
},
44+
}));
45+
vi.mock("../utilities/windows.js", () => ({
46+
spinner: () => ({
47+
start: vi.fn(),
48+
message: vi.fn(),
49+
stop: vi.fn(),
50+
}),
51+
}));
52+
53+
describe("updateTriggerPackages", () => {
54+
beforeEach(() => {
55+
vi.resetAllMocks();
56+
57+
// Default mocks
58+
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
59+
vi.mocked(fs.rm).mockResolvedValue(undefined);
60+
vi.mocked(pkgTypes.readPackageJSON).mockResolvedValue({
61+
dependencies: {
62+
"@trigger.dev/sdk": "2.0.0", // Mismatch
63+
},
64+
});
65+
vi.mocked(pkgTypes.resolvePackageJSON).mockResolvedValue("/path/to/package.json");
66+
vi.mocked(clack.confirm).mockResolvedValue(true); // User confirms update
67+
vi.mocked(nypm.installDependencies).mockResolvedValue(undefined);
68+
});
69+
70+
afterEach(() => {
71+
vi.clearAllMocks();
72+
});
73+
74+
it("should pass --no-engine-strict for npm when ignoreEngines is true", async () => {
75+
vi.mocked(nypm.detectPackageManager).mockResolvedValue({ name: "npm", command: "npm", version: "1.0.0" } as any);
76+
77+
await updateTriggerPackages(".", { ignoreEngines: true } as any, true, true);
78+
79+
expect(nypm.installDependencies).toHaveBeenCalledWith(expect.objectContaining({
80+
args: ["--no-engine-strict"],
81+
}));
82+
});
83+
84+
it("should pass --config.engine-strict=false for pnpm when ignoreEngines is true", async () => {
85+
vi.mocked(nypm.detectPackageManager).mockResolvedValue({ name: "pnpm", command: "pnpm", version: "1.0.0" } as any);
86+
87+
await updateTriggerPackages(".", { ignoreEngines: true } as any, true, true);
88+
89+
expect(nypm.installDependencies).toHaveBeenCalledWith(expect.objectContaining({
90+
args: ["--config.engine-strict=false"],
91+
}));
92+
});
93+
94+
it("should pass --ignore-engines for yarn when ignoreEngines is true", async () => {
95+
vi.mocked(nypm.detectPackageManager).mockResolvedValue({ name: "yarn", command: "yarn", version: "1.0.0" } as any);
96+
97+
await updateTriggerPackages(".", { ignoreEngines: true } as any, true, true);
98+
99+
expect(nypm.installDependencies).toHaveBeenCalledWith(expect.objectContaining({
100+
args: ["--ignore-engines"],
101+
}));
102+
});
103+
104+
it("should NOT pass engine flags if ignoreEngines is false (default)", async () => {
105+
vi.mocked(nypm.detectPackageManager).mockResolvedValue({ name: "npm", command: "npm", version: "1.0.0" } as any);
106+
107+
await updateTriggerPackages(".", { ignoreEngines: false } as any, true, true);
108+
109+
expect(nypm.installDependencies).toHaveBeenCalledWith(expect.objectContaining({
110+
args: [],
111+
}));
112+
});
113+
});

packages/cli-v3/src/commands/update.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import * as semver from "semver";
1818
export const UpdateCommandOptions = CommonCommandOptions.pick({
1919
logLevel: true,
2020
skipTelemetry: true,
21+
ignoreEngines: true,
2122
});
2223

2324
export type UpdateCommandOptions = z.infer<typeof UpdateCommandOptions>;
@@ -257,11 +258,26 @@ export async function updateTriggerPackages(
257258
`Installing new package versions${packageManager ? ` with ${packageManager.name}` : ""}`
258259
);
259260

260-
await installDependencies({ cwd: projectPath, silent: true });
261+
const installArgs: string[] = [];
262+
263+
if (options.ignoreEngines && packageManager) {
264+
switch (packageManager.name) {
265+
case "npm":
266+
installArgs.push("--no-engine-strict");
267+
break;
268+
case "pnpm":
269+
installArgs.push("--config.engine-strict=false");
270+
break;
271+
case "yarn":
272+
installArgs.push("--ignore-engines");
273+
break;
274+
}
275+
}
276+
277+
await installDependencies({ cwd: projectPath, silent: true, args: installArgs });
261278
} catch (error) {
262279
installSpinner.stop(
263-
`Failed to install new package versions${
264-
packageManager ? ` with ${packageManager.name}` : ""
280+
`Failed to install new package versions${packageManager ? ` with ${packageManager.name}` : ""
265281
}`
266282
);
267283

0 commit comments

Comments
 (0)