155 lines
5.9 KiB
YAML
155 lines
5.9 KiB
YAML
name: CI-wasm
|
|
|
|
# Builds the Magic WebAssembly target on every push and pull request.
|
|
# When the VERSION file changes on the default branch, the package is
|
|
# additionally published to GitHub Packages (npm.pkg.github.com) as
|
|
# @<owner>/magic-vlsi-wasm — no manual tag or token required.
|
|
# Tim Edwards updates VERSION to trigger a new release; the scope resolves
|
|
# automatically to the repo owner, so forks publish under their own namespace.
|
|
#
|
|
# WASM is architecture-independent — built once on x86-64, usable everywhere.
|
|
|
|
on:
|
|
push:
|
|
pull_request:
|
|
workflow_dispatch:
|
|
inputs:
|
|
emsdk_version:
|
|
description: 'emsdk version to build with (default: latest; pin a version number to bisect)'
|
|
type: string
|
|
default: 'latest'
|
|
dry_run:
|
|
description: 'Dry run: pack only, do not publish even on tag pushes'
|
|
type: boolean
|
|
default: true
|
|
|
|
# actions/upload-artifact@v5 still runs on Node.js 20. Force Node 24 to
|
|
# silence the deprecation warning until upload-artifact ships a Node-24
|
|
# release. Drop this once upgraded.
|
|
env:
|
|
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
|
|
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
|
|
jobs:
|
|
build-wasm:
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- uses: actions/checkout@v5
|
|
with:
|
|
fetch-depth: 2
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v5
|
|
with:
|
|
node-version: '22'
|
|
registry-url: 'https://npm.pkg.github.com'
|
|
|
|
- name: Install emsdk
|
|
env:
|
|
# Defaults to latest so CI tracks emsdk HEAD and catches breakage early.
|
|
# Override via workflow_dispatch to pin a specific version when needed
|
|
# (e.g. to bisect a regression or verify a post-build.sh patch still applies).
|
|
EMSDK_VERSION: ${{ github.event.inputs.emsdk_version || 'latest' }}
|
|
run: |
|
|
git clone https://github.com/emscripten-core/emsdk.git
|
|
cd emsdk
|
|
./emsdk install "$EMSDK_VERSION"
|
|
./emsdk activate "$EMSDK_VERSION"
|
|
|
|
# Dump native + emscripten preprocessor defines. Useful for diagnosing
|
|
# WASM-build differences after an emsdk bump.
|
|
- name: Emscripten Diagnostic
|
|
run: |
|
|
source ./emsdk/emsdk_env.sh
|
|
echo "===== gcc -dM -E - ====="; echo | gcc -dM -E - | sort
|
|
echo "===== g++ -dM -E - ====="; echo | g++ -dM -E - | sort
|
|
echo "===== emcc -dM -E - ====="; echo | emcc -dM -E - | sort
|
|
echo "===== em++ -dM -E - ====="; echo | em++ -dM -E - | sort
|
|
|
|
- name: Build WASM
|
|
run: |
|
|
source ./emsdk/emsdk_env.sh
|
|
# --without/--disable flags: no WASM library available for these features
|
|
CFLAGS="--std=c17 -D_DEFAULT_SOURCE=1 -DEMSCRIPTEN=1" emconfigure ./configure \
|
|
--without-cairo --without-opengl --without-x --without-tk --without-tcl \
|
|
--disable-readline --disable-compression \
|
|
--host=asmjs-unknown-emscripten \
|
|
--target=asmjs-unknown-emscripten
|
|
# Append WASM linker flags and activate the WASM link target
|
|
cat toolchains/emscripten/defs.mak >> defs.mak
|
|
# Echo the merged defs.mak so CI logs show the exact build config
|
|
echo "===== defs.mak ====="; cat defs.mak; echo "===== defs.mak ====="
|
|
# Build in order: techs must exist before mains (--embed-file embeds them)
|
|
emmake make depend
|
|
emmake make -j$(nproc) modules libs
|
|
emmake make techs
|
|
emmake make mains
|
|
|
|
- name: Copy WASM artifacts into npm/
|
|
run: |
|
|
cp magic/magic.js npm/
|
|
cp magic/magic.wasm npm/
|
|
|
|
- name: Run example tests
|
|
run: cd npm && npm run test
|
|
|
|
# Dump generated text outputs (.ext, .spice, .cif, …) into the CI log
|
|
# so a regression in extraction / netlisting / cifoutput is visible
|
|
# without having to download artifacts. The .gds output is binary —
|
|
# skip it and just record its size.
|
|
- name: Display example outputs
|
|
run: |
|
|
shopt -s nullglob
|
|
for f in npm/examples/output/*; do
|
|
name=$(basename "$f")
|
|
case "$f" in
|
|
*.gds) echo "===== $name (binary, $(wc -c < "$f") bytes — skipped) =====" ;;
|
|
*) echo "===== $name ====="; cat "$f" ;;
|
|
esac
|
|
done
|
|
|
|
- name: Set package version and scope
|
|
run: |
|
|
base=$(cat VERSION) # e.g. 8.3.637
|
|
date=$(git show -s --format=%cs | tr -d '-') # e.g. 20260414
|
|
hash=$(git show -s --format=%h) # e.g. d157eea
|
|
VERSION="${base}-${date}.${hash}"
|
|
# Scope the package to the repo owner so it lands in the right
|
|
# GitHub Packages namespace regardless of who hosts the repo.
|
|
# e.g. @rtimothyedwards/magic-vlsi-wasm on Tim's repo,
|
|
# @intubun/magic-vlsi-wasm on a fork.
|
|
SCOPED_NAME="@${{ github.repository_owner }}/magic-vlsi-wasm"
|
|
cd npm
|
|
npm pkg set name="$SCOPED_NAME"
|
|
npm pkg set publishConfig.registry="https://npm.pkg.github.com"
|
|
npm version "$VERSION" --no-git-tag-version
|
|
|
|
- name: Pack
|
|
run: ./npm/pack.sh
|
|
|
|
- name: Upload tarball as artifact
|
|
uses: actions/upload-artifact@v5
|
|
with:
|
|
name: magic-vlsi-wasm-npm
|
|
path: npm/*.tgz
|
|
|
|
- name: Check if VERSION changed
|
|
id: version_changed
|
|
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) && github.event_name == 'push'
|
|
run: |
|
|
if git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -q '^VERSION$'; then
|
|
echo "changed=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "changed=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Publish to GitHub Packages
|
|
if: steps.version_changed.outputs.changed == 'true' && github.event.inputs.dry_run != 'true'
|
|
run: cd npm && npm publish
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|