name: Publish to Cargo, JSR, & NPM

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      version:
        description: "Version to publish (e.g. v1.2.3). Used when manually dispatching."
        required: false
        type: string

permissions: write-all

jobs:
  codegen:
    runs-on: ubuntu-24.04
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  

      - name: Show files exist
        run: |
          set -euxo pipefail
          ls -la packages/ts || true
          ls -la packages/rust || true
          cat packages/ts/deno.json
          cat packages/ts/package.json
          cat packages/rust/Cargo.toml

      - name: Determine VERSION
        run: |
          set -euo pipefail
          if [ "${{ github.ref_type }}" = "tag" ]; then
            VERSION="${{ github.ref_name }}"
          elif [ -n "${{ inputs.version || '' }}" ]; then
            VERSION="${{ inputs.version }}"
          else
            echo "No tag ref and no 'version' input. Provide a tag (push a tag) or pass inputs.version." >&2
            exit 1
          fi
          # If you don't want the leading 'v' inside files, strip it:
          STRIPPED="${VERSION#v}"
          echo "VERSION=$STRIPPED" >> "$GITHUB_ENV"
          echo "Resolved VERSION=$STRIPPED"

      - name: Set Package Versions to current tag
        run: |
          set -euxo pipefail
          for f in \
            packages/ts/deno.json \
            packages/ts/package.json \
            packages/rust/Cargo.toml
          do
            test -f "$f" || { echo "Missing $f" >&2; exit 1; }
            # replace __PACKAGE_VERSION__ with env VERSION
            sed -i "s/__PACKAGE_VERSION__/${VERSION//\//-}/g" "$f"
          done

      - name: Setup Buf
        uses: bufbuild/buf-setup-action@main
        with:
          github_token: ${{ github.token }}

      - name: Generate code
        run: buf generate

      - name: Copy license & README
        run: |
          cp LICENSE packages/ts
          cp LICENSE packages/rust
          cp README.md packages/ts
          cp README.md packages/rust

      - name: Upload Rust code
        uses: actions/upload-artifact@v4
        with:
          name: rust_code
          path: packages/rust

      - name: Upload TypeScript code
        uses: actions/upload-artifact@v4
        with:
          name: ts_code
          path: packages/ts

      - name: Push to schema registry
        env:
          BUF_TOKEN: ${{ secrets.BUF_TOKEN }}
        run: |
          buf push --tag ${{ github.ref_name }}

  publish-jsr:
    runs-on: ubuntu-24.04
    needs: codegen
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Download TypeScript code
        uses: actions/download-artifact@v4
        with:
          name: ts_code
      - name: Remove package.json (JSR doesn’t need it)
        run: rm -f package.json
      - name: Set up Deno
        uses: denoland/setup-deno@main
        with:
          deno-version: rc
      - name: Publish to JSR
        run: deno publish --unstable-sloppy-imports

  publish-cargo:
    runs-on: ubuntu-24.04
    needs: codegen
    steps:
      - name: Download Rust code
        uses: actions/download-artifact@v4
        with:
          name: rust_code
      - name: Set up Rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
      - name: Check Library
        run: cargo check
      - name: Publish to crates.io
        uses: katyo/publish-crates@v2
        with:
          registry-token: ${{ secrets.CARGO_TOKEN }}
          ignore-unpublished-changes: true