167 lines
6.5 KiB
YAML
167 lines
6.5 KiB
YAML
name: CI-wasm
|
|
|
|
# Builds the Magic WebAssembly target (both the non-TCL and TCL variants)
|
|
# on every push and pull request as a CI check. **Publishing** only happens
|
|
# when a release tag of the form v<x.y.z>... is pushed — that gate is the
|
|
# manual release trigger:
|
|
#
|
|
# # bump magic/VERSION and/or npm/tcl.ref, commit, push to default branch
|
|
# git tag v8.3.638
|
|
# git push origin v8.3.638
|
|
#
|
|
# The tag name (minus the leading "v") becomes the published npm version.
|
|
# Forks publish under their own namespace via the @<owner>/ scope.
|
|
|
|
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
|
|
|
|
# Clone intubun/tcl into a sibling directory at the pinned ref from
|
|
# npm/tcl.ref. npm/build.sh would do this on its own, but doing it as
|
|
# an explicit step makes the resolved SHA visible at the top of the
|
|
# job log and keeps the build step's output focused on the C build.
|
|
# The TCL source tree is treated as read-only — the actual WASM build
|
|
# runs inside magic (toolchains/emscripten/build-tcl-wasm.sh).
|
|
- name: Pin and clone tcltk/tcl
|
|
run: |
|
|
. npm/tcl.ref
|
|
: "${TCL_REPO_URL:=https://github.com/tcltk/tcl.git}"
|
|
: "${TCL_REF:=main}"
|
|
echo "Pinned TCL: $TCL_REF ($TCL_REPO_URL)"
|
|
# autocrlf=false: ubuntu-latest is already LF, but make it explicit.
|
|
git -c core.autocrlf=false clone "$TCL_REPO_URL" ../tcl
|
|
( cd ../tcl && git checkout --detach "$TCL_REF" )
|
|
|
|
- name: Build WASM — both variants (tcl + notcl)
|
|
run: |
|
|
source ./emsdk/emsdk_env.sh
|
|
bash npm/build.sh --variant=both
|
|
|
|
- name: Run example tests (non-TCL variant)
|
|
run: cd npm && npm test
|
|
|
|
- name: Run smoke test (TCL variant)
|
|
run: cd npm && npm run test:tcl
|
|
|
|
# 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
|
|
|
|
# The release gate. We publish a new npm version only when a tag of the
|
|
# shape v<x.y.z>... is pushed. The tag name (minus the leading "v") is
|
|
# taken as the npm version verbatim — so `v8.3.638` → npm 8.3.638.
|
|
- name: Determine release version (tag-driven only)
|
|
id: release
|
|
run: |
|
|
if [ "${{ github.event_name }}" = "push" ] && \
|
|
echo "${{ github.ref }}" | grep -Eq '^refs/tags/v[0-9]+\.[0-9]+\.[0-9]+'; then
|
|
tag="${GITHUB_REF#refs/tags/}"
|
|
echo "publish=true" >> "$GITHUB_OUTPUT"
|
|
echo "version=${tag#v}" >> "$GITHUB_OUTPUT"
|
|
echo "Tag release: $tag → npm version ${tag#v}"
|
|
else
|
|
# For non-tag CI runs, use a dev-suffixed version so the packed
|
|
# tarball is still consumable for local inspection / artifact upload.
|
|
base=$(cat VERSION)
|
|
date=$(git show -s --format=%cs | tr -d '-')
|
|
hash=$(git show -s --format=%h)
|
|
echo "publish=false" >> "$GITHUB_OUTPUT"
|
|
echo "version=${base}-${date}.${hash}" >> "$GITHUB_OUTPUT"
|
|
echo "Non-tag build: will not publish."
|
|
fi
|
|
|
|
- name: Set package version and scope
|
|
env:
|
|
VERSION: ${{ steps.release.outputs.version }}
|
|
run: |
|
|
# Scope the package to the repo owner so it lands in the right
|
|
# GitHub Packages namespace regardless of who hosts the repo.
|
|
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 --allow-same-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: Publish to GitHub Packages
|
|
if: steps.release.outputs.publish == 'true' && github.event.inputs.dry_run != 'true'
|
|
run: cd npm && npm publish
|
|
env:
|
|
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|