name: release

on:
  workflow_dispatch:
  push:
    tags: ["v*"]

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  version:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.v.outputs.version }}
    steps:
      - uses: actions/checkout@v4
      - id: v
        run: echo "version=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"(.*)".*/\1/')" >> "$GITHUB_OUTPUT"

  build:
    needs: version
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: aarch64-apple-darwin
            os: macos-14
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}
      - name: build
        run: cargo build --release --locked --bin pgpaw --target ${{ matrix.target }}
      - name: package
        run: tar -C "target/${{ matrix.target }}/release" -czf "pgpaw-${{ matrix.target }}.tar.gz" pgpaw
      - uses: actions/upload-artifact@v4
        with:
          name: pgpaw-${{ matrix.target }}
          path: pgpaw-${{ matrix.target }}.tar.gz

  release:
    needs: [version, build]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true
      - name: create or update GitHub release
        env:
          GH_TOKEN: ${{ github.token }}
          V: ${{ needs.version.outputs.version }}
        run: |
          if gh release view "v$V" >/dev/null 2>&1; then
            gh release upload "v$V" dist/*.tar.gz --clobber
          else
            gh release create "v$V" dist/*.tar.gz \
              --title "v$V" \
              --notes "Automated release v$V" \
              --target "$GITHUB_SHA"
          fi

  publish-cargo:
    needs: [version]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
          V: ${{ needs.version.outputs.version }}
        run: |
          if curl -sf -A "pgpaw-ci (release workflow)" "https://crates.io/api/v1/crates/pgpaw/$V" >/dev/null; then
            echo "pgpaw $V already on crates.io, skipping publish"
          else
            cargo publish --locked
          fi

  publish-npm:
    needs: [version, release]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"
      - name: sync package version
        working-directory: npm
        env:
          V: ${{ needs.version.outputs.version }}
        run: npm version "$V" --no-git-tag-version --allow-same-version
      - name: publish to npm
        working-directory: npm
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_SECRET_KEY }}
          V: ${{ needs.version.outputs.version }}
        run: |
          if npm view "pgpaw@$V" version >/dev/null 2>&1; then
            echo "pgpaw@$V already on npm, skipping publish"
          else
            npm publish --access public
          fi
