Skip to content

Commit 1b02f37

Browse files
committed
feat(cli,webapp): default new projects to node-24
1 parent 6e77102 commit 1b02f37

15 files changed

Lines changed: 80 additions & 25 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
New projects created with `trigger init` use Node.js 24 by default. Deployments whose config omits `runtime` now use their project's configured default runtime.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
area: webapp
3+
type: feature
4+
---
5+
6+
New projects use Node.js 24 when their deployment config does not specify a runtime.

apps/webapp/app/models/project.server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export async function createProject(
113113
// for historical rows; the V1->V2 upgrade guards on worker-register / deploy
114114
// stay in place to migrate existing legacy projects.
115115
engine: "V2",
116+
defaultRuntime: "node-24",
116117
onboardingData,
117118
},
118119
include: {

apps/webapp/app/routes/api.v1.projects.$projectRef.$env.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { json, type LoaderFunctionArgs } from "@remix-run/server-runtime";
2-
import { type GetProjectEnvResponse } from "@trigger.dev/core/v3";
2+
import { BuildRuntime, type GetProjectEnvResponse } from "@trigger.dev/core/v3";
33
import { z } from "zod";
44
import { env as processEnv } from "~/env.server";
55
import {
@@ -65,6 +65,7 @@ export async function loader({ request, params }: LoaderFunctionArgs) {
6565
name: environment.project.name,
6666
apiUrl: processEnv.API_ORIGIN ?? processEnv.APP_ORIGIN,
6767
projectId: environment.project.id,
68+
defaultRuntime: BuildRuntime.nullable().parse(environment.project.defaultRuntime),
6869
};
6970

7071
return json(result);

apps/webapp/app/routes/api.v1.projects.$projectRef.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { json } from "@remix-run/server-runtime";
2-
import type { GetProjectResponseBody } from "@trigger.dev/core/v3";
2+
import { BuildRuntime, type GetProjectResponseBody } from "@trigger.dev/core/v3";
33
import { z } from "zod";
44
import { prisma } from "~/db.server";
55
import { DeleteProjectService } from "~/services/deleteProject.server";
@@ -53,6 +53,7 @@ export const loader = createLoaderPATApiRoute(
5353
slug: project.slug,
5454
createdAt: project.createdAt,
5555
defaultRegion: project.defaultWorkerGroup?.name ?? null,
56+
defaultRuntime: BuildRuntime.nullable().parse(project.defaultRuntime),
5657
organization: {
5758
id: project.organization.id,
5859
title: project.organization.title,

apps/webapp/app/v3/services/initializeDeployment.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ export class InitializeDeploymentService extends BaseService {
253253
imagePlatform: env.DEPLOY_IMAGE_PLATFORM,
254254
git: payload.gitMeta ?? undefined,
255255
commitSHA: payload.gitMeta?.commitSha ?? undefined,
256-
runtime: payload.runtime ?? undefined,
256+
runtime: payload.runtime ?? environment.project.defaultRuntime ?? undefined,
257257
triggeredVia: payload.triggeredVia ?? undefined,
258258
startedAt: initialStatus === "BUILDING" ? new Date() : undefined,
259259
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Project" ADD COLUMN "defaultRuntime" TEXT;

internal-packages/database/prisma/schema.prisma

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,9 @@ model Project {
474474
/// Set the first time the CLI `init` command completes against this project. Drives the dev onboarding progress.
475475
initializedAt DateTime?
476476
477+
/// Runtime used when a deployment config does not specify one. Null preserves the legacy Node 20 fallback.
478+
defaultRuntime String?
479+
477480
version ProjectVersion @default(V2)
478481
engine RunEngineVersion @default(V1)
479482
@@ -790,26 +793,26 @@ model WebhookEndpoint {
790793
791794
source String // provider tag e.g. "stripe","slack","github"
792795
handlerWebhookId String // declared webhook() id (string ref, GOLDEN LAW, no relation)
793-
routingTarget Json // RoutingTarget tagged union ({ type: "task" } | { type: "session" })
794-
verifierArtifact Json // VerifierArtifact tagged union (config|preset in P1)
796+
routingTarget Json // RoutingTarget tagged union ({ type: "task" } | { type: "session" })
797+
verifierArtifact Json // VerifierArtifact tagged union (config|preset in P1)
795798
filter String? // source filter DSL string (display/round-trip)
796-
filterAst Json? // compiled FilterAst, evaluated at ingest; null = route all
797-
filterAstVersion Int? // re-parse `filter` on a format bump
798-
metadata Json @default("{}") // arbitrary user metadata; flows into the webhook task
799+
filterAst Json? // compiled FilterAst, evaluated at ingest; null = route all
800+
filterAstVersion Int? // re-parse `filter` on a format bump
801+
metadata Json @default("{}") // arbitrary user metadata; flows into the webhook task
799802
800803
// who supplies the secret/key; drives the Connect UI (paste vs generate). From the source.
801804
secretProvisioning String @default("either") // "provider" | "integrator" | "either"
802805
803806
/// SecretReference.key string. Plain String, NO @relation -> no FK to SecretReference.
804807
signingSecretKey String?
805808
806-
status WebhookEndpointStatus @default(ACTIVE)
809+
status WebhookEndpointStatus @default(ACTIVE)
807810
/// When an operator disabled the endpoint via the dashboard/API. Null means the declarative sync
808811
/// owns the status: a redeploy that re-declares a previously-removed (auto-deactivated) webhook
809812
/// reactivates it. Non-null means the operator disabled it, so the sync leaves the status alone.
810813
manuallyDeactivatedAt DateTime?
811-
createdAt DateTime @default(now())
812-
updatedAt DateTime @updatedAt
814+
createdAt DateTime @default(now())
815+
updatedAt DateTime @updatedAt
813816
814817
@@unique([runtimeEnvironmentId, handlerWebhookId, endpointTenantId, endpointExternalRef]) // deploy-sync key
815818
@@index([runtimeEnvironmentId, source])
@@ -842,8 +845,8 @@ model WebhookDelivery {
842845
/// Set from the x-trigger-test ingress header; marks console/test-send deliveries so the list can filter them.
843846
isTest Boolean @default(false)
844847
845-
parsedEvent Json? // size-capped snapshot of the verified event (full event lives in ClickHouse)
846-
headers Json? // inbound request headers, surfaced to the webhook task via onEvent({ headers })
848+
parsedEvent Json? // size-capped snapshot of the verified event (full event lives in ClickHouse)
849+
headers Json? // inbound request headers, surfaced to the webhook task via onEvent({ headers })
847850
rawBodyHash String? // sha256 of raw bytes; cheap P2 replay anchor
848851
errorMessage String?
849852
filterReason String? // why a FILTERED delivery was not routed (failing clause + actual value)
@@ -2370,8 +2373,8 @@ model TaskSchedule {
23702373
timezone String @default("UTC")
23712374
23722375
// Cron spread
2373-
windowDurationSeconds Int?
2374-
windowPercentage Int?
2376+
windowDurationSeconds Int?
2377+
windowPercentage Int?
23752378
23762379
///Can be provided by the user then accessed inside a run
23772380
externalId String?

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
300300
logger.debug("Using project ref from env", { ref: envVars.TRIGGER_PROJECT_REF });
301301
}
302302

303-
const resolvedConfig = await loadConfig({
303+
let resolvedConfig = await loadConfig({
304304
cwd: projectPath,
305305
overrides: { project: options.projectRef ?? envVars.TRIGGER_PROJECT_REF },
306306
configFile: options.config,
@@ -364,6 +364,15 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
364364
throw new Error("Failed to get project client");
365365
}
366366

367+
if (projectClient.defaultRuntime) {
368+
resolvedConfig = await loadConfig({
369+
cwd: projectPath,
370+
overrides: { project: options.projectRef ?? envVars.TRIGGER_PROJECT_REF },
371+
configFile: options.config,
372+
defaultRuntime: projectClient.defaultRuntime,
373+
});
374+
}
375+
367376
if (options.nativeBuildServer) {
368377
await handleNativeBuildServerDeploy({
369378
apiClient: projectClient.client,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const InitCommandOptions = CommonCommandOptions.extend({
5050
overrideConfig: z.boolean().default(false),
5151
tag: z.string().default(cliVersion),
5252
skipPackageInstall: z.boolean().default(false),
53-
runtime: z.string().default("node"),
53+
runtime: z.string().default("node-24"),
5454
pkgArgs: z.string().optional(),
5555
gitRef: z.string().default("main"),
5656
javascript: z.boolean().default(false),
@@ -94,8 +94,8 @@ Examples:
9494
)
9595
.option(
9696
"-r, --runtime <runtime>",
97-
"Which runtime to use for the project. Supported: node, node-22, bun",
98-
"node"
97+
"Which runtime to use for the project. Supported: node, node-22, node-24, node-26, bun",
98+
"node-24"
9999
)
100100
.option("--skip-package-install", "Skip installing the @trigger.dev/sdk package")
101101
.option("--override-config", "Override the existing config file if it exists")

0 commit comments

Comments
 (0)