name: Release

on:
  pull_request:
    branches:
      - master
    types:
      - closed

concurrency:
  group: release
  cancel-in-progress: false

jobs:
  release:
    name: Release to crates.io
    runs-on: ubuntu-latest
    permissions:
      contents: write
    if: github.event.pull_request.merged == true
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          ref: master

      - name: Check for changesets
        id: check
        run: |
          if [ ! -d ".changeset" ]; then
            echo "has_changesets=false" >> "$GITHUB_OUTPUT"
            echo "No .changeset directory, skipping release"
            exit 0
          fi

          CHANGESETS=$(find .changeset -maxdepth 1 -name "*.md" ! -name "README.md" 2>/dev/null || true)
          if [ -z "$CHANGESETS" ]; then
            echo "has_changesets=false" >> "$GITHUB_OUTPUT"
            echo "No changesets found, skipping release"
          else
            echo "has_changesets=true" >> "$GITHUB_OUTPUT"
            echo "Found changesets:"
            echo "$CHANGESETS"
          fi

      - uses: cachix/install-nix-action@v27
        if: steps.check.outputs.has_changesets == 'true'
        with:
          github_access_token: ${{ secrets.GITHUB_TOKEN }}
          extra_nix_config: |
            experimental-features = nix-command flakes

      - name: Setup SSH deploy key
        if: steps.check.outputs.has_changesets == 'true'
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/deploy_key
          chmod 600 ~/.ssh/deploy_key
          ssh-keyscan github.com >> ~/.ssh/known_hosts

      - name: Configure Git
        if: steps.check.outputs.has_changesets == 'true'
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          git remote set-url origin git@github.com:fulsomenko/kanban.git

      # bump-version reads changesets, aggregate-changelog reads then deletes them.
      # These two steps must run in this order.
      - name: Bump version from changesets
        if: steps.check.outputs.has_changesets == 'true'
        run: |
          nix develop --command bump-version

      - name: Aggregate changelog
        if: steps.check.outputs.has_changesets == 'true'
        run: |
          nix develop --command aggregate-changelog "${{ github.event.pull_request.number }}"

      - name: Commit release changes
        if: steps.check.outputs.has_changesets == 'true'
        id: release
        run: |
          NEW_VERSION=$(grep -m1 'version = ' Cargo.toml | cut -d'"' -f2)
          echo "new=$NEW_VERSION" >> "$GITHUB_OUTPUT"
          echo "Release version: $NEW_VERSION"
          git add .
          git commit -m "chore: release v${NEW_VERSION}"

      - name: Validate release build
        if: steps.check.outputs.has_changesets == 'true'
        run: |
          nix develop --command validate-release

      - name: Push release commit
        if: steps.check.outputs.has_changesets == 'true'
        env:
          GIT_SSH_COMMAND: "ssh -i ~/.ssh/deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no"
        run: |
          git push origin master

      - name: Publish to crates.io
        if: steps.check.outputs.has_changesets == 'true'
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          echo "Publishing to crates.io..."
          nix run .#publish-crates
          echo "Published successfully"

      - name: Tag version
        if: steps.check.outputs.has_changesets == 'true'
        env:
          GIT_SSH_COMMAND: "ssh -i ~/.ssh/deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no"
        run: |
          git tag "v${{ steps.release.outputs.new }}"
          git push origin "v${{ steps.release.outputs.new }}"

      - name: Create GitHub Release
        if: steps.check.outputs.has_changesets == 'true'
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ steps.release.outputs.new }}
          generate_release_notes: true

      - name: Update PKGBUILD version and sha256
        if: steps.check.outputs.has_changesets == 'true'
        env:
          VERSION: ${{ steps.release.outputs.new }}
        run: |
          set -euo pipefail
          URL="https://github.com/fulsomenko/kanban/archive/v${VERSION}.tar.gz"
          SHA256=$(curl -fsL "$URL" | sha256sum | cut -d' ' -f1)
          sed -i "s|^pkgver=.*|pkgver=${VERSION}|" ./aur/PKGBUILD
          sed -i "s|^pkgrel=.*|pkgrel=1|" ./aur/PKGBUILD
          sed -i "s|sha256sums=.*|sha256sums=(\"${SHA256}\")|" ./aur/PKGBUILD

      - name: Generate .SRCINFO
        if: steps.check.outputs.has_changesets == 'true'
        run: |
          nix shell nixpkgs#pacman -c sh -c '
            PACMAN_ROOT="$(dirname "$(dirname "$(command -v makepkg)")")"
            export MAKEPKG_CONF="$PACMAN_ROOT/etc/makepkg.conf"
            cd aur && makepkg --printsrcinfo > .SRCINFO
          '

      - name: Commit and push AUR files
        if: steps.check.outputs.has_changesets == 'true'
        env:
          GIT_SSH_COMMAND: "ssh -i ~/.ssh/deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no"
        run: |
          git add aur/PKGBUILD aur/.SRCINFO
          if git diff --cached --quiet; then
            echo "No changes to commit"
          else
            git commit -m "chore: update AUR package to v${{ steps.release.outputs.new }}"
            git push origin master
          fi

      - name: Deploy to AUR
        if: steps.check.outputs.has_changesets == 'true'
        uses: KSXGitHub/github-actions-deploy-aur@da03e160361ce01bf087e790b6ffd196d7dccff7
        with:
          pkgname: kanban
          pkgbuild: ./aur/PKGBUILD
          commit_username: github-actions[bot]
          commit_email: 41898282+github-actions[bot]@users.noreply.github.com
          commit_message: "Update to v${{ steps.release.outputs.new }}"
          ssh_private_key: ${{ secrets.AUR_SSH_KEY }}
          updpkgsums: false
          allow_empty_commits: false

      - name: Sync develop with master
        if: steps.check.outputs.has_changesets == 'true'
        env:
          GIT_SSH_COMMAND: "ssh -i ~/.ssh/deploy_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no"
        run: |
          git checkout develop
          git pull origin develop
          if ! git merge origin/master --no-edit; then
            echo "::warning::Failed to auto-merge master into develop. Manual merge required."
            git merge --abort
            exit 0
          fi
          git push origin develop
