Files
zeekayandHanzo Dev 9dd1d42ba5 build: ship the wasip1 module and the native binaries
The wasm service mode is what the estate wants from this fork — a persistent
esbuild inside a stock wasip1 module, fed over the plugin protocol, needing no
filesystem at all — and nothing here built that module.

hanzo/Makefile builds it and the four native hosts, reproducibly: GOTOOLCHAIN
pinned to go.version so the compiler is the repo's pin and not the laptop's,
-trimpath, no VCS stamp, cleared build id, CGO off. Two runs of the lane give
the same digest. It is a separate file from upstream's Makefile, which stays
the development and npm lane, so a rebase touches none of this.

The version handshake was the shipping hazard. A host drives the service with
--service=<version> and cmd/esbuild/main.go exits 1 on any mismatch, so a
version written down anywhere outside the artifact can drift from it and the
drift only appears as "Cannot start service" at run time. Three things close
it. The lane reads the version from the constant that is compiled in, not from
version.txt, and refuses to build when those two disagree. Every artifact is
named for its version. And hanzo/stamp gets the version for the manifest by
starting each artifact in service mode — the .wasm under wazero with zero
preopened directories — and recording the version the artifact itself
announces, so the manifest cannot claim one the binary would reject.

.hanzo/workflows/release.yml runs the lane on main and publishes on a v* tag.
Not .github/: there is no runner there and such a job waits forever while
looking like CI.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-17 15:02:08 -07:00

80 lines
2.9 KiB
YAML

name: Release
# Builds what the estate ships from this fork — the native esbuild binaries and
# the wasip1/wasm module — and attaches them to the release for a v* tag.
#
# Separate from cicd.yml, which is the merge gate (hanzo.yml -> hanzoai/ci ->
# `make test-go vet-go`). A release must not be cancelled by whatever lands
# behind it, and the gate must be; they cannot share a concurrency group.
#
# It builds on every push to main as well, so a tag never discovers the lane is
# broken. Only the tag publishes.
on:
push:
branches: [main]
tags: ['v*']
workflow_dispatch:
permissions:
contents: write
# Keyed on the ref, not the repository: a repo-wide group means pushing v0.28.3
# cancels v0.28.2's build, leaving a tag that promises artifacts nobody can
# pull. Re-running the same ref still supersedes its own run.
concurrency:
group: release-${{ github.repository }}-${{ github.ref }}
cancel-in-progress: false
jobs:
build:
# One job, not a matrix: every target cross-compiles from here with
# CGO_ENABLED=0, and the manifest has to see all five artifacts at once to
# digest them together. A matrix would produce five partial manifests.
runs-on: [linux-amd64]
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
# Bootstrap only. hanzo/Makefile exports GOTOOLCHAIN=go$(cat go.version),
# so the compiler that produces the artifacts is the one this repo pins,
# whichever Go starts the build.
- uses: actions/setup-go@v5
with:
go-version-file: go.version
- run: make -f hanzo/Makefile all
- name: Name the artifact for the version inside it
id: v
run: echo "version=$(make -f hanzo/Makefile version)" >> "$GITHUB_OUTPUT"
# v3, not v4+: this workflow runs on git.hanzo.ai, which presents as GHES,
# and the v4 action refuses outright — "@actions/artifact v2.0.0+ ... not
# currently supported on GHES". A v4 upload builds everything and then
# discards it at the last step, so a good build reads as a failed run.
- uses: actions/upload-artifact@v3
with:
name: esbuild-${{ steps.v.outputs.version }}
path: hanzo/dist/
release:
needs: build
if: startsWith(github.ref, 'refs/tags/v')
runs-on: [linux-amd64]
timeout-minutes: 20
steps:
# v3 for the same reason, and it must be the SAME version: a v4 download
# cannot read a v3 artifact even where it runs.
- uses: actions/download-artifact@v3
with:
path: dist/
- uses: softprops/action-gh-release@v2
with:
# generate_release_notes is NOT set: it calls
# POST <api>/repos/<o>/<r>/releases/generate-notes, a GitHub-only
# endpoint this forge answers with a bare `404 page not found`. The
# release step alone then fails, which reads as a release problem
# rather than one unsupported flag.
files: dist/**/*