Skip to content
Merged
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
35 changes: 34 additions & 1 deletion apps/webapp/app/v3/services/initializeDeployment.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,40 @@ export class InitializeDeploymentService extends BaseService {
environment: AuthenticatedEnvironment,
payload: InitializeDeploymentRequestBody
) {
return this.traceWithEnv("call", environment, async (span) => {
return this.traceWithEnv("call", environment, async () => {
if (payload.gitMeta?.commitSha?.startsWith("deployment_")) {
// When we introduced automatic deployments via the build server, we slightly changed the deployment flow
// mainly in the initialization and starting step: now deployments are first initialized in the `PENDING` status
// and updated to `BUILDING` once the build server dequeues the build job.
// Newer versions of the `deploy` command in the CLI will automatically attach to the existing deployment
// and continue with the build process. For older versions, we can't change the command's client-side behavior,
// so we need to handle this case here in the initialization endpoint. As we control the env variables which
// the git meta is extracted from in the build server, we can use those to pass the existing deployment ID
// to this endpoint. This doesn't affect the git meta on the deployment as it is set prior to this step using the
// /start endpoint. It's a rather hacky solution, but it will do for now as it enables us to avoid degrading the
// build server experience for users with older CLI versions. We'll eventually be able to remove this workaround
// once we stop supporting 3.x CLI versions.

const existingDeploymentId = payload.gitMeta.commitSha;
const existingDeployment = await this._prisma.workerDeployment.findFirst({
where: {
environmentId: environment.id,
friendlyId: existingDeploymentId,
},
});

if (!existingDeployment) {
throw new ServiceValidationError(
"Existing deployment not found during deployment initialization"
);
}

return {
deployment: existingDeployment,
imageRef: existingDeployment.imageReference ?? "",
};
}

Comment on lines +22 to +55
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Legacy path bypasses self-hosted restriction check. Add the same guard as the main path.

Right now, the early-return path skips the payload.selfHosted && remoteBuildsEnabled() gate, potentially allowing flows the main path blocks. Mirror that check here to keep policy parity.

Apply this diff inside the legacy branch before querying Prisma:

 if (payload.gitMeta?.commitSha?.startsWith("deployment_")) {
+  // Parity with the main path: do not allow self-hosted on this instance
+  if (payload.selfHosted && remoteBuildsEnabled()) {
+    throw new ServiceValidationError("Self-hosted deployments are not supported on this instance");
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return this.traceWithEnv("call", environment, async () => {
if (payload.gitMeta?.commitSha?.startsWith("deployment_")) {
// When we introduced automatic deployments via the build server, we slightly changed the deployment flow
// mainly in the initialization and starting step: now deployments are first initialized in the `PENDING` status
// and updated to `BUILDING` once the build server dequeues the build job.
// Newer versions of the `deploy` command in the CLI will automatically attach to the existing deployment
// and continue with the build process. For older versions, we can't change the command's client-side behavior,
// so we need to handle this case here in the initialization endpoint. As we control the env variables which
// the git meta is extracted from in the build server, we can use those to pass the existing deployment ID
// to this endpoint. This doesn't affect the git meta on the deployment as it is set prior to this step using the
// /start endpoint. It's a rather hacky solution, but it will do for now as it enables us to avoid degrading the
// build server experience for users with older CLI versions. We'll eventually be able to remove this workaround
// once we stop supporting 3.x CLI versions.
const existingDeploymentId = payload.gitMeta.commitSha;
const existingDeployment = await this._prisma.workerDeployment.findFirst({
where: {
environmentId: environment.id,
friendlyId: existingDeploymentId,
},
});
if (!existingDeployment) {
throw new ServiceValidationError(
"Existing deployment not found during deployment initialization"
);
}
return {
deployment: existingDeployment,
imageRef: existingDeployment.imageReference ?? "",
};
}
return this.traceWithEnv("call", environment, async () => {
if (payload.gitMeta?.commitSha?.startsWith("deployment_")) {
// When we introduced automatic deployments via the build server, we slightly changed the deployment flow
// mainly in the initialization and starting step: now deployments are first initialized in the `PENDING` status
// and updated to `BUILDING` once the build server dequeues the build job.
// Newer versions of the `deploy` command in the CLI will automatically attach to the existing deployment
// and continue with the build process. For older versions, we can't change the command's client-side behavior,
// so we need to handle this case here in the initialization endpoint. As we control the env variables which
// the git meta is extracted from in the build server, we can use those to pass the existing deployment ID
// to this endpoint. This doesn't affect the git meta on the deployment as it is set prior to this step using the
// /start endpoint. It's a rather hacky solution, but it will do for now as it enables us to avoid degrading the
// build server experience for users with older CLI versions. We'll eventually be able to remove this workaround
// once we stop supporting 3.x CLI versions.
// Parity with the main path: do not allow self-hosted on this instance
if (payload.selfHosted && remoteBuildsEnabled()) {
throw new ServiceValidationError("Self-hosted deployments are not supported on this instance");
}
const existingDeploymentId = payload.gitMeta.commitSha;
const existingDeployment = await this._prisma.workerDeployment.findFirst({
where: {
environmentId: environment.id,
friendlyId: existingDeploymentId,
},
});
if (!existingDeployment) {
throw new ServiceValidationError(
"Existing deployment not found during deployment initialization"
);
}
return {
deployment: existingDeployment,
imageRef: existingDeployment.imageReference ?? "",
};
}
🤖 Prompt for AI Agents
In apps/webapp/app/v3/services/initializeDeployment.server.ts around lines 22 to
55, the legacy early-return path that looks up an existing deployment using
payload.gitMeta.commitSha bypasses the same self-hosted vs remote-builds gate
used in the main path; add the identical check before querying Prisma: if
payload.selfHosted is true and remoteBuildsEnabled() is false, throw a
ServiceValidationError (same message/behavior as the main path) to block the
legacy flow, ensuring parity with the primary initialization branch.

if (payload.type === "UNMANAGED") {
throw new ServiceValidationError("UNMANAGED deployments are not supported");
}
Expand Down
Loading