SRE-974: Update vite and storybook, add esbuild resolution for tsup - #9373
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #9373 +/- ##
==========================================
+ Coverage 60.66% 61.01% +0.35%
==========================================
Files 1439 1448 +9
Lines 143119 144648 +1529
Branches 6654 6692 +38
==========================================
+ Hits 86817 88262 +1445
- Misses 55211 55282 +71
- Partials 1091 1104 +13 Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Both The cause is a Sentry-side This is therefore not a failure of this PR, and there is no fix to port: the fault is external. Re-running both jobs once. Generated by Claude Code |
e2e12a8 to
5e9facc
Compare
PR SummaryLow Risk Overview
No application source changes—only manifest pins, one scoped resolution, and lockfile hygiene. Reviewed by Cursor Bugbot for commit c6572ae. Bugbot is set up for automated code reviews on this repo. Configure here. |
Move vite to 7.3.6 in ds-components and storybook to 10.4.6 in petrinaut and refractive, taking @storybook/react-vite to 10.4.6 in both so every Storybook package sits on one version, as Storybook requires. These versions accept esbuild 0.28, so the vite@7.3.5, storybook@10.2.19 and storybook@10.3.6 resolutions no longer earn their place. Keep tsup/esbuild: tsup is unmaintained and still asks for esbuild ^0.27.0, the last remaining route to the vulnerable 0.27.7.
|
The merge queue dropped this PR at 11:05 UTC today with The failure is not this PR's. The same arm64 job passed on #9455's queue branch a few minutes earlier (run 33383240605, 10:38–10:44), with the same four tasks racing but correctly blocking on the file lock, and the error here is a missing There is nothing to port into this PR, because the fix belongs in the build Dockerfiles and is out of scope here: Generated by Claude Code |
Benchmark results
|
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 2002 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 1002 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 3314 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 1527 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 2078 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 1033 | Flame Graph |
policy_resolution_medium
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 102 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 52 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 269 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 108 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 133 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 63 | Flame Graph |
policy_resolution_none
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 2 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 2 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 8 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 3 | Flame Graph |
policy_resolution_small
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 52 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 26 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 94 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 27 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 66 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 29 | Flame Graph |
read_scaling_complete
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id;one_depth | 1 entities | Flame Graph | |
| entity_by_id;one_depth | 10 entities | Flame Graph | |
| entity_by_id;one_depth | 25 entities | Flame Graph | |
| entity_by_id;one_depth | 5 entities | Flame Graph | |
| entity_by_id;one_depth | 50 entities | Flame Graph | |
| entity_by_id;two_depth | 1 entities | Flame Graph | |
| entity_by_id;two_depth | 10 entities | Flame Graph | |
| entity_by_id;two_depth | 25 entities | Flame Graph | |
| entity_by_id;two_depth | 5 entities | Flame Graph | |
| entity_by_id;two_depth | 50 entities | Flame Graph | |
| entity_by_id;zero_depth | 1 entities | Flame Graph | |
| entity_by_id;zero_depth | 10 entities | Flame Graph | |
| entity_by_id;zero_depth | 25 entities | Flame Graph | |
| entity_by_id;zero_depth | 5 entities | Flame Graph | |
| entity_by_id;zero_depth | 50 entities | Flame Graph |
read_scaling_linkless
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id | 1 entities | Flame Graph | |
| entity_by_id | 10 entities | Flame Graph | |
| entity_by_id | 100 entities | Flame Graph | |
| entity_by_id | 1000 entities | Flame Graph | |
| entity_by_id | 10000 entities | Flame Graph |
representative_read_entity
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1
|
Flame Graph |
representative_read_entity_type
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| get_entity_type_by_id | Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba
|
Flame Graph |
representative_read_multiple_entities
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_property | traversal_paths=0 | 0 | |
| entity_by_property | traversal_paths=255 | 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=0 | 0 | |
| link_by_source_by_property | traversal_paths=255 | 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true |
scenarios
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| full_test | query-limited | Flame Graph | |
| full_test | query-unlimited | Flame Graph | |
| linked_queries | query-limited | Flame Graph | |
| linked_queries | query-unlimited | Flame Graph |
Requested by Ciaran Morinan · Slack thread
🌟 What is the purpose of this PR?
This removes
esbuild0.27.7 fromyarn.lockby moving the first-party pins that held it there, leaving a singleresolutionsentry for the one consumer that cannot be moved.Before:
esbuild0.27.7 is in the lockfile. It carries GHSA-g7r4-m6w7-qqqr, a low-severity arbitrary file read in esbuild's development server on Windows (CVSS 2.5), affecting>=0.27.3 <0.28.1and fixed in 0.28.1. Four consumers share that one locked copy, and each declares a range that stops below 0.28:vite@7.3.5andtsup@^8.5.1inlibs/@hashintel/ds-components,storybook@10.3.6inlibs/@hashintel/petrinaut, andstorybook@10.2.19inlibs/@hashintel/refractive.After:
esbuild0.27.7 is absent from the lockfile. Three of those four consumers are moved to versions that accept 0.28 on their own, so they need no help:vite7.3.6 widened its range to^0.27.0 || ^0.28.0, andstorybook10.4.6 widened its chain to include^0.28.0. Onlytsupstill needs aresolutionsentry. The lockfile now holds twoesbuildgroups instead of three, 0.28.2 and 0.25.12, and the 0.25.12 entry is byte-identical tomain— same four descriptors (^0.18.0 || … || ^0.25.0,^0.25.0,^0.25.1,~0.25.0), same resolved version.Bumping the pins is preferred over scoping a
resolutionsentry at each consumer. A resolution silently rewrites a dependency's own declared range, so it has to be revisited every time that consumer's version changes, and entries keyed to exact versions (vite@npm:7.3.5,storybook@npm:10.2.19,storybook@npm:10.3.6) would have gone stale on the next routine bump.🔗 Related links
🚫 Blocked by
🔍 What does this change?
Six version bumps across three workspaces:
libs/@hashintel/ds-componentsvitelibs/@hashintel/petrinautstorybooklibs/@hashintel/petrinaut@storybook/react-vitelibs/@hashintel/refractivestorybooklibs/@hashintel/refractive@storybook/react-viteresolutions+ "tsup/esbuild": "^0.28.1"All are exact pins, as
.yarnrc.ymlsetsdefaultSemverRangePrefix: "".@storybook/react-vitemoves in both workspaces alongsidestorybookbecause Storybook requires its packages in lockstep —@storybook/react-vite@10.4.6declaresstorybook: ^10.4.6as a peer. It had drifted to 10.2.19 in both places whilestorybookitself was 10.3.6 inpetrinaut, so this also closes a pre-existing skew. Every versioned Storybook package in the tree now resolves to 10.4.6:storybook,@storybook/react-vite,@storybook/react,@storybook/builder-vite,@storybook/csf-pluginand@storybook/react-dom-shim.@storybook/csf,@storybook/globaland@storybook/iconsare versioned independently of the 10.x line and are unaffected.The one remaining
resolutionsentry istsup/esbuild.tsup8.5.1 declaresesbuild: ^0.27.0, whose highest match is exactly 0.27.7, so dropping this entry would bring the advisory straight back. It needs no version selector because the lockfile holds a singletsup@npm:^8.5.1entry.storybook9.1.19 inlibs/@hashintel/query-editorandlibs/@hashintel/type-editoris untouched. Itsesbuildrange stops at^0.25.0, so it resolves to the clean 0.25.12 group and can never reach 0.27.Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
Three publishable libraries have their manifests touched, but only in
devDependencies, and no published output changes.ds-componentsis built bytsupandtsc; itsviteis used byvitestand Ladle, not by the library build.petrinautandrefractiveare built byvite8.1.0, which this PR does not change. Storybook is development tooling in all three. So no changeset is required.📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
No
scriptsentry is added, removed or renamed.This is lockfile hygiene rather than a fix for live exposure. The vulnerable code path is esbuild's development server on Windows, reached through
--servediror theserve()API. None oftsup,viteorstorybookreferencesservediror callsserve()anywhere in its publisheddist, so no consumer here started that server. Removing 0.27.7 closes the scanner finding.storybook10.2.19 → 10.4.6 and 10.3.6 → 10.4.6 are minor bumps within the 10.x line. The Storybook builds and thepetrinauttest suite pass on 10.4.6 (see below), and no.storybookconfig or story file needed changing.@storybook/react-vite10.4.6 moves@joshwooding/vite-plugin-react-docgen-typescriptfrom^0.6.4to^0.7.0, which pulls inoxc-parserandoxc-resolver. Those two account for most of the lockfile growth: their platform binaries are optional per-architecture packages, so the lockfile gains around 45 entries while the installed footprint changes by 8 packages. This affects Storybook's docgen at development time only; it is not in any library's build path.yarn dedupe --strategy highestis run as part of this change. The new@emnapiand@napi-rs/wasm-runtimetransitives arrived at versions that left four older copies dedupable, whichyarn lint:yarn-deduplicatetreats as a failure. That check now passes.esbuild 0.28.0's only breaking change is integrity checking in the npm install script.
.yarnrc.ymlsetsenableScripts: false, so that script does not run here in any case; the platform binary comes from the@esbuild/*optional dependency. Nothing in 0.28.0 changes the build API.🐾 Next steps
tsup/esbuildentry can come out whentsuppublishes above 8.5.1, or whends-componentsmoves offtsup. There is no release to wait for:tsup's README declares the project unmaintained and points attsdown, the last publish was 8.5.1 on 2025-11-12, and egoist/tsup#1401, the Renovate PR that performs this exact bump, has been open with no maintainer reply since 2026-06-14. Movingds-componentsfromtsuptotsdownwould remove the last entry and is worth a ticket of its own.🛡 What tests cover this?
Existing tests. This changes no source code.
What I ran locally on this branch:
yarn install— succeeds, and regenerates the lockfile.grep -n 'esbuild@npm:0\.27' yarn.lock— returns nothing.grep -c '0\.27\.7' yarn.lockreturns 0.esbuild@npm:0.25.12entry is byte-identical tomain, compared programmatically rather than by eye.esbuildbinaries are only 0.28.2 (2 copies) and 0.25.12 (5 copies, intsx,bundle-n-require,@ladle/react,type-editorandquery-editor). No 0.27.x is on disk.yarn lint:format— passes.yarn dedupe --strategy highest --check— passes, which is whatyarn lint:yarn-deduplicateruns.yarn workspace @hashintel/ds-components build— passes (tsup+tsc+panda ship).yarn workspace @hashintel/refractive build— passes.yarn workspace @hashintel/refractive build-storybook— passes on Storybook 10.4.6.yarn workspace @hashintel/petrinaut build— passes.yarn workspace @hashintel/ds-components test:unit— 7 files, 87 tests, all pass.yarn workspace @hashintel/petrinaut test:unit— 33 files, 267 tests, all pass.petrinaut's build and tests need@hashintel/petrinaut-corebuilt first; the earlier report that they fail on both this branch andmainwas that missing prerequisite, not a real failure. Withyarn workspace @hashintel/petrinaut-core buildrun beforehand, both pass.turboorders this automatically in CI.❓ How to test this?
yarn install --immutable.grep 'esbuild@npm:0\.27' yarn.lockreturns nothing, and that theesbuild@npm:0.25.12entry is unchanged againstmain.turbo run build --filter '@hashintel/ds-components' --filter '@hashintel/petrinaut' --filter '@hashintel/refractive'and confirm all three succeed.yarn workspace @hashintel/refractive build-storybookand confirm Storybook 10.4.6 builds.📹 Demo
Not applicable.
Generated by Claude Code