sdforge 0.5.0-rc.4

Multi-protocol SDK framework with unified macro configuration
name: Release

on:
  push:
    tags:
      - 'v*.*.*'
  workflow_dispatch:

permissions:
  contents: write

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: false

env:
  CARGO_TERM_COLOR: always

jobs:
  verify:
    name: Verify Release
    runs-on: ubuntu-latest
    timeout-minutes: 45
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
      - uses: dtolnay/rust-toolchain@4716b85f2fac3e324e64fa2810f6b5c3905760a5 # 1.97.1
      - name: Install protoc (for grpc feature)
        run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
      - name: Verify build (full features)
        run: cargo build --release --features full --workspace
      - name: Verify tests pass
        run: cargo test --features full --workspace --no-fail-fast

  publish-crates:
    name: Publish to crates.io (conditional)
    needs: verify
    runs-on: ubuntu-latest
    timeout-minutes: 20
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
      - uses: dtolnay/rust-toolchain@4716b85f2fac3e324e64fa2810f6b5c3905760a5 # 1.97.1
      - name: Install protoc (for grpc feature)
        run: sudo apt-get update && sudo apt-get install -y protobuf-compiler

      - name: Check CARGO_REGISTRY_TOKEN
        id: check_token
        env:
          TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          if [ -z "$TOKEN" ]; then
            echo "has_token=false" >> $GITHUB_OUTPUT
            echo "No CARGO_REGISTRY_TOKEN secret set, skipping publish."
          else
            echo "has_token=true" >> $GITHUB_OUTPUT
          fi

      - name: Resolve version from tag
        id: ver
        run: echo "version=${GITHUB_REF_NAME#v}" >> $GITHUB_OUTPUT

      - name: Check already published
        id: published
        run: |
          CODE=$(curl -s -o /dev/null -w "%{http_code}" https://crates.io/api/v1/crates/sdforge/${{ steps.ver.outputs.version }})
          CODE_M=$(curl -s -o /dev/null -w "%{http_code}" https://crates.io/api/v1/crates/sdforge-macros/${{ steps.ver.outputs.version }})
          echo "crates.io: sdforge=$CODE sdforge-macros=$CODE_M for ${{ steps.ver.outputs.version }}"
          echo "main_exists=$([[ "$CODE" == "200" ]] && echo true || echo false)" >> $GITHUB_OUTPUT
          echo "macros_exists=$([[ "$CODE_M" == "200" ]] && echo true || echo false)" >> $GITHUB_OUTPUT

      - name: Publish sdforge-macros
        if: steps.check_token.outputs.has_token == 'true' && steps.published.outputs.macros_exists == 'false'
        run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} --manifest-path macros/Cargo.toml

      - name: Wait for crates.io index update
        if: steps.check_token.outputs.has_token == 'true' && steps.published.outputs.main_exists == 'false'
        run: sleep 30

      - name: Publish sdforge
        if: steps.check_token.outputs.has_token == 'true' && steps.published.outputs.main_exists == 'false'
        run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }} --features full

  github-release:
    name: Create GitHub Release
    needs: [verify, publish-crates]
    if: ${{ !cancelled() && !failure() }}
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7

      - name: Get version from tag
        id: version
        run: |
          TAG_NAME="${GITHUB_REF#refs/tags/}"
          VERSION="${TAG_NAME#v}"
          echo "tag_name=$TAG_NAME" >> $GITHUB_OUTPUT
          echo "version=$VERSION" >> $GITHUB_OUTPUT

      - name: Install protoc (for grpc feature)
        run: sudo apt-get update && sudo apt-get install -y protobuf-compiler

      - name: Package sdforge-macros
        run: cargo package --no-verify --manifest-path macros/Cargo.toml

      - name: Package sdforge
        continue-on-error: true
        run: cargo package --no-verify --features full

      - name: Collect crate packages
        run: |
          mkdir -p release-assets
          cp target/package/sdforge-macros-*.crate release-assets/ 2>/dev/null || true
          cp target/package/sdforge-*.crate release-assets/ 2>/dev/null || true
          ls -la release-assets/

      - name: Create Release
        uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 # v3
        with:
          tag_name: ${{ steps.version.outputs.tag_name }}
          name: Release ${{ steps.version.outputs.tag_name }}
          generate_release_notes: true
          files: |
            release-assets/*.crate
          draft: false
          prerelease: ${{ contains(github.ref, '-rc') || contains(github.ref, '-beta') || contains(github.ref, '-alpha') }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}