mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 20:07:18 +01:00
Move ts_core and web_ui to vitest 5, React 19.3 and pnpm 12
Clears the last of the dependency-freshness backlog, so the gate exits 0 with only the pre-existing npm:typescript exception. vitest 5's text reporter no longer prints a per-file table; the summary and coverage-final.json still carry the real numbers, and both packages hold their 100% thresholds. CI's pnpm/action-setup moves 10 -> 12 to match the regenerated packageManager field, rather than relying on pnpm 10 self-switching to 12.4.1 at install time. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019kMvSMtsVMB3d2uoZ56pbp
This commit is contained in:
parent
be4269ab79
commit
c952cc13ef
2
.github/workflows/ts-core-tests.yml
vendored
2
.github/workflows/ts-core-tests.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
version: 12
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
|
||||
2
.github/workflows/web-ui-tests.yml
vendored
2
.github/workflows/web-ui-tests.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
- uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
version: 12
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
|
||||
@ -1,127 +0,0 @@
|
||||
# TODO — utils deps, session 1 of 2: the mechanical bumps
|
||||
|
||||
REMOVE ME AFTER FINISH
|
||||
|
||||
Running order: **this file first**, then `TODO-deps-02-major-upgrades.md`.
|
||||
Session 2 does not depend on this one having run, but doing this first shrinks
|
||||
the gate output to just the three majors, so a failure in session 2 is
|
||||
unambiguous.
|
||||
|
||||
## Why this exists
|
||||
|
||||
`~/src/utils` has been red on the **dependency freshness** CI workflow since
|
||||
2026-09-11 — every run on `main` since commit `001670f` has failed. It is not
|
||||
a broken build: upstream moved and the exact pins did not. Measured
|
||||
2026-09-12 with `./scripts/check_dependency_freshness.sh --all` (exit 1,
|
||||
29 findings across 9 sub-packages).
|
||||
|
||||
This session does the **16 low-risk bumps only**. The three majors
|
||||
(`very_good_analysis 11`, `vitest`/`@vitest/coverage-v8 5`, `pnpm 12`) are
|
||||
session 2's job — do not touch them here, they need hand edits and a
|
||||
separate blast-radius check.
|
||||
|
||||
`~/src/utils` is a shared monorepo: 8 Flutter apps consume its Dart packages
|
||||
(`home_inventory`, `kuhylog`, `lyricanki`, `punchme`, `todo`, `untools`,
|
||||
`restaurant-rater`, `epopeja_karta`) and 4 TS repos consume `@kuhyx/ts-core`
|
||||
/ `@kuhyx/web-ui` (`europe-county-map`, `iron-and-anvil`,
|
||||
`awesome-mcp-explorer`, `konbini-67`). Breaking a pin here breaks twelve
|
||||
downstream repos, which is why every sub-package's suite must go green before
|
||||
you commit.
|
||||
|
||||
## Read first
|
||||
|
||||
- `rules/dependency-freshness.instructions.md` — exact pins, stable only, the
|
||||
two allowlist classes, and **never `--no-verify`**.
|
||||
- `dependency-freshness.allowlist.yaml` — top-of-file comment explains the two
|
||||
entry classes. It already holds ONE active entry (`npm:typescript` pinned
|
||||
6.0.3, `blocked_by: transitive:typescript-eslint@8.70.0`). **Leave it
|
||||
alone.** It is fleet-wide and correct; touching TypeScript is out of scope
|
||||
for both sessions.
|
||||
- `scripts/run_subproject_tests.sh` — pre-commit runs hooks from the git root,
|
||||
but each sub-package's pytest config is relative to its own directory. This
|
||||
wrapper supplies the missing `cd`. Use it; do not hand-roll one.
|
||||
|
||||
## The 16 bumps
|
||||
|
||||
Exact, with the file and line the gate named:
|
||||
|
||||
| Ecosystem | Package | From → To | File |
|
||||
|---|---|---|---|
|
||||
| toolchain | node | 24.20.0 → 24.21.0 | `.github/workflows/ts-core-tests.yml:27` |
|
||||
| toolchain | node | 24.20.0 → 24.21.0 | `.github/workflows/web-ui-tests.yml:27` |
|
||||
| pypi | ruff | 0.16.5 → 0.16.7 | `crdt-sync/requirements.txt:11` |
|
||||
| pypi | types-requests | 2.33.0.20260712 → 2.33.0.20260906 | `crdt-sync/requirements.txt:12` |
|
||||
| pypi | ruff | 0.16.6 → 0.16.7 | `freedays/requirements.txt:10` |
|
||||
| pypi | ruff | 0.16.5 → 0.16.7 | `gatelock/requirements.txt:10` |
|
||||
| pub | test | 1.31.2 → 1.32.0 | `crdt_sync_dart/pubspec.yaml:17` |
|
||||
| pub | flutter_secure_storage | 11.0.0 → 11.1.1 | `crdt_sync_flutter/pubspec.yaml:21` |
|
||||
| npm | eslint | 10.9.1 → 10.10.0 | `ts_core/package.json:34` |
|
||||
| npm | typescript-eslint | 8.68.0 → 8.70.0 | `ts_core/package.json:36` |
|
||||
| npm | eslint | 10.9.1 → 10.10.0 | `web_ui/package.json:43` |
|
||||
| npm | typescript-eslint | 8.68.0 → 8.70.0 | `web_ui/package.json:48` |
|
||||
| npm | @testing-library/user-event | 14.6.6 → 14.6.7 | `web_ui/package.json:39` |
|
||||
| npm | @types/react | 19.2.18 → 19.3.0 | `web_ui/package.json:40` |
|
||||
| npm | @types/react-dom | 19.2.5 → 19.3.0 | `web_ui/package.json:41` |
|
||||
| npm | react + react-dom | 19.2.8 → 19.3.0 | `web_ui/package.json:33,46` |
|
||||
|
||||
`react` and `react-dom` must move together — a split version pair is a
|
||||
runtime error, not a lint finding.
|
||||
|
||||
Note `typescript-eslint 8.70.0` is already the version the allowlist entry
|
||||
names as the TS-7 blocker. Bumping to it is expected and does **not**
|
||||
invalidate that entry; do not edit the allowlist.
|
||||
|
||||
## Constraints you would otherwise rediscover painfully
|
||||
|
||||
- **pnpm only, never npm.** `@kuhyx/web-ui` is consumed as `&path:/web_ui`;
|
||||
npm cannot install a monorepo subdirectory and running it locks the repo
|
||||
into a broken state. Local pnpm is 11.26.0 (leave it — session 2 owns the
|
||||
pnpm 12 move), node is v24.18.0 via nvm. The node bumps above are **CI
|
||||
workflow pins only**; your local node does not need to match.
|
||||
- **250-line cap** on every file, code and prose, enforced by
|
||||
`scripts/check_file_length.sh`.
|
||||
- **No `# noqa`, no `type: ignore`, no per-file-ignores** without asking
|
||||
first, every time. Fix the underlying issue.
|
||||
- **Never `--no-verify`.** If a hook fails, fix the failure.
|
||||
- Heavy commands go through `~/.claude/scripts/capped.sh` (2 GiB / 10% CPU;
|
||||
raise per-invocation with `CAP_MEM=4G CAP_CPU_PCT=20`).
|
||||
- Work on `main`; branch creation is blocked by a hook. Stage narrowly — no
|
||||
blanket `git add .`.
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Apply the 16 edits above. Exact pins, no carets (the `very_good_analysis`
|
||||
carets stay as-is — they are session 2's).
|
||||
2. Regenerate lockfiles where the ecosystem has one:
|
||||
- `crdt_sync_dart`, `crdt_sync_flutter`: `dart pub get` / `flutter pub get`
|
||||
- `ts_core`, `web_ui`: `pnpm install` (in each package directory)
|
||||
- Python requirements have no lockfile here.
|
||||
3. Run each touched sub-package's suite and fix what breaks:
|
||||
- `scripts/run_subproject_tests.sh crdt-sync`
|
||||
- `scripts/run_subproject_tests.sh freedays`
|
||||
- `scripts/run_subproject_tests.sh gatelock`
|
||||
- `cd crdt_sync_dart && dart test`
|
||||
- `cd crdt_sync_flutter && flutter test`
|
||||
- `cd ts_core && pnpm lint && pnpm test`
|
||||
- `cd web_ui && pnpm lint && pnpm test`
|
||||
The React 19.2→19.3 bump is the one most likely to surface a test change;
|
||||
`eslint 10.10.0` may add a rule that fires. Fix the code, not the config.
|
||||
4. `./scripts/check_dependency_freshness.sh --all` — expect exit 1 still, but
|
||||
**only** the three majors remaining (very_good_analysis ×4, vitest ×2,
|
||||
@vitest/coverage-v8 ×2, pnpm ×2). If anything else is listed, you missed a
|
||||
bump.
|
||||
5. `pre-commit run --files <changed files>`.
|
||||
6. Commit and push with `~/.claude/scripts/finish_auto.sh` (it runs the gate,
|
||||
stages narrowly, commits, pushes and watches CI with no LLM turns). Pass
|
||||
the changed files explicitly — it does not stage untracked files on its
|
||||
own.
|
||||
|
||||
## Exit condition
|
||||
|
||||
- `./scripts/check_dependency_freshness.sh --all` lists **only** the three
|
||||
major upgrades named above; every other finding is gone.
|
||||
- Every sub-package suite listed in step 3 passes.
|
||||
- Pushed to `main`, and the **dependency freshness** workflow is the only red
|
||||
CI check left on the repo (it stays red until session 2 lands — that is
|
||||
expected and is why session 2 exists).
|
||||
- Delete this file as part of the final commit.
|
||||
@ -1,141 +0,0 @@
|
||||
# TODO — utils deps, session 2 of 2: the three major upgrades
|
||||
|
||||
REMOVE ME AFTER FINISH
|
||||
|
||||
Running order: `TODO-deps-01-mechanical-bumps.md` first, then **this file**.
|
||||
If session 1 has not run, `./scripts/check_dependency_freshness.sh --all` will
|
||||
list ~16 extra low-risk findings alongside the three below — ignore them here
|
||||
and do session 1 first, or the gate can never reach exit 0.
|
||||
|
||||
## Why this exists
|
||||
|
||||
`~/src/utils` has been red on the **dependency freshness** CI workflow since
|
||||
2026-09-11. Session 1 cleared the mechanical bumps. What is left are three
|
||||
major-version moves, each with real breaking-change surface, measured
|
||||
2026-09-12:
|
||||
|
||||
| Ecosystem | Package | From → To | Files |
|
||||
|---|---|---|---|
|
||||
| pub | very_good_analysis | `^10.3.0` → `11.0.0` | `crdt_sync_flutter/pubspec.yaml:37`, `design_system/pubspec.yaml:20`, `github_device_auth/pubspec.yaml:21`, `sync_settings_ui/pubspec.yaml:25` |
|
||||
| npm | vitest | 4.1.11 → 5.0.0 | `ts_core/package.json:37`, `web_ui/package.json:49` |
|
||||
| npm | @vitest/coverage-v8 | 4.1.11 → 5.0.0 | `ts_core/package.json:33`, `web_ui/package.json:42` |
|
||||
| npm | pnpm | 11.24.0 → 12.4.1 | `ts_core/package.json:12`, `web_ui/package.json:12` |
|
||||
|
||||
`very_good_analysis` keeps a caret by an explicit carve-out in
|
||||
`rules/dependency-freshness.instructions.md` (SDK-coupled packages may keep a
|
||||
range), but **its range floor is still checked** — `^10.3.0` fails because the
|
||||
floor is behind latest. `^11.0.0` is the target, not a bare `11.0.0`.
|
||||
|
||||
`~/src/utils` is shared: 8 Flutter apps consume its Dart packages
|
||||
(`home_inventory`, `kuhylog`, `lyricanki`, `punchme`, `todo`, `untools`,
|
||||
`restaurant-rater`, `epopeja_karta`) and 4 TS repos consume `@kuhyx/ts-core` /
|
||||
`@kuhyx/web-ui` (`europe-county-map`, `iron-and-anvil`,
|
||||
`awesome-mcp-explorer`, `konbini-67`). Every one of those repos pins its own
|
||||
`very_good_analysis`, so lint changes here are a preview of work they will
|
||||
each need — **do not fix them in this session**, just note what you hit.
|
||||
|
||||
## Read first
|
||||
|
||||
- `rules/dependency-freshness.instructions.md` — the Dart caret carve-out, the
|
||||
"range floor is still checked" rule, and **never `--no-verify`**.
|
||||
- `dependency-freshness.allowlist.yaml` — ONE active entry (`npm:typescript`
|
||||
pinned 6.0.3, `blocked_by: transitive:typescript-eslint@8.70.0`, held
|
||||
fleet-wide). **Leave it alone.** TypeScript stays on 6.0.3 in both sessions.
|
||||
- `design_system/analysis_options.yaml` — line 1 is
|
||||
`include: package:very_good_analysis/analysis_options.yaml`, so the lint set
|
||||
changes the moment the pin moves. The other three Dart packages follow the
|
||||
same pattern.
|
||||
|
||||
## What `very_good_analysis 11` actually changes
|
||||
|
||||
Recorded when the fleet first hit this (2026-09-11), so expect these three
|
||||
and confirm against the package's own changelog before assuming the list is
|
||||
complete:
|
||||
|
||||
- `async_return_with_no_await` — **needs hand edits.** Not auto-fixable.
|
||||
- `unnecessary_type_name_in_constructor` — `dart fix --apply` handles it.
|
||||
- `unnecessary_const_in_enum_constructor` — `dart fix --apply` handles it.
|
||||
|
||||
For scale: in `betting-sim` the two auto-fixable rules alone hit 164 sites.
|
||||
The four utils packages are much smaller, but run `dart fix --dry-run` first
|
||||
so you know what you are about to change.
|
||||
|
||||
## Constraints you would otherwise rediscover painfully
|
||||
|
||||
- **pnpm only, never npm.** `@kuhyx/web-ui` is consumed as `&path:/web_ui`;
|
||||
npm cannot install a monorepo subdirectory.
|
||||
- **The pnpm 11 → 12 move is the riskiest item here.** Local pnpm is 11.26.0
|
||||
and `corepack` is present at `~/.nvm/versions/node/v24.18.0/bin/corepack`.
|
||||
The `packageManager` field carries a full `+sha512...` integrity hash —
|
||||
regenerate it, do not hand-edit the hash. A past "Failed to switch pnpm to
|
||||
vX" was a **stale shim in `$PNPM_HOME`**, not a pnpm bug; if you see it,
|
||||
look for a stale binary on `PATH` and never delete `PNPM_HOME` itself.
|
||||
- **`vitest 5` is a major** — check its migration notes for config and
|
||||
coverage-provider changes before editing. `vitest` and
|
||||
`@vitest/coverage-v8` must move together; a version-skewed pair fails at
|
||||
coverage time, not at install time.
|
||||
- **Coverage bars are not negotiable.** `scripts/check_coverage.sh` is the
|
||||
adjudicator; if vitest 5 reports coverage differently, fix the config, do
|
||||
not lower the bar.
|
||||
- **No `# noqa` / `type: ignore` / per-file-ignores / lint disables** without
|
||||
asking first, every time. All 7 "unavoidable" disables in a past konbini-67
|
||||
session were reverted — exhaust refactors first.
|
||||
- **250-line cap** on every file, enforced by `scripts/check_file_length.sh`.
|
||||
- Heavy commands through `~/.claude/scripts/capped.sh`
|
||||
(`CAP_MEM=4G CAP_CPU_PCT=20` to raise).
|
||||
- Work on `main`; branching is hook-blocked. Stage narrowly.
|
||||
|
||||
## Procedure
|
||||
|
||||
Do these as **three separate commits**, in this order — each is independently
|
||||
revertable, and mixing them makes a CI failure impossible to attribute.
|
||||
|
||||
**A. `very_good_analysis` → `^11.0.0`** (4 pubspecs)
|
||||
1. Bump all four, then `flutter pub get` / `dart pub get` in each.
|
||||
2. `dart fix --dry-run` in each; review, then `dart fix --apply`.
|
||||
3. Hand-fix every `async_return_with_no_await` finding.
|
||||
4. `flutter analyze` / `dart analyze` clean in all four.
|
||||
5. Suites — all four are Flutter packages, so `flutter test` in each (not
|
||||
`dart test`; only `crdt_sync_dart`, which this session does not touch, is
|
||||
pure Dart): `crdt_sync_flutter`, `design_system`, `github_device_auth`,
|
||||
`sync_settings_ui`.
|
||||
|
||||
**B. `vitest` + `@vitest/coverage-v8` → 5.0.0** (`ts_core`, `web_ui`)
|
||||
1. Bump both packages in both manifests together. `pnpm install` in each.
|
||||
2. `pnpm lint && pnpm test && pnpm coverage` in each.
|
||||
3. If coverage reporting changed shape, fix the config so
|
||||
`scripts/check_coverage.sh` still adjudicates — do not relax the bar.
|
||||
|
||||
**C. `pnpm` → 12.4.1** (`ts_core`, `web_ui`)
|
||||
1. `corepack use pnpm@12.4.1` in each package so the `packageManager` field
|
||||
and its integrity hash are regenerated, not hand-written.
|
||||
2. `pnpm install` in each; commit the updated lockfiles.
|
||||
3. `pnpm lint && pnpm test` in each.
|
||||
4. Sanity-check one downstream consumer still resolves — e.g.
|
||||
`cd ~/src/konbini-67 && pnpm install` — but **do not commit** in that repo.
|
||||
|
||||
After all three: `./scripts/check_dependency_freshness.sh --all` → **exit 0**
|
||||
(the one `npm:typescript` allowlist entry will print as an active exception;
|
||||
that is expected and is not a failure).
|
||||
|
||||
Then `pre-commit run --files <changed>` and push each commit with
|
||||
`~/.claude/scripts/finish_auto.sh`, passing changed files explicitly.
|
||||
|
||||
## Exit condition
|
||||
|
||||
- `./scripts/check_dependency_freshness.sh --all` exits **0**, with only the
|
||||
pre-existing `npm:typescript` exception reported.
|
||||
- All four Dart packages analyze clean; `ts_core` and `web_ui` lint, test and
|
||||
meet their coverage bars.
|
||||
- No new allowlist entries, no new lint suppressions, `typescript` still 6.0.3.
|
||||
- The **dependency freshness** workflow is green on `main` — the whole point;
|
||||
it has been red since 2026-09-11.
|
||||
- Delete this file (and `TODO-deps-01-*` if it is still present) in the final
|
||||
commit.
|
||||
|
||||
## If a transitive conflict blocks a bump
|
||||
|
||||
Stop and ask, per conflict. Exact pins plus latest-everywhere is provably
|
||||
unsatisfiable when a dependency internally constrains a shared transitive.
|
||||
**Never auto-add an allowlist entry** — that is the user's call, and a
|
||||
discretionary entry needs an `expires` date capped at 90 days.
|
||||
@ -9,7 +9,7 @@
|
||||
"node": ">=24",
|
||||
"pnpm": ">=10"
|
||||
},
|
||||
"packageManager": "pnpm@11.24.0+sha512.bd27e345e976dcb0be0b7a1228217b049a817e21b1f355c90dbe7dc46671895a8bc1e6d06c24554505ea93ea0b45f489a27ec1bfbc8de6a9659fca0f16fa0000",
|
||||
"packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
@ -30,10 +30,10 @@
|
||||
"devDependencies": {
|
||||
"@eslint/js": "10.0.1",
|
||||
"@types/node": "26.4.0",
|
||||
"@vitest/coverage-v8": "4.1.11",
|
||||
"eslint": "10.9.1",
|
||||
"@vitest/coverage-v8": "5.0.0",
|
||||
"eslint": "10.10.0",
|
||||
"typescript": "6.0.3",
|
||||
"typescript-eslint": "8.68.0",
|
||||
"vitest": "4.1.11"
|
||||
"typescript-eslint": "8.70.0",
|
||||
"vitest": "5.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
"node": ">=24",
|
||||
"pnpm": ">=10"
|
||||
},
|
||||
"packageManager": "pnpm@11.24.0+sha512.bd27e345e976dcb0be0b7a1228217b049a817e21b1f355c90dbe7dc46671895a8bc1e6d06c24554505ea93ea0b45f489a27ec1bfbc8de6a9659fca0f16fa0000",
|
||||
"packageManager": "pnpm@12.4.1+sha512.2e81e399d73fe8390dab25e06aa788ab7a5908248d2f5a370f82b481147a6a7a367bf8048f9a6fdb6460f21a66f0542dedb8b94ca2c8723596741920b1656d4c",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
@ -36,17 +36,17 @@
|
||||
"@eslint/js": "10.0.1",
|
||||
"@testing-library/jest-dom": "7.0.1",
|
||||
"@testing-library/react": "16.3.3",
|
||||
"@testing-library/user-event": "14.6.6",
|
||||
"@types/react": "19.2.18",
|
||||
"@types/react-dom": "19.2.5",
|
||||
"@vitest/coverage-v8": "4.1.11",
|
||||
"eslint": "10.9.1",
|
||||
"@testing-library/user-event": "14.6.7",
|
||||
"@types/react": "19.3.0",
|
||||
"@types/react-dom": "19.3.0",
|
||||
"@vitest/coverage-v8": "5.0.0",
|
||||
"eslint": "10.10.0",
|
||||
"jsdom": "30.0.1",
|
||||
"react": "19.2.8",
|
||||
"react-dom": "19.2.8",
|
||||
"react": "19.3.0",
|
||||
"react-dom": "19.3.0",
|
||||
"typescript": "6.0.3",
|
||||
"typescript-eslint": "8.68.0",
|
||||
"vitest": "4.1.11",
|
||||
"typescript-eslint": "8.70.0",
|
||||
"vitest": "5.0.0",
|
||||
"@types/node": "26.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user