Skip to content

feat(targets): add vercel deploy target - #865

Merged
BYK merged 9 commits into
masterfrom
issue-864-vercel-target
Aug 7, 2026
Merged

feat(targets): add vercel deploy target#865
BYK merged 9 commits into
masterfrom
issue-864-vercel-target

Conversation

@jared-outpost

@jared-outpost jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

adds a release-gated vercel target so a monorepo can deploy the CLI docs website to vercel on release — the vercel equivalent of the existing cloudflare target (#843), superseding the cloudflare approach for the CLI docs site (#842).

what it does

  • new src/targets/vercel.ts, modeled directly on cloudflare.ts:
    • extracts a vercel.zip (or *-vercel.zip) artifact and shells out to the vercel CLI to promote it to production: vercel deploy --prod --yes --prebuilt --meta craftRelease=<version>.
    • prebuilt defaults to true (the docs site is built in CI; the release just promotes the prebuilt .vercel/output). set prebuilt: false to build from source.
    • VERCEL_TOKEN is the only secret; it is passed via the environment, never on argv. optional VERCEL_ORG_ID / VERCEL_PROJECT_ID identifiers are forwarded through the env when set so the deploy links to the right project non-interactively.
    • rejects config values that look like ${ENV} expansions (defense against spawnProcess expanding a config string into a secret), and hard-guards against dry-run so a remote deploy never runs in dry-run/worktree mode.
  • registered vercel in TARGET_MAP (src/targets/index.ts).
  • bundled the vercel CLI (pinned vercel@58.7.1) in the Dockerfile, next to the pinned wrangler install.
  • docs: new docs/src/content/docs/targets/vercel.md + linked it from the targets overview.

answering the issue's questions

  • craft now has a first-class vercel target — no need for a command-style workaround.
  • it is release-gated by construction: publish() only runs during craft publish, so the deployed docs stay in sync with the released version (same guarantee as gh-pages).
  • it composes with prefixed release tags (feat: support prefixed tags for monorepo multi-product releases #844): the target reads no tag/branch state itself, so per-product .craft.yml invocation (cli@x.y.z) drives it unchanged.

tests

  • new 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, and prettier --check all pass locally.

Closes #864

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
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-08-07 16:15 UTC

@jared-outpost
jared-outpost Bot marked this pull request as ready for review August 6, 2026 13:41
@jared-outpost
jared-outpost Bot requested a review from BYK August 6, 2026 13:41
@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

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.

Comment thread src/targets/vercel.ts Outdated
@BYK

BYK commented Aug 6, 2026

Copy link
Copy Markdown
Member

Jared, can we avoid requiring the vercel CLI? Looks like they have a decent API: https://vercel.com/docs/rest-api/deployments/create-a-new-deployment

Maybe they also have a TS/JS SDK that we can use?

@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

The current design mirrors the existing cloudflare target (which shells out to wrangler). Using the REST API or @vercel/client would be a bigger refactor and add HTTP/dependency surface we don't need for a simple "upload prebuilt + promote" flow. Happy to revisit if the CLI approach becomes painful, but the parity with cloudflare made this the pragmatic choice.

@BYK

BYK commented Aug 6, 2026

Copy link
Copy Markdown
Member

Jared, we use wrangler for CloudFlare as we didn't have the other option as a viable alternative. For Vercel, that doesn't seem to be the case

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
@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Fair point — the CLI requirement is the main downside vs. the Cloudflare case. The REST deploy endpoint (or @vercel/client) would remove the binary entirely.

Want me to prototype a switch to the HTTP path, or keep the CLI version for now (same shape as cloudflare) and revisit later?

@BYK

BYK commented Aug 6, 2026

Copy link
Copy Markdown
Member

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

@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Got it — switching to the REST deploy endpoint (no CLI, no Dockerfile change). I'll rework the target + tests and push an update.

@BYK

BYK commented Aug 6, 2026

Copy link
Copy Markdown
Member

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.
@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Done — switched to the Vercel deploy API via @vercel/client, no CLI. Pushed in 003a98a.

what changed:

  • vercel.ts now drives createDeployment (hash → upload → create → poll) instead of spawnProcess-ing the CLI. resolves on the ready event, throws on error so a failed deploy fails the release.
  • dropped the vercel@58.7.1 install from the Dockerfile — no binary to bundle anymore.
  • VERCEL_ORG_IDteamId, VERCEL_PROJECT_ID → deploy name; token stays in-process, never on argv. the old ${ENV} argv-expansion guard is gone since nothing reaches a command line now.
  • tests rewritten against a mocked createDeployment (15 pass), docs updated, added @vercel/client to deps (lockfile updated).

one note: this adds @vercel/client (+ transitive deps) to the runtime dependency tree — that's the tradeoff for dropping the CLI. lmk if you'd rather hand-roll the raw REST calls to keep the dep surface smaller.

Comment thread src/targets/vercel.ts Outdated
Comment thread pnpm-lock.yaml Outdated
Comment thread src/targets/vercel.ts Outdated
Comment thread src/targets/vercel.ts Outdated
@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

fix-ci: attempt 1 — the built dist/craft throws Cannot find module './impl/format'. it's the new @vercel/client dep (via @vercel/microfrontends → jsonc-parser): jsonc-parser's UMD entry does a runtime require('./impl/format') that esbuild can't bundle. fixing the build to pull in jsonc-parser's ESM entry instead.

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
@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

pushed 65a54b0. root cause: the @vercel/client refactor added jsonc-parser (transitively via @vercel/microfrontends), whose UMD main does runtime require('./impl/format') — esbuild can't statically follow those, so the bundled binary crashed at startup and took out the CLI smoke + prepare-dry-run e2e tests (the obsolete-snapshot error was a cascade from the e2e failures).

fix is an esbuild resolve plugin in build.mjs that redirects jsonc-parser to its ESM entry (module), which uses static imports that bundle cleanly. verified locally: dist/craft --version/--help run, and the full suite is green (1085 passed).

@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

the image job failed in job setup with Service Unavailable (github actions couldn't resolve action download info) — pure CI infra flake, unrelated to the build fix. re-ran it. all other checks are green.

@jared-outpost

jared-outpost Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

status: the actual Build & Test (Node 22) job is now green — the jsonc-parser/esbuild fix in 65a54b0 resolved the Cannot find module './impl/format' failure.

the remaining red/cancelled checks (image, enforce-license-compliance, preview, codeql Analyze, dependency-review) all failed in job setup with github actions Service Unavailable — Failed to resolve action download info, i.e. a github actions control-plane incident, not anything in this branch. re-running as runners recover; no code change needed.

Comment thread docs/src/content/docs/targets/vercel.md Outdated
Comment thread docs/src/content/docs/targets/vercel.md Outdated
Comment thread src/targets/vercel.ts Outdated
Comment thread src/targets/vercel.ts Outdated
@BYK

BYK commented Aug 7, 2026

Copy link
Copy Markdown
Member

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.
@jared-outpost

jared-outpost Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review threads:

  • extraction: switched back to extractZipArchive (preserves .vercel/output)
  • project linking: removed the name: projectId hack — the SDK reads .vercel/project.json from the extracted artifact (the documented path)
  • meta key: craftReleaserelease
  • stream: now consumes until alias-assigned (falls back to the ready URL)
  • dry-run log and docs wording updated per the suggestions
  • tests updated and all green locally

Pushed in 77b5ddb. Re-requesting review.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread AGENTS.md Outdated
Comment thread docs/src/content/docs/targets/vercel.md Outdated
Comment thread AGENTS.md
@BYK BYK added the jared label Aug 7, 2026
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
Comment thread src/targets/vercel.ts Outdated

@BYK BYK left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

@BYK
BYK merged commit 8cc5425 into master Aug 7, 2026
23 checks passed
@BYK
BYK deleted the issue-864-vercel-target branch August 7, 2026 16:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Vercel deploy target for CLI docs website (getsentry/toolkit)

2 participants