Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-console-interceptor-2900.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/core": patch
---

Fix: ConsoleInterceptor now delegates to original console methods to preserve log chain when other interceptors (like Sentry) are present. (#2900)
5 changes: 5 additions & 0 deletions .changeset/fix-docker-hub-rate-limit-2911.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/cli-v3": patch
---

Fix: Native build server failed with Docker Hub rate limits. Added support for checking checking `DOCKER_USERNAME` and `DOCKER_PASSWORD` in environment variables and logging into Docker Hub before building. (#2911)
5 changes: 5 additions & 0 deletions .changeset/fix-github-install-node-version-2913.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/cli-v3": patch
---

Fix: Ignore engine checks during deployment install phase to prevent failure on build server when Node version mismatch exists. (#2913)
5 changes: 5 additions & 0 deletions .changeset/fix-orphaned-workers-2909.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/cli-v3": patch
---

Fix: `trigger.dev dev` command left orphaned worker processes when exited via Ctrl+C (SIGINT). Added signal handlers to ensure proper cleanup of child processes and lockfiles. (#2909)
5 changes: 5 additions & 0 deletions .changeset/fix-sentry-oom-2920.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@trigger.dev/cli-v3": patch
---

Fix Sentry OOM: Allow disabling `source-map-support` via `TRIGGER_SOURCE_MAPS=false`. Also supports `node` for native source maps. (#2920)
40 changes: 40 additions & 0 deletions consolidated_pr_body.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Consolidated Bug Fixes

This PR combines fixes for several independent issues identified in the codebase, covering CLI stability, deployment/build reliability, and runtime correctness.

## Fixes

| Issue / Feature | Description |
|-----------------|-------------|
| **Orphaned Workers** | Fixes `trigger dev` leaving orphaned `trigger-dev-run-worker` processes by ensuring graceful shutdown on `SIGINT`/`SIGTERM` and robust process cleanup. |
| **Sentry Interception** | Fixes `ConsoleInterceptor` swallowing logs when Sentry (or other monkey-patchers) are present by delegating to the original preserved console methods. |
| **Engine Strictness** | Fixes deployment failures on GitHub Integration when `engines.node` is strict (e.g. "22") by passing `--no-engine-strict` (and equivalents) during the `trigger deploy` build phase. |
| **Docker Hub Rate Limits** | Adds support for `DOCKER_USERNAME` and `DOCKER_PASSWORD` in `buildImage.ts` to authenticate with Docker Hub and avoid rate limits during native builds. |
| **Dead Process Hang** | Fixes a hang in `TaskRunProcess.execute()` by checking specific process connectivity before attempting to send IPC messages. |
| **Superjson ESM** | Bundles `superjson` into `packages/core/src/v3/vendor` to resolve `ERR_REQUIRE_ESM` issues in certain environments (Lambda, Node <22.12). |
| **Realtime Hooks** | Fixes premature firing of `onComplete` in `useRealtime` hooks when the stream disconnects but the run hasn't actually finished. |
| **Stream Targets** | Aligns `getRunIdForOptions` logic between SDK and Core to ensure Consistent semantic targets for streams. |
| **Hook Exports** | Exports `AnyOnStartAttemptHookFunction` from `trigger-sdk` to allow proper typing of `onStartAttempt`. |

## Verification

### Automated Verification
- **Engine Strictness**: Pass in `packages/cli-v3/src/commands/update.test.ts`.
- **Superjson**: Validated via reproduction scripts importing the vendored bundle in both ESM and CJS modes.
- **Sentry**: Validated via `repro_2900_sentry.ts` script ensuring logs flow through Sentry patches.

### Manual Verification
- **Orphaned Workers**: Verified locally by interrupting `trigger dev` and observing process cleanup.
- **Docker Hub**: Verified code logic correctly identifies env vars and executes login.
- **React Hooks & Streams**: Verified by code review of the corrected logic matching the intended fix.

## Changesets
- `fix-orphaned-workers-2909`
- `fix-sentry-console-interceptor-2900`
- `fix-github-install-node-version-2913`
- `fix-docker-hub-rate-limit-2911`
- `fix-dead-process-execute-hang`
- `vendor-superjson-esm-fix`
- `calm-hooks-wait`
- `consistent-stream-targets`
- `export-start-attempt-hook-type`
7 changes: 4 additions & 3 deletions packages/cli-v3/src/cli/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const CommonCommandOptions = z.object({
logLevel: z.enum(["debug", "info", "log", "warn", "error", "none"]).default("log"),
skipTelemetry: z.boolean().default(false),
profile: z.string().default(readAuthConfigCurrentProfileName()),
ignoreEngines: z.boolean().default(false),
});

export type CommonCommandOptions = z.infer<typeof CommonCommandOptions>;
Expand All @@ -30,9 +31,9 @@ export function commonOptions(command: Command) {
.option("--skip-telemetry", "Opt-out of sending telemetry");
}

export class SkipLoggingError extends Error {}
export class SkipCommandError extends Error {}
export class OutroCommandError extends SkipCommandError {}
export class SkipLoggingError extends Error { }
export class SkipCommandError extends Error { }
export class OutroCommandError extends SkipCommandError { }

export async function handleTelemetry(action: () => Promise<void>) {
try {
Expand Down
86 changes: 36 additions & 50 deletions packages/cli-v3/src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
}

if (!options.skipUpdateCheck) {
await updateTriggerPackages(dir, { ...options }, true, true);
await updateTriggerPackages(dir, { ...options, ignoreEngines: true }, true, true);
}

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

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

const deploymentLink = cliLink("View deployment", rawDeploymentLink);
const testLink = cliLink("Test tasks", rawTestLink);
Expand Down Expand Up @@ -708,8 +707,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
}
} else {
outro(
`Version ${version} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${
isLinksSupported ? `| ${deploymentLink} | ${testLink}` : ""
`Version ${version} deployed with ${taskCount} detected task${taskCount === 1 ? "" : "s"} ${isLinksSupported ? `| ${deploymentLink} | ${testLink}` : ""
}`
);

Expand All @@ -733,18 +731,16 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
TRIGGER_VERSION: version,
TRIGGER_DEPLOYMENT_SHORT_CODE: deployment.shortCode,
TRIGGER_DEPLOYMENT_URL: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`,
TRIGGER_TEST_URL: `${authorization.dashboardUrl}/projects/v3/${
resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
TRIGGER_TEST_URL: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
},
outputs: {
deploymentVersion: version,
workerVersion: version,
deploymentShortCode: deployment.shortCode,
deploymentUrl: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project}/deployments/${deployment.shortCode}`,
testUrl: `${authorization.dashboardUrl}/projects/v3/${
resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
testUrl: `${authorization.dashboardUrl}/projects/v3/${resolvedConfig.project
}/test?environment=${options.env === "prod" ? "prod" : "stg"}`,
needsPromotion: options.skipPromotion ? "true" : "false",
},
});
Expand Down Expand Up @@ -787,8 +783,7 @@ async function failDeploy(
checkLogsForErrors(logs);

outro(
`${chalkError(`${prefix}:`)} ${
error.message
`${chalkError(`${prefix}:`)} ${error.message
}. Full build logs have been saved to ${logPath}`
);

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

const rawDeploymentLink = `${dashboardUrl}/projects/v3/${config.project}/deployments/${deployment.shortCode}`;
const rawTestLink = `${dashboardUrl}/projects/v3/${config.project}/test?environment=${
options.env === "prod" ? "prod" : "stg"
}`;
const rawTestLink = `${dashboardUrl}/projects/v3/${config.project}/test?environment=${options.env === "prod" ? "prod" : "stg"
}`;

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

outro(
`Version ${deployment.version} is being deployed ${
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
`Version ${deployment.version} is being deployed ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
}`
);

Expand Down Expand Up @@ -1204,10 +1197,10 @@ async function handleNativeBuildServerDeploy({
level === "error"
? chalk.bold(chalkError(message))
: level === "warn"
? chalkWarning(message)
: level === "debug"
? chalkGrey(message)
: message;
? chalkWarning(message)
: level === "debug"
? chalkGrey(message)
: message;

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

throw new OutroCommandError(
`Version ${deployment.version} ${
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
`Version ${deployment.version} ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
}`
);
}
Expand All @@ -1256,8 +1248,7 @@ async function handleNativeBuildServerDeploy({
}

throw new OutroCommandError(
`Version ${deployment.version} ${
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
`Version ${deployment.version} ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
}`
);
}
Expand All @@ -1283,13 +1274,12 @@ async function handleNativeBuildServerDeploy({
}

outro(
`Version ${deployment.version} was deployed ${
isLinksSupported
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
"View deployment",
rawDeploymentLink
)}`
: ""
`Version ${deployment.version} was deployed ${isLinksSupported
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
"View deployment",
rawDeploymentLink
)}`
: ""
}`
);
return process.exit(0);
Expand All @@ -1303,14 +1293,13 @@ async function handleNativeBuildServerDeploy({
chalk.bold(
chalkError(
"Deployment failed" +
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
)
)
);

throw new OutroCommandError(
`Version ${deployment.version} deployment failed ${
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
`Version ${deployment.version} deployment failed ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
}`
);
}
Expand All @@ -1323,14 +1312,13 @@ async function handleNativeBuildServerDeploy({
chalk.bold(
chalkError(
"Deployment timed out" +
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
)
)
);

throw new OutroCommandError(
`Version ${deployment.version} deployment timed out ${
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
`Version ${deployment.version} deployment timed out ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
}`
);
}
Expand All @@ -1343,14 +1331,13 @@ async function handleNativeBuildServerDeploy({
chalk.bold(
chalkError(
"Deployment was canceled" +
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
(finalDeploymentEvent.message ? `: ${finalDeploymentEvent.message}` : "")
)
)
);

throw new OutroCommandError(
`Version ${deployment.version} deployment canceled ${
isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
`Version ${deployment.version} deployment canceled ${isLinksSupported ? `| ${cliLink("View deployment", rawDeploymentLink)}` : ""
}`
);
}
Expand All @@ -1369,13 +1356,12 @@ async function handleNativeBuildServerDeploy({
}

outro(
`Version ${deployment.version} ${
isLinksSupported
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
"View deployment",
rawDeploymentLink
)}`
: ""
`Version ${deployment.version} ${isLinksSupported
? `| ${cliLink("Test tasks", rawTestLink)} | ${cliLink(
"View deployment",
rawDeploymentLink
)}`
: ""
}`
);
return process.exit(0);
Expand Down
30 changes: 23 additions & 7 deletions packages/cli-v3/src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,22 +171,38 @@ export async function devCommand(options: DevCommandOptions) {
);
} else {
logger.log(
`${chalkError("X Error:")} You must login first. Use the \`login\` CLI command.\n\n${
authorization.error
`${chalkError("X Error:")} You must login first. Use the \`login\` CLI command.\n\n${authorization.error
}`
);
}
process.exitCode = 1;
return;
}

let watcher;
let devInstance: Awaited<ReturnType<typeof startDev>> | undefined;

const cleanup = async () => {
if (devInstance) {
await devInstance.stop();
}
};

const signalHandler = async (signal: string) => {
logger.debug(`Received ${signal}, cleaning up...`);
await cleanup();
process.exit(0);
};

try {
const devInstance = await startDev({ ...options, cwd: process.cwd(), login: authorization });
watcher = devInstance.watcher;
process.on("SIGINT", signalHandler);
process.on("SIGTERM", signalHandler);

devInstance = await startDev({ ...options, cwd: process.cwd(), login: authorization });
await devInstance.waitUntilExit();
} finally {
await watcher?.stop();
process.off("SIGINT", signalHandler);
process.off("SIGTERM", signalHandler);
await cleanup();
}
}

Expand Down Expand Up @@ -272,7 +288,7 @@ async function startDev(options: StartDevOptions) {

devInstance = await bootDevSession(watcher.config);

const waitUntilExit = async () => {};
const waitUntilExit = async () => { };

return {
watcher,
Expand Down
5 changes: 3 additions & 2 deletions packages/cli-v3/src/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export async function login(options?: LoginOptions): Promise<LoginResult> {
profile: options?.profile ?? "default",
skipTelemetry: !span.isRecording(),
logLevel: logger.loggerLevel,
ignoreEngines: false,
},
true,
opts.silent
Expand All @@ -148,8 +149,7 @@ export async function login(options?: LoginOptions): Promise<LoginResult> {

if (!opts.embedded) {
outro(
`Login failed using stored token. To fix, first logout using \`trigger.dev logout${
options?.profile ? ` --profile ${options.profile}` : ""
`Login failed using stored token. To fix, first logout using \`trigger.dev logout${options?.profile ? ` --profile ${options.profile}` : ""
}\` and then try again.`
);

Expand Down Expand Up @@ -290,6 +290,7 @@ export async function login(options?: LoginOptions): Promise<LoginResult> {
profile: options?.profile ?? "default",
skipTelemetry: !span.isRecording(),
logLevel: logger.loggerLevel,
ignoreEngines: false,
},
opts.embedded
);
Expand Down
Loading