diff --git a/.server-changes/allow-rollbacks-promote-api.md b/.server-changes/allow-rollbacks-promote-api.md new file mode 100644 index 0000000000..fc03fa114f --- /dev/null +++ b/.server-changes/allow-rollbacks-promote-api.md @@ -0,0 +1,6 @@ +--- +area: webapp +type: feature +--- + +Add allowRollbacks query param to the promote deployment API to enable version downgrades diff --git a/apps/webapp/app/routes/api.v1.deployments.$deploymentVersion.promote.ts b/apps/webapp/app/routes/api.v1.deployments.$deploymentVersion.promote.ts index 24f8e74a5e..893b260dc8 100644 --- a/apps/webapp/app/routes/api.v1.deployments.$deploymentVersion.promote.ts +++ b/apps/webapp/app/routes/api.v1.deployments.$deploymentVersion.promote.ts @@ -32,6 +32,9 @@ export async function action({ request, params }: ActionFunctionArgs) { const authenticatedEnv = authenticationResult.environment; + const url = new URL(request.url); + const allowRollbacks = url.searchParams.get("allowRollbacks") === "true"; + const { deploymentVersion } = parsedParams.data; const deployment = await prisma.workerDeployment.findFirst({ @@ -47,7 +50,7 @@ export async function action({ request, params }: ActionFunctionArgs) { try { const service = new ChangeCurrentDeploymentService(); - await service.call(deployment, "promote"); + await service.call(deployment, "promote", allowRollbacks); return json( { diff --git a/apps/webapp/app/v3/services/changeCurrentDeployment.server.ts b/apps/webapp/app/v3/services/changeCurrentDeployment.server.ts index bc0dd04eaa..00360df946 100644 --- a/apps/webapp/app/v3/services/changeCurrentDeployment.server.ts +++ b/apps/webapp/app/v3/services/changeCurrentDeployment.server.ts @@ -7,7 +7,11 @@ import { CURRENT_DEPLOYMENT_LABEL } from "@trigger.dev/core/v3/isomorphic"; export type ChangeCurrentDeploymentDirection = "promote" | "rollback"; export class ChangeCurrentDeploymentService extends BaseService { - public async call(deployment: WorkerDeployment, direction: ChangeCurrentDeploymentDirection) { + public async call( + deployment: WorkerDeployment, + direction: ChangeCurrentDeploymentDirection, + disableVersionCheck?: boolean + ) { if (!deployment.workerId) { throw new ServiceValidationError( direction === "promote" @@ -42,26 +46,34 @@ export class ChangeCurrentDeploymentService extends BaseService { } // if there is a current promotion, we have to validate we are moving in the right direction based on the deployment versions - switch (direction) { - case "promote": { - if ( - compareDeploymentVersions(currentPromotion.deployment.version, deployment.version) >= 0 - ) { - throw new ServiceValidationError( - "Cannot promote a deployment that is older than the current deployment." - ); + if (!disableVersionCheck) { + switch (direction) { + case "promote": { + if ( + compareDeploymentVersions( + currentPromotion.deployment.version, + deployment.version + ) >= 0 + ) { + throw new ServiceValidationError( + "Cannot promote a deployment that is older than the current deployment." + ); + } + break; } - break; - } - case "rollback": { - if ( - compareDeploymentVersions(currentPromotion.deployment.version, deployment.version) <= 0 - ) { - throw new ServiceValidationError( - "Cannot rollback to a deployment that is newer than the current deployment." - ); + case "rollback": { + if ( + compareDeploymentVersions( + currentPromotion.deployment.version, + deployment.version + ) <= 0 + ) { + throw new ServiceValidationError( + "Cannot rollback to a deployment that is newer than the current deployment." + ); + } + break; } - break; } } }