-
-
Notifications
You must be signed in to change notification settings - Fork 840
feat: enable canceling deployments #2545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
WalkthroughAdds end-to-end deployment cancellation support: DB migration and Prisma schema add canceledAt and canceledReason to WorkerDeployment. API/schema: new CancelDeploymentRequestBody zod schema, a POST route api.v1.deployments.$deploymentId.cancel, and a resources action to cancel by projectId/deploymentShortCode. Service: DeploymentService.cancelDeployment added and FINAL_DEPLOYMENT_STATUSES exported/extended (includes TIMED_OUT). Presenter: deployment payload now includes installedAt, canceledAt, canceledReason. UI: CANCELED added to deploymentStatuses; deployment views render canceled/installed fields; new Cancel dialog wired in routes; RollbackDeploymentDialog file removed. Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
12ee260
to
209242f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (10)
apps/webapp/app/components/runs/v3/DeploymentStatus.tsx (1)
131-141
: Outdated/misleading comment (and typo) above statusesThe comment contradicts the array (CANCELED is included) and “ommited” is misspelled.
Apply this diff:
-// PENDING and CANCELED are not used so are ommited from the UI +// Full list of deployment statuses used by the UI (including PENDING and CANCELED)internal-packages/database/prisma/migrations/20250923192901_add_canceled_at_to_deployments/migration.sql (1)
1-2
: Migration looks goodOptional: consider a follow-up partial index on status (non-final) if you routinely query/update “active” deployments.
apps/webapp/app/v3/services/failDeployment.server.ts (1)
8-13
: Make FINAL_DEPLOYMENT_STATUSES readonly at type levelPrevents accidental mutation and keeps narrow literal types.
Apply this diff:
-export const FINAL_DEPLOYMENT_STATUSES: WorkerDeploymentStatus[] = [ - "CANCELED", - "DEPLOYED", - "FAILED", - "TIMED_OUT", -]; +export const FINAL_DEPLOYMENT_STATUSES = + ["CANCELED", "DEPLOYED", "FAILED", "TIMED_OUT"] as const satisfies ReadonlyArray<WorkerDeploymentStatus>;apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx (1)
171-176
: Fix spelling: “Cancellation reason”Minor UI text polish.
Apply this diff:
- <Property.Label>Cancelation reason</Property.Label> + <Property.Label>Cancellation reason</Property.Label>packages/core/src/v3/schemas/api.ts (1)
388-393
: Trim and disallow whitespace-only reasonsAvoids accepting strings that are effectively empty.
Apply this diff:
-export const CancelDeploymentRequestBody = z.object({ - reason: z.string().max(200, "Reason must be less than 200 characters").optional(), -}); +export const CancelDeploymentRequestBody = z.object({ + reason: z + .string() + .trim() + .min(1, "Reason cannot be empty") + .max(200, "Reason must be less than 200 characters") + .optional(), +});apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts (1)
12-15
: Return 405 with Allow headerInclude the Allow header for better client behavior.
Apply this diff:
- if (request.method.toUpperCase() !== "POST") { - return json({ error: "Method Not Allowed" }, { status: 405 }); - } + if (request.method.toUpperCase() !== "POST") { + return json({ error: "Method Not Allowed" }, { status: 405, headers: { Allow: "POST" } }); + }apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (1)
11-13
: Rename schema for clarity.
promoteSchema
is used by a cancel route. Consider renaming tocancelSchema
to avoid confusion.apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx (3)
416-418
: Avoid duplicating final-status lists in UI.Hard-coding final statuses risks drift from server truth. Consider a shared UI constant or deriving from a single source used across the app.
528-535
: Use the formAction variable to avoid divergence.Minor: the action string is duplicated; prefer the
formAction
variable used forisLoading
.- <Form - action={`/resources/${projectId}/deployments/${deploymentShortCode}/rollback`} - method="post" - > + <Form action={formAction} method="post">
570-577
: Same here: reuse formAction for promote dialog.- <Form - action={`/resources/${projectId}/deployments/${deploymentShortCode}/promote`} - method="post" - > + <Form action={formAction} method="post">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
apps/webapp/app/components/runs/v3/DeploymentStatus.tsx
(1 hunks)apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx
(0 hunks)apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
(2 hunks)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
(2 hunks)apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
(7 hunks)apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
(1 hunks)apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
(1 hunks)apps/webapp/app/v3/services/deployment.server.ts
(2 hunks)apps/webapp/app/v3/services/failDeployment.server.ts
(1 hunks)internal-packages/database/prisma/migrations/20250923192901_add_canceled_at_to_deployments/migration.sql
(1 hunks)internal-packages/database/prisma/schema.prisma
(1 hunks)packages/core/src/v3/schemas/api.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- apps/webapp/app/components/runs/v3/RollbackDeploymentDialog.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}
: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations
Files:
packages/core/src/v3/schemas/api.ts
apps/webapp/app/components/runs/v3/DeploymentStatus.tsx
apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/v3/services/failDeployment.server.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
We use zod a lot in packages/core and in the webapp
Files:
packages/core/src/v3/schemas/api.ts
apps/webapp/app/components/runs/v3/DeploymentStatus.tsx
apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/v3/services/failDeployment.server.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json
Files:
apps/webapp/app/components/runs/v3/DeploymentStatus.tsx
apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/v3/services/failDeployment.server.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
{apps/webapp/app/**/*.server.{ts,tsx},apps/webapp/app/routes/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access environment variables only via the env export from app/env.server.ts; do not reference process.env directly
Files:
apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/v3/services/failDeployment.server.ts
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Modules intended for test consumption under apps/webapp/app/**/*.ts must not read environment variables; accept configuration via options instead
Files:
apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/v3/services/failDeployment.server.ts
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
🧬 Code graph analysis (5)
apps/webapp/app/v3/services/deployment.server.ts (2)
apps/webapp/app/v3/services/createDeploymentBackgroundWorkerV4.server.ts (1)
deployment
(182-200)apps/webapp/app/v3/services/failDeployment.server.ts (1)
FINAL_DEPLOYMENT_STATUSES
(8-13)
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts (3)
apps/webapp/app/services/apiAuth.server.ts (1)
authenticateRequest
(379-441)packages/core/src/v3/schemas/api.ts (2)
CancelDeploymentRequestBody
(388-390)CancelDeploymentRequestBody
(392-392)apps/webapp/app/v3/services/deployment.server.ts (1)
DeploymentService
(11-222)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx (1)
apps/webapp/app/components/primitives/DateTime.tsx (1)
DateTimeAccurate
(196-242)
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (3)
apps/webapp/app/services/session.server.ts (1)
requireUserId
(25-35)apps/webapp/app/v3/services/deployment.server.ts (1)
DeploymentService
(11-222)apps/webapp/app/models/message.server.ts (2)
redirectWithErrorMessage
(181-198)redirectWithSuccessMessage
(162-179)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx (3)
apps/webapp/app/components/primitives/Dialog.tsx (6)
Dialog
(113-113)DialogTrigger
(114-114)DialogContent
(115-115)DialogHeader
(116-116)DialogDescription
(119-119)DialogFooter
(117-117)apps/webapp/app/components/primitives/Buttons.tsx (1)
Button
(296-331)apps/webapp/app/components/primitives/Spinner.tsx (1)
SpinnerWhite
(76-78)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: typecheck / typecheck
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (7)
apps/webapp/app/components/runs/v3/DeploymentStatus.tsx (1)
140-141
: CANCELED added to statuses — LGTMThis aligns the list with the rest of the UI logic and schemas.
internal-packages/database/prisma/schema.prisma (1)
1775-1777
: New fields on WorkerDeployment — LGTMTypes match the migration and downstream usage.
apps/webapp/app/v3/services/failDeployment.server.ts (1)
4-6
: Type‑only imports — nice cleanupKeeps runtime lean.
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts (1)
8-10
: Verify identifier semantics: friendlyId vs database idThe service expects a friendlyId (findFirst by friendlyId), but the route param is named deploymentId. Confirm that clients supply the friendly ID (e.g., deploy_…) and that docs reflect this. Otherwise, either rename the route param to deploymentFriendlyId or update the service to accept id as well.
Would you like me to update the route/docs, or adjust the service to accept either id or friendlyId and return 404/409 appropriately on race?
Also applies to: 34-36, 46-50
apps/webapp/app/presenters/v3/DeploymentPresenter.server.ts (2)
106-109
: Good: selecting new fields (installedAt/canceledAt/canceledReason).Selection aligns with the new columns and keeps the presenter authoritative for UI needs.
153-158
: Good: exposing installedAt/canceledAt/canceledReason in payload.Matches the DB selection and enables UI rendering without extra queries.
apps/webapp/app/v3/services/deployment.server.ts (1)
104-105
: Good: set installedAt at transition to BUILDING.This timestamp placement is appropriate and consistent with the deployment lifecycle.
...outes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
Outdated
Show resolved
Hide resolved
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
Outdated
Show resolved
Hide resolved
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
Show resolved
Hide resolved
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}
: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
We use zod a lot in packages/core and in the webapp
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
{apps/webapp/app/**/*.server.{ts,tsx},apps/webapp/app/routes/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access environment variables only via the env export from app/env.server.ts; do not reference process.env directly
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Modules intended for test consumption under apps/webapp/app/**/*.ts must not read environment variables; accept configuration via options instead
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
🧬 Code graph analysis (1)
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (3)
apps/webapp/app/services/session.server.ts (1)
requireUserId
(25-35)apps/webapp/app/v3/services/deployment.server.ts (1)
DeploymentService
(11-222)apps/webapp/app/models/message.server.ts (2)
redirectWithErrorMessage
(181-198)redirectWithSuccessMessage
(162-179)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: units / webapp / 📊 Merge Reports
🔇 Additional comments (6)
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (6)
86-93
: Fix log message: it's a cancel route, not promote.The logger message incorrectly says "Failed to promote deployment" even though this is the cancel route.
Apply this diff to correct the log message:
- logger.error( - `Failed to promote deployment: ${result.error.type}`, + logger.error( + `Failed to cancel deployment: ${result.error.type}`,
104-109
: Correct user message for non-cancellable deployments.The error case for
deployment_cannot_be_cancelled
incorrectly returns "Deployment not found", which is misleading to users.Apply this diff to provide the correct error message:
case "deployment_cannot_be_cancelled": return redirectWithErrorMessage( submission.value.redirectUrl, request, - "Deployment not found" + "Deployment cannot be canceled" );
31-54
: LGTM - Proper project membership verification.The project membership verification correctly ensures only authorized users can cancel deployments by checking organization membership through the userId.
56-76
: LGTM - Efficient deployment lookup using composite key.The deployment lookup uses the efficient
projectId_shortCode
composite unique constraint and properly handles the not-found case.
79-83
: LGTM - Service integration follows established patterns.The deployment service integration uses the Result pattern consistently with proper error chaining, following the established patterns seen in other deployment operations.
121-126
: LGTM - Clear success feedback.The success message clearly indicates the deployment was canceled and includes the deployment short code for user reference.
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts (1)
37-38
: Optional: log malformed JSON to aid diagnostics.Swallowing parse errors and treating the body as {} is fine here. Consider logging at debug to trace bad clients.
Apply this diff:
- const [, rawBody] = await tryCatch(request.json()); + const [parseErr, rawBody] = await tryCatch(request.json()); + if (parseErr) { + logger.debug("Invalid JSON in progress request body; treating as empty object", { + url: request.url, + }); + }apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts (1)
37-39
: Optional: add debug log on JSON parse failure.Helps trace clients sending malformed JSON without changing behavior.
- const [, rawBody] = await tryCatch(request.json()); + const [parseErr, rawBody] = await tryCatch(request.json()); + if (parseErr) { + logger.debug("Invalid JSON in cancel request body; treating as empty object", { + url: request.url, + }); + }apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx (3)
416-418
: Avoid duplicating final status lists in UI.Hardcoding finalStatuses in the client risks drift from server truth. Centralize in a shared module (e.g., a client-shared constants file) and import here.
Example:
- Create a shared finalDeploymentStatuses export in a client-available module and replace this array with that import.
528-543
: Use the computed formAction for consistency and to prevent drift.The isLoading check relies on formAction, but the Form uses a string literal. Use the variable.
- <Form - action={`/resources/${projectId}/deployments/${deploymentShortCode}/rollback`} - method="post" - > + <Form action={formAction} method="post">
570-585
: Same here: align Form action with formAction variable.Prevents mismatches if the path changes.
- <Form - action={`/resources/${projectId}/deployments/${deploymentShortCode}/promote`} - method="post" - > + <Form action={formAction} method="post">
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
(7 hunks)apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
(1 hunks)apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts
(2 hunks)apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
(1 hunks)apps/webapp/app/v3/services/deployment.server.ts
(2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.{ts,tsx}
: Always prefer using isomorphic code like fetch, ReadableStream, etc. instead of Node.js specific code
For TypeScript, we usually use types over interfaces
Avoid enums
No default exports, use function declarations
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
apps/webapp/app/v3/services/deployment.server.ts
{packages/core,apps/webapp}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
We use zod a lot in packages/core and in the webapp
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
When importing from @trigger.dev/core in the webapp, never import the root package path; always use one of the documented subpath exports from @trigger.dev/core’s package.json
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx
apps/webapp/app/v3/services/deployment.server.ts
{apps/webapp/app/**/*.server.{ts,tsx},apps/webapp/app/routes/**/*.ts}
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Access environment variables only via the env export from app/env.server.ts; do not reference process.env directly
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts
apps/webapp/app/v3/services/deployment.server.ts
apps/webapp/app/**/*.ts
📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Modules intended for test consumption under apps/webapp/app/**/*.ts must not read environment variables; accept configuration via options instead
Files:
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts
apps/webapp/app/v3/services/deployment.server.ts
🧬 Code graph analysis (5)
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (3)
apps/webapp/app/services/session.server.ts (1)
requireUserId
(25-35)apps/webapp/app/v3/services/deployment.server.ts (1)
DeploymentService
(11-234)apps/webapp/app/models/message.server.ts (2)
redirectWithErrorMessage
(181-198)redirectWithSuccessMessage
(162-179)
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts (5)
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts (1)
action
(12-76)apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (1)
action
(20-133)apps/webapp/app/services/apiAuth.server.ts (1)
authenticateRequest
(379-441)packages/core/src/v3/schemas/api.ts (2)
CancelDeploymentRequestBody
(388-390)CancelDeploymentRequestBody
(392-392)apps/webapp/app/v3/services/deployment.server.ts (1)
DeploymentService
(11-234)
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts (1)
packages/core/src/v3/schemas/api.ts (2)
ProgressDeploymentRequestBody
(380-384)ProgressDeploymentRequestBody
(386-386)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx (3)
apps/webapp/app/components/primitives/Dialog.tsx (6)
Dialog
(113-113)DialogTrigger
(114-114)DialogContent
(115-115)DialogHeader
(116-116)DialogDescription
(119-119)DialogFooter
(117-117)apps/webapp/app/components/primitives/Buttons.tsx (1)
Button
(296-331)apps/webapp/app/components/primitives/Spinner.tsx (1)
SpinnerWhite
(76-78)
apps/webapp/app/v3/services/deployment.server.ts (3)
apps/webapp/app/v3/services/createDeploymentBackgroundWorkerV4.server.ts (1)
deployment
(182-200)apps/webapp/app/v3/services/failDeployment.server.ts (1)
FINAL_DEPLOYMENT_STATUSES
(8-13)apps/webapp/app/v3/services/timeoutDeployment.server.ts (1)
TimeoutDeploymentService
(8-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (23)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
- GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
- GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
- GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
- GitHub Check: typecheck / typecheck
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
- GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (13)
apps/webapp/app/routes/api.v1.deployments.$deploymentId.progress.ts (1)
2-2
: Good use of guarded JSON parsing via tryCatch and subpath import.Importing tryCatch from @trigger.dev/core/v3 aligns with our subpath guideline and avoids throwing on empty/invalid JSON.
apps/webapp/app/routes/api.v1.deployments.$deploymentId.cancel.ts (3)
37-39
: Guarded JSON parse implemented correctly.Using tryCatch to avoid request.json() throws and validating with zod keeps the route robust when the body is empty/invalid.
46-49
: Correct mapping from API body to service input.Passing canceledReason from body.data.reason matches the schema and service.
55-69
: Error mapping looks solid and consistent with other routes.Correct statuses, including ignoring timeout dequeue failures.
apps/webapp/app/v3/services/deployment.server.ts (4)
94-105
: Installed timestamp set during BUILDING transition.Setting installedAt when moving to BUILDING is coherent with exposing install milestones.
185-191
: Final-state guard prevents canceling completed deployments.Correct use of FINAL_DEPLOYMENT_STATUSES with a clear error path.
196-221
: Concurrency-safe cancel write with proper verification.Using updateMany with a status guard and checking result.count avoids TOCTOU issues.
222-233
: Timeout cleanup after cancel.Dequeueing the timeout job prevents post-cancel transitions; correct to surface a distinct error so callers can decide to ignore.
apps/webapp/app/routes/resources.$projectId.deployments.$deploymentShortCode.cancel.ts (3)
11-13
: Schema naming matches route intent.cancelSchema is clear and exported; usage updated accordingly.
85-94
: Accurate logging context for cancel failures.Message and conditional cause logging look good.
95-125
: Error-to-UX mapping is precise.Good distinction for non-cancelable vs not found; ignoring dequeue failures as success is pragmatic.
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments/route.tsx (2)
597-621
: Cancel dialog wiring looks correct.Correct formAction usage, loading indicator, and danger styling.
433-444
: Action labels streamlined.“Rollback” and “Promote” labels are concise and consistent with menu context.
Also applies to: 454-465
This PR enables canceling deployments via the dashboard or the API. This
feature is especially useful for deployments created by the build server, where
the user does not otherwise have control on the deployment process.