From 0eddc16ed0badae1fecc4e005d4e1f317b6d4102 Mon Sep 17 00:00:00 2001 From: rawan10101 Date: Sat, 8 Aug 2026 22:28:43 +0300 Subject: [PATCH] ci: add nvim.wasm build and nightly release Add a dedicated nvim.wasm build workflow and include the resulting WASM artifact in nightly releases. --- .github/scripts/build_wasm.sh | 81 ++++++++++++++++++++++++++++++++ .github/workflows/build_wasm.yml | 62 ++++++++++++++++++++++++ .github/workflows/release.yml | 47 ++++++++++++++++-- 3 files changed, 187 insertions(+), 3 deletions(-) create mode 100755 .github/scripts/build_wasm.sh create mode 100644 .github/workflows/build_wasm.yml diff --git a/.github/scripts/build_wasm.sh b/.github/scripts/build_wasm.sh new file mode 100755 index 0000000000..0ca95da381 --- /dev/null +++ b/.github/scripts/build_wasm.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +# Build nvim.wasm + +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +OUTDIR="$ROOT/build-wasm" + +source "$ROOT/.emsdk/emsdk_env.sh" + +mkdir -p "$OUTDIR" + +if ! command -v emcc >/dev/null 2>&1; then + echo "ERROR: emcc not found" + exit 1 +fi + +if ! command -v zig >/dev/null 2>&1; then + echo "ERROR: zig not found" + exit 1 +fi + +emcc --version +zig version + +# Install Binaryen if it is not already available. +BINARYEN_VERSION=132 +BINARYEN_DIR="$ROOT/.binaryen" +BINARYEN_BIN="$BINARYEN_DIR/binaryen-version_${BINARYEN_VERSION}/bin" + +if [ ! -x "$BINARYEN_BIN/wasm-opt" ]; then + echo "Installing Binaryen ${BINARYEN_VERSION}..." + + mkdir -p "$BINARYEN_DIR" + + curl -L \ + "https://github.com/WebAssembly/binaryen/releases/download/version_${BINARYEN_VERSION}/binaryen-version_${BINARYEN_VERSION}-x86_64-linux.tar.gz" \ + -o /tmp/binaryen.tar.gz + + tar -xf /tmp/binaryen.tar.gz -C "$BINARYEN_DIR" +fi + +export PATH="$BINARYEN_BIN:$PATH" + +wasm-opt --version + +zig build nvim_bin \ + -Dtarget=wasm32-emscripten \ + -Dcpu=generic+atomics+bulk_memory+mutable_globals \ + -Demscripten-sysroot="$EMSDK/upstream/emscripten/cache/sysroot" \ + -Doptimize=ReleaseSmall + +ZIG_OUT="$ROOT/zig-out/bin" + +# Optimize the final WASM artifact with Binaryen. +wasm-opt -Oz -o "$ZIG_OUT/nvim.wasm" "$ZIG_OUT/nvim.wasm" + +required=( + nvim.wasm + nvim.js + nvim.data +) + +missing=() + +for name in "${required[@]}"; do + if [ -f "$ZIG_OUT/$name" ]; then + cp "$ZIG_OUT/$name" "$OUTDIR/$name" + else + missing+=("$name") + fi +done + +if [ "${#missing[@]}" -ne 0 ]; then + echo "ERROR: Missing required WASM artifacts: ${missing[*]}" + ls -la "$ZIG_OUT" || true + exit 2 +fi + +echo "build-wasm.sh finished successfully." diff --git a/.github/workflows/build_wasm.yml b/.github/workflows/build_wasm.yml new file mode 100644 index 0000000000..14bd499042 --- /dev/null +++ b/.github/workflows/build_wasm.yml @@ -0,0 +1,62 @@ +name: nvim.wasm build + +on: + pull_request: + branches: + - 'master' + - 'release-[0-9]+.[0-9]+' + paths: + - 'build.zig' + - 'build.zig.zon' + - '.github/scripts/build_wasm.sh' + - '.github/workflows/build_wasm.yml' + workflow_dispatch: + +permissions: + contents: read + +jobs: + build-wasm: + name: Build nvim.wasm (Emscripten + Zig) + runs-on: ubuntu-24.04 + timeout-minutes: 90 + + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Set up Zig + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 + with: + version: 0.16.0 + use-cache: false + + - name: Cache emsdk, Binaryen & build outputs + uses: actions/cache@v6.1.0 + with: + path: | + ./.emsdk + ./.binaryen + key: ${{ runner.os }}-wasm-${{ hashFiles('build.zig', 'build.zig.zon', '.github/scripts/build_wasm.sh') }} + + - name: Install system deps + run: | + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3 python3-pip curl unzip + + - name: Install Emscripten SDK + run: | + set -euo pipefail + if [ ! -d ./.emsdk ]; then + git clone https://github.com/emscripten-core/emsdk.git ./.emsdk + cd ./.emsdk + ./emsdk install 6.0.2 + ./emsdk activate 6.0.2 + cd - + fi + + - name: Build nvim.wasm + run: .github/scripts/build_wasm.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7c646a54e4..5f8e227f8e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -190,8 +190,49 @@ jobs: build/${{ matrix.archive_name }}.msi retention-days: 1 + wasm: + needs: setup + runs-on: ubuntu-24.04 + + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + persist-credentials: false + + - name: Set up Zig + uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2.2.1 + with: + version: 0.16.0 + use-cache: false + + - name: Install system deps + run: | + sudo apt-get update + sudo DEBIAN_FRONTEND=noninteractive apt-get install -y \ + python3 python3-pip curl unzip + + - name: Install Emscripten SDK + run: | + set -euo pipefail + git clone https://github.com/emscripten-core/emsdk.git ./.emsdk + cd ./.emsdk + ./emsdk install 6.0.2 + ./emsdk activate 6.0.2 + cd - + + - name: Build nvim.wasm + run: .github/scripts/build_wasm.sh + + - name: Upload wasm artifact + uses: actions/upload-artifact@v7 + with: + name: nvim-wasm + path: build-wasm/* + retention-days: 1 + publish: - needs: [linux, macos, windows] + needs: [linux, macos, windows, wasm] runs-on: ubuntu-latest env: GH_REPO: ${{ github.repository }} @@ -244,6 +285,6 @@ jobs: run: | envsubst < "$GITHUB_WORKSPACE/.github/workflows/notes.md" > "$RUNNER_TEMP/notes.md" if [ "$TAG_NAME" != "nightly" ]; then - gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win-x86_64/* nvim-win-arm64/* + gh release create stable $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win-x86_64/* nvim-win-arm64/* nvim-wasm/* fi - gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win-x86_64/* nvim-win-arm64/* + gh release create $TAG_NAME $PRERELEASE --notes-file "$RUNNER_TEMP/notes.md" --title "$SUBJECT" --target $GITHUB_SHA nvim-macos-x86_64/* nvim-macos-arm64/* nvim-linux-x86_64/* nvim-linux-arm64/* nvim-appimage-x86_64/* nvim-appimage-arm64/* nvim-win-x86_64/* nvim-win-arm64/* nvim-wasm/*