feat(targets): add vercel deploy target - #865
Conversation
Adds a release-gated `vercel` target that promotes a prebuilt docs artifact to production via `vercel deploy --prod --prebuilt`, modeled on the existing cloudflare target. Reads VERCEL_TOKEN (secret) plus optional VERCEL_ORG_ID / VERCEL_PROJECT_ID identifiers, guards against dry-run, and bundles the vercel CLI in the Docker image. Fixes #864
|
|
ci is green across the board (build & test on node 22/24, lint, warden, license compliance, secret scan, codeql, socket, docs + changelog previews, and the docker image build with the new vercel cli pin). self-review turned up nothing outstanding, so i've taken this out of draft — ready for a look, @BYK. |
|
Jared, can we avoid requiring the Maybe they also have a TS/JS SDK that we can use? |
|
The current design mirrors the existing |
|
Jared, we use |
extractZipArchiveWithFlattening unwraps a sole top-level directory, which would turn a prebuilt `.vercel/output` artifact into a bare `output/` and break `vercel deploy --prebuilt`. Use plain extractZipArchive so the `.vercel` layout is preserved. #skip-changelog
|
Fair point — the CLI requirement is the main downside vs. the Cloudflare case. The REST deploy endpoint (or Want me to prototype a switch to the HTTP path, or keep the CLI version for now (same shape as cloudflare) and revisit later? |
Let's do it now |
|
Got it — switching to the REST deploy endpoint (no CLI, no Dockerfile change). I'll rework the target + tests and push an update. |
|
Jared, still working? |
use @vercel/client's createDeployment instead of shelling out to the pinned vercel CLI. drops the CLI from the Docker image and removes the argv env-expansion guard (nothing goes to a command line anymore). org/project IDs are forwarded as teamId/name; token stays in-process.
|
Done — switched to the Vercel deploy API via what changed:
one note: this adds |
|
fix-ci: attempt 1 — the built |
The new @vercel/client dependency pulls in jsonc-parser (via
@vercel/microfrontends), whose UMD main does runtime
`require('./impl/format')`. esbuild can't follow those dynamic sibling
requires, so the bundled `dist/craft` crashed at startup with
"Cannot find module './impl/format'", failing the CLI smoke and
prepare-dry-run e2e tests. Redirect the package to its ESM entry, whose
static imports bundle cleanly.
#skip-changelog
|
pushed 65a54b0. root cause: the @vercel/client refactor added jsonc-parser (transitively via @vercel/microfrontends), whose UMD fix is an esbuild resolve plugin in build.mjs that redirects jsonc-parser to its ESM entry ( |
|
the |
|
status: the actual Build & Test (Node 22) job is now green — the jsonc-parser/esbuild fix in 65a54b0 resolved the the remaining red/cancelled checks ( |
|
Jared, address all review comments, resolve once they are addressed (including the ones you already replied to) Also make sure the CI is green |
… meta key, consume alias-assigned - switch extraction back to extractZipArchive (fixes prebuilt .vercel/output layout) - remove name: projectId (SDK reads .vercel/project.json from the artifact) - change meta key from craftRelease to release (BYK) - keep consuming the stream until alias-assigned (or return ready URL) - update dry-run log and tests to match - docs wording nits from review Addresses review threads on flattening, project linking, ready-vs-alias, and wording.
|
Addressed the review threads:
Pushed in 77b5ddb. Re-requesting review. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 77b5ddb. Configure here.
The container-harness AGENTS.md overlay was accidentally committed; restore the repository's own AGENTS.md so it's not part of this PR's diff. #skip-changelog
…nd related advisories
BYK
left a comment
There was a problem hiding this comment.
All review comments addressed and all threads resolved. CI is green across the board (build/test on Node 22 & 24, lint, dependency-review, Seer, warden, license, secret scan, codeql, socket, docs preview, docker image). LGTM.

adds a release-gated
verceltarget so a monorepo can deploy the CLI docs website to vercel on release — the vercel equivalent of the existingcloudflaretarget (#843), superseding the cloudflare approach for the CLI docs site (#842).what it does
src/targets/vercel.ts, modeled directly oncloudflare.ts:vercel.zip(or*-vercel.zip) artifact and shells out to thevercelCLI to promote it to production:vercel deploy --prod --yes --prebuilt --meta craftRelease=<version>.prebuiltdefaults totrue(the docs site is built in CI; the release just promotes the prebuilt.vercel/output). setprebuilt: falseto build from source.VERCEL_TOKENis the only secret; it is passed via the environment, never on argv. optionalVERCEL_ORG_ID/VERCEL_PROJECT_IDidentifiers are forwarded through the env when set so the deploy links to the right project non-interactively.${ENV}expansions (defense againstspawnProcessexpanding a config string into a secret), and hard-guards against dry-run so a remote deploy never runs in dry-run/worktree mode.vercelinTARGET_MAP(src/targets/index.ts).vercelCLI (pinnedvercel@58.7.1) in theDockerfile, next to the pinned wrangler install.docs/src/content/docs/targets/vercel.md+ linked it from the targets overview.answering the issue's questions
verceltarget — no need for acommand-style workaround.publish()only runs duringcraft publish, so the deployed docs stay in sync with the released version (same guarantee asgh-pages)..craft.ymlinvocation (cli@x.y.z) drives it unchanged.tests
src/targets/__tests__/vercel.test.ts(17 tests, mirrors the cloudflare test): config defaults/overrides, required-secret enforcement, env-expansion rejection, argv construction, org/project env forwarding, workingDir, artifact count errors, and dry-run safety.pnpm test(vercel + index target tests),pnpm run typecheck,eslint, andprettier --checkall pass locally.Closes #864