Commit b97c021
feat: deployment approval UI and backend handlers (#5256)
* feat: deployment approval UI and backend handlers
Add the complete approval/rejection flow for gated deployments:
Backend (ctrl service):
- Add ApproveDeployment and RejectDeployment RPCs to DeployService proto
- Implement approve handler: validates status, updates to pending, records
approval, triggers deploy workflow via Restate
- Implement reject handler: validates status, updates to failed
- Add FindAppBuildSettingByAppEnv SQL query for approval flow
Dashboard:
- Add awaiting_approval to deployment status badges, filters, and collection
- Add DeploymentApprovalBanner component with approve/reject buttons
- Show banner on deployment detail page when awaiting approval
- Add tRPC mutations for approve/reject calling ctrl service
- Add deployment.approve and deployment.reject audit log events
* feat: add rejected status to dashboard UI
- Add 'rejected' to deployment status badges, filters, and collections
- Add DeploymentRejectedBanner with red error styling
- Show rejected banner on deployment detail page
- Add rejected to grouped status filter with error color
* feat: dashboard authorize page and cleanup old approval UI
Remove deployment approval/rejection banners, status badge configs,
filter options, and tRPC routes for awaiting_approval/rejected statuses.
Add /projects/[projectId]/authorize page that reads branch from URL
params and calls AuthorizeDeployment RPC. Add authorize tRPC route.
* fix: use correct Loading import from @unkey/ui
* fix: pass through actual error message from ctrl service
* fix: add GitHub App credentials to ctrl-api config
The ctrl API needs GitHub App credentials to fetch branch HEAD
when authorizing deployments from external contributors.
* fix: remove stale approval/rejected statuses, extract shared ctrl client
- Remove awaiting_approval and rejected from deployment statuses, filters,
and status badge configs (no longer used — authorization is handled via
GitHub Check Runs, not deployment status)
- Remove deployment.approve and deployment.reject audit log events
- Delete unused duplicate deployment-status-badge.tsx in table components
- Fix broken page.tsx referencing undefined awaitingApproval/rejected vars
- Extract createCtrlClient helper to deduplicate identical ctrl client
creation boilerplate across 9 trpc router files
* feat: redesign deployment authorization page
Centered layout with GitHub + shield icons, commit details card showing
branch/SHA/message/sender from URL query params, proper Button components,
success/error states, and non-member handling hint.
* feat: link branch, commit SHA, and sender to GitHub on authorize page
* refactor: use nuqs for authorize page search params, remove null fallbacks
* fix: pass commit SHA through authorization flow and validate on frontend
Frontend now validates SHA format (40-char hex) before allowing authorization
and passes it to the backend which verifies it matches the branch HEAD.
* feat: show dedicated stale commit UI when branch has moved
Instead of a generic error, show a clear message explaining the branch
has new commits and direct the user to GitHub to find the latest
authorization link.
* feat: redirect to latest commit authorization when stale
Instead of telling the user to check GitHub, parse the new HEAD SHA
from the backend error and offer a direct "View Latest Commit" button
that navigates to the updated authorize page.
* fix: reset mutation state before navigating to latest commit
* fix: resolve TypeScript null check on authorize.error
* fix: use optional chain instead of non-null assertion for biome lint
* [autofix.ci] apply automated fixes
* feat: rewrite authorize page to use deploymentId, fetch deployment from DB
- Rewrite authorize page to take single deploymentId search param
- Fetch deployment details from DB via getById instead of URL params
- Handle awaiting_approval, already authorized, and failed states
- Simplify authorize mutation input to just deploymentId
- Add gitCommitMessage, gitCommitAuthorHandle, gitCommitAuthorAvatarUrl, projectId to getById response
- Register getById in tRPC router
* fix: replace dots with X icon in authorization connection indicator
* feat: move approval UI inline on deployment detail page
Replace the separate /authorize page with an inline DeploymentApproval
component shown when deployment status is awaiting_approval. Delete the
standalone authorize page. Add awaiting_approval to deriveStatusFromSteps
valid statuses so it doesn't fall back to pending.
* [autofix.ci] apply automated fixes
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>1 parent 4ea5d2e commit b97c021
File tree
17 files changed
+296
-205
lines changed- dev
- config
- k8s/manifests
- web/apps/dashboard
- app/(app)/[workspaceSlug]/projects/[projectId]/(overview)/deployments/[deploymentId]
- (deployment-progress)
- lib
- trpc/routers
- deploy
- custom-domains
- deployment
17 files changed
+296
-205
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
| 18 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
27 | 29 | | |
28 | 30 | | |
29 | 31 | | |
| |||
70 | 72 | | |
71 | 73 | | |
72 | 74 | | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
73 | 87 | | |
74 | 88 | | |
75 | 89 | | |
| |||
Lines changed: 126 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
Lines changed: 6 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
20 | 21 | | |
21 | 22 | | |
22 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
23 | 29 | | |
24 | 30 | | |
25 | 31 | | |
| |||
Lines changed: 14 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
15 | 16 | | |
16 | 17 | | |
17 | 18 | | |
| 19 | + | |
18 | 20 | | |
19 | 21 | | |
20 | 22 | | |
21 | | - | |
| 23 | + | |
22 | 24 | | |
23 | 25 | | |
24 | 26 | | |
| |||
33 | 35 | | |
34 | 36 | | |
35 | 37 | | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
36 | 49 | | |
37 | 50 | | |
38 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
Lines changed: 3 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | | - | |
4 | 4 | | |
5 | | - | |
6 | | - | |
| 5 | + | |
7 | 6 | | |
8 | 7 | | |
9 | 8 | | |
| |||
17 | 16 | | |
18 | 17 | | |
19 | 18 | | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
| 19 | + | |
27 | 20 | | |
28 | 21 | | |
29 | 22 | | |
| |||
60 | 53 | | |
61 | 54 | | |
62 | 55 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | 56 | | |
77 | 57 | | |
78 | 58 | | |
| |||
Lines changed: 2 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | | - | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | 5 | | |
8 | 6 | | |
9 | 7 | | |
| |||
16 | 14 | | |
17 | 15 | | |
18 | 16 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
| 17 | + | |
26 | 18 | | |
27 | 19 | | |
28 | 20 | | |
| |||
60 | 52 | | |
61 | 53 | | |
62 | 54 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | 55 | | |
77 | 56 | | |
78 | 57 | | |
| |||
Lines changed: 2 additions & 23 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | | - | |
4 | 4 | | |
5 | | - | |
6 | | - | |
7 | 5 | | |
8 | 6 | | |
9 | 7 | | |
| |||
16 | 14 | | |
17 | 15 | | |
18 | 16 | | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
| 17 | + | |
26 | 18 | | |
27 | 19 | | |
28 | 20 | | |
| |||
60 | 52 | | |
61 | 53 | | |
62 | 54 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | 55 | | |
77 | 56 | | |
78 | 57 | | |
| |||
0 commit comments