#3 CI: build, lint, test + working TinyGo/Wasm build #25

Merged
JMR-dev merged 5 commits from ticket-3-ci into main 2026-07-02 19:24:33 +00:00
JMR-dev commented 2026-07-02 18:31:44 +00:00 (Migrated from github.com)

Summary

Adds the ci GitHub Actions pipeline (build / lint / test) and makes the TinyGo/Wasm Worker build green on Go 1.26 by applying a small, pinned upstream TinyGo fix in CI. The ci check is fully green on this branch.

Triggers: pull_request targeting main, and push to main.

Job ci (ubuntu-latest), in order:

  1. Check out the repo.
  2. Set up Go 1.26 (module/build caching on by default).
  3. Set up TinyGo 0.41.1 (Binaryen/wasm-opt installed via the action default).
  4. Set up pnpm 10 + Node 22, pnpm store cached (keyed on pnpm-lock.yaml), then pnpm install --frozen-lockfile.
  5. go vet ./... and go test ./... at the repo root. (The js && wasm worker/ package is skipped on the host build, as intended.)
  6. Future-proofing: if infra/go.mod exists, also go vet + go test inside infra/ (guarded; no-op until ticket #2).
  7. Patch TinyGo net/http (temporary) — see below.
  8. pnpm run build — builds the Wasm Worker end to end (workers-assets-gen shim + tinygo build -> build/app.wasm).

Any step failing fails the workflow. permissions: contents: read (least privilege); a concurrency group cancels superseded runs.

The TinyGo net/http fix (Closes #26)

The first CI run failed at Build Wasm Worker:

net/http/roundtrip_js.go: t.roundTrip undefined (type *Transport has no field or method roundTrip, but does have method RoundTrip)

Root cause: TinyGo ships net/http via a submodule (src/net -> tinygo-org/net). Its js/wasm client overlay roundtrip_js.go calls the private t.roundTrip fallback, which no longer exists in Go 1.25+/1.26's net/http. Importing net/http at all (the Worker uses syumai/workers.Serve(http.Handler) + internal/handler) compiles that file, so the build breaks. This is tinygo-org/tinygo#5467.

The upstream fix is tinygo-org/net@1026408a (2026-04-27, +4/-2 in roundtrip_js.go). It is not in any released TinyGo: v0.41.1 (latest, 2026-04-22) predates it and pins the net submodule at the parent commit e54965e; the fix is already on TinyGo's dev branch, so the next TinyGo release will carry it.

Per the maintainer decision to keep Go 1.26 (not downgrade) and not redesign the Worker, CI applies the exact upstream fix to the installed TinyGo before building:

  • .ci/tinygo-net-roundtrip.patch — the byte-exact 1026408a diff (verified: its parent is exactly the e54965e commit 0.41.1 ships, and applying it reproduces the upstream fixed file identically). Targets src/net/http/roundtrip_js.go.
  • ci.yml step "Patch TinyGo net/http (temporary)" applies it to $(tinygo env TINYGOROOT) via git apply --verbose, and fails the job loudly (::error:: + exit 1) if the source has drifted — so we notice when TinyGo changes upstream.
  • .gitattributes forces *.patch to LF so git apply works on the Linux runner regardless of committer platform.
  • README documents the temporary patch and its removal condition.

This is explicitly temporary. Remove .ci/tinygo-net-roundtrip.patch and the CI step once a TinyGo release later than 0.41.1 ships the net fix. Tracked in #26; there is a TODO in both the workflow step and the patch file.

CI evidence (run on commit 47f9bab):

Applying .../.ci/tinygo-net-roundtrip.patch to /opt/hostedtoolcache/tinygo/0.41.1/amd64/tinygo/src/net/http/roundtrip_js.go
Checking patch src/net/http/roundtrip_js.go...
Applied patch src/net/http/roundtrip_js.go cleanly.
...
Build Wasm Worker: success

Pinned actions (supply-chain)

Every action is pinned by full commit SHA with a # vX.Y.Z comment, matching autoupdate.yml:

Action SHA Version
actions/checkout 9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 v7.0.0
actions/setup-go 924ae3a1cded613372ab5595356fb5720e22ba16 v6.5.0
acifani/setup-tinygo dd8a7075d951a7595b2ef2123ed0ab1af0c13e56 v3.0.0
pnpm/action-setup 0ebf47130e4866e96fce0953f49152a61190b271 v6.0.9
actions/setup-node 48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e v6.4.0

Validation

  • go run github.com/rhysd/actionlint/cmd/actionlint@latest .github/workflows/ci.yml -> exit 0, no findings.
  • go vet ./... / go test ./... -> green locally on Go 1.26.
  • The full ci job (including the TinyGo patch and Wasm build) is green on this branch (run 47f9bab).

Required status check (orchestrator action needed)

The check name is ci (the single job's name). Making it a required check that blocks merge is a repo-ruleset change — the current "Protect main" ruleset requires a PR but has no required status checks. I did not modify the ruleset. Suggest adding ci as a required check now that it is confirmed green.

Closes #3
Closes #26

## Summary Adds the `ci` GitHub Actions pipeline (build / lint / test) **and** makes the TinyGo/Wasm Worker build green on Go 1.26 by applying a small, pinned upstream TinyGo fix in CI. The `ci` check is fully green on this branch. **Triggers:** `pull_request` targeting `main`, and `push` to `main`. **Job `ci` (ubuntu-latest), in order:** 1. Check out the repo. 2. Set up Go **1.26** (module/build caching on by default). 3. Set up TinyGo **0.41.1** (Binaryen/`wasm-opt` installed via the action default). 4. Set up pnpm 10 + Node 22, pnpm store cached (keyed on `pnpm-lock.yaml`), then `pnpm install --frozen-lockfile`. 5. `go vet ./...` and `go test ./...` at the repo root. (The `js && wasm` `worker/` package is skipped on the host build, as intended.) 6. **Future-proofing:** if `infra/go.mod` exists, also `go vet` + `go test` inside `infra/` (guarded; no-op until ticket #2). 7. **Patch TinyGo net/http (temporary)** — see below. 8. `pnpm run build` — builds the Wasm Worker end to end (`workers-assets-gen` shim + `tinygo build` -> `build/app.wasm`). Any step failing fails the workflow. `permissions: contents: read` (least privilege); a `concurrency` group cancels superseded runs. ## The TinyGo net/http fix (Closes #26) The first CI run failed at **Build Wasm Worker**: ``` net/http/roundtrip_js.go: t.roundTrip undefined (type *Transport has no field or method roundTrip, but does have method RoundTrip) ``` Root cause: TinyGo ships `net/http` via a submodule (`src/net` -> `tinygo-org/net`). Its js/wasm client overlay `roundtrip_js.go` calls the private `t.roundTrip` fallback, which no longer exists in Go 1.25+/1.26's `net/http`. Importing `net/http` at all (the Worker uses `syumai/workers.Serve(http.Handler)` + `internal/handler`) compiles that file, so the build breaks. This is [tinygo-org/tinygo#5467](https://github.com/tinygo-org/tinygo/issues/5467). The upstream fix is `tinygo-org/net@1026408a` (2026-04-27, +4/-2 in `roundtrip_js.go`). It is **not in any released TinyGo**: v0.41.1 (latest, 2026-04-22) predates it and pins the net submodule at the parent commit `e54965e`; the fix is already on TinyGo's `dev` branch, so the next TinyGo release will carry it. Per the maintainer decision to keep **Go 1.26** (not downgrade) and not redesign the Worker, CI applies the exact upstream fix to the installed TinyGo before building: - **`.ci/tinygo-net-roundtrip.patch`** — the byte-exact `1026408a` diff (verified: its parent is exactly the `e54965e` commit 0.41.1 ships, and applying it reproduces the upstream fixed file identically). Targets `src/net/http/roundtrip_js.go`. - **`ci.yml`** step *"Patch TinyGo net/http (temporary)"* applies it to `$(tinygo env TINYGOROOT)` via `git apply --verbose`, and **fails the job loudly** (`::error::` + `exit 1`) if the source has drifted — so we notice when TinyGo changes upstream. - **`.gitattributes`** forces `*.patch` to LF so `git apply` works on the Linux runner regardless of committer platform. - **README** documents the temporary patch and its removal condition. **This is explicitly temporary.** Remove `.ci/tinygo-net-roundtrip.patch` and the CI step once a TinyGo release later than 0.41.1 ships the net fix. Tracked in #26; there is a `TODO` in both the workflow step and the patch file. CI evidence (run on commit `47f9bab`): ``` Applying .../.ci/tinygo-net-roundtrip.patch to /opt/hostedtoolcache/tinygo/0.41.1/amd64/tinygo/src/net/http/roundtrip_js.go Checking patch src/net/http/roundtrip_js.go... Applied patch src/net/http/roundtrip_js.go cleanly. ... Build Wasm Worker: success ``` ## Pinned actions (supply-chain) Every action is pinned by full commit SHA with a `# vX.Y.Z` comment, matching `autoupdate.yml`: | Action | SHA | Version | | --- | --- | --- | | `actions/checkout` | `9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0` | v7.0.0 | | `actions/setup-go` | `924ae3a1cded613372ab5595356fb5720e22ba16` | v6.5.0 | | `acifani/setup-tinygo` | `dd8a7075d951a7595b2ef2123ed0ab1af0c13e56` | v3.0.0 | | `pnpm/action-setup` | `0ebf47130e4866e96fce0953f49152a61190b271` | v6.0.9 | | `actions/setup-node` | `48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e` | v6.4.0 | ## Validation - `go run github.com/rhysd/actionlint/cmd/actionlint@latest .github/workflows/ci.yml` -> exit 0, no findings. - `go vet ./...` / `go test ./...` -> green locally on Go 1.26. - The full `ci` job (including the TinyGo patch and Wasm build) is **green** on this branch (run `47f9bab`). ## Required status check (orchestrator action needed) The check name is **`ci`** (the single job's name). Making it a **required** check that blocks merge is a repo-ruleset change — the current "Protect main" ruleset requires a PR but has **no** required status checks. I did **not** modify the ruleset. Suggest adding `ci` as a required check now that it is confirmed green. Closes #3 Closes #26
Sign in to join this conversation.