macroforge_ts 0.1.78

TypeScript macro expansion engine - write compile-time macros in Rust
Documentation
name: CI

env:
    DEBUG: napi:*
    APP_NAME: macroforge
    MACOSX_DEPLOYMENT_TARGET: '10.13'

permissions:
    contents: write
    id-token: write

on:
    push:
        branches: [main]
        tags:
            - 'v*'
        paths-ignore:
            - '**/*.md'
            - LICENSE
            - '**/*.gitignore'
    pull_request: null

jobs:
    build:
        strategy:
            fail-fast: false
            matrix:
                settings:
                    - host: macos-15-intel
                      target: x86_64-apple-darwin
                    - host: macos-15-intel
                      target: aarch64-apple-darwin
                    - host: ubuntu-latest
                      target: x86_64-unknown-linux-gnu
                    - host: ubuntu-latest
                      target: aarch64-unknown-linux-gnu
                    - host: windows-latest
                      target: x86_64-pc-windows-msvc
                    - host: windows-latest
                      target: aarch64-pc-windows-msvc

        name: Build - ${{ matrix.settings.target }}
        runs-on: ${{ matrix.settings.host }}
        steps:
            - uses: actions/checkout@v6

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

            - name: Install Rust
              uses: dtolnay/rust-toolchain@stable
              with:
                  targets: ${{ matrix.settings.target }}

            - name: Cache Rust
              uses: Swatinem/rust-cache@v2
              with:
                  shared-key: ${{ matrix.settings.target }}

            - name: Install cross-compile tools (Linux arm64)
              if: matrix.settings.target == 'aarch64-unknown-linux-gnu'
              run: |
                  sudo apt-get update
                  sudo apt-get install -y gcc-aarch64-linux-gnu

            - name: Install dependencies
              run: deno install

            - name: Build native module
              run: deno run -A npm:@napi-rs/cli/napi build --platform --release --target ${{ matrix.settings.target }}
              env:
                  CARGO_PROFILE_RELEASE_CODEGEN_UNITS: '16'
                  CC_aarch64_unknown_linux_gnu: aarch64-linux-gnu-gcc
                  CXX_aarch64_unknown_linux_gnu: aarch64-linux-gnu-g++
                  CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc

            - name: Upload artifact
              uses: actions/upload-artifact@v7
              with:
                  name: bindings-${{ matrix.settings.target }}
                  path: '*.node'
                  if-no-files-found: error

    clippy:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v6

            - name: Install Rust
              uses: dtolnay/rust-toolchain@stable
              with:
                  components: clippy

            - name: Cache Rust
              uses: Swatinem/rust-cache@v2

            - name: Run clippy
              run: cargo clippy --all-targets --all-features -- -D warnings

    fmt:
        runs-on: ubuntu-latest
        steps:
            - uses: actions/checkout@v6

            - name: Install Rust
              uses: dtolnay/rust-toolchain@stable
              with:
                  components: rustfmt

            - name: Format check
              run: cargo fmt --all -- --check

    publish:
        name: Publish
        runs-on: ubuntu-latest
        needs: [build, clippy, fmt]
        if: startsWith(github.ref, 'refs/tags/v')
        steps:
            - uses: actions/checkout@v6

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

            - name: Setup Node.js
              uses: actions/setup-node@v6
              with:
                  node-version: 24
                  registry-url: https://registry.npmjs.org

            - name: Download all artifacts
              uses: actions/download-artifact@v8
              with:
                  path: artifacts
                  merge-multiple: true

            - name: List downloaded artifacts
              run: find artifacts -name "*.node" -type f

            - name: Install dependencies
              run: deno install

            - name: Move artifacts to npm packages
              run: deno run -A npm:@napi-rs/cli/napi artifacts --npm-dir npm --build-output-dir artifacts

            - name: List packages
              run: ls -laR npm/

            - name: Publish platform packages first
              run: |
                  for dir in npm/*/; do
                    if [ -d "$dir" ]; then
                      PKG_NAME=$(node -p "require('./${dir}package.json').name")
                      PKG_VERSION=$(node -p "require('./${dir}package.json').version")
                      echo "Checking $PKG_NAME@$PKG_VERSION..."
                      if npm view "$PKG_NAME@$PKG_VERSION" version 2>/dev/null; then
                        echo "  Already published, skipping"
                      else
                        echo "  Publishing $dir"
                        npm publish "$dir" --access public --provenance
                      fi
                    fi
                  done
              env:
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

            - name: Publish macroforge
              run: |
                  PKG_NAME=$(node -p "require('./package.json').name")
                  PKG_VERSION=$(node -p "require('./package.json').version")
                  echo "Checking $PKG_NAME@$PKG_VERSION..."
                  if npm view "$PKG_NAME@$PKG_VERSION" version 2>/dev/null; then
                    echo "  Already published, skipping"
                  else
                    echo "  Publishing macroforge"
                    npm publish --access public --provenance
                  fi
              env:
                  NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

            - name: Install Rust
              uses: dtolnay/rust-toolchain@stable

            - name: Publish to crates.io
              run: |
                  CRATE_VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
                  echo "Checking macroforge_ts@$CRATE_VERSION on crates.io..."
                  if cargo search macroforge_ts --limit 1 | grep -q "macroforge_ts = \"$CRATE_VERSION\""; then
                    echo "  Already published, skipping"
                  else
                    echo "  Publishing to crates.io"
                    cargo publish --allow-dirty
                  fi
              env:
                  CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}