fix(api): skip external build creation for native builds (#3024)

Native builds don't use depot, but the `/deployments/:id/progress`
endpoint was unconditionally generating depot build tokens. This is now
fixed.

The initialize deployment endpoint was already doing this check.

<!-- devin-review-badge-begin -->

---

<a
href="https://app.devin.ai/review/triggerdotdev/trigger.dev/pull/3024"
target="_blank">
  <picture>
<source media="(prefers-color-scheme: dark)"
srcset="https://static.devin.ai/assets/gh-open-in-devin-review-dark.svg?v=1">
<img
src="https://static.devin.ai/assets/gh-open-in-devin-review-light.svg?v=1"
alt="Open with Devin">
  </picture>
</a>
<!-- devin-review-badge-end -->
This commit is contained in:
Saadi Myftija
2026-02-10 19:44:44 +01:00
committed by GitHub
parent 48a96efbdc
commit 2feecece88
@@ -2,7 +2,7 @@ import { type AuthenticatedEnvironment } from "~/services/apiAuth.server";
import { BaseService } from "./baseService.server";
import { errAsync, fromPromise, okAsync, type ResultAsync } from "neverthrow";
import { type WorkerDeployment, type Project } from "@trigger.dev/database";
import { logger, type GitMeta, type DeploymentEvent } from "@trigger.dev/core/v3";
import { BuildServerMetadata, logger, type GitMeta, type DeploymentEvent } from "@trigger.dev/core/v3";
import { TimeoutDeploymentService } from "./timeoutDeployment.server";
import { env } from "~/env.server";
import { createRemoteImageBuild } from "../remoteImageBuilder.server";
@@ -40,7 +40,7 @@ export class DeploymentService extends BaseService {
friendlyId: string,
updates: Partial<Pick<WorkerDeployment, "contentHash" | "runtime"> & { git: GitMeta }>
) {
const validateDeployment = (deployment: Pick<WorkerDeployment, "id" | "status">) => {
const validateDeployment = (deployment: Pick<WorkerDeployment, "id" | "status"> & { buildServerMetadata?: BuildServerMetadata }) => {
if (deployment.status !== "PENDING" && deployment.status !== "INSTALLING") {
logger.warn(
"Attempted progressing deployment that is not in PENDING or INSTALLING status",
@@ -75,14 +75,17 @@ export class DeploymentService extends BaseService {
return okAsync({ id: deployment.id, status: "INSTALLING" as const });
});
const createRemoteBuild = (deployment: Pick<WorkerDeployment, "id">) =>
fromPromise(createRemoteImageBuild(authenticatedEnv.project), (error) => ({
type: "failed_to_create_remote_build" as const,
cause: error,
}));
const progressToBuilding = (
deployment: Pick<WorkerDeployment, "id"> & { buildServerMetadata?: BuildServerMetadata }
) => {
const createRemoteBuildIfNeeded = deployment.buildServerMetadata?.isNativeBuild
? okAsync(undefined)
: fromPromise(createRemoteImageBuild(authenticatedEnv.project), (error) => ({
type: "failed_to_create_remote_build" as const,
cause: error,
}));
const progressToBuilding = (deployment: Pick<WorkerDeployment, "id">) =>
createRemoteBuild(deployment)
return createRemoteBuildIfNeeded
.andThen((externalBuildData) =>
fromPromise(
this._prisma.workerDeployment.updateMany({
@@ -106,6 +109,7 @@ export class DeploymentService extends BaseService {
}
return okAsync({ id: deployment.id, status: "BUILDING" as const });
});
};
const extendTimeout = (deployment: Pick<WorkerDeployment, "id" | "status">) =>
fromPromise(
@@ -432,6 +436,7 @@ export class DeploymentService extends BaseService {
select: {
status: true,
id: true,
buildServerMetadata: true,
imageReference: true,
shortCode: true,
environment: {
@@ -454,6 +459,9 @@ export class DeploymentService extends BaseService {
return errAsync({ type: "deployment_not_found" as const });
}
return okAsync(deployment);
});
}).map((deployment) => ({
...deployment,
buildServerMetadata: BuildServerMetadata.safeParse(deployment.buildServerMetadata).data,
}));
}
}