openrouter-rs 0.11.1

A type-safe OpenRouter Rust SDK
Documentation
name: CLI Release

on:
  push:
    tags:
      - "openrouter-cli-v*.*.*"

permissions:
  contents: write

concurrency:
  group: cli-release-${{ github.ref }}
  cancel-in-progress: true

jobs:
  verify:
    name: Verify CLI release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Rust (stable)
        uses: dtolnay/rust-toolchain@stable

      - name: Cache Rust artifacts
        uses: Swatinem/rust-cache@v2

      - name: Check tag matches crates/openrouter-cli/Cargo.toml version
        run: |
          TAG_VERSION="${GITHUB_REF_NAME#openrouter-cli-v}"
          CRATE_VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' crates/openrouter-cli/Cargo.toml | head -n 1)"
          if [ "$TAG_VERSION" != "$CRATE_VERSION" ]; then
            echo "Tag version ($TAG_VERSION) does not match openrouter-cli version ($CRATE_VERSION)."
            exit 1
          fi

      - name: Run CLI tests
        run: cargo test -p openrouter-cli

      - name: Validate CLI package contents
        run: cargo package -p openrouter-cli --locked

  publish-crates-io:
    name: Publish openrouter-cli to crates.io
    needs: verify
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Rust (stable)
        uses: dtolnay/rust-toolchain@stable

      - name: Cache Rust artifacts
        uses: Swatinem/rust-cache@v2

      - name: Publish openrouter-cli (skip when already published)
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          set -euo pipefail
          VERSION="${GITHUB_REF_NAME#openrouter-cli-v}"

          if [ -z "${CARGO_REGISTRY_TOKEN}" ]; then
            echo "CARGO_REGISTRY_TOKEN is required for CLI release publishing."
            exit 1
          fi

          if curl -fsS "https://crates.io/api/v1/crates/openrouter-cli/${VERSION}" > /dev/null; then
            echo "openrouter-cli ${VERSION} is already published; skipping cargo publish."
            exit 0
          fi

          cargo publish -p openrouter-cli --locked --token "${CARGO_REGISTRY_TOKEN}"

  build-binaries:
    name: Build CLI binary (${{ matrix.target }})
    needs: [verify, publish-crates-io]
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
            exe_suffix: ""
          - os: macos-14
            target: aarch64-apple-darwin
            exe_suffix: ""
    steps:
      - name: Checkout
        uses: actions/checkout@v5

      - name: Setup Rust (stable)
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Cache Rust artifacts
        uses: Swatinem/rust-cache@v2

      - name: Build openrouter-cli
        run: cargo build --release --locked -p openrouter-cli --target ${{ matrix.target }}

      - name: Package release asset
        shell: bash
        run: |
          set -euo pipefail
          VERSION="${GITHUB_REF_NAME#openrouter-cli-v}"
          TARGET="${{ matrix.target }}"
          BIN="openrouter-cli${{ matrix.exe_suffix }}"
          ASSET="openrouter-cli-${VERSION}-${TARGET}.tar.gz"

          mkdir -p dist
          cp "target/${TARGET}/release/${BIN}" "dist/${BIN}"
          cp crates/openrouter-cli/README.md dist/README.md
          cp LICENSE dist/LICENSE

          tar -C dist -czf "${ASSET}" "${BIN}" README.md LICENSE

      - name: Upload binary artifact
        uses: actions/upload-artifact@v7
        with:
          name: openrouter-cli-${{ matrix.target }}
          path: openrouter-cli-*.tar.gz

  publish-release:
    name: Publish CLI release assets
    needs: build-binaries
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v5
        with:
          fetch-depth: 0

      - name: Download built artifacts
        uses: actions/download-artifact@v8
        with:
          path: dist

      - name: Build checksum manifest
        shell: bash
        run: |
          set -euo pipefail
          find dist -name '*.tar.gz' -type f -exec cp {} . \;
          sha256sum openrouter-cli-*.tar.gz > SHA256SUMS

      - name: Create GitHub release with assets
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          if gh release view "${GITHUB_REF_NAME}" > /dev/null 2>&1; then
            echo "Release ${GITHUB_REF_NAME} already exists; uploading assets with clobber."
            gh release upload "${GITHUB_REF_NAME}" \
              openrouter-cli-*.tar.gz \
              SHA256SUMS \
              --clobber
            exit 0
          fi

          gh release create "${GITHUB_REF_NAME}" \
            openrouter-cli-*.tar.gz \
            SHA256SUMS \
            --generate-notes \
            --verify-tag