feat: attach the assembled site to every release, and let the page name its build
improvise-oujb. A tagged release carried four native tarballs and nothing for the web; the site shipped only by ci.yml's pages-deploy, on a push to main. Pages keeps tracking main (user, 2026-09-22: "I like Pages showing the latest main for now"), so this is a CAPTURE, not a second deployment: the tarball is a self-hostable copy of the site as of the tag and a rollback target, not what a visitor to the published site is running. pages-deploy is untouched. Mechanism is dist's own [[dist.extra-artifacts]], so it survives `dist init`: `dist plan` under the pinned 0.30.4 lists improvise-web.tar.gz beside the four platform tarballs and `dist generate` leaves release.yml byte-identical. The build command is scripts/build-web-release.sh, which calls web/build.sh and web/assemble.sh -- the same two scripts ci.yml and a developer run, so there is no second way to build the bundle. Its toolchain pins come from scripts/web-toolchain-versions.env, which ci.yml's build job now reads too. `github-build-setup` was measured and does NOT help: it injects into build-local-artifacts only, which is the wrong job for a global artifact. The page now names the build it was assembled from in #build-version, stamped by web/assemble.sh with the same token as the bundles and verified by the same scripts/assemble-stamp.sh gate. An unassembled tree honestly reads "unstamped". Verified by running `dist build --artifacts=global` locally: the script ran, the site assembled, and dist placed improvise-web.tar.gz in target/distrib. Not verified: a real tag push, which would require cutting a tag. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH
This commit is contained in:
Executable
+95
@@ -0,0 +1,95 @@
|
||||
#!/bin/sh
|
||||
# Capture the assembled site as a release artifact (improvise-oujb).
|
||||
#
|
||||
# `dist` runs this from the repo root as an `[[dist.extra-artifacts]]` build
|
||||
# command, inside release.yml's `build-global-artifacts` job, and then uploads
|
||||
# the file named here to the GitHub Release. Nothing about that job is edited
|
||||
# by hand: see the comment in dist-workspace.toml.
|
||||
#
|
||||
# WHAT THIS IS FOR, and it is narrower than it looks. GitHub Pages keeps
|
||||
# tracking `main` (user ruling, 2026-09-22: "I like Pages showing the latest
|
||||
# main for now"), so this tarball is NOT what a visitor to the published site
|
||||
# is running. It is a self-hostable copy of the site as of the tag, and a
|
||||
# rollback target. A reader who assumes it is the deployed site will be wrong.
|
||||
#
|
||||
# IT BUILDS NOTHING OF ITS OWN. web/build.sh and web/assemble.sh are the same
|
||||
# two scripts a developer runs and the same two ci.yml's `build` job runs; a
|
||||
# release that assembled the bundle its own way would reintroduce exactly the
|
||||
# drift that job's comment exists to prevent (improvise-vvl3). Everything
|
||||
# below the toolchain block is those two calls and a `tar`.
|
||||
#
|
||||
# Usage: scripts/build-web-release.sh [OUT_TARBALL]
|
||||
#
|
||||
# The cache-bust token is the tag (`GITHUB_REF_NAME`), where the Pages build
|
||||
# passes the commit SHA and a bare local run defaults to `dev`. A release is
|
||||
# the one case where a human-readable name is available and is what a bug
|
||||
# report will quote, and web/assemble.sh stamps it into the page's
|
||||
# #build-version element as well as into the two bundle URLs.
|
||||
set -eu
|
||||
|
||||
root=$(cd "$(dirname "$0")/.." && pwd)
|
||||
out=${1:-"$root/improvise-web.tar.gz"}
|
||||
|
||||
# A tag may legally contain `/` and a release.yml PR run puts `NN/merge` here,
|
||||
# so the token is reduced to what is safe in a URL query and a filename.
|
||||
raw=${IMPROVISE_WEB_TOKEN:-${GITHUB_REF_NAME:-dev}}
|
||||
token=$(printf '%s' "$raw" | sed 's|[^A-Za-z0-9._-]|-|g')
|
||||
|
||||
# One home for the two pinned versions, read here and fed to $GITHUB_ENV by
|
||||
# ci.yml's `build` job. Pinning is what makes a local measurement evidence
|
||||
# about a CI run, and two copies of a pin is one of them going stale.
|
||||
. "$root/scripts/web-toolchain-versions.env"
|
||||
|
||||
# The global build job carries a Rust toolchain and dist, and nothing else --
|
||||
# `github-build-setup` injects only into build-local-artifacts, which is the
|
||||
# wrong job for a global artifact, so the provisioning has to live here.
|
||||
# Installs are Linux-only and on-demand: a developer running this on a Mac
|
||||
# gets told what is missing rather than handed a linux-x64 binary.
|
||||
os=$(uname -s)
|
||||
|
||||
need_linux() {
|
||||
echo "build-web-release: $1 — install it, or run this on Linux/CI" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
if command -v rustup > /dev/null 2>&1; then
|
||||
rustup target add wasm32-unknown-unknown
|
||||
fi
|
||||
|
||||
if ! wasm-pack --version 2>/dev/null | grep -qF "${WASM_PACK_VERSION#v}"; then
|
||||
[ "$os" = Linux ] || need_linux "wasm-pack ${WASM_PACK_VERSION} not on PATH"
|
||||
url="https://github.com/rustwasm/wasm-pack/releases/download/${WASM_PACK_VERSION}/wasm-pack-${WASM_PACK_VERSION}-x86_64-unknown-linux-musl.tar.gz"
|
||||
curl -sSfL "$url" | tar -xz --strip-components=1 -C /usr/local/bin \
|
||||
"wasm-pack-${WASM_PACK_VERSION}-x86_64-unknown-linux-musl/wasm-pack"
|
||||
fi
|
||||
wasm-pack --version
|
||||
|
||||
# `latest-v<major>.x` is the same resolution actions/setup-node performs for a
|
||||
# bare major, so the pin means here what it means in ci.yml. SHASUMS256.txt is
|
||||
# read for the filename because the directory has no stable one.
|
||||
node_major=$(node --version 2>/dev/null | sed -n 's|^v\([0-9][0-9]*\).*|\1|p' || true)
|
||||
if [ "${node_major:-0}" != "$NODE_VERSION" ]; then
|
||||
[ "$os" = Linux ] || need_linux "node ${NODE_VERSION}.x not on PATH (found ${node_major:-none})"
|
||||
base="https://nodejs.org/dist/latest-v${NODE_VERSION}.x"
|
||||
file=$(curl -sSfL "$base/SHASUMS256.txt" \
|
||||
| sed -n 's|.* \(node-v[0-9.]*-linux-x64\.tar\.xz\)$|\1|p')
|
||||
test -n "$file" || { echo "build-web-release: no linux-x64 node in $base" >&2; exit 1; }
|
||||
mkdir -p "$root/target/node"
|
||||
curl -sSfL "$base/$file" | tar -xJ --strip-components=1 -C "$root/target/node"
|
||||
PATH="$root/target/node/bin:$PATH"
|
||||
export PATH
|
||||
fi
|
||||
node --version
|
||||
|
||||
sh "$root/web/build.sh"
|
||||
|
||||
# The site is assembled into a directory named for what it is, so extracting
|
||||
# the tarball leaves one self-describing folder rather than loose files.
|
||||
stage="$root/target/web-release"
|
||||
rm -rf "$stage"
|
||||
mkdir -p "$stage"
|
||||
sh "$root/web/assemble.sh" "$stage/improvise-web" "$token"
|
||||
|
||||
rm -f "$out"
|
||||
tar -czf "$out" -C "$stage" improvise-web
|
||||
echo "build-web-release: wrote $out (token $token)"
|
||||
@@ -0,0 +1,2 @@
|
||||
WASM_PACK_VERSION=v0.15.0
|
||||
NODE_VERSION=24
|
||||
Reference in New Issue
Block a user