name: Publish distribution branches

on:
  push:
    branches: [main]

env:
  SOURCE_BRANCH: main
  MARKETPLACE_BRANCH: marketplace
  WEBSITE_DEPLOY_REF: main

concurrency:
  group: publish-distribution-branches
  cancel-in-progress: true

permissions:
  contents: write
  actions: write

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout source branch
        uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
        with:
          ref: ${{ env.SOURCE_BRANCH }}
          fetch-depth: 0

      - name: Extract Node version from package.json
        id: node-version
        run: |
          NODE_VERSION=$(jq -r '.engines.node // "22"' package.json)
          echo "version=${NODE_VERSION}" >> "$GITHUB_OUTPUT"

      - name: Setup Node.js
        uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
        with:
          node-version: ${{ steps.node-version.outputs.version }}

      - name: Install dependencies
        run: npm ci

      - name: Materialize plugin files
        run: node eng/materialize-plugins.mjs

      - name: Build generated files
        run: npm run build

      - name: Fix line endings
        run: bash eng/fix-line-endings.sh

      - name: Publish to distribution branches
        run: |
          set -euo pipefail

          git config user.name "github-actions[bot]"
          git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
          snapshot_dir="$(mktemp -d)"
          marketplace_worktree_dir="$(mktemp -d)"
          marketplace_publish_ref="refs/heads/publish-${MARKETPLACE_BRANCH}"
          marketplace_base_sha=""

          cleanup() {
            git worktree remove --force "${marketplace_worktree_dir}" 2>/dev/null || true
            git update-ref -d "${marketplace_publish_ref}" 2>/dev/null || true
            rm -rf "${snapshot_dir}"
          }
          trap cleanup EXIT

          rsync -a --delete \
            --exclude '.git' \
            --exclude 'node_modules' \
            ./ "${snapshot_dir}/"

          publish_branch() {
            local branch="$1"
            local worktree_dir="$2"
            local publish_ref="$3"

            git fetch origin "${branch}"
            marketplace_base_sha="$(git rev-parse "origin/${branch}")"
            git worktree add --force --detach "${worktree_dir}" "origin/${branch}"

            rsync -a --delete \
              --exclude '.git' \
              --exclude 'node_modules' \
              "${snapshot_dir}/" "${worktree_dir}/"

            (
              cd "${worktree_dir}"
              git add -A
              find plugins -mindepth 2 -maxdepth 2 -type d \( -name agents -o -name skills \) -exec git add -f -- '{}' +
              git commit -m "chore: publish from ${SOURCE_BRANCH}" --allow-empty
              git update-ref "${publish_ref}" HEAD
            )
          }

          publish_branch "${MARKETPLACE_BRANCH}" "${marketplace_worktree_dir}" "${marketplace_publish_ref}"

          git fetch origin "${MARKETPLACE_BRANCH}"
          current_marketplace_tip="$(git rev-parse "origin/${MARKETPLACE_BRANCH}")"
          if [[ "${current_marketplace_tip}" != "${marketplace_base_sha}" ]]; then
            echo "Remote branch tip changed: ${MARKETPLACE_BRANCH} expected ${marketplace_base_sha}, got ${current_marketplace_tip}"
            echo "Concurrent branch update detected during publish. Please rerun the publish workflow."
            exit 1
          fi

          git push origin --atomic \
            "${marketplace_publish_ref}:${MARKETPLACE_BRANCH}"

          echo "Successfully published to ${MARKETPLACE_BRANCH}"

      - name: Dispatch website deployment
        run: gh workflow run deploy-website.yml --ref "${WEBSITE_DEPLOY_REF}"
        env:
          GH_TOKEN: ${{ github.token }}
