name: Publish SDK to npm

on:
  release:
    types: [published]
  workflow_dispatch:
    inputs:
      version:
        description: "Version to publish (e.g., 1.0.0). Leave empty to use package.json version."
        required: false
      dry-run:
        description: "Dry run (don't actually publish)"
        type: boolean
        default: false

permissions:
  contents: write

jobs:
  publish:
    name: Build & Publish @debros/orama
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: sdk

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Verify VERSION file matches release tag
        if: github.event_name == 'release'
        working-directory: .
        run: |
          TAG="${{ github.event.release.tag_name }}"
          EXPECTED="${TAG#v}"
          EXPECTED="${EXPECTED%-nightly}"
          ACTUAL=$(tr -d '[:space:]' < VERSION)
          if [ "$EXPECTED" != "$ACTUAL" ]; then
            echo "::error::Tag $TAG implies version '$EXPECTED' but /VERSION says '$ACTUAL'."
            echo "::error::Run 'make -C core bump VER=$EXPECTED' and commit before tagging."
            exit 1
          fi

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: 9

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Bump version
        run: |
          if [ "${{ github.event_name }}" = "release" ]; then
            VERSION="${{ github.event.release.tag_name }}"
            VERSION="${VERSION#v}"
            # --allow-same-version: when /VERSION was already bumped on the
            # source branch before tagging, package.json may already match
            # the tag. npm version errors as 'Version not changed' without
            # this flag.
            npm version "$VERSION" --no-git-tag-version --allow-same-version
          elif [ -n "${{ inputs.version }}" ]; then
            npm version ${{ inputs.version }} --no-git-tag-version --allow-same-version
          fi

      - name: Typecheck
        run: pnpm typecheck

      - name: Build
        run: pnpm build

      - name: Run unit tests
        run: pnpm vitest run tests/unit

      - name: Publish (dry run)
        if: inputs.dry-run == true
        run: npm publish --access public --dry-run
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Publish
        if: github.event_name == 'release' || inputs.dry-run != true
        run: |
          if [[ "${{ github.event.release.target_commitish }}" != "main" && "${{ github.event_name }}" == "release" ]]; then
            npm publish --access public --tag nightly
          else
            npm publish --access public
          fi
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

      - name: Get published version
        if: github.event_name == 'release' || inputs.dry-run != true
        id: version
        run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT

      - name: Create git tag
        if: github.event_name != 'release' && inputs.dry-run != true
        working-directory: .
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git tag "sdk/v${{ steps.version.outputs.version }}"
          git push origin "sdk/v${{ steps.version.outputs.version }}"
