name: Release
on:
push:
tags:
- "v*.*.*"
permissions:
contents: read
env:
NODE_VERSION: "24"
WASM_PACK_VERSION: "0.14.0"
WASM_BINDGEN_CLI_VERSION: "0.2.115"
jobs:
prepare:
name: Prepare Release Metadata
runs-on: ubuntu-24.04
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Verify tag version
id: version
shell: bash
run: |
VERSION="$(node .github/scripts/sync_versions.mjs --print-version)"
TAG_VERSION="${GITHUB_REF_NAME#v}"
if [[ "$TAG_VERSION" != "$VERSION" ]]; then
echo "Release tag version ${TAG_VERSION} does not match workspace version ${VERSION}" >&2
exit 1
fi
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
preflight:
name: Release Preflight
runs-on: ubuntu-24.04
needs: prepare
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm
cache-dependency-path: packages/unluac-js/package-lock.json
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Install Linux Lua build dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y build-essential cmake libreadline-dev
- name: Restore vendored Lua toolchain cache
id: lua-toolchain-cache
uses: actions/cache@v4
with:
path: |
lua/sources
lua/build
key: ${{ runner.os }}-lua-toolchains-${{ hashFiles('xtask/Cargo.toml', 'xtask/src/toolchain.rs', '.cargo/config.toml') }}
- name: Build vendored Lua toolchains
if: steps.lua-toolchain-cache.outputs.cache-hit != 'true'
run: cargo lua init all
- name: Restore wasm tool cache
id: wasm-tool-cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/wasm-pack
~/.cargo/bin/wasm-bindgen
~/.cargo/bin/wasm-bindgen-test-runner
~/.cargo/bin/wasm2es6js
~/.cargo/.crates2.json
~/.cargo/.crates.toml
key: ${{ runner.os }}-wasm-tools-wasm-pack-${{ env.WASM_PACK_VERSION }}-wasm-bindgen-${{ env.WASM_BINDGEN_CLI_VERSION }}
- name: Install wasm-pack
if: steps.wasm-tool-cache.outputs.cache-hit != 'true'
run: cargo install wasm-pack --version ${{ env.WASM_PACK_VERSION }} --locked
- name: Install wasm-bindgen CLI
if: steps.wasm-tool-cache.outputs.cache-hit != 'true'
run: cargo install wasm-bindgen-cli --version ${{ env.WASM_BINDGEN_CLI_VERSION }} --locked
- name: Check synced package versions
run: node .github/scripts/sync_versions.mjs --check
- name: Run Rust lint and tests
run: |
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
cargo unit-test --jobs 8
- name: Dry-run crate publish
run: cargo publish -p unluac --locked --dry-run
- name: Dry-run npm pack
working-directory: packages/unluac-js
run: |
npm install
npm run build
cd dist
npm pack --pack-destination "${RUNNER_TEMP}"
build-cli:
name: Build CLI (${{ matrix.platform }})
runs-on: ${{ matrix.os }}
needs:
- prepare
- preflight
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-24.04
platform: linux-x86_64
binary_path: target/release/unluac-cli
extension: ""
- os: windows-2025
platform: windows-x86_64
binary_path: target/release/unluac-cli.exe
extension: ".exe"
- os: macos-15-intel
platform: macos-x86_64
binary_path: target/release/unluac-cli
extension: ""
- os: macos-15
platform: macos-aarch64
binary_path: target/release/unluac-cli
extension: ""
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
- name: Build release binary
run: cargo build -p unluac-cli --release --locked
- name: Rename release binary
shell: bash
env:
VERSION: ${{ needs.prepare.outputs.version }}
run: |
mkdir -p release-assets
cp "${{ matrix.binary_path }}" "release-assets/unluac-${VERSION}-${{ matrix.platform }}${{ matrix.extension }}"
- name: Upload CLI artifact
uses: actions/upload-artifact@v4
with:
name: cli-${{ matrix.platform }}
path: release-assets/*
publish-and-release:
name: Publish crate, npm and Create Release
runs-on: ubuntu-24.04
needs:
- prepare
- preflight
- build-cli
permissions:
contents: write
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: https://registry.npmjs.org
cache: npm
cache-dependency-path: packages/unluac-js/package-lock.json
- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: wasm32-unknown-unknown
- name: Restore wasm tool cache
id: wasm-tool-cache
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/wasm-pack
~/.cargo/bin/wasm-bindgen
~/.cargo/bin/wasm-bindgen-test-runner
~/.cargo/bin/wasm2es6js
~/.cargo/.crates2.json
~/.cargo/.crates.toml
key: ${{ runner.os }}-wasm-tools-wasm-pack-${{ env.WASM_PACK_VERSION }}-wasm-bindgen-${{ env.WASM_BINDGEN_CLI_VERSION }}
- name: Install wasm-pack
if: steps.wasm-tool-cache.outputs.cache-hit != 'true'
run: cargo install wasm-pack --version ${{ env.WASM_PACK_VERSION }} --locked
- name: Install wasm-bindgen CLI
if: steps.wasm-tool-cache.outputs.cache-hit != 'true'
run: cargo install wasm-bindgen-cli --version ${{ env.WASM_BINDGEN_CLI_VERSION }} --locked
- name: Check synced package versions
run: node .github/scripts/sync_versions.mjs --check
- name: Inspect release registry state
id: release-state
shell: bash
env:
VERSION: ${{ needs.prepare.outputs.version }}
run: |
if npm view "unluac-js@${VERSION}" version >/dev/null 2>&1; then
echo "npm_published=true" >> "$GITHUB_OUTPUT"
echo "npm package unluac-js@${VERSION} is already published"
else
echo "npm_published=false" >> "$GITHUB_OUTPUT"
fi
if curl --silent --fail "https://crates.io/api/v1/crates/unluac/${VERSION}" >/dev/null; then
echo "crate_published=true" >> "$GITHUB_OUTPUT"
echo "crate unluac ${VERSION} is already published on crates.io"
else
echo "crate_published=false" >> "$GITHUB_OUTPUT"
fi
- name: Install npm dependencies
working-directory: packages/unluac-js
run: npm install
- name: Build npm package
working-directory: packages/unluac-js
run: npm run build
- name: Publish npm package
if: steps.release-state.outputs.npm_published != 'true'
working-directory: packages/unluac-js
run: npm publish ./dist --access public
- name: Publish Rust crate
if: steps.release-state.outputs.crate_published != 'true'
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
VERSION: ${{ needs.prepare.outputs.version }}
shell: bash
run: |
set +e
OUTPUT="$(cargo publish -p unluac --locked 2>&1)"
STATUS=$?
set -e
if [[ $STATUS -eq 0 ]]; then
printf '%s\n' "$OUTPUT"
exit 0
fi
printf '%s\n' "$OUTPUT"
if grep -Fq "crate unluac@${VERSION} already exists on crates.io index" <<<"$OUTPUT"; then
echo "crate unluac ${VERSION} was already published while this workflow was running; continuing"
exit 0
fi
exit "$STATUS"
- name: Download CLI artifacts
uses: actions/download-artifact@v4
with:
pattern: cli-*
merge-multiple: true
path: ${{ runner.temp }}/release-assets
- name: Add wasm release asset
shell: bash
run: |
cp packages/unluac-js/.wasm-build/unluac_wasm_bg.wasm "${{ runner.temp }}/release-assets/unluac_wasm_bg.wasm"
- name: Create or update GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
TAG="${GITHUB_REF_NAME}"
if ! gh release view "$TAG" >/dev/null 2>&1; then
gh release create "$TAG" --title "$TAG" --generate-notes
fi
gh release upload "$TAG" "${{ runner.temp }}/release-assets"/* --clobber