Skip to content

Cloudflare deploy: upload a Worker build made in an earlier step #471

Open

Description

@jd-solanki

What

On Cloudflare, void deploy always builds a Worker app itself. --skip-build works only for static output (CLI: deploy, Cloudflare › Scope and limitations).

That leaves CI no point between build and upload to check what's about to ship. We scan every build for leaked secrets before it goes out, and we release exactly the artifact that passed the checks.

Done when

void deploy can upload a Worker build from an earlier CI step without rebuilding it.

Activity

  1. davidgustys commented on Oct 23, 2026

    @davidgustys

    We needed this for per-pull-request previews on Cloudflare and built it in a fork. Sharing it in case it's useful upstream.

    It adds two experimental functions to void/deploy:

    • prepareCloudflareArtifact(root, { outDir, seed?, commit? }) builds the app without Cloudflare credentials (it refuses to run while they're set, because the build runs project code). It writes Cloudflare Build Output (.cloudflare/output/v0, via the existing prepareCfBuildOutput), the D1 migrations, an optional seed, and a manifest with file digests and the bindings and secrets the app requires.
    • publishCloudflareArtifact(dir, target) checks the directory against its manifest, then publishes into resources that already exist (D1, KV, R2, queues, ISR cache). The target gives the account, Worker name, binding IDs, secrets and routes. Publishing reuses the void deploy steps: a D1 restore point and migrations, the optional seed, a version upload, a readiness check on that version, activation, trigger sync, and automatic rollback on failure.

    CI can then build in a job without credentials, scan the artifact, and publish exactly that artifact later with the token. Publish creates no resources; the caller provisions them (we use Alchemy). It passes a live end-to-end run on Cloudflare: first deploy, rollback after failed readiness, rollback across a secret change, two previews side by side, and teardown.

    It's about 4k lines of source and 4k of tests, so I'd like to check before opening a PR:

    1. Is "publish into resources the caller already created" something you'd want in Void? That fits tools that provision per-PR resources (Cloudflare deploy: preview deployments for pull requests #467). This issue may be better served by void deploy accepting a prebuilt artifact and provisioning as usual. The artifact format would work for both.
    2. If yes, I'd open one PR with commits in dependency order (artifact format, preparation, target validation, config translation, publishing), so it can be reviewed commit by commit. I can split it into stacked PRs instead if you prefer.

    Two fixes from this work are already open as #570 and #571.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions