Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
7 changes: 7 additions & 0 deletions .changeset/tricky-suits-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@trigger.dev/sdk": patch
"trigger.dev": patch
"@trigger.dev/core": patch
---

Fixed a minor issue in the deployment command on distinguishing between local builds for the cloud vs local builds for self-hosting setups.
28 changes: 15 additions & 13 deletions apps/webapp/app/v3/services/deployment.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ export class DeploymentService extends BaseService {
const createRemoteBuildIfNeeded = deployment.buildServerMetadata?.isNativeBuild
? okAsync(undefined)
: fromPromise(createRemoteImageBuild(authenticatedEnv.project), (error) => ({
type: "failed_to_create_remote_build" as const,
cause: error,
}));
type: "failed_to_create_remote_build" as const,
cause: error,
}));

const existingBuildServerMetadata = deployment.buildServerMetadata as
| BuildServerMetadata
Expand All @@ -134,7 +134,7 @@ export class DeploymentService extends BaseService {
},
}
: {}),
externalBuildData,
...(externalBuildData ? { externalBuildData } : {}),
status: "BUILDING",
installedAt: new Date(),
},
Expand Down Expand Up @@ -496,14 +496,16 @@ export class DeploymentService extends BaseService {
type: "other" as const,
cause: error,
})
).andThen((deployment) => {
if (!deployment) {
return errAsync({ type: "deployment_not_found" as const });
}
return okAsync(deployment);
}).map((deployment) => ({
...deployment,
buildServerMetadata: BuildServerMetadata.safeParse(deployment.buildServerMetadata).data,
}));
)
.andThen((deployment) => {
if (!deployment) {
return errAsync({ type: "deployment_not_found" as const });
}
return okAsync(deployment);
})
.map((deployment) => ({
...deployment,
buildServerMetadata: BuildServerMetadata.safeParse(deployment.buildServerMetadata).data,
}));
}
}
24 changes: 17 additions & 7 deletions apps/webapp/app/v3/services/initializeDeployment.server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { BuildServerMetadata, type InitializeDeploymentRequestBody } from "@trigger.dev/core/v3";
import {
BuildServerMetadata,
type InitializeDeploymentRequestBody,
type ExternalBuildData,
} from "@trigger.dev/core/v3";
import { customAlphabet } from "nanoid";
import { env } from "~/env.server";
import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
Expand Down Expand Up @@ -89,12 +93,18 @@ export class InitializeDeploymentService extends BaseService {
);
}

// For the `PENDING` initial status, defer the creation of the Depot build until the deployment is started.
// This helps avoid Depot token expiration issues.
const externalBuildData =
payload.initialStatus === "PENDING" || payload.isNativeBuild
? undefined
: await createRemoteImageBuild(environment.project);
// For the `PENDING` initial status, defer the creation of the Depot build until the deployment is started to avoid token expiration issues.
// 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.
const generateExternalBuildToken =
payload.initialStatus === "PENDING" || payload.isNativeBuild || payload.isLocal;

const externalBuildData = generateExternalBuildToken
? ({
projectId: "-",
buildToken: "-",
buildId: "-",
} satisfies ExternalBuildData)
: await createRemoteImageBuild(environment.project);

const triggeredBy = payload.userId
? await this._prisma.user.findFirst({
Expand Down
19 changes: 14 additions & 5 deletions packages/cli-v3/src/commands/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,11 @@ export function configureDeployCommand(program: Command) {
localBuild: true,
})
)
.addOption(new CommandOption("--local-build", "Build the deployment image locally"))
.addOption(
new CommandOption("--local-build", "Build the deployment image locally").conflicts(
"nativeBuildServer"
)
)
.addOption(new CommandOption("--push", "Push the image after local builds").hideHelp())
.addOption(
new CommandOption("--no-push", "Do not push the image after local builds").hideHelp()
Expand Down Expand Up @@ -420,14 +424,19 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
gitMeta,
type: features.run_engine_v2 ? "MANAGED" : "V1",
runtime: buildManifest.runtime,
isLocal: options.localBuild,
isNativeBuild: false,
triggeredVia: getTriggeredVia(),
},
envVars.TRIGGER_EXISTING_DEPLOYMENT_ID
);

// When `externalBuildData` is not present the deployment implicitly goes into the local build path
// which is used in self-hosted setups. There are a few subtle differences between local builds for the cloud
// and local builds for self-hosted setups. We need to make the separation of the two paths clearer to avoid confusion.
const isLocalBuild = options.localBuild || !deployment.externalBuildData;
// Would be best to actually store this separately in the deployment object. This is an okay proxy for now.
const remoteBuildExplicitlySkipped = options.localBuild && !!deployment.externalBuildData;
const authenticateToTriggerRegistry = options.localBuild;
const skipServerSideRegistryPush = options.localBuild;

// Fail fast if we know local builds will fail
if (isLocalBuild) {
Expand Down Expand Up @@ -559,7 +568,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
network: options.network,
builder: options.builder,
push: options.push,
authenticateToRegistry: remoteBuildExplicitlySkipped,
authenticateToRegistry: authenticateToTriggerRegistry,
});

logger.debug("Build result", buildResult);
Expand Down Expand Up @@ -657,7 +666,7 @@ async function _deployCommand(dir: string, options: DeployCommandOptions) {
{
imageDigest: buildResult.digest,
skipPromotion: options.skipPromotion,
skipPushToRegistry: remoteBuildExplicitlySkipped,
skipPushToRegistry: skipServerSideRegistryPush,
},
(logMessage) => {
if (options.plain || isCI) {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/v3/schemas/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ const InitializeDeploymentRequestBodyBase = z.object({
runtime: z.string().optional(),
initialStatus: z.enum(["PENDING", "BUILDING"]).optional(),
triggeredVia: DeploymentTriggeredVia.optional(),
buildId: z.string().optional()
buildId: z.string().optional(),
});
type BaseOutput = z.output<typeof InitializeDeploymentRequestBodyBase>;

Expand All @@ -624,6 +624,7 @@ type NonNativeBuildOutput = BaseOutput & {

const InitializeDeploymentRequestBodyFull = InitializeDeploymentRequestBodyBase.extend({
isNativeBuild: z.boolean().default(false),
isLocal: z.boolean().optional(),
skipPromotion: z.boolean().optional(),
artifactKey: z.string().optional(),
configFilePath: z.string().optional(),
Expand Down
Loading