Conversation
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
📝 WalkthroughWalkthroughRemoves per-deployment isRolledBack and introduces project-level rolledBackDeploymentId across DB schema, generated types/queries, Go services, tRPC, collections, and UI; UI logic and hooks now derive rolled-back state from project. Adds UpdateProjectDeployments and removes per-deployment rollback queries. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant UI as Dashboard UI
participant API as tRPC / Go Services
participant DB as Database
rect rgba(220,240,255,0.12)
note right of UI: Deployment ready/complete flow
User->>UI: mark deployment ready
UI->>API: mark deployment ready
API->>DB: UPDATE deployments (status, updated_at)
DB-->>API: OK
API->>DB: UpdateProjectDeployments(live_id, rolled_back_id?, updated_at)
DB-->>API: OK
API-->>UI: success
end
rect rgba(255,235,220,0.12)
note right of UI: Rollback flow (source -> target)
User->>UI: trigger rollback
UI->>API: request rollback
API->>DB: UpdateProjectDeployments(live=target, rolled_back=source, updated_at)
DB-->>API: OK
API-->>UI: done
end
rect rgba(225,255,225,0.12)
note right of UI: Rendering rolled-back state
UI->>API: fetch project + deployments
API-->>UI: { project.rolledBackDeploymentId, deployments[] }
UI->>UI: isRolledBack := deployment.id == project.rolledBackDeploymentId
UI-->>User: render table rows with rolled-back styling
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ 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). (2)
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 |
|
Thank you for following the naming conventions for pull request titles! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (7)
internal/db/src/schema/projects.ts (1)
22-24: Add a typed relation for rolledBackDeploymentId.Define a relation like activeDeployment for better type-safety and DX.
Add this to projectsRelations:
export const projectsRelations = relations(projects, ({ one, many }) => ({ workspace: one(workspaces, { fields: [projects.workspaceId], references: [workspaces.id], }), deployments: many(deployments), activeDeployment: one(deployments, { fields: [projects.liveDeploymentId], references: [deployments.id], }), + rolledBackDeployment: one(deployments, { + fields: [projects.rolledBackDeploymentId], + references: [deployments.id], + }), // environments: many(projectEnvironments), }));apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/components/env-status-badge.tsx (1)
13-15: Color tokens switched to “A” (alpha) variants — contradicts “non‑alpha” goal.To meet the PR objective, use non‑A tokens.
Apply:
- live: "text-featureA-11 bg-featureA-4", - rolledBack: "text-warningA-11 bg-warningA-4", + live: "text-feature-11 bg-feature-4", + rolledBack: "text-warning-11 bg-warning-4",Also consider aligning enabled/disabled to non‑alpha for consistency:
- enabled: "text-successA-11 bg-successA-3", - disabled: "text-warningA-11 bg-warningA-3", + enabled: "text-success-11 bg-success-3", + disabled: "text-warning-11 bg-warning-3",Also applies to: 20-20
apps/dashboard/lib/collections/deploy/projects.ts (1)
47-48: Polling interval: verify impact on larger workspacesRefetching every 5s across big workspaces can add load. Consider gating by document visibility or reducing frequency if not on the deployments page.
If useful, I can draft a small guard (e.g., use Page Visibility API) to disable background polling. Want that?
go/pkg/db/project_update_deployments.sql_generated.go (1)
38-45: Check RowsAffected to detect lost CASSurface an error if no row was updated (stale expected live).
- _, err := db.ExecContext(ctx, updateProjectDeployments, + res, err := db.ExecContext(ctx, updateProjectDeployments, arg.LiveDeploymentID, arg.RolledBackDeploymentID, arg.UpdatedAt, arg.ID, + arg.ExpectedLiveDeploymentID, ) - return err + if err != nil { + return err + } + n, _ := res.RowsAffected() + if n == 0 { + return fmt.Errorf("update conflict: project live_deployment_id changed") + } + return nilNote: implement in SQL (queries/project_update_deployments.sql) and regenerate.
go/apps/ctrl/services/deployment/rollback.go (1)
176-181: Align error message with operationMessage mentions “live deployment id” only; it now updates both pointers.
- return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to update project's live deployment id: %w", err)) + return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to update project deployments: %w", err))apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx (2)
300-301: Narrow useMemo deps to avoid unnecessary recalculationsDepend on stable scalars instead of the whole objects.
- }, [selectedDeployment?.deployment.id, isCompactView, liveDeployment, project]); + }, [ + selectedDeployment?.deployment.id, + isCompactView, + liveDeployment?.id, + project?.rolledBackDeploymentId, + ]);
309-309: keyExtractor likely targets the wrong shapeRows are
{ deployment, environment? }(per Column typing). Use the nested deployment id.- keyExtractor={(deployment) => deployment.id} + keyExtractor={(row) => row.deployment.id}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (24)
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/components/env-status-badge.tsx(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx(4 hunks)apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.ts(1 hunks)apps/dashboard/app/(app)/projects/[projectId]/deployments/hooks/use-deployments.ts(1 hunks)apps/dashboard/app/(app)/projects/_components/create-project/create-project-dialog.tsx(1 hunks)apps/dashboard/lib/collections/deploy/deployments.ts(0 hunks)apps/dashboard/lib/collections/deploy/projects.ts(2 hunks)apps/dashboard/lib/trpc/routers/deploy/deployment/list.ts(0 hunks)apps/dashboard/lib/trpc/routers/deploy/project/list.ts(3 hunks)go/apps/ctrl/services/deployment/deploy_workflow.go(1 hunks)go/apps/ctrl/services/deployment/rollback.go(1 hunks)go/pkg/db/deployment_update_rollback.sql_generated.go(0 hunks)go/pkg/db/models_generated.go(1 hunks)go/pkg/db/project_find_by_id.sql_generated.go(3 hunks)go/pkg/db/project_update_deployments.sql_generated.go(1 hunks)go/pkg/db/project_update_live_deployment_id.sql_generated.go(0 hunks)go/pkg/db/querier_generated.go(2 hunks)go/pkg/db/queries/deployment_update_rollback.sql(0 hunks)go/pkg/db/queries/project_find_by_id.sql(1 hunks)go/pkg/db/queries/project_update_deployments.sql(1 hunks)go/pkg/db/queries/project_update_live_deployment_id.sql(0 hunks)go/pkg/db/schema.sql(1 hunks)internal/db/src/schema/deployments.ts(1 hunks)internal/db/src/schema/projects.ts(1 hunks)
💤 Files with no reviewable changes (6)
- apps/dashboard/lib/collections/deploy/deployments.ts
- go/pkg/db/project_update_live_deployment_id.sql_generated.go
- go/pkg/db/queries/project_update_live_deployment_id.sql
- apps/dashboard/lib/trpc/routers/deploy/deployment/list.ts
- go/pkg/db/queries/deployment_update_rollback.sql
- go/pkg/db/deployment_update_rollback.sql_generated.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: mcstepp
PR: unkeyed/unkey#3952
File: apps/dashboard/app/(app)/projects/[projectId]/deployments/components/rollback-dialog.tsx:70-79
Timestamp: 2025-09-12T17:57:18.337Z
Learning: In the deployment rollback functionality, self-rollback scenarios are prevented at the UI level in the actions menu through the `canRollback` condition which includes `!("active" in deployment && deployment.active)`, making additional checks in the dialog component redundant.
📚 Learning: 2025-07-25T19:09:43.284Z
Learnt from: mcstepp
PR: unkeyed/unkey#3662
File: apps/dashboard/lib/trpc/routers/deployment/list.ts:11-11
Timestamp: 2025-07-25T19:09:43.284Z
Learning: In apps/dashboard/lib/trpc/routers/deployment/list.ts, the listDeployments procedure intentionally queries the versions table rather than a deployments table. The user mcstepp indicated that renaming the table would require a database migration, which was deferred for the current PR focused on UI features.
Applied to files:
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.tsinternal/db/src/schema/deployments.tsapps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsxapps/dashboard/lib/trpc/routers/deploy/project/list.ts
🧬 Code graph analysis (7)
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.ts (2)
go/pkg/db/models_generated.go (1)
Deployment(569-587)apps/dashboard/lib/collections/deploy/deployments.ts (1)
Deployment(39-39)
go/apps/ctrl/services/deployment/deploy_workflow.go (4)
go/pkg/hydra/step.go (1)
StepVoid(303-311)go/pkg/db/deployment_update_status.sql_generated.go (1)
UpdateDeploymentStatusParams(19-23)go/pkg/db/models_generated.go (1)
DeploymentsStatusReady(200-200)go/pkg/db/project_update_deployments.sql_generated.go (1)
UpdateProjectDeploymentsParams(22-27)
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx (2)
apps/dashboard/app/(app)/projects/[projectId]/deployments/hooks/use-deployments.ts (1)
useDeployments(8-120)apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.ts (1)
getRowClassName(49-69)
go/pkg/db/project_find_by_id.sql_generated.go (1)
go/pkg/db/types/null_string.go (1)
NullString(10-10)
apps/dashboard/lib/trpc/routers/deploy/project/list.ts (2)
apps/dashboard/lib/collections/deploy/projects.ts (1)
projects(42-108)internal/db/src/schema/projects.ts (1)
projects(8-34)
go/pkg/db/querier_generated.go (2)
go/pkg/partition/db/database.go (1)
DBTX(10-10)go/pkg/db/project_update_deployments.sql_generated.go (1)
UpdateProjectDeploymentsParams(22-27)
go/apps/ctrl/services/deployment/rollback.go (1)
go/pkg/db/project_update_deployments.sql_generated.go (1)
UpdateProjectDeploymentsParams(22-27)
⏰ 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). (4)
- GitHub Check: Test API / API Test Local
- GitHub Check: Test Go API Local / Test
- GitHub Check: Build / Build
- GitHub Check: Test Packages / Test
🔇 Additional comments (16)
go/pkg/db/queries/project_find_by_id.sql (1)
11-11: LGTM — projection updated to include rolled_back_deployment_id.Keeps FindProjectById aligned with the new schema.
apps/dashboard/app/(app)/projects/_components/create-project/create-project-dialog.tsx (1)
43-44: rolledBackDeploymentId exists in schema — no action required.
internal/db/src/schema/projects.ts defines rolledBackDeploymentId and apps/dashboard/lib/collections/deploy/projects.ts declares it as z.string().nullable(), so create-project's rolledBackDeploymentId: null is compatible.go/pkg/db/queries/project_update_deployments.sql (1)
1-7: Approve — single atomic project update in use; legacy rollback updater not foundUpdateProjectDeployments is generated (go/pkg/db/project_update_deployments.sql_generated.go) and invoked from go/apps/ctrl/services/deployment/deploy_workflow.go and rollback.go; no references to UpdateDeploymentRollback were found.
apps/dashboard/app/(app)/projects/[projectId]/deployments/hooks/use-deployments.ts (1)
116-119: Approved — call sites use project.rolledBackDeploymentIdRepo search shows no uses of deployment.isRolledBack in UI/TS files (only DB schema declares isRolledBack). UI/utils and API mapping use project.rolledBackDeploymentId — apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx, apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.ts, apps/dashboard/lib/trpc/routers/deploy/project/list.ts.
internal/db/src/schema/deployments.ts (1)
2-2: LGTM — removed boolean import aligns with column removal; verify lingering isRolledBack usagesRemoval in internal/db/src/schema/deployments.ts looks correct. Found remaining references to isRolledBack / is_rolled_back — review/update these or confirm they're unrelated:
- apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx
- apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.ts
- internal/db/src/schema/domains.ts
- go/pkg/db/domain_find_by_deployment_id.sql_generated.go
- go/pkg/db/domain_reassign.sql_generated.go
- go/pkg/db/models_generated.go
- go/pkg/db/querier_generated.go
- go/pkg/db/queries/domain_find_by_deployment_id.sql
- go/pkg/db/queries/domain_reassign.sql
- go/pkg/db/schema.sql
Confirm these refer to the domains table (not deployments) or update/remove usages and regenerate affected generated code/assets.
apps/dashboard/lib/trpc/routers/deploy/project/list.ts (1)
14-21: Plumbing rolledBackDeploymentId end-to-end — LGTMSelection, row typing, and mapping to Project look correct.
Also applies to: 36-37, 62-63
go/pkg/db/project_find_by_id.sql_generated.go (1)
23-24: Generated query + struct update — LGTMField is correctly selected, scanned, and exposed.
Also applies to: 31-41, 72-73
apps/dashboard/lib/collections/deploy/projects.ts (1)
14-15: Schema update — LGTMNew rolledBackDeploymentId is correctly added to the zod schema and typed.
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/utils/get-row-class.ts (2)
49-58: Row styling update — LGTMNew rolled-back param and precedence (failed > rolled-back > default) look good.
49-53: No action required — deployments call site passes the new argumentapps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx imports getRowClassName and calls it with three args: (deployment, selectedDeployment?.deployment.id ?? null, project?.rolledBackDeploymentId ?? null). No other imports of this utils file were found.
go/pkg/db/querier_generated.go (2)
598-606: FindProjectById exposure of rolled_back_deployment_id — LGTM
1698-1706: New UpdateProjectDeployments in Querier — LGTMInterface reflects the consolidated project-level pointer update.
go/apps/ctrl/services/deployment/deploy_workflow.go (1)
396-405: Ready status step conversion — LGTMStepVoid usage with UpdatedAt now/time is fine.
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/deployments-list.tsx (2)
49-50: Plumbing project from useDeployments: LGTMThis enables using project.rolledBackDeploymentId in UI logic.
63-64: Rolled-back detection via project ID: LGTMCorrect comparison against project.rolledBackDeploymentId.
go/pkg/db/models_generated.go (1)
717-727: Project.RolledBackDeploymentID addition looks correct; project-level usage migrated — domain-level is_rolled_back remainsVerified: project column and generated queries/models include rolled_back_deployment_id and UI/trpc use rolledBackDeploymentId (e.g. go/pkg/db/schema.sql, go/pkg/db/queries/project_update_deployments.sql_generated.go, go/pkg/db/models_generated.go, internal/db/src/schema/projects.ts, apps/dashboard/lib/trpc/... and deployments-list.tsx). No Deployment-level isRolledBack usages found. Remaining is_rolled_back/IsRolledBack references are domain-scoped (internal/db/src/schema/domains.ts, go/pkg/db/domain.go, apps/ctrl/services/deployment/{rollback.go,deploy_workflow.go}) and appear to be a separate flag.

What does this PR do?
This PR refactors the rollback functionality by moving the rollback state from the deployment to the project level. Instead of marking deployments with an
isRolledBackflag, we now store a reference to the rolled back deployment in the project record with a newrolledBackDeploymentIDfield.The changes include:
rolledBackDeploymentIDfield to the projects tableisRolledBackfield from deploymentsType of change
How should this be tested?
Checklist
Required
pnpm buildpnpm fmtconsole.logsgit pull origin mainAppreciated
Summary by CodeRabbit
New Features
Bug Fixes
Style
Chores