keygen-rs 0.11.1

Unofficial Rust SDK for integrating with the keygen.sh licensing service.
Documentation
name: Release

on:
  push:
    branches:
      - master
  workflow_dispatch:
    inputs:
      publish-npm:
        description: "Publish @keygen-rs/napi to npm"
        required: false
        type: boolean
        default: false
      publish-wasm:
        description: "Publish @keygen-rs/wasm to npm"
        required: false
        type: boolean
        default: false

permissions:
  contents: write
  pull-requests: write
  id-token: write

env:
  NAPI_WORKING_DIR: packages/keygen-rs-napi
  WASM_WORKING_DIR: packages/keygen-rs-wasm

jobs:
  release-plz:
    name: Release-plz
    runs-on: ubuntu-latest
    outputs:
      releases-created: ${{ steps.release-plz.outputs.releases_created }}
    steps:
      - name: Checkout repository
        uses: actions/checkout@v5
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

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

      - name: Install system dependencies (for tauri-plugin-keygen-rs2)
        run: |
          sudo apt-get update
          sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libglib2.0-dev

      - name: Run release-plz
        id: release-plz
        uses: MarcoIeni/release-plz-action@v0.5
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

  napi-build:
    name: Napi Build - ${{ matrix.target }}
    needs: release-plz
    if: needs.release-plz.outputs.releases-created == 'true' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish-npm == 'true')
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            use-zig: true
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
            use-zig: true
          - target: aarch64-unknown-linux-musl
            os: ubuntu-latest
            use-zig: true
          - target: x86_64-pc-windows-msvc
            os: windows-latest
          - target: aarch64-pc-windows-msvc
            os: windows-latest

    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-version: 22

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

      - uses: Swatinem/rust-cache@v2
        with:
          shared-key: napi-${{ matrix.target }}

      - name: Install ziglang (Linux cross-compile)
        if: matrix.use-zig
        uses: goto-bus-stop/setup-zig@v2

      - name: Install cargo-zigbuild (Linux cross-compile)
        if: matrix.use-zig
        run: cargo install cargo-zigbuild

      - name: Install dependencies
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: npm ci

      - name: Build
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: npx napi build --platform --release --target ${{ matrix.target }} ${{ matrix.use-zig && '--cross-compile' || '' }}

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: bindings-${{ matrix.target }}
          path: |
            ${{ env.NAPI_WORKING_DIR }}/*.node
            ${{ env.NAPI_WORKING_DIR }}/index.js
            ${{ env.NAPI_WORKING_DIR }}/index.d.ts
          if-no-files-found: error

  napi-test:
    name: Napi Test
    needs: napi-build
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-version: 22

      - name: Install dependencies
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: npm ci

      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: bindings-aarch64-apple-darwin
          path: ${{ env.NAPI_WORKING_DIR }}

      - name: Run unit tests
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: npm test

  napi-publish:
    name: Napi Publish
    needs: [napi-build, napi-test]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org

      - name: Install dependencies
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: npm ci

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: ${{ env.NAPI_WORKING_DIR }}/artifacts

      - name: Move artifacts
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: npx napi artifacts

      - name: Sync version from Cargo.toml
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: |
          VERSION=$(grep -A1 '^\[workspace.package\]' ../../Cargo.toml | grep version | sed 's/.*"\(.*\)".*/\1/')
          echo "Syncing npm version to $VERSION"
          npm version "$VERSION" --no-git-tag-version --allow-same-version
          npx napi version

      - name: List packages
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: ls -R npm/

      - name: Publish to npm
        working-directory: ${{ env.NAPI_WORKING_DIR }}
        run: |
          npx napi prepublish -t npm --skip-optional-publish
          for dir in npm/*/; do
            if [ -f "$dir/package.json" ]; then
              npm publish "$dir" --access public --provenance
            fi
          done
          npm publish --access public --provenance
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  wasm-publish:
    name: WASM Publish
    needs: release-plz
    if: needs.release-plz.outputs.releases-created == 'true' || (github.event_name == 'workflow_dispatch' && github.event.inputs.publish-wasm == 'true')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org

      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: wasm32-unknown-unknown

      - uses: Swatinem/rust-cache@v2

      - name: Install wasm-pack
        run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

      - name: Build WASM package
        working-directory: ${{ env.WASM_WORKING_DIR }}
        run: wasm-pack build --target bundler --release

      - name: Prepare package for publish
        working-directory: ${{ env.WASM_WORKING_DIR }}/pkg
        run: |
          npm pkg set name='@keygen-rs/wasm'
          npm pkg set 'repository.type'='git'
          npm pkg set 'repository.url'='https://github.com/ahonn/keygen-rs'
          npm pkg set 'repository.directory'='packages/keygen-rs-wasm'
          VERSION=$(grep -A1 '^\[workspace.package\]' ../../../Cargo.toml | grep version | sed 's/.*"\(.*\)".*/\1/')
          echo "Syncing npm version to $VERSION"
          npm version "$VERSION" --no-git-tag-version --allow-same-version

      - name: Publish to npm
        working-directory: ${{ env.WASM_WORKING_DIR }}/pkg
        run: npm publish --access public --provenance
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}