Skip to content

feat(deploy): added deploy wizard#260

Draft
wyattjoh wants to merge 24 commits into
mainfrom
wyattjoh/deploy
Draft

feat(deploy): added deploy wizard#260
wyattjoh wants to merge 24 commits into
mainfrom
wyattjoh/deploy

Conversation

@wyattjoh
Copy link
Copy Markdown
Contributor

@wyattjoh wyattjoh commented May 6, 2026

Summary

Adds clerk deploy, an interactive wizard that promotes a linked Clerk application from development to production. The wizard validates clone compatibility, creates the production instance and primary domain, walks the user through the returned CNAME records (with optional BIND zone export to ./clerk-<domain>.zone), verifies DNS/SSL/mail with a per-component spinner chain, and collects production OAuth credentials for Google, GitHub, Microsoft, Apple, and Linear.

State is derived from the Platform API on each run, not persisted locally. The wizard reads the live application, domains, deploy status, and instance config on entry and resumes from the next pending step. The only profile write is instances.production once the production instance exists. Pressing Ctrl-C or picking "Skip" at an OAuth provider exits with Deploy paused and exit code 1; rerunning resumes from whatever the API now reports.

Platform API errors specific to the deploy lifecycle are mapped to typed CliErrors in commands/deploy/errors.ts (unsupported plan features, provider/taken domains, production_instance_exists recovery, SSL/mail retry throttles). The wizard refuses to start in agent mode because production configuration is interactive.

Test plan

  • bun run format:check
  • bun run lint
  • bun run typecheck
  • bun run test
  • bun run test:e2e:op
  • Manual smoke: unlinked directory exits with error: No Clerk project linked; linked directory walks through create → DNS records → BIND export → verification → OAuth → production summary; Ctrl-C at OAuth exits with Deploy paused and exit code 1; rerun resumes at the skipped provider.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 6, 2026

🦋 Changeset detected

Latest commit: c749d58

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
clerk Minor

Not sure what this means? Click here to learn what changesets are.

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

@wyattjoh
Copy link
Copy Markdown
Contributor Author

!snapshot

@github-actions
Copy link
Copy Markdown
Contributor

Snapshot published

npm install -g clerk@1.3.1-snapshot.0dd30be
Package Version
clerk 1.3.1-snapshot.0dd30be

Published from 0dd30be

@wyattjoh wyattjoh changed the base branch from main to wyattjoh/api-error-classification May 13, 2026 22:30
@wyattjoh
Copy link
Copy Markdown
Contributor Author

wyattjoh commented May 13, 2026

Stack: wyattjoh/deploy

Part of a stacked-prs chain. Do not merge manually.

@wyattjoh wyattjoh force-pushed the wyattjoh/api-error-classification branch from 93d7a24 to bf05f3e Compare May 19, 2026 13:55
@wyattjoh wyattjoh force-pushed the wyattjoh/api-error-classification branch from bf05f3e to ffb869f Compare May 21, 2026 06:40
@wyattjoh wyattjoh force-pushed the wyattjoh/deploy branch 2 times, most recently from a3d8b46 to 7e6819c Compare May 21, 2026 15:26
@wyattjoh wyattjoh force-pushed the wyattjoh/api-error-classification branch from ffb869f to 162f269 Compare May 21, 2026 15:26
Base automatically changed from wyattjoh/api-error-classification to main May 21, 2026 19:21
wyattjoh and others added 13 commits May 21, 2026 13:22
- Preserve completed providers when pausing OAuth setup mid-loop, so
  `clerk deploy --continue` can finish multi-provider stacks.
- Surface a warning for OAuth providers enabled in dev that the wizard
  does not yet support, instead of silently skipping them.
- Close the gutter as Paused (not Failed) when DNS verification times
  out, since the state is recoverable via --continue.
- Tighten the production-domain regex to reject malformed inputs like
  example..com or example-.com before they reach the API.
Move deploy lifecycle endpoint wrappers into the shared PLAPI client while routing the deploy wizard through a command-local adapter that defaults to mocked operations until the backend endpoints are ready.
Switch the deploy command from the in-process mock lifecycle to the live
PLAPI endpoints. Add a typed error mapper that translates known PLAPI
failures (plan_insufficient, home_url_taken, ssl_retry_throttled, etc.)
into CliError with stable codes, with a recovery path for the
production_instance_exists case so the wizard re-derives state instead
of surfacing the error.

Surface per-component progress (DNS / SSL / mail) during deploy_status
polling, and drop the four hidden --test-fail-* CLI options now that
failure injection is routed through the test's module mock.

Collapse the api/mock indirection layer to a thin re-export of the
plapi endpoints + a no-op configureMockDeployApi stub for the test
seam, and strip the dead mockDeployApi implementation that the
indirection used to back.
Swap the "Continue to OAuth setup?" yes/no prompt during initial
production setup for the same verify/skip select used when resuming.
Choosing skip records DNS as pending and continues to OAuth instead of
pausing the deploy, so the dashboard remains the single place to monitor
propagation.
- Tolerate getDeployStatus failures inside the reconcile-path snapshot
  read so the deploy continues to the verify-or-skip prompt instead of
  failing before the user can react.
- Split the snapshot fetch into separate "Reading development
  configuration" and "Reading production configuration" spinners so the
  gutter reflects what is actually being loaded.
- Add triggerDomainDnsCheck (POST .../dns_check) and call it best-effort
  when the user picks "Check DNS now" so an active check job is kicked
  rather than waiting on background reconciliation.
- Type the dns_ok/ssl_ok/mail_ok booleans on DeployStatusResponse and use
  them to name the specific pending component in the timeout warning.
Switch deploy command imports back to lib/plapi.ts directly and remove the
./mock.ts harness plus the --test-force-* / --test-fail-* CLI flags it
backed. The wrappers were added for an earlier mockable-deploy-API
experiment that is no longer needed.
wyattjoh added 9 commits May 21, 2026 13:22
Replace the single-spinner pollDeployStatus loop with a chained
mail/dns/ssl spinner sequence that emits a per-component success
line as each boolean flips true. Add a defensive status === "complete"
check after all three components succeed so the proxy_ok server-side
case fails closed rather than reporting verified. When all DNS
components are resolved but the server has not yet marked the
deployment complete, exit the verification path without reaching
finishDeploy.
After the DNS records block in both runDnsSetup and
runExistingDomainDnsVerification, prompt the user (default: no) to
export the records as a clerk-<domain>.zone BIND zone file.
@wyattjoh wyattjoh marked this pull request as ready for review May 21, 2026 19:23
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b5319cf2-d0cc-43c7-8983-aaade6b6105f

📥 Commits

Reviewing files that changed from the base of the PR and between 337e796 and f65cea4.

📒 Files selected for processing (19)
  • .changeset/deploy-wizard.md
  • README.md
  • packages/cli-core/src/cli-program.test.ts
  • packages/cli-core/src/cli-program.ts
  • packages/cli-core/src/commands/deploy/README.md
  • packages/cli-core/src/commands/deploy/copy.test.ts
  • packages/cli-core/src/commands/deploy/copy.ts
  • packages/cli-core/src/commands/deploy/domain-connect.ts
  • packages/cli-core/src/commands/deploy/errors.ts
  • packages/cli-core/src/commands/deploy/index.test.ts
  • packages/cli-core/src/commands/deploy/index.ts
  • packages/cli-core/src/commands/deploy/prompts.ts
  • packages/cli-core/src/commands/deploy/providers.ts
  • packages/cli-core/src/commands/deploy/state.ts
  • packages/cli-core/src/lib/errors.ts
  • packages/cli-core/src/lib/plapi.test.ts
  • packages/cli-core/src/lib/plapi.ts
  • packages/cli-core/src/lib/sleep.ts
  • packages/cli-core/src/lib/spinner.ts

📝 Walkthrough

Walkthrough

This pull request implements clerk deploy, a complete interactive deployment wizard for promoting Clerk applications to production. The changes add Platform API client functions for instance/domain management, create a comprehensive deploy orchestration flow with DNS verification and OAuth credential setup, introduce interactive prompts for user input, define OAuth provider metadata, and generate user-facing display output including BIND zone files. The implementation includes extensive test coverage for deployment scenarios, error handling, and prompt interactions. Supporting changes update CLI command registration and error detection mechanisms.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.94% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(deploy): implement resumable deploy wizard' accurately summarizes the main change: adding a new resumable deploy wizard feature for the clerk deploy command.
Description check ✅ Passed The description provides comprehensive details about the deploy wizard implementation including human/agent modes, OAuth flows, state persistence, and test plan, and is clearly related to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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


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

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR implements a complete interactive clerk deploy command that guides developers through promoting a development Clerk instance to production. The wizard validates project subscriptions, creates production instances, orchestrates DNS configuration with CNAME record export as BIND zone files, verifies DNS/SSL/mail status via Platform API polling with component-level progress spinners, collects OAuth provider credentials from Google JSON imports or manual entry, and supports resuming from saved state on subsequent runs. The implementation includes new PLAPI endpoint wrappers for instance/domain management, state modeling and error translation for API responses, interactive prompts with validation, and comprehensive test coverage including mocking of async workflows, file operations, and prompt sequences.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 2.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title 'feat(deploy): added deploy wizard' directly describes the main feature addition: a new interactive deploy wizard for the clerk CLI.
Description check ✅ Passed The description comprehensively explains the deploy wizard feature, its functionality (clone validation, OAuth credential collection, DNS/SSL/mail verification, resumable state), implementation approach, and known limitations (agent mode not supported).

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


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

@wyattjoh wyattjoh marked this pull request as draft May 21, 2026 19:59
wyattjoh added 2 commits May 21, 2026 14:48
The Domain Connect URL helper returned Cloudflare's template for every
domain regardless of the actual registrar — a misleading prompt for any
user not on Cloudflare. Remove it entirely until NS-based registrar
detection lands as its own change.

Other cleanups from the same review pass: runDeploy throws a NOT_LINKED
CliError on unlinked directories instead of warning and exiting zero;
startNewDeploy's 409 production_instance_exists recovery now persists
the recovered production instance id to the profile; OAuth skip routes
through deployPausedError so its exit code matches Ctrl-C (1 instead of
silent 0); runDnsVerification loops on timeout retry instead of
recursing; and runOAuthSetup drops the redundant startIndex slice since
the completed set already skips previously-saved providers.
@wyattjoh wyattjoh changed the title feat(deploy): implement resumable deploy wizard feat(deploy): added deploy wizard May 21, 2026
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.

2 participants