Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,34 @@

- name: GitHub Actions linter
uses: docker://rhysd/actionlint:1.7.12@sha256:b1934ee5f1c509618f2508e6eb47ee0d3520686341fec936f3b79331f9315667

vite-toolchain-drift:
name: Check vite-plus/vite/vitest drift [vp migrate]
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Setup Node.js
uses: ./.github/actions/setup-node

# Fails if vite-plus, vite, vitest, or the @vitest/* family have drifted
# out of the alignment vp migrate expects (e.g. a raw version pin
# instead of a catalog: reference, or a version vite-plus does not
# bundle). Complements the Renovate `vite monorepo` packageRules group,
# which prevents a *Renovate* PR from splitting these updates, by also
# catching drift introduced by a manual edit. See
# openspec/changes/fix-vite-plus-dependency-drift.
- name: Run vp migrate and check for drift
run: |
pnpm exec vp migrate --no-interactive
if ! git diff --quiet; then
echo "::error::vp migrate produced changes. This means vite-plus, vite, vitest, or the @vitest/* family have drifted out of alignment. Run 'pnpm exec vp migrate' locally and commit the result."
git diff
exit 1
fi
65 changes: 65 additions & 0 deletions .github/workflows/renovate-vite-migrate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Renovate vite toolchain reconcile

# Runs `vp migrate` against Renovate's grouped vite-plus/vite/vitest PR branch
# and pushes back any reconciliation it makes (catalog/override alignment),
# so the versions vite-plus bundles internally and the versions this project
# depends on directly can never land out of sync. See
# openspec/changes/fix-vite-plus-dependency-drift for the incident history
# and rationale.
#
# Triggered on file changes rather than branch name, since Renovate's grouped
# branch/slug naming for the "vite monorepo" packageRules group has not been
# empirically confirmed yet (see design.md open questions).
on:
pull_request:
types: [opened, synchronize]
paths:
- package.json
- pnpm-lock.yaml
- pnpm-workspace.yaml

permissions: {}

jobs:
vp-migrate:
name: Reconcile vite-plus/vite/vitest versions
runs-on: ubuntu-latest
# Only Renovate's own branches: this workflow pushes commits back onto
# the PR branch, which would be surprising (and is unnecessary) on a
# human-authored PR.
if: github.event.pull_request.user.login == 'renovate[bot]'
permissions:
contents: write

steps:
- name: Checkout PR head
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.event.pull_request.head.ref }}
persist-credentials: true

- name: Setup Node.js
uses: ./.github/actions/setup-node

- name: Run vp migrate
run: pnpm exec vp migrate --no-interactive

- name: Commit and push reconciliation, if any
env:
GIT_AUTHOR_NAME: github-actions[bot]
GIT_AUTHOR_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
GIT_COMMITTER_NAME: github-actions[bot]
GIT_COMMITTER_EMAIL: 41898282+github-actions[bot]@users.noreply.github.com
# Routed through env rather than interpolated directly into the
# script, per actionlint/zizmor: github.event.pull_request.head.ref
# is attacker-influenceable (a PR author controls their own branch
# name) and must not be expanded directly inside a run: block.
HEAD_REF: ${{ github.event.pull_request.head.ref }}
run: |
if git diff --quiet; then
echo "vp migrate produced no changes; nothing to commit."
exit 0
fi
git add -A
git commit -m "chore(deps): reconcile vite-plus/vite/vitest versions via vp migrate"
git push origin "HEAD:${HEAD_REF}"
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ pnpm dev

Tooling is unified through [Vite+][vite-plus-website], which bundles the linter (oxlint), formatter (oxfmt), test runner (Vitest), and dev/build pipeline (Vite).

> [!IMPORTANT]
> `vite-plus`, `vite`, `vitest`, and the `@vitest/*` family are version-coupled: `vite-plus` bundles/targets a specific `vite`/`vitest` release internally, and this project depends on the same real packages directly. Bumping one side independently has broken the test suite before by loading two different `vitest` copies into the test workers. Renovate groups these packages into a single PR, and CI (`vp migrate --no-interactive`, currently advisory) fails if they drift apart — but if you ever bump one of these packages by hand, always run `pnpm exec vp migrate` afterward and let it manage `package.json`/`pnpm-workspace.yaml` (catalog references), rather than pinning a raw version yourself. See `openspec/changes/fix-vite-plus-dependency-drift` for the incident history.

```shell
# Run lint, format, and type checks
pnpm check
Expand Down
9 changes: 5 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@
"@types/react-router-dom": "5.3.3",
"@types/semver": "7.8.0",
"@vitejs/plugin-react": "6.1.0",
"@vitest/browser-playwright": "4.1.10",
"@vitest/coverage-v8": "4.1.10",
"@vitest/browser-playwright": "catalog:",
"@vitest/coverage-v8": "catalog:",
"clsx": "2.1.1",
"concurrently": "10.0.5",
"date-fns": "4.4.0",
Expand All @@ -128,10 +128,11 @@
"tailwind-merge": "3.6.0",
"tailwindcss": "4.3.3",
"typescript": "7.0.2",
"vite": "8.2.2",
"vite": "catalog:",
"vite-plugin-checker": "0.14.5",
"vite-plugin-electron": "1.1.1",
"vite-plus": "0.2.9",
"vite-plus": "catalog:",
"vitest": "catalog:",
"zustand": "5.0.15"
},
"engines": {
Expand Down
Loading