Skip to content

feat!: remove the AWS target; Cloudflare is the one deploy pipeline - #48

Open
aynaash wants to merge 8 commits into
mainfrom
chore/remove-aws-target
Open

aynaash wants to merge 8 commits into
mainfrom
chore/remove-aws-target

Conversation

@aynaash

@aynaash aynaash commented Sep 5, 2026 •

Copy link
Copy Markdown
Owner

Depth on one target is worth more than breadth across three. The AWS lane is occupied by OpenNext + SST with Amplify Hosting underneath, and holding it cost ~4,600 lines of the least testable code in the repo plus eleven direct AWS SDK dependencies — none of which transfers to the Cloudflare resource layer where the differentiated work actually lives.

BREAKING CHANGE: serverless.provider: aws no longer resolves. The last release with Lambda/CloudFront support is v0.15.1. VPS is unaffected.

63 files changed, +215 / −6,750. go build, go vet, go test ./... and the 156 node --test runtime tests are green. golangci-lint adds no new findings.

Three commits, and why they're together

This branch carries more than the AWS deletion, because the second and third commits fix things the first one exposed. Splitting them would leave commit 1 with a README link pointing at a gitignored file.

ed29aa8 Remove the AWS target
64e485a Rewrite CLOUDFLARE_PARITY.md — it pointed users at AWS, which no longer exists
ddbb6d1 Freeze VPS properly: payload schema_version, smoke CI, a tracked VPS doc

1 — AWS removal

Deleted: the 10 aws*.go adapter files (Lambda, CloudFront, S3, ACM, IAM, SQS, Secrets Manager), cmd/revalidator, cmd/imgopt and their embedded bootstrap binaries, build-lambdas.sh, dist-config.json, the Lambda config fields, the AWS scaffold template, the AWS CI branch, and the ACM/CloudFront half of the DNS guide.

Also deleted resource_view.go (856 lines). It was an ACM-validation and CloudFront walkthrough end to end, and it was already rendering empty CloudFront/Lambda/ACM cards on every Cloudflare deploy. ship now logs an accurate summary instead. A Cloudflare-shaped report (worker, bindings, routes) is follow-up work, not something faked here.

Direct aws-sdk-go-v2 modules: 14 → 3. The three that stay (core, credentials, service/s3) are what R2's S3-compatible API needs.

Two judgment calls worth a look:

  • packaging.S3Asset / S3Assets / S3Key renamed to StaticAsset / StaticAssets / Key. Compiler-verified; R2 is the only consumer now. Happy to revert if you'd rather keep the churn out.
  • Dropped buildflow's 200MB/250MB warnings rather than inventing Workers equivalents. They measured the standalone dir against a Lambda limit; the number that matters on Workers is esbuild bundle size, which isn't that one. Left as a gap rather than a wrong threshold.

2 — Parity doc

Verified against the source rather than the commit messages, which turned up two comments the code had outgrown (both corrected in place):

  • actions.mjs claimed action results go out as JSON. They are Flight-encoded (text/x-component) via encodeFlightReply; JSON is the fallback.
  • dispatcher.mjs claimed "revalidation arrives with cache.mjs". cache.mjs is wired — revalidatePath/revalidateTag/unstable_cache, an in-memory tier and a KV tier behind NEXTCOMPILE_CACHE.

The doc now states that dynamic SSR is implemented but unverified, with both reasons cited: ssr.test.mjs and rsc.test.mjs exclude the render path, and the react-server export-condition gap in vendor/README.md is still open against --conditions=workerd,worker,node. It adds a version support matrix, a failure-mode table mapping each status code to its cause (including the quietest one — 200 with a blank page, when RSC encoding succeeded but the SSR builds were missing), and states ISR precisely: on-demand invalidation works, time-based revalidate never fires, no R2 rewrite.

3 — VPS freeze

VPS stays as the fallback for the quarter after a Next.js release Workers can't run yet. An unmaintained fallback that has quietly rotted is worse than no fallback, so freezing it means three things:

  • NextCorePayload carries a schema_version (the one real correctness gap). Written by the CLI, shipped in the tarball, unmarshalled by a separately versioned daemon — Go's decoder turns skew into zero values, so a stale daemon would deploy a release with no health path and no cgroup limits and report success. ValidateSchema now runs before any field is read and names the remedy.
  • .github/workflows/vps-smoke.yml — builds the daemon for linux/amd64, runs daemon + payload tests, scaffolds a real Next.js app, drives the VPS build path, and asserts the artifact the daemon receives. No server, no SSH. Not yet executed; it runs on merge.
  • docs/vps.md, tracked and curated, with a 2026-03-05 review date so the target gets deleted on evidence rather than argument. The old docs/VPS_DEPLOY_FLOW.md is gitignored as personal notes.

Review notes

  • The VPS smoke workflow now runs on this PR and passes.
  • No dynamic App Router page has been deployed to Workers to confirm SSR actually renders — that needs a real Cloudflare account and is the single most valuable thing to do after this lands.
  • gofmt is clean; main currently has 8 unformatted files, and this branch clears them.
  • Nothing was running the 156 Worker-runtime tests under shared/nextcompile/runtime_src. mage testUnit now does.

Depth on one target beats breadth across three, and AWS cost ~4,600 lines of
the least testable code here plus eleven direct SDK modules.

BREAKING CHANGE: `serverless.provider: aws` no longer resolves. Last release
with Lambda/CloudFront support is v0.15.1; VPS is unaffected.

Also deletes resource_view.go, an ACM/CloudFront report that already rendered
empty cards on every Cloudflare deploy. Direct aws-sdk-go-v2 modules drop from
14 to 3, the ones R2's S3-compatible API needs.
…time

The doc predated the SSR work and pointed users at AWS, which no longer exists.

Checking the source rather than the commit messages exposed two stale comments,
both corrected here: actions.mjs claimed results go out as JSON when they are
Flight-encoded, and dispatcher.mjs claimed revalidation had not landed when
cache.mjs is wired.

It now states dynamic SSR as implemented but unverified, and adds a version
matrix plus a failure-mode table mapping each status code to its cause.
…ated docs

A fallback that has quietly rotted is worse than no fallback.

NextCorePayload now carries a schema_version, validated by the daemon before
any field is read; previously CLI/daemon skew became zero values and a release
would deploy with no health path and report success.

Adds vps-smoke.yml, which drives a real Next.js app through the VPS build path
and asserts the artifact the daemon receives, and docs/vps.md with a 2026-03-05
review date.
aynaash added a commit that referenced this pull request Sep 5, 2026
…rypto

Five CI failures on #48, diagnosed against main to separate mine from
pre-existing.

Mine:

  - internal/packaging/runtime/bridge.test.js was left behind when the AWS
    target went. bridge.js was the Lambda shim; the test outlived it, and
    magefile's TestUnit ran it via mg.Deps(TestBridge). `go test ./...` never
    touched it, which is why it passed locally and failed in CI — the repo's
    real unit entrypoint is `mage testUnit`, and that is what I should have run.

    Replaced TestBridge with TestRuntime, which runs the 156 tests under
    shared/nextcompile/runtime_src. Nothing in the magefile or in any workflow
    was running those: the dispatcher, RSC, SSR, Server Actions, metadata and
    middleware-matching tests — the code that actually executes on workerd —
    had zero automated coverage. The only Node test wired into CI was the one
    for the runtime we just deleted.

  - provider.go declared serverless.ServerlessResourceMap, which stutters
    (revive). Renamed to serverless.ResourceMap.

  - guide.go's verification section still printed ACM validation-CNAME examples
    (`dig _5f2eb7... CNAME`). That guide is VPS-only now, and VPS uses A records
    with Caddy issuing certs on first request, so the instructions were telling
    users to look up records that will never exist. Rewritten against A records,
    and it now takes the domain instead of hardcoding nextdeploy.org.

Pre-existing on main, fixed here because they block the merge:

  - gofmt: main has 8 unformatted files. Deleting the AWS ones took it to 4;
    formatted the rest. Small diffs (3-28 lines each).
  - govulncheck: GO-2026-6354 and GO-2026-6355, two SSH DoS advisories in
    golang.org/x/crypto v0.53.0, reachable from server.connectSSH. Bumped to
    v0.56.0, the fixed version named by both advisories.
bridge.test.js outlived the Lambda shim it tested, and mage testUnit ran it;
`go test ./...` did not, which is why this passed locally and failed in CI.

Replaced it with TestRuntime, which runs the 156 tests under
shared/nextcompile/runtime_src. Nothing was running those — the dispatcher,
RSC, SSR and Server Actions tests had no automated coverage at all.

Also renames the ServerlessResourceMap stutter, rewrites the VPS DNS guide's
ACM-era dig examples, and clears main's gofmt backlog.
aynaash added a commit that referenced this pull request Sep 5, 2026
Four CI failures on #48, diagnosed against main to separate mine from
pre-existing.

Mine:

  - internal/packaging/runtime/bridge.test.js was left behind when the AWS
    target went. bridge.js was the Lambda shim; the test outlived it, and
    magefile's TestUnit ran it via mg.Deps(TestBridge). `go test ./...` never
    touched it, which is why it passed locally and failed in CI — the repo's
    real unit entrypoint is `mage testUnit`, and that is what I should have run.

    Replaced TestBridge with TestRuntime, which runs the 156 tests under
    shared/nextcompile/runtime_src. Nothing in the magefile or in any workflow
    was running those: the dispatcher, RSC, SSR, Server Actions, metadata and
    middleware-matching tests — the code that actually executes on workerd —
    had zero automated coverage. The only Node test wired into CI was the one
    for the runtime we just deleted.

  - provider.go declared serverless.ServerlessResourceMap, which stutters
    (revive). Renamed to serverless.ResourceMap.

  - guide.go's verification section still printed ACM validation-CNAME examples
    (`dig _5f2eb7... CNAME`). That guide is VPS-only now, and VPS uses A records
    with Caddy issuing certs on first request, so the instructions were telling
    users to look up records that will never exist. Rewritten against A records,
    and it now takes the domain instead of hardcoding nextdeploy.org.

Pre-existing on main, fixed here because it blocks the merge:

  - gofmt: main has 8 unformatted files. Deleting the AWS ones took it to 4;
    formatted the rest. Small diffs (3-28 lines each).

Left alone deliberately: the Vulnerability Check failure (GO-2026-6354 and
GO-2026-6355, SSH DoS advisories in golang.org/x/crypto v0.53.0, reachable from
server.connectSSH). It fails on main too. The fixed version, v0.56.0, requires
Go 1.26, and go.mod currently declares 1.25.0 while five workflows pin
GO_VERSION 1.25.x with GOTOOLCHAIN=local — so taking the fix means a repo-wide
toolchain upgrade that also touches the release pipeline. That is a deliberate
change of its own, not something to smuggle into an AWS removal.
@aynaash
aynaash force-pushed the chore/remove-aws-target branch from b1070a0 to 667744d Compare September 5, 2026 19:49
Both are pre-existing code that my edits pulled into golangci-lint's
new-issues diff.

The G204 exec is annotated rather than restructured: resolveNextBinary only
ever returns node_modules/.bin/next after stat'ing it, args are a fixed verb
plus a closed flag set, and exec takes argv directly with no shell.
@aynaash

aynaash commented Sep 5, 2026

Copy link
Copy Markdown
Owner Author

CI: 13 of 15 green. The two red checks are pre-existing on main and deliberately not fixed here.

Vulnerability Check / security/snyk — GO-2026-6354 and GO-2026-6355, two SSH DoS advisories in golang.org/x/crypto v0.53.0, reachable from server.connectSSH. Same dependency version and same code path as main, so main fails identically; this PR doesn't make it worse.

I did try fixing it and backed it out. The fixed release, v0.56.0, requires Go 1.26, which bumps go.mod's directive from 1.25.0 — and five workflows pin GO_VERSION: 1.25.x with GOTOOLCHAIN: local, so every build failed with go.mod requires go >= 1.26.0 (running go 1.25.14). Taking the fix means a repo-wide toolchain upgrade that also touches .goreleaser.yml and the release pipeline. That's a deliberate change worth its own PR, not something to smuggle into an AWS removal.

Worth flagging from fixing the other failures: nothing was running the 156 tests under shared/nextcompile/runtime_src — not the magefile, not any workflow. The dispatcher, RSC, SSR, Server Actions, metadata and middleware-matching tests all had zero automated coverage; the only Node test wired into CI was bridge.test.js, for the Lambda shim this PR deletes. mage testUnit now runs them via TestRuntime.

Also: go test ./... passes while mage testUnit did not, because the latter is the real entrypoint and pulls in the Node tests. That's what let the orphaned test through my local verification.

The AWS removal took out the adapters but left their vocabulary in places
users read.

`nextdeploy inspect` scored bundles against a 250MB Lambda limit; it now sizes
the actual shipped worker.mjs against Cloudflare's real 64 MiB uncompressed
limit and notes the 1-second startup budget. ship --verbose and creds also
still advertised S3, Lambda and aws.

CODE_QUALITY.md's examples move to Cloudflare equivalents, cloudflare.go's
header no longer claims the adapter is unimplemented, and the tracked `last`
file (contents: this repo's own path) is gone. pivot.md, burdenremoval.md and
yussuf.md get status blocks rather than deletion.
@aynaash
aynaash force-pushed the chore/remove-aws-target branch from 4e1d8dd to 222c8be Compare September 5, 2026 20:22
Next's Deployment Adapter API went stable in 16.2 and replaces the manifest
archaeology in shared/nextcore with a typed, versioned public contract.

The package does one thing — serialize the build output to a versioned
envelope — and deliberately contains no mapping or Cloudflare knowledge, so it
cannot grow into a second implementation of the product.

Records the five decisions that are expensive to change later: repo-relative
path normalization, a whitelisted config subset, deterministic serialization,
a schemaVersion validated Go-side, and atomic write-or-throw. Also notes that
prerenders show no tags field in the reference, which needs confirming against
a real build before the ISR tag store is designed around it.
Adds shared/ui and updates the apply/ship/generate-ci commands along
with preview and workflow CI/CD internals.
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.

1 participant