llmshim 0.1.20

Blazing fast LLM API translation layer in pure Rust
Documentation
name: Release

on:
  push:
    tags:
      - "v*"

env:
  PYTHON_VERSION: "3.12"

jobs:
  # --- Run tests first ---
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Check formatting
        run: cargo fmt --check
      - name: Clippy
        run: cargo clippy --features proxy -- -D warnings
      - name: Unit tests
        run: cargo test --features proxy --tests

  # --- Publish to crates.io ---
  crates-io:
    needs: test
    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 }}
        run: cargo publish --allow-dirty

  # --- Build standalone macOS binaries + GitHub release ---
  github-release:
    needs: test
    runs-on: macos-14
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: aarch64-apple-darwin,x86_64-apple-darwin
      - name: Build arm64
        run: cargo build --release --features proxy --target aarch64-apple-darwin
      - name: Build x86_64
        run: cargo build --release --features proxy --target x86_64-apple-darwin
      - name: Package tarballs
        run: |
          for target in aarch64-apple-darwin x86_64-apple-darwin; do
            mkdir -p staging
            cp target/$target/release/llmshim staging/
            tar -czf llmshim-${target}.tar.gz -C staging llmshim
            rm -rf staging
          done
      - name: Create GitHub release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create ${{ github.ref_name }} \
            --title "${{ github.ref_name }}" \
            --generate-notes \
            llmshim-aarch64-apple-darwin.tar.gz \
            llmshim-x86_64-apple-darwin.tar.gz

  # --- Update Homebrew tap ---
  homebrew:
    needs: github-release
    runs-on: macos-14
    steps:
      - name: Update Homebrew formula
        env:
          GH_TOKEN: ${{ secrets.HOMEBREW_TAP_TOKEN }}
        run: |
          VERSION=${GITHUB_REF_NAME#v}
          BASE_URL="https://github.com/sanjay920/llmshim/releases/download/${GITHUB_REF_NAME}"

          # Download tarballs to compute sha256
          curl -sL "${BASE_URL}/llmshim-aarch64-apple-darwin.tar.gz" -o /tmp/arm64.tar.gz
          curl -sL "${BASE_URL}/llmshim-x86_64-apple-darwin.tar.gz" -o /tmp/x86.tar.gz
          SHA_ARM=$(shasum -a 256 /tmp/arm64.tar.gz | cut -d' ' -f1)
          SHA_X86=$(shasum -a 256 /tmp/x86.tar.gz | cut -d' ' -f1)

          # Generate formula
          cat > /tmp/llmshim.rb << 'ENDOFTEMPLATE'
          class Llmshim < Formula
            desc "Blazing fast LLM API translation layer — one interface, every provider"
            homepage "https://github.com/sanjay920/llmshim"
            license "MIT"
            version "VERSION_PLACEHOLDER"

            on_macos do
              if Hardware::CPU.arm?
                url "URL_ARM_PLACEHOLDER"
                sha256 "SHA_ARM_PLACEHOLDER"
              else
                url "URL_X86_PLACEHOLDER"
                sha256 "SHA_X86_PLACEHOLDER"
              end
            end

            def install
              bin.install "llmshim"
            end

            test do
              assert_predicate bin/"llmshim", :executable?
            end
          end
          ENDOFTEMPLATE

          # Replace placeholders
          sed -i '' "s|VERSION_PLACEHOLDER|${VERSION}|g" /tmp/llmshim.rb
          sed -i '' "s|URL_ARM_PLACEHOLDER|${BASE_URL}/llmshim-aarch64-apple-darwin.tar.gz|g" /tmp/llmshim.rb
          sed -i '' "s|URL_X86_PLACEHOLDER|${BASE_URL}/llmshim-x86_64-apple-darwin.tar.gz|g" /tmp/llmshim.rb
          sed -i '' "s|SHA_ARM_PLACEHOLDER|${SHA_ARM}|g" /tmp/llmshim.rb
          sed -i '' "s|SHA_X86_PLACEHOLDER|${SHA_X86}|g" /tmp/llmshim.rb

          # Remove leading whitespace from heredoc
          sed -i '' 's/^          //' /tmp/llmshim.rb

          # Get existing file SHA (if updating)
          EXISTING_SHA=$(gh api repos/sanjay920/homebrew-tap/contents/Formula/llmshim.rb --jq .sha 2>/dev/null || echo "")

          # Push to homebrew-tap repo
          if [ -n "$EXISTING_SHA" ]; then
            gh api repos/sanjay920/homebrew-tap/contents/Formula/llmshim.rb \
              --method PUT \
              --field message="Update llmshim to ${VERSION}" \
              --field content="$(base64 -i /tmp/llmshim.rb)" \
              --field sha="${EXISTING_SHA}"
          else
            gh api repos/sanjay920/homebrew-tap/contents/Formula/llmshim.rb \
              --method PUT \
              --field message="Add llmshim ${VERSION}" \
              --field content="$(base64 -i /tmp/llmshim.rb)"
          fi

  # --- Build PyPI source distribution ---
  sdist:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Build sdist
        uses: PyO3/maturin-action@v1
        with:
          command: sdist
          args: --out dist
          working-directory: clients/python
      - uses: actions/upload-artifact@v4
        with:
          name: wheels-sdist
          path: clients/python/dist

  # --- macOS wheels (ARM64 + x86_64) ---
  macos:
    needs: test
    runs-on: macos-14
    strategy:
      matrix:
        target: [aarch64-apple-darwin, x86_64-apple-darwin]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Build wheel
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --out dist
          working-directory: clients/python
      - uses: actions/upload-artifact@v4
        with:
          name: wheels-macos-${{ matrix.target }}
          path: clients/python/dist

  # --- Linux x86_64 wheel ---
  linux-x86:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Build wheel
        uses: PyO3/maturin-action@v1
        with:
          target: x86_64-unknown-linux-gnu
          manylinux: "2_17"
          args: --release --out dist
          working-directory: clients/python
      - uses: actions/upload-artifact@v4
        with:
          name: wheels-linux-x86_64
          path: clients/python/dist

  # --- Linux aarch64 wheel (use zig for cross-compilation) ---
  linux-arm:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Build wheel
        uses: PyO3/maturin-action@v1
        with:
          target: aarch64-unknown-linux-gnu
          manylinux: "2_17"
          args: --release --out dist --zig
          working-directory: clients/python
      - uses: actions/upload-artifact@v4
        with:
          name: wheels-linux-aarch64
          path: clients/python/dist

  # --- Windows x86_64 wheel ---
  windows:
    needs: test
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ env.PYTHON_VERSION }}
      - name: Build wheel
        uses: PyO3/maturin-action@v1
        with:
          target: x86_64-pc-windows-msvc
          args: --release --out dist
          working-directory: clients/python
      - uses: actions/upload-artifact@v4
        with:
          name: wheels-windows-x86_64
          path: clients/python/dist

  # --- Publish to PyPI ---
  pypi:
    needs: [sdist, macos, linux-x86, linux-arm, windows]
    runs-on: ubuntu-latest
    environment: release
    permissions:
      id-token: write
    steps:
      - uses: actions/download-artifact@v4
        with:
          pattern: wheels-*
          path: dist
          merge-multiple: true
      - name: Publish to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1
        with:
          packages-dir: dist/