Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ export async function action({ request, params }: ActionFunctionArgs) {
return json({ error: "Deployment not found" }, { status: 404 });
case "deployment_not_pending":
return json({ error: "Deployment is not pending" }, { status: 409 });
case "failed_to_create_remote_build":
return json({ error: "Failed to create remote build" }, { status: 500 });
case "other":
default:
error.type satisfies "other";
Expand Down
7 changes: 5 additions & 2 deletions apps/webapp/app/v3/remoteImageBuilder.server.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { depot } from "@depot/sdk-node";
import { Project } from "@trigger.dev/database";
import { type ExternalBuildData } from "@trigger.dev/core/v3";
import { type Project } from "@trigger.dev/database";
import { prisma } from "~/db.server";
import { env } from "~/env.server";

export async function createRemoteImageBuild(project: Project) {
export async function createRemoteImageBuild(
project: Project
): Promise<ExternalBuildData | undefined> {
if (!remoteBuildsEnabled()) {
return;
}
Expand Down
31 changes: 26 additions & 5 deletions apps/webapp/app/v3/services/deployment.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
import { BaseService } from "./baseService.server";
import { errAsync, fromPromise, okAsync } from "neverthrow";
import { type WorkerDeploymentStatus, type WorkerDeployment } from "@trigger.dev/database";
import { logger, type GitMeta } from "@trigger.dev/core/v3";
import { type ExternalBuildData, logger, type GitMeta } from "@trigger.dev/core/v3";
import { TimeoutDeploymentService } from "./timeoutDeployment.server";
import { env } from "~/env.server";
import { createRemoteImageBuild } from "../remoteImageBuilder.server";

export class DeploymentService extends BaseService {
public startDeployment(
Expand Down Expand Up @@ -46,11 +47,29 @@ export class DeploymentService extends BaseService {
return okAsync(deployment);
};

const updateDeployment = (deployment: Pick<WorkerDeployment, "id">) =>
const createRemoteBuild = (deployment: Pick<WorkerDeployment, "id">) =>
fromPromise(createRemoteImageBuild(authenticatedEnv.project), (error) => ({
type: "failed_to_create_remote_build" as const,
cause: error,
})).map((build) => ({
id: deployment.id,
externalBuildData: build,
}));

const updateDeployment = (
deployment: Pick<WorkerDeployment, "id"> & {
externalBuildData: ExternalBuildData | undefined;
}
) =>
fromPromise(
this._prisma.workerDeployment.updateMany({
where: { id: deployment.id, status: "PENDING" }, // status could've changed in the meantime, we're not locking the row
data: { ...updates, status: "BUILDING", startedAt: new Date() },
data: {
...updates,
externalBuildData: deployment.externalBuildData,
status: "BUILDING",
startedAt: new Date(),
},
}),
(error) => ({
type: "other" as const,
Expand All @@ -75,11 +94,13 @@ export class DeploymentService extends BaseService {
type: "failed_to_extend_deployment_timeout" as const,
cause: error,
})
).map(() => undefined);
);

return getDeployment()
.andThen(validateDeployment)
.andThen(createRemoteBuild)
.andThen(updateDeployment)
.andThen(extendTimeout);
.andThen(extendTimeout)
.map(() => undefined);
}
}
8 changes: 6 additions & 2 deletions apps/webapp/app/v3/services/initializeDeployment.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,12 @@ export class InitializeDeploymentService extends BaseService {
);
}

// Try and create a depot build and get back the external build data
const externalBuildData = await createRemoteImageBuild(environment.project);
// 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"
? undefined
: await createRemoteImageBuild(environment.project);

const triggeredBy = payload.userId
? await this._prisma.user.findFirst({
Expand Down
Loading