litellm-rs 0.6.0

A high-performance AI Gateway written in Rust, providing OpenAI-compatible APIs with intelligent routing, load balancing, and enterprise features
Documentation
name: Version Bump

on:
  workflow_dispatch:
    inputs:
      bump_type:
        description: "Release bump (auto follows conventional commits)"
        type: choice
        default: auto
        options:
          - auto
          - patch
          - minor
          - major
      confirm_breaking_changes:
        description: "I verified the public compatibility gate and migration notes for a breaking release"
        type: boolean
        default: false

env:
  CARGO_TERM_COLOR: always

jobs:
  version-bump:
    name: Analyze and Bump Version
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write

    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: Install cargo-edit
        run: cargo install cargo-edit --locked

      - name: Analyze commits and determine version bump
        id: version
        run: |
          # Get current version
          CURRENT_VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[0].version')
          echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT

          # Get commits since last tag
          LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
          if [ -z "$LAST_TAG" ]; then
            COMMITS=$(git log --oneline)
          else
            COMMITS=$(git log ${LAST_TAG}..HEAD --oneline)
          fi

          echo "Analyzing commits since $LAST_TAG:"
          echo "$COMMITS"

          IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION"
          BREAKING=false
          if git log ${LAST_TAG:+${LAST_TAG}..HEAD} --format='%s%n%b' | grep -E '(^|[[:space:]])(BREAKING[ -]CHANGE:|[[:alnum:]_-]+(\([^)]+\))?!:)' >/dev/null; then
            BREAKING=true
          fi

          if [ "$BREAKING" = true ] && [ "${{ inputs.confirm_breaking_changes }}" != "true" ]; then
            echo "::error::Breaking commits require confirm_breaking_changes=true after compatibility and migration review"
            exit 1
          fi

          REQUESTED_BUMP="${{ inputs.bump_type }}"
          BUMP_TYPE="patch"

          if [ "$BREAKING" = true ]; then
            if [ "$MAJOR" -eq 0 ]; then
              BUMP_TYPE="minor"
            else
              BUMP_TYPE="major"
            fi
          elif grep -E "^[a-f0-9]+ feat(\(.+\))?:" <<< "$COMMITS" >/dev/null; then
            BUMP_TYPE="minor"
          elif grep -E "^[a-f0-9]+ (fix|perf|refactor|style|docs|test|chore)(\(.+\))?:" <<< "$COMMITS" >/dev/null; then
            BUMP_TYPE="patch"
          fi

          if [ "$REQUESTED_BUMP" != "auto" ]; then
            if [ "$BREAKING" = true ]; then
              if [ "$MAJOR" -eq 0 ] && [ "$REQUESTED_BUMP" = "patch" ]; then
                echo "::error::Requested bump '$REQUESTED_BUMP' is too small for detected breaking changes"
                exit 1
              elif [ "$MAJOR" -gt 0 ] && [ "$REQUESTED_BUMP" != "major" ]; then
                echo "::error::Requested bump '$REQUESTED_BUMP' is too small for detected breaking changes"
                exit 1
              fi
            fi
            BUMP_TYPE="$REQUESTED_BUMP"
          fi

          echo "bump_type=$BUMP_TYPE" >> $GITHUB_OUTPUT

          # Calculate new version
          case $BUMP_TYPE in
            major)
              NEW_VERSION="$((MAJOR + 1)).0.0"
              ;;
            minor)
              NEW_VERSION="${MAJOR}.$((MINOR + 1)).0"
              ;;
            patch)
              NEW_VERSION="${MAJOR}.${MINOR}.$((PATCH + 1))"
              ;;
          esac

          echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
          echo "Bumping from $CURRENT_VERSION to $NEW_VERSION ($BUMP_TYPE)"

      - name: Bump version
        if: steps.version.outputs.current_version != steps.version.outputs.new_version
        run: |
          cargo set-version ${{ steps.version.outputs.new_version }}

      - name: Update CHANGELOG
        if: steps.version.outputs.current_version != steps.version.outputs.new_version
        run: |
          NEW_VERSION="${{ steps.version.outputs.new_version }}"
          DATE=$(date +%Y-%m-%d)

          # Get commits for changelog
          LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "")

          # Build changelog entry
          ENTRY="## [$NEW_VERSION] - $DATE\n\n"

          # Categorize commits
          if [ -n "$LAST_TAG" ]; then
            ADDED=$(git log ${LAST_TAG}..HEAD --oneline --grep="^feat" 2>/dev/null | sed 's/^[a-f0-9]* /- /' || true)
            FIXED=$(git log ${LAST_TAG}..HEAD --oneline --grep="^fix" 2>/dev/null | sed 's/^[a-f0-9]* /- /' || true)
            CHANGED=$(git log ${LAST_TAG}..HEAD --oneline --grep="^refactor\|^perf\|^style" 2>/dev/null | sed 's/^[a-f0-9]* /- /' || true)
          fi

          if [ -n "$ADDED" ]; then
            ENTRY="${ENTRY}### Added\n${ADDED}\n\n"
          fi
          if [ -n "$FIXED" ]; then
            ENTRY="${ENTRY}### Fixed\n${FIXED}\n\n"
          fi
          if [ -n "$CHANGED" ]; then
            ENTRY="${ENTRY}### Changed\n${CHANGED}\n\n"
          fi

          # Insert after [Unreleased] section
          sed -i "/## \[Unreleased\]/a\\
          \\
          $(echo -e "$ENTRY" | sed 's/$/\\n/' | tr -d '\n')" CHANGELOG.md

      - name: Commit and push version bump
        if: steps.version.outputs.current_version != steps.version.outputs.new_version
        run: |
          git add Cargo.toml Cargo.lock CHANGELOG.md
          git commit -m "chore(release): bump version to ${{ steps.version.outputs.new_version }}"
          git push

      - name: Create Release Tag
        if: steps.version.outputs.current_version != steps.version.outputs.new_version
        run: |
          git tag -a "v${{ steps.version.outputs.new_version }}" -m "Release v${{ steps.version.outputs.new_version }}"
          git push origin "v${{ steps.version.outputs.new_version }}"

      - name: Summary
        run: |
          echo "## Version Bump Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "| Field | Value |" >> $GITHUB_STEP_SUMMARY
          echo "|-------|-------|" >> $GITHUB_STEP_SUMMARY
          echo "| Previous Version | ${{ steps.version.outputs.current_version }} |" >> $GITHUB_STEP_SUMMARY
          echo "| New Version | ${{ steps.version.outputs.new_version }} |" >> $GITHUB_STEP_SUMMARY
          echo "| Bump Type | ${{ steps.version.outputs.bump_type }} |" >> $GITHUB_STEP_SUMMARY