solverforge-ui 0.5.2

Frontend component library for SolverForge constraint-optimization applications
Documentation
name: Release

on:
  push:
    tags:
      - 'v*'
  workflow_dispatch:
    inputs:
      version:
        description: 'Version to release (e.g., 0.2.0)'
        required: true

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  test:
    name: Run Tests
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        run: |
          rm -rf .git
          git init .
          git remote add origin "https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git"
          git fetch --depth=1 origin "${{ github.sha }}"
          git checkout --detach FETCH_HEAD

      - name: Install Rust
        run: |
          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
          echo "$HOME/.cargo/bin" >> $GITHUB_PATH

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

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

      - name: Build
        run: cargo build --release

      - name: Run tests
        run: |
          cargo test
          node --test tests/*.test.js

  create-release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs: [test]

    steps:
      - name: Checkout repository
        run: |
          rm -rf .git
          git init .
          git remote add origin "https://x-access-token:${{ github.token }}@github.com/${{ github.repository }}.git"
          git fetch --force --tags origin "+refs/heads/*:refs/remotes/origin/*"
          git fetch --force origin "${{ github.sha }}"
          git checkout --detach FETCH_HEAD

      - name: Get version
        id: version
        run: |
          if [ -n "${{ github.event.inputs.version }}" ]; then
            echo "version=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT
          else
            echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
          fi

      - name: Extract changelog entry
        id: changelog
        run: |
          VERSION="${{ steps.version.outputs.version }}"
          CHANGELOG_RE="^## (\\[)?${VERSION//./\\.}(\\]| )"
          SECTION=$(awk "/${CHANGELOG_RE}/{flag=1; next} /^## /{flag=0} flag" CHANGELOG.md)
          if ! grep -qE "${CHANGELOG_RE}" CHANGELOG.md; then
            echo "Missing CHANGELOG.md entry for version $VERSION" >&2
            exit 1
          fi
          CHANGELOG="$SECTION"
          if [ -z "$CHANGELOG" ]; then
            CHANGELOG="- See CHANGELOG.md for version $VERSION."
          fi
          echo "changelog<<EOF" >> $GITHUB_OUTPUT
          echo "$CHANGELOG" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Create Release
        env:
          GITHUB_TOKEN: ${{ github.token }}
        run: |
          cat <<'EOF' > release-notes.md
          ## What's Changed

          ${{ steps.changelog.outputs.changelog }}

          ## Installation

          ```toml
          [dependencies]
          solverforge-ui = "${{ steps.version.outputs.version }}"
          ```
          EOF

          release_args=(
            "v${{ steps.version.outputs.version }}"
            --target "${{ github.sha }}"
            --title "v${{ steps.version.outputs.version }}"
            --notes-file release-notes.md
            --verify-tag
          )

          if [[ "${{ steps.version.outputs.version }}" == *-* ]]; then
            release_args+=(--prerelease)
          fi

          if gh release view "v${{ steps.version.outputs.version }}" >/dev/null 2>&1; then
            gh release edit "${release_args[@]}"
          else
            gh release create "${release_args[@]}"
          fi