icepick 0.4.1

Experimental Rust client for Apache Iceberg with WASM support for AWS S3 Tables and Cloudflare R2
Documentation
name: Release

on:
  push:
    tags: ["v*"]
  workflow_dispatch:
    inputs:
      tag:
        description: "Release tag (e.g., v0.3.0)"
        required: true
        type: string

env:
  RUST_BACKTRACE: 1
  CARGO_TERM_COLOR: always
  RUSTFLAGS: -Dwarnings

jobs:
  # Determine the tag to use (from push or workflow_dispatch)
  prepare:
    name: Prepare Release
    runs-on: ubuntu-latest
    outputs:
      tag: ${{ steps.tag.outputs.tag }}
      version: ${{ steps.tag.outputs.version }}
    steps:
      - uses: actions/checkout@v4

      - name: Determine tag
        id: tag
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            TAG="${{ inputs.tag }}"
          else
            TAG="${{ github.ref_name }}"
          fi
          # Validate tag format
          if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+.*$ ]]; then
            echo "::error::Invalid tag format: $TAG (expected vX.Y.Z)"
            exit 1
          fi
          VERSION="${TAG#v}"
          echo "tag=$TAG" >> "$GITHUB_OUTPUT"
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"

      - name: Verify Cargo.toml version matches tag
        run: |
          CARGO_VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
          if [ "$CARGO_VERSION" != "${{ steps.tag.outputs.version }}" ]; then
            echo "::error::Cargo.toml version ($CARGO_VERSION) does not match tag (${{ steps.tag.outputs.version }})"
            exit 1
          fi
          echo "Version verified: $CARGO_VERSION"

  # Validate the release before publishing
  validate:
    name: Validate Release
    runs-on: ubuntu-latest
    needs: prepare
    steps:
      - uses: actions/checkout@v5

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - uses: Swatinem/rust-cache@v2

      - name: Check formatting
        run: cargo fmt -- --check

      - name: Run clippy
        run: cargo clippy --all-targets --all-features -- -D warnings

      - name: Run all tests
        run: cargo test --verbose

      - name: Build release
        run: cargo build --release --verbose

      - name: Verify WASM compatibility
        run: |
          rustup target add wasm32-unknown-unknown
          cargo build --target wasm32-unknown-unknown --release

      - name: Check documentation
        run: cargo doc --no-deps --all-features

  # Cargo publish dry run
  publish-check:
    name: Cargo Publish (Dry Run)
    runs-on: ubuntu-latest
    needs: [prepare, validate]
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - uses: Swatinem/rust-cache@v2

      - name: Cargo publish dry run
        run: cargo publish --dry-run

  # Create GitHub release
  github-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs: [prepare, publish-check]
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4

      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          gh release create ${{ needs.prepare.outputs.tag }} \
            --title "${{ needs.prepare.outputs.tag }}" \
            --generate-notes

  # Publish to crates.io
  publish:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    needs: [prepare, github-release]
    steps:
      - uses: actions/checkout@v4

      - name: Install Rust
        uses: dtolnay/rust-toolchain@stable

      - uses: Swatinem/rust-cache@v2

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish