axonflow-sdk-rust 0.1.0

Rust SDK for the AxonFlow AI governance platform
Documentation
name: Release

on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

env:
  AXONFLOW_TELEMETRY: 'off'
  CARGO_TERM_COLOR: always

jobs:
  preflight:
    name: Preflight (CHANGELOG)
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Extract CHANGELOG section for tag
        run: |
          VERSION="${GITHUB_REF#refs/tags/v}"
          awk -v ver="$VERSION" '$0 ~ "^## \\["ver"\\]" {p=1; next} p && /^## \[/ {exit} p {print}' CHANGELOG.md > /tmp/release-body.md
          if [ ! -s /tmp/release-body.md ]; then
            echo "::error::No CHANGELOG.md section found for version $VERSION — refusing to publish."
            echo "::error::Add a '## [$VERSION] - YYYY-MM-DD' section to CHANGELOG.md and re-tag."
            exit 1
          fi
          {
            echo "## AxonFlow Rust SDK v${VERSION}"
            echo ""
            echo "### Installation"
            echo ""
            echo '```toml'
            echo "[dependencies]"
            echo "axonflow-sdk-rust = \"${VERSION}\""
            echo '```'
            echo ""
            echo "### Documentation"
            echo ""
            echo "- [docs.rs](https://docs.rs/axonflow-sdk-rust/${VERSION})"
            echo "- [README](https://github.com/getaxonflow/axonflow-sdk-rust#readme)"
            echo "- [Examples](https://github.com/getaxonflow/axonflow-sdk-rust/tree/main/examples)"
            echo ""
            cat /tmp/release-body.md
          } > /tmp/release-body-final.md
          echo "Release body: $(wc -l < /tmp/release-body-final.md) lines"

      - name: Verify Cargo.toml version matches tag
        run: |
          VERSION="${GITHUB_REF#refs/tags/v}"
          CARGO_VERSION=$(awk -F'"' '/^version *=/ {print $2; exit}' Cargo.toml)
          if [ "$VERSION" != "$CARGO_VERSION" ]; then
            echo "::error::Tag v${VERSION} does not match Cargo.toml version ${CARGO_VERSION}."
            echo "::error::Bump Cargo.toml to ${VERSION} and re-tag."
            exit 1
          fi

      - uses: actions/upload-artifact@v7
        with:
          name: release-body
          path: /tmp/release-body-final.md
          retention-days: 1

  test:
    name: Test (release)
    needs: preflight
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2
      - run: cargo test --all-features
      - run: cargo build --examples

  release:
    name: Create GitHub Release
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - uses: actions/download-artifact@v8
        with:
          name: release-body
          path: /tmp/release-body

      - name: Create Release
        uses: softprops/action-gh-release@v3
        with:
          name: Release ${{ github.ref_name }}
          body_path: /tmp/release-body/release-body-final.md
          generate_release_notes: false
          draft: false
          prerelease: false
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  # Publish to crates.io. Mirrors the PyPI / npm / Maven Central publish-on-tag
  # pattern from the established four SDKs. Requires CARGO_REGISTRY_TOKEN repo
  # secret (https://crates.io/me — generate a publish token, save as a secret).
  #
  # Runs AFTER the GitHub release is created, so a transient crates.io failure
  # does not erase the GH release. If publish fails, fix the underlying issue
  # and run `cargo publish` locally one time, OR cut a patch tag (vX.Y.Z+1).
  publish-cratesio:
    name: Publish to crates.io
    needs: release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable
      - uses: Swatinem/rust-cache@v2

      - name: Verify CARGO_REGISTRY_TOKEN secret is configured
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          if [ -z "$CARGO_REGISTRY_TOKEN" ]; then
            echo "::error::CARGO_REGISTRY_TOKEN secret is not set."
            echo "::error::Generate a publish token at https://crates.io/me and add it as a repo secret."
            exit 1
          fi

      - name: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish

      - name: Wait for crates.io propagation
        run: sleep 30

      - name: Verify version is live on crates.io
        run: |
          VERSION="${GITHUB_REF#refs/tags/v}"
          curl -sf "https://crates.io/api/v1/crates/axonflow-sdk-rust/${VERSION}" > /dev/null \
            || { echo "::error::axonflow-sdk-rust@${VERSION} not found on crates.io after publish."; exit 1; }
          echo "✅ axonflow-sdk-rust@${VERSION} is live on crates.io"