Repository navigation
Build: Narrow only quarantined ranges when generating sandboxes - #35775
Merged
Merged
Conversation
The age-gate recovery path ran `yarn up '*'`, which is documented as the counterpart to `yarn upgrade --latest`: it ignores the declared ranges and moves every dependency to its newest allowed release. One template failing to resolve therefore rewrote the template's whole manifest. Hand `yarn up` only the packages Yarn reported as quarantined, anchored at the bottom of the major they already declared, so a workaround for one dependency cannot upgrade the rest of the template.
Contributor
WalkthroughThe lockfile refresh now handles Yarn age-gate failures through targeted dependency upgrades. It preserves declared version bounds, rejects unsafe prerelease ranges, retries bounded rounds, handles failure cases, and adds comprehensive tests. ChangesLockfile refresh
Sequence Diagram(s)sequenceDiagram
participant refreshBeforeStorybookLockfile
participant Yarn
participant PackageManifest
refreshBeforeStorybookLockfile->>Yarn: Run lockfile installation
Yarn-->>refreshBeforeStorybookLockfile: Return YN0016 package failures
refreshBeforeStorybookLockfile->>PackageManifest: Read dependency ranges
PackageManifest-->>refreshBeforeStorybookLockfile: Return bounded descriptors
refreshBeforeStorybookLockfile->>Yarn: Run targeted retry
Yarn-->>refreshBeforeStorybookLockfile: Return installation result
Possibly related PRs
✨ Finishing Touches📝 Generate docstrings
Comment |
Contributor
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/sandbox/utils/yarn.test.ts`:
- Around line 111-119: Update failResolveSteps so it only stores the supplied
errors for the test, without calling mockImplementation. Add a beforeEach block
that installs the single runCommand mock implementation, consuming the queued
errors for resolve steps while preserving the existing successful response
behavior.
- Around line 17-18: Update the generate module mock in yarn.test.ts to use a
spy mock via vi.mock('../generate.ts', { spy: true }). Move runCommand’s
mockImplementation from failResolveSteps into beforeEach, and leave
failResolveSteps responsible only for configuring the error queue consumed by
that implementation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 0948e7d4-a2ee-43f6-9fd6-2ff51671ccdf
📒 Files selected for processing (3)
scripts/sandbox/generate.tsscripts/sandbox/utils/yarn.test.tsscripts/sandbox/utils/yarn.ts
ndelangen
approved these changes
Aug 6, 2026
This was referenced Aug 6, 2026
Merged
1 of 9 tasks
ndelangen
pushed a commit
that referenced
this pull request
Aug 6, 2026
…narrow-ranges Build: Narrow only quarantined ranges when generating sandboxes (cherry picked from commit 98fb332)
3 of 9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What I did
We generate sandboxes with a 7 day npm minimum age gate now, so a package published within the last week never ends up in a sandbox. When a declared range has no release old enough to clear that gate, the install cannot resolve at all, and our recovery path upgraded every dependency of the template to its newest allowed version.
That recovery is pretty much the broadest thing we could have done.
yarn upignores the ranges in your manifest per default, it is basically the counterpart toyarn upgrade --latest. So one single blocked package rewrote the whole manifest, 154 files in the last publish:Solution: only narrow the ranges that Yarn actually reports as quarantined, and hand
yarn upan explicit range anchored at the major the template already declared. Yarn respects a range you give it, so it then picks the newest allowed version inside that range, and every other dependency keeps whatever its own scaffolder generated. Regenerating the Angular sandbox now keeps TypeScript on 6 and only moves the Angular packages, which is the minimum needed to get a resolvable lockfile.Two cases fail loudly now instead of quietly publishing a wrong sandbox: a package pinned to a prerelease (every stable release sorts above it, so any narrowing would land on stable) and a package that only its parent can move off. Both are solved by adding the package to that template's age gate exemption list.
Worth knowing: the currently published sandboxes are already mangled, so they need a regeneration once this lands. The failing tanstack jobs are unrelated to this PR, though, that one is an upstream
@tanstack/react-routerrelease and I am handling it separately.Checklist for Contributors
Testing
The changes in this PR are covered in the following automated tests:
Manual testing
"typescript": "^7.0.2":curl -s https://raw.githubusercontent.com/storybookjs/sandboxes/next/angular-vite/default-ts/before-storybook/package.jsoncd code && yarn generate-sandboxes --templates angular-vite/default-ts --debugrepros/angular-vite-default-ts/before-storybook/package.jsonand compare:typescriptstays on~6.x, it must not be^7@types/nodestays on^20.xexpress,rxjs,tslibandprettierkeep the ranges from step 1's pre-gate state@angular/*entries moved, and they stay inside^22⚠️ narrowed 11 range(s) with no release older than the 10080min age gate: @angular/build@^22.0.0, ...angular-vite/21-tsas well and verify it is still on Angular 21.Documentation
MIGRATION.MD
This only touches our own sandbox generation tooling, so there is no user facing surface to document.
Checklist for Maintainers
When this PR is ready for testing, make sure to add
ci:normal,ci:mergedorci:dailyGH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli-storybook/src/sandbox-templates.tsDeclare whether manual QA will be needed for this PR during the next release, through
qa:neededorqa:skipMake sure this PR contains one of the labels below:
Available labels
bug: Internal changes that fixes incorrect behavior.maintenance: User-facing maintenance tasks.dependencies: Upgrading (sometimes downgrading) dependencies.build: Internal-facing build tooling & test updates. Will not show up in release changelog.cleanup: Minor cleanup style change. Will not show up in release changelog.documentation: Documentation only changes. Will not show up in release changelog.feature request: Introducing a new feature.BREAKING CHANGE: Changes that break compatibility in some way with current major version.other: Changes that don't fit in the above categories.🦋 Canary release
This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the
@storybookjs/coreteam here.core team members can create a canary release here or locally with
gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>