Skip to content

Latest commit

 

History

History
245 lines (189 loc) · 5.37 KB

File metadata and controls

245 lines (189 loc) · 5.37 KB

WASM Builder - Example Usage

GitHub Actions Integration

Option 1: Use as Container

jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/discere-os/wasm-builder:latest

    steps:
      - uses: actions/checkout@v4

      - name: Build WASM with Deno
        run: deno task build:wasm

      - name: Run tests
        run: deno task test

Option 2: Replace Individual Setup Steps

Before (multiple setup steps, ~2-3 minutes):

steps:
  - uses: actions/checkout@v4

  - name: Setup Deno
    uses: denoland/setup-deno@v2
    with:
      deno-version: v2.x

  - name: Setup Emscripten
    uses: mymindstorm/setup-emsdk@v14
    with:
      version: 4.0.14

  - name: Install Meson and Ninja
    run: |
      sudo apt-get update
      sudo apt-get install -y meson ninja-build pkg-config

  - name: Build WASM
    run: deno task build:wasm

After (single container, ~30 seconds):

steps:
  - uses: actions/checkout@v4

  - name: Build WASM
    uses: docker://ghcr.io/discere-os/wasm-builder:latest
    with:
      args: deno task build:wasm

Local Development

Build zlib.wasm Example (No Dependencies)

# Navigate to zlib.wasm directory
cd client/emscripten/zlib.wasm

# Build using Docker (SIDE_MODULE - no dependencies)
docker run --rm \
  -v $(pwd):/workspace \
  -w /workspace \
  ghcr.io/discere-os/wasm-builder:latest \
  bash -c "deno task build:wasm"

Build libpng.wasm Example (With Dependencies)

# libpng depends on zlib - must build both
cd client/emscripten

# Build dependency first
docker run --rm \
  -v $(pwd)/zlib.wasm:/workspace \
  -w /workspace \
  ghcr.io/discere-os/wasm-builder:latest \
  bash -c "./build-dual.sh side"

# Build libpng with dependency
docker run --rm \
  -v $(pwd)/zlib.wasm:/workspace/zlib.wasm \
  -v $(pwd)/libpng.wasm:/workspace/libpng.wasm \
  -w /workspace/libpng.wasm \
  ghcr.io/discere-os/wasm-builder:latest \
  bash -c "deno task build:wasm"
# Meson finds zlib via PKG_CONFIG_PATH="../zlib.wasm/install/lib/pkgconfig"

Build with Meson

# Navigate to any Meson-based project (e.g., glib.wasm)
cd client/emscripten/glib.wasm

# Build using Docker
docker run --rm \
  -v $(pwd):/workspace \
  -w /workspace \
  ghcr.io/discere-os/wasm-builder:latest \
  bash -c "meson setup build --cross-file=emscripten-cross.ini && ninja -C build"

Interactive Shell

# Start an interactive shell in the build environment
docker run --rm -it \
  -v $(pwd):/workspace \
  -w /workspace \
  ghcr.io/discere-os/wasm-builder:latest \
  bash

# Now you can run any build commands:
# emcc main.c -o main.js
# deno task build:wasm
# meson setup build && ninja -C build

Real-World Example: client/emscripten/.github/workflows/wasm-ci.yml

name: CI/CD Pipeline

on:
  push:
    branches: [ wasm ]
  pull_request:
    branches: [ wasm ]

jobs:
  test:
    name: Test Suite (Deno)
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/discere-os/wasm-builder:latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Type check
        run: deno check src/lib/index.ts

      - name: Build WASM modules
        run: deno task build:wasm

      - name: Run tests
        run: deno task test

      - name: Run benchmarks
        run: deno task bench

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: wasm-modules
          path: install/wasm/

Performance Comparison

Traditional GitHub Actions (without Docker)

  • Setup time: 2-3 minutes
    • Deno setup: ~30s
    • Emscripten setup: ~90s
    • System dependencies: ~30-60s
  • Build time: Varies by project
  • Total for small project: ~3-5 minutes

With WASM Builder Container

  • Setup time: ~20-30 seconds (pull cached image)
  • Build time: Same as traditional
  • Total for small project: ~1-2 minutes

Savings: 2-3 minutes per build, 40-60% faster CI/CD

Advanced: Multi-Project Builds

# Build multiple dependent libraries
for lib in zlib libpng freetype harfbuzz; do
  docker run --rm \
    -v $(pwd)/client/emscripten/$lib.wasm:/workspace \
    -w /workspace \
    ghcr.io/discere-os/wasm-builder:latest \
    bash -c "deno task build:wasm"
done

Troubleshooting

Permission Errors

If you encounter permission errors with mounted volumes:

# Run as current user
docker run --rm \
  --user $(id -u):$(id -g) \
  -v $(pwd):/workspace \
  -w /workspace \
  ghcr.io/discere-os/wasm-builder:latest \
  deno task build:wasm

Cache Emscripten for Faster Builds

# Mount Emscripten cache directory
docker run --rm \
  -v $(pwd):/workspace \
  -v ~/.emscripten_cache:/emsdk/.emscripten_cache \
  -w /workspace \
  ghcr.io/discere-os/wasm-builder:latest \
  deno task build:wasm

Next Steps

  1. Push to GitHub: cd toolchain/wasm-builder && git push
  2. Trigger Build: GitHub Actions will automatically build and publish to GHCR
  3. Update Workflows: Replace setup steps in client/emscripten/*/.github/workflows/ with container usage
  4. Test Locally: Run a local build with one of the WASM projects

Expected Results

After pushing, GitHub Actions will:

  1. Build the Docker image (~10-15 minutes first time)
  2. Run security scan with Trivy
  3. Publish to ghcr.io/discere-os/wasm-builder:latest
  4. Tag with git SHA and version
  5. Make available for all workflows