Skip to content

feat: allow triggering initial deploy from dashboard#5166

Merged
ogzhanolguncu merged 4 commits intomainfrom
trigger-deploy
Mar 3, 2026
Merged

feat: allow triggering initial deploy from dashboard#5166
ogzhanolguncu merged 4 commits intomainfrom
trigger-deploy

Conversation

@ogzhanolguncu
Copy link
Contributor

@ogzhanolguncu ogzhanolguncu commented Mar 2, 2026

What does this PR do?

Adds support for unauthenticated deployments from public GitHub repositories. This enables deployments from public repos without requiring GitHub App installation or authentication.

The changes include:

  • Added GetBranchHeadCommitPublic method to GitHub client interface and implementations that uses the public GitHub API without authentication
  • Modified deployment handler to use the public API when allowUnauthenticatedDeployments is enabled
  • Enhanced project onboarding flow with a functional "Deploy" button that triggers actual deployments
  • Added new tRPC endpoint deployment.create for triggering deployments from the frontend
  • Fixed project creation flow to properly return the created project ID
  • Added deployment.create audit log event type

Fixes # (issue)

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test creating a new project through the onboarding flow and verify the project ID is properly returned
  • Test the deployment creation functionality by clicking the "Deploy" button in the onboarding flow
  • Test deployment from a public GitHub repository without GitHub App authentication
  • Verify that the public GitHub API is used when allowUnauthenticatedDeployments is enabled
  • Test that audit logs are properly created for deployment creation events

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Ran make fmt on /go directory
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

@vercel
Copy link

vercel bot commented Mar 2, 2026

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

Project Deployment Actions Updated (UTC)
dashboard Ready Ready Preview, Comment Mar 3, 2026 4:20pm

Request Review

This was referenced Mar 2, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

This change adds support for unauthenticated deployments and implements a complete deployment creation flow. Backend support for public GitHub API access enables unauthenticated branch lookups. A new TRPC mutation endpoint with rate limiting, external control service integration, and audit logging enables dashboard-based deployment creation. Project creation is simplified to use transaction metadata for project ID retrieval.

Changes

Cohort / File(s) Summary
GitHub Public API Support
svc/ctrl/worker/github/interface.go, svc/ctrl/worker/github/client.go, svc/ctrl/worker/github/noop.go, svc/ctrl/worker/deploy/deploy_handler.go
Added GetBranchHeadCommitPublic method to retrieve branch HEAD commits via unauthenticated public GitHub API. Deploy handler now conditionally uses public API when allowUnauthenticatedDeployments is enabled.
Deployment Creation Endpoint
web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts, web/apps/dashboard/lib/trpc/routers/index.ts
New TRPC mutation endpoint for creating deployments with input validation, rate limiting, external control service integration, error handling, and audit log recording. Endpoint is wired into the deployment router.
Dashboard Deployment UI
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/onboarding/steps/configure-deployment.tsx
Integrated deployment mutation into the configure-deployment component with workspace navigation, success/error toast notifications, loading states, and proper routing after deployment creation.
Project Creation Flow Optimization
web/apps/dashboard/app/(app)/[workspaceSlug]/projects/onboarding/steps/create-project.tsx, web/apps/dashboard/lib/collections/deploy/projects.ts
Simplified project creation to retrieve the new project ID from transaction metadata instead of database lookup. Collections handler now captures projectId in metadata from mutation result.
Audit Logging Schema
web/internal/schema/src/auditlog.ts
Added "deployment.create" event type to the audit log events enum.

Sequence Diagram(s)

sequenceDiagram
    participant User as User
    participant Dashboard as Dashboard UI
    participant TRPC as TRPC Server
    participant CtrlSvc as Control Service
    participant DB as Database
    participant AuditLog as Audit Log

    User->>Dashboard: Click Deploy
    Dashboard->>TRPC: deploy.deployment.create(projectId, environmentSlug)
    TRPC->>TRPC: Validate input & check rate limit
    TRPC->>DB: Resolve project by projectId
    TRPC->>CtrlSvc: Create deployment request
    CtrlSvc-->>TRPC: deploymentId
    TRPC->>AuditLog: Log "deployment.create" event
    TRPC-->>Dashboard: Return deploymentId
    Dashboard->>Dashboard: Invalidate deployments query
    Dashboard->>Dashboard: Show success toast
    Dashboard->>Dashboard: Navigate to deployment page
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main feature: allowing initial deployments to be triggered from the dashboard, which matches the core changes across frontend and backend components.
Description check ✅ Passed The PR description covers the main changes, objectives, testing instructions, and includes the type of change selection; however, most required checklist items remain unchecked and 'Fixes #' lacks an issue number.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch trigger-deploy

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.5.0)

Command failed


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

@ogzhanolguncu ogzhanolguncu mentioned this pull request Mar 2, 2026
19 tasks
@ogzhanolguncu ogzhanolguncu marked this pull request as ready for review March 2, 2026 17:18
@ogzhanolguncu ogzhanolguncu force-pushed the update-all-env-settings branch from d46f025 to 09b4777 Compare March 2, 2026 17:50
@ogzhanolguncu ogzhanolguncu force-pushed the update-all-env-settings branch from 09b4777 to aa3d88f Compare March 2, 2026 17:55
@ogzhanolguncu ogzhanolguncu force-pushed the update-all-env-settings branch from aa3d88f to c654a92 Compare March 2, 2026 18:03
@ogzhanolguncu ogzhanolguncu force-pushed the update-all-env-settings branch from c790e8d to 61a2959 Compare March 3, 2026 09:54
@graphite-app graphite-app bot changed the base branch from graphite-base/5166 to main March 3, 2026 14:25
@graphite-app
Copy link

graphite-app bot commented Mar 3, 2026

Merge activity

  • Mar 3, 2:25 PM UTC: Graphite rebased this pull request, because this pull request is set to merge when ready.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@svc/ctrl/worker/github/noop.go`:
- Around line 35-78: The Noop GetBranchHeadCommitPublic implementation violates
the Noop contract by performing real HTTP requests; change
Noop.GetBranchHeadCommitPublic to behave like other Noop methods and immediately
return an error instead of making network calls. Replace the body in
Noop.GetBranchHeadCommitPublic to return a suitable fault (e.g., fault.New("noop
client: operation not supported", fault.Internal("no-op github client")), or a
consistent sentinel error) and zero-value CommitInfo, or alternatively move the
current HTTP logic into the real GitHub client implementation (e.g., the
non-Noop type) and keep Noop as a pure error-returning stub; ensure refs to
CommitInfo, GetBranchHeadCommitPublic and Noop are updated accordingly.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/onboarding/steps/create-project.tsx:
- Line 54: Replace the unsafe type assertion on tx.metadata with a runtime type
guard: create a small predicate (e.g., isProjectMetadata(obj): obj is {
projectId: string }) that checks obj is non-null and typeof obj.projectId ===
"string", use it to validate tx.metadata then call onProjectCreated(projectId)
when valid, and handle the error/early-return when the check fails; reference
the existing onProjectCreated call and tx.metadata to locate where to apply the
guard.

In `@web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts`:
- Line 14: The createDeploy router is wired to the wrong rate-limit bucket:
replace the call using ratelimit.update with the create bucket so create traffic
is tracked correctly; locate the chain where createDeploy applies middleware
(.use(withRatelimit(ratelimit.update))) and change it to use ratelimit.create
(i.e., .use(withRatelimit(ratelimit.create))) so the createDeploy mutation
consumes from the create quota/telemetry.
- Around line 57-67: The inline .catch on the promise returned by
ctrl.createDeployment should be removed so raw Error objects aren't passed into
TRPCError; instead return the awaited result directly from createDeployment and
allow the surrounding try/catch (the outer catch that constructs a sanitized
TRPCError) to handle failures. Locate the call to ctrl.createDeployment in the
create-deploy handler and delete the chained .catch(...) block (including
console.error and the TRPCError construction) so that any thrown error bubbles
to the existing outer catch which already converts unknown errors to a safe
string message.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 656a0b6 and 7cbb92d.

📒 Files selected for processing (10)
  • svc/ctrl/worker/deploy/deploy_handler.go
  • svc/ctrl/worker/github/client.go
  • svc/ctrl/worker/github/interface.go
  • svc/ctrl/worker/github/noop.go
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/onboarding/steps/configure-deployment.tsx
  • web/apps/dashboard/app/(app)/[workspaceSlug]/projects/onboarding/steps/create-project.tsx
  • web/apps/dashboard/lib/collections/deploy/projects.ts
  • web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts
  • web/apps/dashboard/lib/trpc/routers/index.ts
  • web/internal/schema/src/auditlog.ts

Comment on lines +35 to +78

// GetBranchHeadCommitPublic retrieves the HEAD commit using the public GitHub
// API without authentication. Works for public repositories even when GitHub
// App credentials are not configured.
func (n *Noop) GetBranchHeadCommitPublic(repo string, branch string) (CommitInfo, error) {
httpClient := &http.Client{Timeout: 30 * time.Second}

requestURL := fmt.Sprintf("https://api.github.com/repos/%s/commits/%s", repo, url.PathEscape(branch))

req, err := http.NewRequest(http.MethodGet, requestURL, nil)
if err != nil {
return CommitInfo{}, fault.Wrap(err, fault.Internal("failed to create request"))
}

req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("X-GitHub-Api-Version", "2022-11-28")

resp, err := httpClient.Do(req)
if err != nil {
return CommitInfo{}, fault.Wrap(err, fault.Internal("failed to fetch branch head commit"))
}
defer func() { _ = resp.Body.Close() }()

if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return CommitInfo{}, fault.New(
"failed to fetch branch head commit (public)",
fault.Internal(fmt.Sprintf("status %d: %s", resp.StatusCode, string(body))),
)
}

var commit ghCommitResponse
if err := json.NewDecoder(resp.Body).Decode(&commit); err != nil {
return CommitInfo{}, fault.Wrap(err, fault.Internal("failed to decode commit response"))
}

return CommitInfoFromRaw(
commit.SHA,
commit.Commit.Message,
commit.Author.Login,
commit.Author.AvatarURL,
commit.Commit.Author.Date,
), nil
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Noop implementation makes real HTTP calls, contradicting its documented purpose.

The Noop struct is documented as "returns errors for all operations" (line 14), but GetBranchHeadCommitPublic performs actual HTTP requests. This breaks the expected contract where Noop should be safe to use when GitHub credentials aren't configured without making external calls.

Consider either:

  1. Return an error like other Noop methods if this behavior is unintended
  2. Rename/restructure to clarify that this client can make unauthenticated calls even without credentials
Option 1: Return error like other Noop methods
 func (n *Noop) GetBranchHeadCommitPublic(repo string, branch string) (CommitInfo, error) {
-	httpClient := &http.Client{Timeout: 30 * time.Second}
-	// ... full implementation ...
+	return CommitInfo{}, fault.New("GitHub client not configured: use Client for public repository access")
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// GetBranchHeadCommitPublic retrieves the HEAD commit using the public GitHub
// API without authentication. Works for public repositories even when GitHub
// App credentials are not configured.
func (n *Noop) GetBranchHeadCommitPublic(repo string, branch string) (CommitInfo, error) {
httpClient := &http.Client{Timeout: 30 * time.Second}
requestURL := fmt.Sprintf("https://api.github.com/repos/%s/commits/%s", repo, url.PathEscape(branch))
req, err := http.NewRequest(http.MethodGet, requestURL, nil)
if err != nil {
return CommitInfo{}, fault.Wrap(err, fault.Internal("failed to create request"))
}
req.Header.Set("Accept", "application/vnd.github+json")
req.Header.Set("X-GitHub-Api-Version", "2022-11-28")
resp, err := httpClient.Do(req)
if err != nil {
return CommitInfo{}, fault.Wrap(err, fault.Internal("failed to fetch branch head commit"))
}
defer func() { _ = resp.Body.Close() }()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return CommitInfo{}, fault.New(
"failed to fetch branch head commit (public)",
fault.Internal(fmt.Sprintf("status %d: %s", resp.StatusCode, string(body))),
)
}
var commit ghCommitResponse
if err := json.NewDecoder(resp.Body).Decode(&commit); err != nil {
return CommitInfo{}, fault.Wrap(err, fault.Internal("failed to decode commit response"))
}
return CommitInfoFromRaw(
commit.SHA,
commit.Commit.Message,
commit.Author.Login,
commit.Author.AvatarURL,
commit.Commit.Author.Date,
), nil
}
// GetBranchHeadCommitPublic retrieves the HEAD commit using the public GitHub
// API without authentication. Works for public repositories even when GitHub
// App credentials are not configured.
func (n *Noop) GetBranchHeadCommitPublic(repo string, branch string) (CommitInfo, error) {
return CommitInfo{}, fault.New("GitHub client not configured: use Client for public repository access")
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@svc/ctrl/worker/github/noop.go` around lines 35 - 78, The Noop
GetBranchHeadCommitPublic implementation violates the Noop contract by
performing real HTTP requests; change Noop.GetBranchHeadCommitPublic to behave
like other Noop methods and immediately return an error instead of making
network calls. Replace the body in Noop.GetBranchHeadCommitPublic to return a
suitable fault (e.g., fault.New("noop client: operation not supported",
fault.Internal("no-op github client")), or a consistent sentinel error) and
zero-value CommitInfo, or alternatively move the current HTTP logic into the
real GitHub client implementation (e.g., the non-Noop type) and keep Noop as a
pure error-returning stub; ensure refs to CommitInfo, GetBranchHeadCommitPublic
and Noop are updated accordingly.

if (created) {
onProjectCreated(created.id);
}
onProjectCreated((tx.metadata as { projectId: string }).projectId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Avoid type assertion as Type per coding guidelines.

The as { projectId: string } cast bypasses type safety. Consider using runtime validation or defining a proper type for the transaction metadata.

Proposed fix using runtime check
-      onProjectCreated((tx.metadata as { projectId: string }).projectId);
+      const metadata = tx.metadata;
+      if (metadata && typeof metadata === "object" && "projectId" in metadata && typeof metadata.projectId === "string") {
+        onProjectCreated(metadata.projectId);
+      } else {
+        throw new Error("Project creation failed: missing projectId in response");
+      }

As per coding guidelines: "Never compromise type safety: No any, no ! (non-null assertion), no as Type"

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onProjectCreated((tx.metadata as { projectId: string }).projectId);
const metadata = tx.metadata;
if (metadata && typeof metadata === "object" && "projectId" in metadata && typeof metadata.projectId === "string") {
onProjectCreated(metadata.projectId);
} else {
throw new Error("Project creation failed: missing projectId in response");
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@web/apps/dashboard/app/`(app)/[workspaceSlug]/projects/onboarding/steps/create-project.tsx
at line 54, Replace the unsafe type assertion on tx.metadata with a runtime type
guard: create a small predicate (e.g., isProjectMetadata(obj): obj is {
projectId: string }) that checks obj is non-null and typeof obj.projectId ===
"string", use it to validate tx.metadata then call onProjectCreated(projectId)
when valid, and handle the error/early-return when the check fails; reference
the existing onProjectCreated call and tx.metadata to locate where to apply the
guard.

import { z } from "zod";

export const createDeploy = workspaceProcedure
.use(withRatelimit(ratelimit.update))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use the create rate-limit bucket for this create mutation.

createDeploy currently uses ratelimit.update, which can skew quota behavior/telemetry for create traffic. Prefer ratelimit.create here.

Suggested surgical change
 export const createDeploy = workspaceProcedure
-  .use(withRatelimit(ratelimit.update))
+  .use(withRatelimit(ratelimit.create))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.use(withRatelimit(ratelimit.update))
.use(withRatelimit(ratelimit.create))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts` at
line 14, The createDeploy router is wired to the wrong rate-limit bucket:
replace the call using ratelimit.update with the create bucket so create traffic
is tracked correctly; locate the chain where createDeploy applies middleware
(.use(withRatelimit(ratelimit.update))) and change it to use ratelimit.create
(i.e., .use(withRatelimit(ratelimit.create))) so the createDeploy mutation
consumes from the create quota/telemetry.

Comment on lines +57 to +67
const result = await ctrl
.createDeployment({
projectId: input.projectId,
environmentSlug: input.environmentSlug,
})
.catch((err) => {
console.error(err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: err,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Read the create-deploy.ts file to see the full context
cat -n web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts

Repository: unkeyed/unkey

Length of output: 3546


🏁 Script executed:

# Check for fault library usage in TRPC routers
rg -l 'fault' web/apps/dashboard/lib/trpc/routers/ --type ts | head -20

Repository: unkeyed/unkey

Length of output: 1296


🏁 Script executed:

# Inspect error handling patterns in this specific file
rg -nP 'TRPCError|catch|fault' web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts

Repository: unkeyed/unkey

Length of output: 328


🏁 Script executed:

# Verify the error flow - check if removing inner catch would work properly
# Look at other TRPC routers to see if they use similar patterns

rg -A8 'createClient|DeployService' web/apps/dashboard/lib/trpc/routers/ -t ts | head -50

Repository: unkeyed/unkey

Length of output: 4796


🏁 Script executed:

# Check if fault library is being used in error handling across TRPC routers
# and what the pattern looks like

rg -B2 -A5 'from.*fault|import.*fault' web/apps/dashboard/lib/trpc/routers/ --type ts | head -60

Repository: unkeyed/unkey

Length of output: 2537


🏁 Script executed:

# Check if fault library is actually used in the codebase at all
rg -l 'fault' web/apps/dashboard/lib --type ts | head -30

Repository: unkeyed/unkey

Length of output: 1905


🏁 Script executed:

# Check the lib directory structure to see where fault might be
fd -t f 'fault' web/apps/dashboard/lib 2>/dev/null | head -20

Repository: unkeyed/unkey

Length of output: 175


🏁 Script executed:

# Search for fault library package or configuration
rg 'fault' web/apps/dashboard/package.json web/package.json

Repository: unkeyed/unkey

Length of output: 39


🏁 Script executed:

# Check if fault is imported anywhere in the codebase with different patterns
rg 'import.*from.*fault|from.*fault|require.*fault' web/apps/dashboard --type ts

Repository: unkeyed/unkey

Length of output: 1590


🏁 Script executed:

# Check the actual fault files to see what they contain
cat -n web/apps/dashboard/lib/zod-helper.ts | head -50

Repository: unkeyed/unkey

Length of output: 1777


🏁 Script executed:

# Look for error handling in similar TRPC routers without the inner catch pattern
rg -B5 -A10 'catch \(error\)' web/apps/dashboard/lib/trpc/routers/deploy/ --type ts -A5 | head -80

Repository: unkeyed/unkey

Length of output: 7126


🏁 Script executed:

# Double-check lines 86-95 are actually correct and not problematic
sed -n '86,96p' web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts

Repository: unkeyed/unkey

Length of output: 359


🏁 Script executed:

# Check if there are any other inner .catch() patterns with message: err in this file
rg -n '\.catch\(' web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts -A3

Repository: unkeyed/unkey

Length of output: 199


Remove the inner .catch() to prevent raw error propagation through TRPC.

At line 66, message: err passes a raw error object that can leak control-plane internals and violates type safety (TRPCError expects a string message). The outer catch block (lines 86–95) already handles this correctly by sanitizing unknown errors with a generic message. Let the outer catch handle all errors from the createDeployment call.

Suggested change
-      const result = await ctrl
-        .createDeployment({
-          projectId: input.projectId,
-          environmentSlug: input.environmentSlug,
-        })
-        .catch((err) => {
-          console.error(err);
-          throw new TRPCError({
-            code: "INTERNAL_SERVER_ERROR",
-            message: err,
-          });
-        });
+      const result = await ctrl.createDeployment({
+        projectId: input.projectId,
+        environmentSlug: input.environmentSlug,
+      });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = await ctrl
.createDeployment({
projectId: input.projectId,
environmentSlug: input.environmentSlug,
})
.catch((err) => {
console.error(err);
throw new TRPCError({
code: "INTERNAL_SERVER_ERROR",
message: err,
});
const result = await ctrl.createDeployment({
projectId: input.projectId,
environmentSlug: input.environmentSlug,
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/apps/dashboard/lib/trpc/routers/deploy/deployment/create-deploy.ts`
around lines 57 - 67, The inline .catch on the promise returned by
ctrl.createDeployment should be removed so raw Error objects aren't passed into
TRPCError; instead return the awaited result directly from createDeployment and
allow the surrounding try/catch (the outer catch that constructs a sanitized
TRPCError) to handle failures. Locate the call to ctrl.createDeployment in the
create-deploy handler and delete the chained .catch(...) block (including
console.error and the TRPCError construction) so that any thrown error bubbles
to the existing outer catch which already converts unknown errors to a safe
string message.

Merged via the queue into main with commit cc6078a Mar 3, 2026
14 checks passed
@ogzhanolguncu ogzhanolguncu deleted the trigger-deploy branch March 3, 2026 16:34
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.

3 participants