Skip to content

09 18 feat sticky rollbacks#3998

Closed
chronark wants to merge 8 commits intomainfrom
09-18-feat_sticky_rollbacks
Closed

09 18 feat sticky rollbacks#3998
chronark wants to merge 8 commits intomainfrom
09-18-feat_sticky_rollbacks

Conversation

@chronark
Copy link
Collaborator

@chronark chronark commented Sep 19, 2025

  • feat: sticky rollbacks
  • chore: cleanup protos
  • chore: dummy change
  • fix: persist domain changes in main db

Summary by CodeRabbit

  • New Features

    • Enhanced rollback flow: select a target deployment against the current live deployment and review associated domains before confirming.
    • Rollbacks now preserve and reassign “sticky” domains for safer switching.
  • UI/UX

    • Clear “Live” status badges and labels for Live vs Target deployments.
    • Deployment list shows environment slugs and streamlined actions with a single Rollback button.
    • Updated deployment cards and domain lists with quick links.
  • Performance/Reliability

    • Deployments list auto-refreshes every 5 seconds.
    • More robust rollback backend for improved reliability.

@vercel
Copy link

vercel bot commented Sep 19, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
dashboard Ignored Ignored Preview Sep 19, 2025 7:13am
engineering Ignored Ignored Preview Sep 19, 2025 7:13am

@changeset-bot
Copy link

changeset-bot bot commented Sep 19, 2025

⚠️ No Changeset found

Latest commit: 0a0fc84

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 19, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Refactors “active” to “live” across dashboard, hooks, and actions; updates rollback UI and mutation to target/live semantics; adds domain awareness. Backend replaces RoutingService with DeploymentService.Rollback, adds sticky domain semantics, gateway deployment_id, and DB schema/queries for rollback. Protos/codegen updated; polling added; minor infra/image and logging tweaks.

Changes

Cohort / File(s) Summary
Dashboard UI: Rollback & Deployments
apps/dashboard/app/(app)/projects/[projectId]/deployments/components/rollback-dialog.tsx, .../components/table/components/actions/deployment-list-table-action.popover.constants.tsx, .../components/table/components/env-status-badge.tsx, .../components/table/deployments-list.tsx
Rename active→live across props/UI; RollbackDialog now takes targetDeployment/liveDeployment, shows live domains, simplifies footer; actions popover updated to selectedDeployment/liveDeployment and rollback conditions; EnvStatusBadge variant renamed to "live"; deployments list renders environment slug and live indicator.
Dashboard data layer & TRPC
apps/dashboard/app/(app)/projects/[projectId]/deployments/hooks/use-deployments.ts, apps/dashboard/lib/collections/deploy/deployments.ts, apps/dashboard/lib/collections/deploy/domains.ts, apps/dashboard/lib/trpc/routers/deploy/deployment/rollback.ts, apps/dashboard/lib/trpc/routers/deploy/domains/list.ts
Hook now exposes liveDeployment (drops activeDeployment/Id); deployments collection adds 5s polling; domains schema adds deploymentId/sticky; rollback router switches to Connect RPC (no hostname, returns domains); domains list includes deploymentId and sticky.
Ctrl service: deployment workflow, domains, rollback, wiring
go/apps/ctrl/run.go, go/apps/ctrl/services/deployment/deploy_workflow.go, go/apps/ctrl/services/deployment/domains.go, go/apps/ctrl/services/deployment/rollback.go, go/apps/ctrl/services/routing/service.go
Removes Routing service and its registration; deployment workflow gains source-type, sticky-aware domain generation, gateway upserts include deployment_id; new DeploymentService.Rollback implements sticky-domain reassignment and project live update; routing service file deleted.
Core DB: domains/projects schema + generated
go/pkg/db/schema.sql, go/pkg/db/models_generated.go, go/pkg/db/domain_insert.sql_generated.go, go/pkg/db/bulk_domain_insert.sql_generated.go, go/pkg/db/domain_find_by_domain.sql_generated.go, go/pkg/db/domain_find_by_deployment_id.sql_generated.go, go/pkg/db/queries/domain_insert.sql, go/pkg/db/queries/domain_find_by_deployment_id.sql, go/pkg/db/queries/domain_rollback.sql, go/pkg/db/domain_rollback.sql_generated.go, go/pkg/db/project_find_by_id.sql_generated.go, go/pkg/db/querier_generated.go
Adds domains.sticky enum and is_rolled_back; extends inserts/upserts to include sticky/updated_at; find queries return sticky/is_rolled_back; adds RollBackDomain exec and types; project finder includes live_deployment_id; generated interfaces/types updated accordingly.
Partition DB: gateways schema + generated
go/pkg/partition/db/schema.sql, go/pkg/partition/db/models_generated.go, go/pkg/partition/db/gateway_upsert.sql_generated.go, go/pkg/partition/db/bulk_gateway_upsert.sql_generated.go, go/pkg/partition/db/queries/gateway_upsert.sql, go/pkg/partition/db/gateway_find_by_deployment_id.sql_generated.go, go/pkg/partition/db/queries/gateway_find_by_deployment_id.sql, go/pkg/partition/db/querier_generated.go
Adds gateways.deployment_id; upsert/bulk upsert now include deployment_id and explicit UPDATE bindings; new query to fetch latest gateway by deployment_id; generated structs/interfaces updated.
Protos & codegen
go/proto/ctrl/v1/deployment.proto, go/proto/ctrl/v1/routing.proto, go/buf.gen.yaml, internal/proto/package.json, internal/proto/src/index.ts
Adds DeploymentService.Rollback (request/response); deletes Routing proto; updates buf ES plugin to v2 and pathing; bumps protobuf TS dependency; adjusts internal exports to new generated paths and drops deployment_connect export.
Internal DB (TS schemas)
internal/db/src/schema/domains.ts, internal/db/src/schema/projects.ts
Adds sticky enum and isRolledBack boolean to domains; adds projects.activeDeployment relation pointing to liveDeploymentId.
Hydra logging
go/pkg/hydra/step.go, go/pkg/hydra/worker.go, go/pkg/hydra/workflow.go
Adds contextual logger to workflowContext and error logging on step failures; no API changes.
Infra & misc
deployment/docker-compose.yaml, dummy
Changes MinIO image tag; adds a no-op dummy file.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant UI as Dashboard UI
  participant TRPC as TRPC Router (dashboard)
  participant CTRL as Ctrl DeploymentService
  participant DB as Core DB
  participant PDB as Partition DB (gateways)

  U->>UI: Open RollbackDialog (live & target deployments)
  UI->>TRPC: mutation.deploy.rollback({ targetDeploymentId })
  TRPC->>CTRL: Rollback(project_id, target_deployment_id)
  CTRL->>DB: Validate project, live & target deployments
  CTRL->>DB: Fetch sticky domains on live
  CTRL->>PDB: Find gateway config by target deployment
  alt Eligible sticky domains
    CTRL->>PDB: Bulk upsert gateways (deployment_id, hostname, config)
    loop For each domain
      CTRL->>DB: RollBackDomain(id, target_deployment_id, is_rolled_back=true)
    end
    CTRL->>DB: Update project.live_deployment_id
    CTRL-->>TRPC: { domains }
    TRPC-->>UI: success
    UI-->>U: Show success and refetch lists
  else None eligible
    CTRL-->>TRPC: InvalidArgument error
    TRPC-->>UI: error
    UI-->>U: Show error
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested labels

Core Team, UI

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 09-18-feat_sticky_rollbacks

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c87b938 and 0a0fc84.

⛔ Files ignored due to path filters (46)
  • go/gen/proto/ctrl/v1/ctrlv1connect/deployment.connect.go is excluded by !**/gen/**
  • go/gen/proto/ctrl/v1/ctrlv1connect/routing.connect.go is excluded by !**/gen/**
  • go/gen/proto/ctrl/v1/deployment.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • go/gen/proto/ctrl/v1/routing.pb.go is excluded by !**/*.pb.go, !**/gen/**
  • internal/proto/generated/assetmanagerd/v1/asset_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/billaged/v1/billing_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/builderd/v1/builder_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/ctrl/v1/acme_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/ctrl/v1/build_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/ctrl/v1/deployment_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/ctrl/v1/openapi_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/ctrl/v1/service_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/metald/v1/deployment_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/metald/v1/metald_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/metald/v1/network_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/metald/v1/storage_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/metald/v1/vm_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/partition/v1/gateway_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/acme_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/acme_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/build_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/build_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/deployment_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/deployment_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/openapi_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/openapi_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/routing_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/routing_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/service_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/ctrl/v1/service_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/deploy/assetmanagerd/v1/asset_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/deploy/assetmanagerd/v1/asset_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/deploy/billaged/v1/billing_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/deploy/billaged/v1/billing_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/deploy/builderd/v1/builder_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/deploy/builderd/v1/builder_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/metal/vmprovisioner/v1/vmprovisioner_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/metal/vmprovisioner/v1/vmprovisioner_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/metal/vmprovisioner/v1/wip_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/partition/v1/gateway_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/vault/v1/object_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/vault/v1/service_connect.ts is excluded by !**/generated/**
  • internal/proto/generated/proto/vault/v1/service_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/vault/v1/object_pb.ts is excluded by !**/generated/**
  • internal/proto/generated/vault/v1/service_pb.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (47)
  • apps/dashboard/app/(app)/projects/[projectId]/deployments/components/rollback-dialog.tsx (4 hunks)
  • apps/dashboard/app/(app)/projects/[projectId]/deployments/components/table/components/actions/deployment-list-table-action.popover.constants.tsx (1 hunks)
  • 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/hooks/use-deployments.ts (2 hunks)
  • apps/dashboard/lib/collections/deploy/deployments.ts (1 hunks)
  • apps/dashboard/lib/collections/deploy/domains.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/deploy/deployment/rollback.ts (2 hunks)
  • apps/dashboard/lib/trpc/routers/deploy/domains/list.ts (1 hunks)
  • deployment/docker-compose.yaml (1 hunks)
  • dummy (1 hunks)
  • go/apps/ctrl/run.go (0 hunks)
  • go/apps/ctrl/services/deployment/deploy_workflow.go (6 hunks)
  • go/apps/ctrl/services/deployment/domains.go (1 hunks)
  • go/apps/ctrl/services/deployment/rollback.go (1 hunks)
  • go/apps/ctrl/services/routing/service.go (0 hunks)
  • go/buf.gen.yaml (1 hunks)
  • go/pkg/db/bulk_domain_insert.sql_generated.go (3 hunks)
  • go/pkg/db/domain_find_by_deployment_id.sql_generated.go (4 hunks)
  • go/pkg/db/domain_find_by_domain.sql_generated.go (2 hunks)
  • go/pkg/db/domain_insert.sql_generated.go (3 hunks)
  • go/pkg/db/domain_rollback.sql_generated.go (1 hunks)
  • go/pkg/db/models_generated.go (2 hunks)
  • go/pkg/db/project_find_by_id.sql_generated.go (4 hunks)
  • go/pkg/db/querier_generated.go (5 hunks)
  • go/pkg/db/queries/domain_find_by_deployment_id.sql (1 hunks)
  • go/pkg/db/queries/domain_insert.sql (1 hunks)
  • go/pkg/db/queries/domain_rollback.sql (1 hunks)
  • go/pkg/db/queries/project_find_by_id.sql (1 hunks)
  • go/pkg/db/schema.sql (1 hunks)
  • go/pkg/hydra/step.go (3 hunks)
  • go/pkg/hydra/worker.go (1 hunks)
  • go/pkg/hydra/workflow.go (3 hunks)
  • go/pkg/partition/db/bulk_gateway_upsert.sql_generated.go (3 hunks)
  • go/pkg/partition/db/gateway_find_by_deployment_id.sql_generated.go (1 hunks)
  • go/pkg/partition/db/gateway_upsert.sql_generated.go (1 hunks)
  • go/pkg/partition/db/models_generated.go (1 hunks)
  • go/pkg/partition/db/querier_generated.go (2 hunks)
  • go/pkg/partition/db/queries/gateway_find_by_deployment_id.sql (1 hunks)
  • go/pkg/partition/db/queries/gateway_upsert.sql (1 hunks)
  • go/pkg/partition/db/schema.sql (1 hunks)
  • go/proto/ctrl/v1/deployment.proto (1 hunks)
  • go/proto/ctrl/v1/routing.proto (0 hunks)
  • internal/db/src/schema/domains.ts (2 hunks)
  • internal/db/src/schema/projects.ts (1 hunks)
  • internal/proto/package.json (1 hunks)
  • internal/proto/src/index.ts (1 hunks)

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 19, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.
Here is an example:

<type>[optional scope]: <description>
fix: I fixed something for Unkey

Details:

No release type found in pull request title "09 18 feat sticky rollbacks". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat: A new feature
 - fix: A bug fix
 - docs: Documentation only changes
 - style: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
 - refactor: A code change that neither fixes a bug nor adds a feature
 - perf: A code change that improves performance
 - test: Adding missing tests or correcting existing tests
 - build: Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)
 - ci: Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)
 - chore: Other changes that don't modify src or test files
 - revert: Reverts a previous commit

@chronark chronark deleted the 09-18-feat_sticky_rollbacks branch November 5, 2025 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant