diff --git a/.ci/tinygo-net-roundtrip.patch b/.ci/tinygo-net-roundtrip.patch new file mode 100644 index 0000000..65db49f --- /dev/null +++ b/.ci/tinygo-net-roundtrip.patch @@ -0,0 +1,36 @@ +Temporary CI patch: fix the TinyGo net/http js/wasm build on Go 1.25/1.26. + +TinyGo <= 0.41.1 vendors github.com/tinygo-org/net at commit e54965e, whose +http/roundtrip_js.go calls the private t.roundTrip fallback that no longer +exists in Go 1.25+/1.26 net/http, so any wasm build importing net/http fails: + + net/http/roundtrip_js.go: t.roundTrip undefined (type *Transport has no + field or method roundTrip, but does have method RoundTrip) + +This is the exact upstream fix tinygo-org/net@1026408a ("http: fix t.roundTrip +undefined on js/wasm builds", whose parent is e54965e -- the commit TinyGo +0.41.1 ships), applied to the installed TinyGo source in CI before the wasm +build. The .patch is applied by the "Patch TinyGo net/http (temporary)" step +in .github/workflows/ci.yml. + +TODO: remove this file AND that CI step once a TinyGo release > 0.41.1 ships +the fix. It is already on TinyGo's dev branch (which pins tinygo-org/net@ +1026408a). Tracking: issue #26; upstream tinygo-org/tinygo#5467. + +diff --git a/src/net/http/roundtrip_js.go b/src/net/http/roundtrip_js.go +--- a/src/net/http/roundtrip_js.go ++++ b/src/net/http/roundtrip_js.go +@@ -68,9 +68,11 @@ + // to fall back on the Fetch API, unless it's not available. + + // TINYGO: Dial/DialTLS & DialContext/DialTLSContext are not present in tinygo Transport struct, therefore the +- // corresponding if statements were removed ++ // corresponding if statements were removed. ++ // TINYGO: t.roundTrip (the private fallback used by upstream Go) is not present in the TinyGo stub ++ // Transport, so return an error when the Fetch API is unavailable instead of calling it. + if jsFetchMissing || jsFetchDisabled { +- return t.roundTrip(req) ++ return nil, errors.New("net/http: Fetch API is not available and no fallback transport is implemented for js/wasm") + } + + ac := js.Global().Get("AbortController") diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a518a5f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +# Keep CI-critical text files LF on every platform. .ci/*.patch is applied with +# `git apply` against TinyGo's Unix (LF) source in CI, so it must never be +# checked out with CRLF (which would make the patch fail to apply). +*.patch text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6dbab4c..d43f1c5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,9 +38,10 @@ jobs: with: go-version: '1.26' - # TinyGo is needed only for the Wasm Worker build (pnpm run build). The - # 0.41.x line is the first with Go 1.26 support; install-binaryen (default - # true) provides wasm-opt, which TinyGo invokes for the -target wasm build. + # TinyGo is needed only for the Wasm Worker build (pnpm run build). + # install-binaryen (default true) provides wasm-opt, which TinyGo invokes + # for the -target wasm build. 0.41.1's vendored net/http js overlay is + # patched just before the build (see "Patch TinyGo net/http" below). - name: Set up TinyGo uses: acifani/setup-tinygo@dd8a7075d951a7595b2ef2123ed0ab1af0c13e56 # v3.0.0 with: @@ -79,6 +80,25 @@ jobs: echo "infra/go.mod not present; skipping (no-op until ticket #2)" fi + # TEMPORARY (tracking #26; tinygo-org/tinygo#5467): TinyGo 0.41.1 and + # earlier vendor tinygo-org/net@e54965e, whose net/http js/wasm overlay + # (roundtrip_js.go) calls the private t.roundTrip fallback that no longer + # exists in Go 1.25+/1.26 net/http, so the wasm build fails to compile. + # Apply the exact upstream fix (tinygo-org/net@1026408a) to the installed + # TinyGo source. git apply exits non-zero (failing the job loudly) if the + # source has drifted, so we notice when TinyGo changes upstream. + # TODO: delete this step and .ci/tinygo-net-roundtrip.patch once a TinyGo + # release later than 0.41.1 ships the fix (already on TinyGo's dev branch). + - name: Patch TinyGo net/http (temporary) + run: | + patch_file="$PWD/.ci/tinygo-net-roundtrip.patch" + tinygoroot="$(tinygo env TINYGOROOT)" + echo "Applying $patch_file to $tinygoroot/src/net/http/roundtrip_js.go" + git -C "$tinygoroot" apply --verbose "$patch_file" || { + echo "::error::TinyGo net/http patch did not apply cleanly; TinyGo source may have changed. Update or remove .ci/tinygo-net-roundtrip.patch (see #26)." + exit 1 + } + # Confirms the Wasm Worker builds end to end: workers-assets-gen emits the # JS shim and TinyGo compiles ./worker into build/app.wasm. - name: Build Wasm Worker diff --git a/README.md b/README.md index e953552..699570d 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,17 @@ This runs the exact handler the deployed Worker uses, minus the Workers runtime. ### Build & run the real Worker (requires TinyGo) Node tooling is managed with **pnpm**; wrangler is a dev dependency. The Wasm -build uses [TinyGo](https://tinygo.org) 0.35.0+. +build uses [TinyGo](https://tinygo.org) 0.41.1 on the Go 1.26 toolchain. + +> **Temporary toolchain patch.** TinyGo 0.41.1 and earlier vendor a `net/http` +> js/wasm overlay (`tinygo-org/net@e54965e`) that fails to compile against Go +> 1.25+/1.26 with `t.roundTrip undefined` (see +> [tinygo-org/tinygo#5467](https://github.com/tinygo-org/tinygo/issues/5467)). +> CI applies the exact upstream fix (`tinygo-org/net@1026408a`, checked in as +> `.ci/tinygo-net-roundtrip.patch`) to the installed TinyGo before building. +> Building locally on Go 1.26 needs the same one-file patch until a TinyGo +> release later than 0.41.1 ships it, at which point the patch and the CI step +> are removed (tracked in #26). ```console pnpm install # install wrangler