- Commit subject prefixed with "[github-actions]" so the audit trail is obvious at a glance in `git log`. - GH_TOKEN exposed as an env var on the commit step so the PAT is also available to any `gh` invocations the step might grow, and the token plumbing is visible at the site where the push happens — not only up at the checkout step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
74 lines
2.9 KiB
YAML
74 lines
2.9 KiB
YAML
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
|