fynd 0.97.3

High-performance DeFi route-finding engine — embeddable library and CLI
name: Release

on:
  release:
    types: [created]

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always

jobs:
  publish-crates:
    name: Publish Crates
    # Pre-releases build a Docker image only; registry publishing happens on
    # full releases.
    if: ${{ !github.event.release.prerelease }}
    runs-on: ubuntu-latest
    timeout-minutes: 30
    env:
      CARGO_REGISTRY_TOKEN: ${{ secrets.CRATESIO_REGISTRY_TOKEN }}
    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Setup toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: Setup Rust Cache
        uses: Swatinem/rust-cache@aa7c1c80a07a27a84c0aa76d0cef0aad3830e330 # v2.7.8
        with:
          cache-on-failure: true

      # Publishes in dependency order, skipping versions already on crates.io so a
      # partially failed release run can be recovered by re-running the job. A single
      # retry (with an index re-check) covers crates.io index propagation lag between
      # consecutive publishes.
      - name: Publish crates
        run: |
          set -euo pipefail
          version="$(cargo metadata --format-version 1 --no-deps \
            | jq -r '.packages[] | select(.name == "fynd") | .version')"
          published() {
            curl -sf "https://crates.io/api/v1/crates/$1/${version}" \
              -H "User-Agent: fynd-ci (github.com/propeller-heads/fynd)" >/dev/null
          }
          for crate in fynd-core fynd-rpc-types fynd-client fynd-rpc fynd; do
            if published "${crate}"; then
              echo "${crate} ${version} already on crates.io, skipping"
              continue
            fi
            if cargo publish --locked --package "${crate}"; then
              continue
            fi
            echo "publish of ${crate} failed, re-checking index and retrying in 30s"
            sleep 30
            if ! published "${crate}"; then
              cargo publish --locked --package "${crate}"
            fi
          done

  publish-npm:
    name: Publish TypeScript packages to npm
    # Pre-releases build a Docker image only; registry publishing happens on
    # full releases (or manual dispatch).
    if: github.event_name == 'workflow_dispatch' || !github.event.release.prerelease
    runs-on: ubuntu-latest
    timeout-minutes: 15
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
        with:
          ref: ${{ github.event.release.tag_name || github.sha }}

      - name: Setup pnpm
        uses: pnpm/action-setup@9fd676a19091d4595eefd76e4bd31c97133911f1 # v4.2.0
        with:
          version: "10.30.3"

      - name: Setup Node
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
        with:
          node-version: "22"
          registry-url: "https://registry.npmjs.org"
          cache: "pnpm"
          cache-dependency-path: clients/typescript/pnpm-lock.yaml

      - name: Update npm (trusted publisher requires >=11.5.1)
        run: npm install -g npm@latest

      - name: Install dependencies
        run: pnpm --dir clients/typescript install --frozen-lockfile

      - name: Set client version from release tag
        if: ${{ github.event.release.tag_name != '' }}
        working-directory: clients/typescript/client
        run: npm version "${{ github.event.release.tag_name }}" --no-git-tag-version --allow-same-version

      - name: Build client
        run: pnpm --dir clients/typescript --filter @kayibal/fynd-client run build

      # Skip when this version is already on npm so a recovered/re-fired release
      # event doesn't fail the job on a duplicate publish.
      - name: Publish client
        working-directory: clients/typescript/client
        run: |
          set -euo pipefail
          name="$(jq -r .name package.json)"
          version="$(jq -r .version package.json)"
          if npm view "${name}@${version}" version >/dev/null 2>&1; then
            echo "${name}@${version} already on npm, skipping"
            exit 0
          fi
          npm publish --provenance --access public