llmsim 0.2.2

LLM Traffic Simulator - A lightweight, high-performance LLM API simulator
Documentation
name: Release

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  release:
    runs-on: ubuntu-latest
    # On push: only run if commit message matches release pattern
    # On workflow_dispatch: always run (version read from Cargo.toml)
    if: >-
      github.event_name == 'workflow_dispatch' ||
      startsWith(github.event.head_commit.message, 'chore(release): prepare v')
    outputs:
      version: ${{ steps.version.outputs.version }}
      tag: ${{ steps.version.outputs.tag }}

    permissions:
      contents: write
      actions: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Extract version
        id: version
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            # Manual dispatch: read version from Cargo.toml
            VERSION=$(grep '^version = ' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
            echo "Source: Cargo.toml (manual dispatch)"
          else
            # Push trigger: extract version from commit message
            VERSION=$(echo "${{ github.event.head_commit.message }}" | grep -oP 'prepare v\K[0-9]+\.[0-9]+\.[0-9]+')
          fi

          if [ -z "$VERSION" ]; then
            echo "::error::Could not extract version"
            exit 1
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "tag=v$VERSION" >> $GITHUB_OUTPUT
          echo "Extracted version: $VERSION"

      - name: Check if tag already exists
        id: check_tag
        run: |
          if git rev-parse "v${{ steps.version.outputs.version }}" >/dev/null 2>&1; then
            echo "::error::Tag v${{ steps.version.outputs.version }} already exists"
            exit 1
          fi
          echo "Tag does not exist, proceeding..."

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

      - name: Extract release notes from CHANGELOG.md
        id: changelog
        run: |
          VERSION="${{ steps.version.outputs.version }}"

          # Extract the section for this version from CHANGELOG.md
          # Matches from "## [X.Y.Z]" until the next "## [" or end of significant content
          NOTES=$(awk -v ver="$VERSION" '
            /^## \[/ {
              if (found) exit
              if (index($0, "[" ver "]")) found=1
              next
            }
            found && /^## \[/ { exit }
            found { print }
          ' CHANGELOG.md)

          if [ -z "$NOTES" ]; then
            echo "::warning::No changelog entry found for version $VERSION"
            NOTES="Release v$VERSION"
          fi

          # Write to file to preserve formatting
          echo "$NOTES" > release_notes.md
          echo "Release notes extracted:"
          cat release_notes.md

      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create "v${{ steps.version.outputs.version }}" \
            --title "v${{ steps.version.outputs.version }}" \
            --notes-file release_notes.md \
            --target "${{ github.sha }}"

          echo "Created release v${{ steps.version.outputs.version }}"

  # Publish to crates.io by calling the publish workflow directly.
  # GitHub Actions events created by GITHUB_TOKEN do not trigger other workflows,
  # so the release event from the job above won't trigger publish.yml on its own.
  publish:
    needs: release
    uses: ./.github/workflows/publish.yml
    with:
      tag_name: v${{ needs.release.outputs.version }}
    secrets: inherit