Skip to content

Commit 967455f

Browse files
committed
Fix external build token generation issue
1 parent 50437ee commit 967455f

File tree

4 files changed

+53
-26
lines changed

4 files changed

+53
-26
lines changed

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

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
22
import { BaseService } from "./baseService.server";
33
import { errAsync, fromPromise, okAsync, type ResultAsync } from "neverthrow";
44
import { type WorkerDeployment, type Project } from "@trigger.dev/database";
5-
import { BuildServerMetadata, logger, type GitMeta, type DeploymentEvent } from "@trigger.dev/core/v3";
5+
import {
6+
BuildServerMetadata,
7+
logger,
8+
type GitMeta,
9+
type DeploymentEvent,
10+
} from "@trigger.dev/core/v3";
611
import { TimeoutDeploymentService } from "./timeoutDeployment.server";
712
import { env } from "~/env.server";
813
import { createRemoteImageBuild } from "../remoteImageBuilder.server";
@@ -40,7 +45,11 @@ export class DeploymentService extends BaseService {
4045
friendlyId: string,
4146
updates: Partial<Pick<WorkerDeployment, "contentHash" | "runtime"> & { git: GitMeta }>
4247
) {
43-
const validateDeployment = (deployment: Pick<WorkerDeployment, "id" | "status"> & { buildServerMetadata?: BuildServerMetadata }) => {
48+
const validateDeployment = (
49+
deployment: Pick<WorkerDeployment, "id" | "status"> & {
50+
buildServerMetadata?: BuildServerMetadata;
51+
}
52+
) => {
4453
if (deployment.status !== "PENDING" && deployment.status !== "INSTALLING") {
4554
logger.warn(
4655
"Attempted progressing deployment that is not in PENDING or INSTALLING status",
@@ -81,9 +90,9 @@ export class DeploymentService extends BaseService {
8190
const createRemoteBuildIfNeeded = deployment.buildServerMetadata?.isNativeBuild
8291
? okAsync(undefined)
8392
: fromPromise(createRemoteImageBuild(authenticatedEnv.project), (error) => ({
84-
type: "failed_to_create_remote_build" as const,
85-
cause: error,
86-
}));
93+
type: "failed_to_create_remote_build" as const,
94+
cause: error,
95+
}));
8796

8897
return createRemoteBuildIfNeeded
8998
.andThen((externalBuildData) =>
@@ -92,7 +101,7 @@ export class DeploymentService extends BaseService {
92101
where: { id: deployment.id, status: "INSTALLING" }, // status could've changed in the meantime, we're not locking the row
93102
data: {
94103
...updates,
95-
externalBuildData,
104+
...(externalBuildData ? { externalBuildData } : {}),
96105
status: "BUILDING",
97106
installedAt: new Date(),
98107
},
@@ -454,14 +463,16 @@ export class DeploymentService extends BaseService {
454463
type: "other" as const,
455464
cause: error,
456465
})
457-
).andThen((deployment) => {
458-
if (!deployment) {
459-
return errAsync({ type: "deployment_not_found" as const });
460-
}
461-
return okAsync(deployment);
462-
}).map((deployment) => ({
463-
...deployment,
464-
buildServerMetadata: BuildServerMetadata.safeParse(deployment.buildServerMetadata).data,
465-
}));
466+
)
467+
.andThen((deployment) => {
468+
if (!deployment) {
469+
return errAsync({ type: "deployment_not_found" as const });
470+
}
471+
return okAsync(deployment);
472+
})
473+
.map((deployment) => ({
474+
...deployment,
475+
buildServerMetadata: BuildServerMetadata.safeParse(deployment.buildServerMetadata).data,
476+
}));
466477
}
467478
}

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,12 +89,18 @@ export class InitializeDeploymentService extends BaseService {
8989
);
9090
}
9191

92-
// For the `PENDING` initial status, defer the creation of the Depot build until the deployment is started.
93-
// This helps avoid Depot token expiration issues.
94-
const externalBuildData =
95-
payload.initialStatus === "PENDING" || payload.isNativeBuild
96-
? undefined
97-
: await createRemoteImageBuild(environment.project);
92+
// For the `PENDING` initial status, defer the creation of the Depot build until the deployment is started to avoid token expiration issues.
93+
// For local and native builds we don't need to generate the Depot tokens. We still need to create an empty object sadly due to a bug in older CLI versions.
94+
const generateExternalBuildToken =
95+
payload.initialStatus === "PENDING" || payload.isNativeBuild || payload.isLocal;
96+
97+
const externalBuildData = generateExternalBuildToken
98+
? ({
99+
projectId: "-",
100+
buildToken: "-",
101+
buildId: "-",
102+
} satisfies ExternalBuildData)
103+
: await createRemoteImageBuild(environment.project);
98104

99105
const triggeredBy = payload.userId
100106
? await this._prisma.user.findFirst({

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

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,11 @@ export function configureDeployCommand(program: Command) {
201201
localBuild: true,
202202
})
203203
)
204-
.addOption(new CommandOption("--local-build", "Build the deployment image locally"))
204+
.addOption(
205+
new CommandOption("--local-build", "Build the deployment image locally").conflicts(
206+
"nativeBuildServer"
207+
)
208+
)
205209
.addOption(new CommandOption("--push", "Push the image after local builds").hideHelp())
206210
.addOption(
207211
new CommandOption("--no-push", "Do not push the image after local builds").hideHelp()
@@ -420,14 +424,19 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
420424
gitMeta,
421425
type: features.run_engine_v2 ? "MANAGED" : "V1",
422426
runtime: buildManifest.runtime,
427+
isLocal: options.localBuild,
423428
isNativeBuild: false,
424429
triggeredVia: getTriggeredVia(),
425430
},
426431
envVars.TRIGGER_EXISTING_DEPLOYMENT_ID
427432
);
433+
434+
// When `externalBuildData` is not present the deployment implicitly goes into the local build path
435+
// which is used in self-hosted setups. There are a few subtle differences between local builds for the cloud
436+
// and local builds for self-hosted setups. We need to make the separation of the two paths clearer to avoid confusion.
428437
const isLocalBuild = options.localBuild || !deployment.externalBuildData;
429-
// Would be best to actually store this separately in the deployment object. This is an okay proxy for now.
430-
const remoteBuildExplicitlySkipped = options.localBuild && !!deployment.externalBuildData;
438+
const authenticateToTriggerRegistry = options.localBuild;
439+
const skipServerSideRegistryPush = options.localBuild;
431440

432441
// Fail fast if we know local builds will fail
433442
if (isLocalBuild) {
@@ -559,7 +568,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
559568
network: options.network,
560569
builder: options.builder,
561570
push: options.push,
562-
authenticateToRegistry: remoteBuildExplicitlySkipped,
571+
authenticateToRegistry: authenticateToTriggerRegistry,
563572
});
564573

565574
logger.debug("Build result", buildResult);
@@ -657,7 +666,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
657666
{
658667
imageDigest: buildResult.digest,
659668
skipPromotion: options.skipPromotion,
660-
skipPushToRegistry: remoteBuildExplicitlySkipped,
669+
skipPushToRegistry: skipServerSideRegistryPush,
661670
},
662671
(logMessage) => {
663672
if (options.plain || isCI) {

packages/core/src/v3/schemas/api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ export const InitializeDeploymentRequestBody = z
599599
gitMeta: GitMeta.optional(),
600600
type: z.enum(["MANAGED", "UNMANAGED", "V1"]).optional(),
601601
runtime: z.string().optional(),
602+
isLocal: z.boolean().optional(),
602603
initialStatus: z.enum(["PENDING", "BUILDING"]).optional(),
603604
triggeredVia: DeploymentTriggeredVia.optional(),
604605
buildId: z.string().optional(),

0 commit comments

Comments
 (0)