name: Publish to pub.dev

on:
  push:
    tags:
      - '[0-9]+.[0-9]+.[0-9]+*'
  workflow_dispatch:

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

permissions:
  contents: read

jobs:
  validate:
    name: Validate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          persist-credentials: false

      - name: Setup Flutter
        uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
        with:
          channel: stable
          cache: true

      - name: Install dependencies
        run: flutter pub get

      - name: Verify formatting
        run: dart format --output=none --set-exit-if-changed lib/ test/ example/lib/

      - name: Analyze code
        run: dart analyze lib/ test/ example/lib/

      - name: Install lcov
        run: sudo apt-get update && sudo apt-get install -y lcov

      - name: Run tests with coverage (90% floor)
        run: ./tool/coverage.sh 90

      - name: Validate publish archive
        run: dart pub publish --dry-run

  publish:
    needs: validate
    permissions:
      id-token: write # Required for authentication using OIDC
    uses: dart-lang/setup-dart/.github/workflows/publish.yml@65eb853c7ba17dde3be364c3d2858773e7144260 # v1

  github-release:
    name: GitHub Release
    needs: publish
    if: startsWith(github.ref, 'refs/tags/')
    runs-on: ubuntu-latest
    permissions:
      contents: write # Required to create the GitHub Release
    steps:
      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          persist-credentials: false

      - name: Extract changelog section
        id: notes
        env:
          VERSION: ${{ github.ref_name }}
        run: |
          notes="$(awk -v ver="$VERSION" '
            $0 ~ "^## \\[" ver "\\]" { flag = 1; next }
            flag && /^## / { exit }
            flag { print }
          ' CHANGELOG.md)"
          if [ -z "$(printf '%s' "$notes" | tr -d '[:space:]')" ]; then
            echo "::error::No CHANGELOG.md section found for $VERSION; refusing to create a release with empty notes." >&2
            exit 1
          fi
          {
            echo 'body<<CHANGELOG_EOF'
            printf '%s\n' "$notes"
            echo 'CHANGELOG_EOF'
          } >> "$GITHUB_OUTPUT"

      - name: Create GitHub Release
        env:
          GH_TOKEN: ${{ github.token }}
          VERSION: ${{ github.ref_name }}
          NOTES: ${{ steps.notes.outputs.body }}
        run: |
          PRERELEASE=""
          case "$VERSION" in
            *-*) PRERELEASE="--prerelease" ;;
            *) PRERELEASE="--latest" ;;
          esac
          gh release create "$VERSION" \
            --title "$VERSION" \
            --notes "$NOTES" \
            --verify-tag \
            $PRERELEASE
