name: Dependabot dedupe

# Dependabot opens a PR after a bump, but `pnpm install` alone doesn't
# dedupe peer copies of packages (e.g. two versions of i18next, each
# holding their own singleton state). That split caused a hydration
# mismatch on #272 until a manual `pnpm dedupe` collapsed them.
#
# This workflow fires on every dependabot PR, runs `pnpm dedupe`, and
# pushes the resulting lockfile update back to the PR branch so the
# subsequent CI run tests the deduped tree.
#
# Requires `DEPENDABOT_DEDUPE_TOKEN` — a repo secret holding a
# fine-grained PAT (or GitHub App token) with `contents: write` on
# this repo. The default `GITHUB_TOKEN` would work for the push but
# would NOT trigger a subsequent CI run on that push (GitHub's
# anti-loop safeguard), leaving the PR with stale green CI from
# before the dedupe commit. A PAT re-triggers CI so the reviewer
# sees test results for the state they'd actually be merging.

on:
  pull_request:
    branches: [main]

permissions:
  contents: write

jobs:
  dedupe:
    if: github.actor == 'dependabot[bot]'
    runs-on: ubuntu-latest
    steps:
      - name: Require DEPENDABOT_DEDUPE_TOKEN
        env:
          TOKEN: ${{ secrets.DEPENDABOT_DEDUPE_TOKEN }}
        run: |
          if [ -z "$TOKEN" ]; then
            echo "::error::DEPENDABOT_DEDUPE_TOKEN is not set. This workflow"
            echo "::error::requires a PAT so the dedupe commit re-triggers CI."
            echo "::error::See .github/workflows/dependabot-dedupe.yml header."
            exit 1
          fi
      - uses: actions/checkout@v6
        with:
          ref: ${{ github.head_ref }}
          # With `persist-credentials: true`, this PAT is stashed by the
          # action (under $RUNNER_TEMP in recent versions) and made
          # available to subsequent git operations in this workspace —
          # so the later `git push` authenticates as the PAT, which is
          # what gets CI to re-trigger on the dedupe commit. `true` is
          # the checkout default; pinned explicitly here because it's
          # load-bearing for this workflow.
          token: ${{ secrets.DEPENDABOT_DEDUPE_TOKEN }}
          persist-credentials: true
      - uses: pnpm/action-setup@v6
      - uses: actions/setup-node@v6
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install --frozen-lockfile=false
      - run: pnpm dedupe
      - name: Commit dedupe changes
        env:
          GH_TOKEN: ${{ secrets.DEPENDABOT_DEDUPE_TOKEN }}
        run: |
          if [ -n "$(git status --porcelain pnpm-lock.yaml)" ]; then
            git config user.name "dependabot[bot]"
            git config user.email "49699333+dependabot[bot]@users.noreply.github.com"
            git add pnpm-lock.yaml
            git commit -m "[github-actions] pnpm dedupe"
            git push
            echo "Deduped lockfile pushed."
          else
            echo "Lockfile already deduped."
          fi
