From 57baf1168e965692d6c989adf9868feb023d8ed9 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 20 Sep 2024 22:49:40 +0800 Subject: [PATCH 01/40] Chore: remove need to run everything under WSL --- CONTRIBUTING.md | 3 ++- docs/contribute/code.mdx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4f65401dd4a8..879a675fcc3c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,7 @@ Storybook is developed against a specific node version which is defined in an `. ## Ensure you have the required system utilities You will need to have the following installed: + - git - node - yarn @@ -20,7 +21,7 @@ You will need to have the following installed: ## Running the local development environment -- Ensure if you are using Windows to use the Windows Subsystem for Linux (WSL). +- Ensure if you are using Windows to use a terminal with admin privileges. - Run `yarn start` in the root directory to run a basic test Storybook "sandbox". The `yarn start` script will generate a React Vite TypeScript sandbox with a set of test stories inside it, as well as taking all steps required to get it running (building the various packages we need etc). There is no need to run `yarn` or `yarn install` as `yarn start` will do this for you. diff --git a/docs/contribute/code.mdx b/docs/contribute/code.mdx index e3b2e3bd0ceb..f0f9d88f1a45 100644 --- a/docs/contribute/code.mdx +++ b/docs/contribute/code.mdx @@ -10,7 +10,7 @@ Contribute a new feature or bug fix to [Storybook's monorepo](https://github.com ## Prerequisites * Ensure you have Node version 18 installed (suggestion: v18.16.0). -* Ensure if you are using Windows to use the Windows Subsystem for Linux (WSL). +* Ensure if you are using Windows to run the commands below in a terminal with administrator privileges. ## Initial setup From 1636ea32a333cb1336cd39bee1f4f40d344c7121 Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 4 Oct 2024 16:43:25 +0800 Subject: [PATCH 02/40] Update docs/contribute/code.mdx Co-authored-by: jonniebigodes --- docs/contribute/code.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contribute/code.mdx b/docs/contribute/code.mdx index f0f9d88f1a45..822b3c625ef3 100644 --- a/docs/contribute/code.mdx +++ b/docs/contribute/code.mdx @@ -10,7 +10,7 @@ Contribute a new feature or bug fix to [Storybook's monorepo](https://github.com ## Prerequisites * Ensure you have Node version 18 installed (suggestion: v18.16.0). -* Ensure if you are using Windows to run the commands below in a terminal with administrator privileges. +* If you're working with Windows, all commands should be run in a terminal with administrator privileges. ## Initial setup From 033dc372fa0af69cdfca2e7395e3a5e15f5c212d Mon Sep 17 00:00:00 2001 From: Tobias Diez Date: Fri, 4 Oct 2024 16:43:32 +0800 Subject: [PATCH 03/40] Update CONTRIBUTING.md Co-authored-by: jonniebigodes --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 879a675fcc3c..6d2f04d9e253 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ You will need to have the following installed: ## Running the local development environment -- Ensure if you are using Windows to use a terminal with admin privileges. +- All commands should be run in a terminal with administrator privileges in Windows environments. - Run `yarn start` in the root directory to run a basic test Storybook "sandbox". The `yarn start` script will generate a React Vite TypeScript sandbox with a set of test stories inside it, as well as taking all steps required to get it running (building the various packages we need etc). There is no need to run `yarn` or `yarn install` as `yarn start` will do this for you. From 03dea27c8077b0a9a6baf575bb7f6fa913d0ace9 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 11 Oct 2024 22:53:30 +0200 Subject: [PATCH 04/40] initial script to bench individual packages --- scripts/bench/bench-package.ts | 157 +++++++++++++++++++++++++++++++++ scripts/package.json | 1 + scripts/yarn.lock | 8 ++ 3 files changed, 166 insertions(+) create mode 100644 scripts/bench/bench-package.ts diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts new file mode 100644 index 000000000000..c7e74c8abbfe --- /dev/null +++ b/scripts/bench/bench-package.ts @@ -0,0 +1,157 @@ +import { program } from 'commander'; +import detectFreePort from 'detect-port'; +import { mkdir, readdir, rm, stat, writeFile } from 'fs/promises'; +import pLimit from 'p-limit'; +import { join } from 'path'; +import { x } from 'tinyexec'; + +import versions from '../../code/core/src/common/versions'; +import { runRegistry } from '../tasks/run-registry'; +import { maxConcurrentTasks } from '../utils/concurrency'; +import { esMain } from '../utils/esmain'; + +const PACKAGES_PATH = join(__dirname, '..', '..', 'bench', 'packages'); +const REGISTRY_PORT = 6001; + +type PackageName = keyof typeof versions; + +/** + * This script is used to bench the size of Storybook packages and their dependencies. For each + * package, the steps are: + * + * 1. Create a temporary directory in /bench/packages and create a package.json file that only depends + * on that one package + * 2. Install the package and its dependencies, without peer dependencies + * 3. Measure the size of the package and its dependencies, and count the number of dependencies + * (including transitive) + * 4. Print the results + */ + +export const benchPackage = async (packageName: PackageName) => { + console.log(`Benching ${packageName}...`); + const packagePath = join(PACKAGES_PATH, packageName.replace('@storybook', '')); + + await rm(packagePath, { recursive: true }).catch(() => {}); + await mkdir(packagePath, { recursive: true }); + + await writeFile( + join(packagePath, 'package.json'), + JSON.stringify( + { + name: `${packageName}-bench`, + version: '1.0.0', + overrides: versions, + }, + null, + 2 + ) + ); + + await x( + 'npm', + `install --save-exact --registry http://localhost:6001 --omit peer ${packageName}@${versions[packageName]}`.split( + ' ' + ), + { + nodeOptions: { cwd: packagePath }, + } + ); + + const npmLsResult = await x('npm', `ls --all --parseable`.split(' '), { + nodeOptions: { cwd: packagePath }, + }); + + const amountOfDependencies = npmLsResult.stdout.trim().split('\n').length - 2; + // the first line is the temporary benching package itself, don't count it + // the second line is the package we're benching, don't count it + + const nodeModulesSize = await getDirSize(join(packagePath, 'node_modules')); + const selfSize = await getDirSize(join(packagePath, 'node_modules', packageName)); + const dependencySize = nodeModulesSize - selfSize; + + console.log({ + package: packageName, + dependencies: amountOfDependencies, + selfSize: formatBytes(selfSize), + dependencySize: formatBytes(dependencySize), + totalSize: formatBytes(nodeModulesSize), + }); +}; + +const getDirSize = async (path: string) => { + const entities = await readdir(path, { + recursive: true, + withFileTypes: true, + }); + const stats = await Promise.all( + entities + .filter((entity) => entity.isFile()) + .map((entity) => stat(join(entity.parentPath, entity.name))) + ); + return stats.reduce((acc, { size }) => acc + size, 0); +}; + +const formatBytes = (bytes: number) => { + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + let size = bytes; + let unitIndex = 0; + + while (size >= 1000 && unitIndex < units.length - 1) { + size /= 1000; + unitIndex++; + } + + // show 2 decimal places for MB, GB and TB and 0 for KB, B + const decimals = unitIndex < 2 ? 0 : 2; + return `${size.toFixed(decimals)} ${units[unitIndex]}`; +}; + +const run = async () => { + program.argument( + '[packages...]', + 'which packages to bench. If omitted, all packages are benched' + ); + program.parse(process.argv); + + const packages = ( + program.args.length > 0 ? program.args : Object.keys(versions) + ) as PackageName[]; + + packages.forEach((packageName) => { + if (!Object.keys(versions).includes(packageName)) { + throw new Error(`Package '${packageName}' not found`); + } + }); + + let registryController: AbortController | undefined; + if ((await detectFreePort(REGISTRY_PORT)) === REGISTRY_PORT) { + registryController = await runRegistry({ dryRun: false, debug: false }); + } + + // The amount of VCPUs for this task in CI is 8 (xlarge resource) + const amountOfVCPUs = 8; + const concurrentLimt = process.env.CI ? amountOfVCPUs - 1 : maxConcurrentTasks; + const limit = pLimit(concurrentLimt); + + const progressIntervalId = setInterval(() => { + const doneCount = packages.length - limit.activeCount - limit.pendingCount; + if (doneCount === packages.length) { + clearInterval(progressIntervalId); + return; + } + console.log( + `Currently benching ${limit.activeCount} packages, ${limit.pendingCount} pending, ${doneCount} done...` + ); + }, 2_000); + await Promise.all(packages.map((packageName) => limit(() => benchPackage(packageName)))); + + console.log('Done benching all packages'); + registryController?.abort(); +}; + +if (esMain(import.meta.url)) { + run().catch((err) => { + console.error(err); + process.exit(1); + }); +} diff --git a/scripts/package.json b/scripts/package.json index d7c89c37cb20..472203aebdbe 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -174,6 +174,7 @@ "slash": "^3.0.0", "sort-package-json": "^2.10.0", "tiny-invariant": "^1.3.3", + "tinyexec": "^0.3.0", "trash": "^7.2.0", "ts-dedent": "^2.2.0", "tsup": "^6.7.0", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 5f52272a0427..d2d3ac97bafd 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -1653,6 +1653,7 @@ __metadata: slash: "npm:^3.0.0" sort-package-json: "npm:^2.10.0" tiny-invariant: "npm:^1.3.3" + tinyexec: "npm:^0.3.0" trash: "npm:^7.2.0" ts-dedent: "npm:^2.2.0" tsup: "npm:^6.7.0" @@ -13393,6 +13394,13 @@ __metadata: languageName: node linkType: hard +"tinyexec@npm:^0.3.0": + version: 0.3.0 + resolution: "tinyexec@npm:0.3.0" + checksum: 10c0/138a4f4241aea6b6312559508468ab275a31955e66e2f57ed206e0aaabecee622624f208c5740345f0a66e33478fd065e359ed1eb1269eb6fd4fa25d44d0ba3b + languageName: node + linkType: hard + "tinypool@npm:^1.0.0": version: 1.0.0 resolution: "tinypool@npm:1.0.0" From ca5efc0ae576c066341bd51636bd9bf599fa4f7f Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 11 Oct 2024 22:53:56 +0200 Subject: [PATCH 05/40] use node apis instead of CLIs to rm files in run-registry script --- scripts/run-registry.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/run-registry.ts b/scripts/run-registry.ts index 5f179501583d..82d6513f40a2 100755 --- a/scripts/run-registry.ts +++ b/scripts/run-registry.ts @@ -1,12 +1,12 @@ import { exec } from 'node:child_process'; -import { mkdir } from 'node:fs/promises'; +import { mkdir, rm } from 'node:fs/promises'; import http from 'node:http'; import type { Server } from 'node:http'; import { join, resolve as resolvePath } from 'node:path'; import { program } from 'commander'; // eslint-disable-next-line depend/ban-dependencies -import { execa, execaSync } from 'execa'; +import { execa } from 'execa'; // eslint-disable-next-line depend/ban-dependencies import { pathExists, readJSON, remove } from 'fs-extra'; import pLimit from 'p-limit'; @@ -207,7 +207,7 @@ const run = async () => { await publish(packages, 'http://localhost:6002'); } - await execa('npx', ['rimraf', '.npmrc'], { cwd: root }); + await rm(join(root, '.npmrc'), { force: true }); if (!opts.open) { verdaccioServer.close(); @@ -217,6 +217,7 @@ const run = async () => { run().catch((e) => { logger.error(e); - execaSync('npx', ['rimraf', '.npmrc'], { cwd: root }); - process.exit(1); + rm(join(root, '.npmrc'), { force: true }).then(() => { + process.exit(1); + }); }); From 4224e79ba17f29f4cde37a7936b81dc7c1a42d91 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 15 Oct 2024 11:15:54 +0200 Subject: [PATCH 06/40] improve readability --- scripts/bench/bench-package.ts | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index c7e74c8abbfe..4e7cb205c7f0 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -10,7 +10,7 @@ import { runRegistry } from '../tasks/run-registry'; import { maxConcurrentTasks } from '../utils/concurrency'; import { esMain } from '../utils/esmain'; -const PACKAGES_PATH = join(__dirname, '..', '..', 'bench', 'packages'); +const BENCH_PACKAGES_PATH = join(__dirname, '..', '..', 'bench', 'packages'); const REGISTRY_PORT = 6001; type PackageName = keyof typeof versions; @@ -29,17 +29,18 @@ type PackageName = keyof typeof versions; export const benchPackage = async (packageName: PackageName) => { console.log(`Benching ${packageName}...`); - const packagePath = join(PACKAGES_PATH, packageName.replace('@storybook', '')); + const tmpBenchPackagePath = join(BENCH_PACKAGES_PATH, packageName.replace('@storybook', '')); - await rm(packagePath, { recursive: true }).catch(() => {}); - await mkdir(packagePath, { recursive: true }); + await rm(tmpBenchPackagePath, { recursive: true }).catch(() => {}); + await mkdir(tmpBenchPackagePath, { recursive: true }); await writeFile( - join(packagePath, 'package.json'), + join(tmpBenchPackagePath, 'package.json'), JSON.stringify( { name: `${packageName}-bench`, version: '1.0.0', + // Overrides ensures that Storybook packages outside the monorepo are using the versions we have in the monorepo overrides: versions, }, null, @@ -53,20 +54,20 @@ export const benchPackage = async (packageName: PackageName) => { ' ' ), { - nodeOptions: { cwd: packagePath }, + nodeOptions: { cwd: tmpBenchPackagePath }, } ); const npmLsResult = await x('npm', `ls --all --parseable`.split(' '), { - nodeOptions: { cwd: packagePath }, + nodeOptions: { cwd: tmpBenchPackagePath }, }); - const amountOfDependencies = npmLsResult.stdout.trim().split('\n').length - 2; // the first line is the temporary benching package itself, don't count it // the second line is the package we're benching, don't count it + const amountOfDependencies = npmLsResult.stdout.trim().split('\n').length - 2; - const nodeModulesSize = await getDirSize(join(packagePath, 'node_modules')); - const selfSize = await getDirSize(join(packagePath, 'node_modules', packageName)); + const nodeModulesSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules')); + const selfSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules', packageName)); const dependencySize = nodeModulesSize - selfSize; console.log({ @@ -101,7 +102,8 @@ const formatBytes = (bytes: number) => { unitIndex++; } - // show 2 decimal places for MB, GB and TB and 0 for KB, B + // B, KB = 0 decimal places + // MB, GB, TB = 2 decimal places const decimals = unitIndex < 2 ? 0 : 2; return `${size.toFixed(decimals)} ${units[unitIndex]}`; }; @@ -125,11 +127,12 @@ const run = async () => { let registryController: AbortController | undefined; if ((await detectFreePort(REGISTRY_PORT)) === REGISTRY_PORT) { + console.log('Starting local registry...'); registryController = await runRegistry({ dryRun: false, debug: false }); } - // The amount of VCPUs for this task in CI is 8 (xlarge resource) - const amountOfVCPUs = 8; + // The amount of VCPUs for this task in CI is 2 (medium resource) + const amountOfVCPUs = 2; const concurrentLimt = process.env.CI ? amountOfVCPUs - 1 : maxConcurrentTasks; const limit = pLimit(concurrentLimt); From c21288098a27ef344bfec720e3d3ed3a675b1490 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 15 Oct 2024 11:25:36 +0200 Subject: [PATCH 07/40] add circleci job for package benching --- .circleci/config.yml | 27 +++++++++++++++++++++++++++ scripts/package.json | 1 + 2 files changed, 28 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1546a7db8430..c63a54226d63 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -211,6 +211,24 @@ jobs: yarn knip --no-exit-code - report-workflow-on-failure - cancel-workflow-on-failure + bench-packages: + executor: + class: medium + name: sb_node_22_classic + steps: + - git-shallow-clone/checkout_advanced: + clone_options: "--depth 1 --verbose" + - attach_workspace: + at: . + - run: + name: Benchmarking Packages + working_directory: scripts + command: yarn bench-package + # - run: + # name: Uploading results + # command: yarn upload-bench $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) << pipeline.parameters.ghPrNumber >> << pipeline.parameters.ghBaseBranch >> + - report-workflow-on-failure + - cancel-workflow-on-failure check: executor: class: xlarge @@ -707,6 +725,9 @@ workflows: - knip: requires: - build + - bench-packages: + requires: + - build - check: requires: - build @@ -776,6 +797,9 @@ workflows: - knip: requires: - build + - bench-packages: + requires: + - build - check: requires: - build @@ -846,6 +870,9 @@ workflows: - knip: requires: - build + - bench-packages: + requires: + - build - check: requires: - build diff --git a/scripts/package.json b/scripts/package.json index 472203aebdbe..fc25e1bed562 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -4,6 +4,7 @@ "private": true, "type": "module", "scripts": { + "bench-package": "jiti ./bench/bench-package.ts", "build-package": "jiti ./build-package.ts", "check": "jiti ./prepare/check-scripts.ts", "check-package": "jiti ./check-package.ts", From a21f3213716079ae6f7124da100a3d0dbbd1b0b2 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 15 Oct 2024 11:33:36 +0200 Subject: [PATCH 08/40] save results to file --- .circleci/config.yml | 10 ++++++---- scripts/bench/bench-package.ts | 32 ++++++++++++++++++++++++++++---- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index c63a54226d63..95c8976a4b1a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -224,6 +224,8 @@ jobs: name: Benchmarking Packages working_directory: scripts command: yarn bench-package + - store_artifacts: + path: code/bench/packages/package-bench-results.json # - run: # name: Uploading results # command: yarn upload-bench $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) << pipeline.parameters.ghPrNumber >> << pipeline.parameters.ghBaseBranch >> @@ -540,7 +542,7 @@ jobs: - store_artifacts: # this is where playwright puts more complex stuff path: code/playwright-results/ destination: playwright - bench: + bench-sandboxes: parameters: parallelism: type: integer @@ -771,7 +773,7 @@ workflows: parallelism: 5 requires: - create-sandboxes - - bench: + - bench-sandboxes: parallelism: 5 requires: - build-sandboxes @@ -849,7 +851,7 @@ workflows: matrix: parameters: directory: ["react", "vue3", "nextjs", "svelte"] - - bench: + - bench-sandboxes: parallelism: 5 requires: - build-sandboxes @@ -940,7 +942,7 @@ workflows: # --smoke-test is not supported for the angular builder right now # - "angular-cli" - "lit-vite-ts" - - bench: + - bench-sandboxes: parallelism: 5 requires: - build-sandboxes diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 4e7cb205c7f0..86422927f273 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -14,7 +14,13 @@ const BENCH_PACKAGES_PATH = join(__dirname, '..', '..', 'bench', 'packages'); const REGISTRY_PORT = 6001; type PackageName = keyof typeof versions; - +type Result = { + package: PackageName; + dependencies: number; + selfSize: string; + dependencySize: string; + totalSize: string; +}; /** * This script is used to bench the size of Storybook packages and their dependencies. For each * package, the steps are: @@ -70,13 +76,15 @@ export const benchPackage = async (packageName: PackageName) => { const selfSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules', packageName)); const dependencySize = nodeModulesSize - selfSize; - console.log({ + const result: Result = { package: packageName, dependencies: amountOfDependencies, selfSize: formatBytes(selfSize), dependencySize: formatBytes(dependencySize), totalSize: formatBytes(nodeModulesSize), - }); + }; + console.log(result); + return result; }; const getDirSize = async (path: string) => { @@ -108,6 +116,19 @@ const formatBytes = (bytes: number) => { return `${size.toFixed(decimals)} ${units[unitIndex]}`; }; +const saveResults = async (results: Result[]) => { + console.log('Saving results...'); + const allResults: Record> = {}; + for (const result of results) { + const { package: packageName, ...withoutPackage } = result; + allResults[result.package] = withoutPackage; + } + await writeFile( + join(BENCH_PACKAGES_PATH, 'package-bench-results.json'), + JSON.stringify(allResults, null, 2) + ); +}; + const run = async () => { program.argument( '[packages...]', @@ -146,7 +167,10 @@ const run = async () => { `Currently benching ${limit.activeCount} packages, ${limit.pendingCount} pending, ${doneCount} done...` ); }, 2_000); - await Promise.all(packages.map((packageName) => limit(() => benchPackage(packageName)))); + const results = await Promise.all( + packages.map((packageName) => limit(() => benchPackage(packageName))) + ); + await saveResults(results); console.log('Done benching all packages'); registryController?.abort(); From 10ec1ede0d1a9f3149b244a9e6a1c0636dce52fb Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 15 Oct 2024 12:38:46 +0200 Subject: [PATCH 09/40] fix result path --- .circleci/config.yml | 2 +- scripts/bench/bench-package.ts | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 95c8976a4b1a..21067d420d5b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -225,7 +225,7 @@ jobs: working_directory: scripts command: yarn bench-package - store_artifacts: - path: code/bench/packages/package-bench-results.json + path: bench/packages/results.json # - run: # name: Uploading results # command: yarn upload-bench $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) << pipeline.parameters.ghPrNumber >> << pipeline.parameters.ghBaseBranch >> diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 86422927f273..40709eba2998 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -117,16 +117,14 @@ const formatBytes = (bytes: number) => { }; const saveResults = async (results: Result[]) => { - console.log('Saving results...'); + const resultPath = join(BENCH_PACKAGES_PATH, 'results.json'); + console.log(`Saving results to ${resultPath}...`); const allResults: Record> = {}; for (const result of results) { const { package: packageName, ...withoutPackage } = result; allResults[result.package] = withoutPackage; } - await writeFile( - join(BENCH_PACKAGES_PATH, 'package-bench-results.json'), - JSON.stringify(allResults, null, 2) - ); + await writeFile(resultPath, JSON.stringify(allResults, null, 2)); }; const run = async () => { From 7af86e2cf834de1f0782b7fb66fc8634f539e02b Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 15 Oct 2024 22:53:53 +0200 Subject: [PATCH 10/40] add support for comparing bench results with a base --- .circleci/config.yml | 7 +- scripts/bench/bench-package.ts | 139 ++++++++++++++++++++++++++++----- 2 files changed, 123 insertions(+), 23 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 21067d420d5b..30d46b4f098c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -223,12 +223,11 @@ jobs: - run: name: Benchmarking Packages working_directory: scripts - command: yarn bench-package + command: yarn bench-package --base << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> - store_artifacts: path: bench/packages/results.json - # - run: - # name: Uploading results - # command: yarn upload-bench $(yarn get-template --cadence << pipeline.parameters.workflow >> --task bench) << pipeline.parameters.ghPrNumber >> << pipeline.parameters.ghBaseBranch >> + - store_artifacts: + path: bench/packages/compare-with-<< pipeline.parameters.ghBaseBranch >>.json - report-workflow-on-failure - cancel-workflow-on-failure check: diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 40709eba2998..b00b22daa512 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -1,3 +1,5 @@ +import { BigQuery } from '@google-cloud/bigquery'; +import { request } from '@octokit/request'; import { program } from 'commander'; import detectFreePort from 'detect-port'; import { mkdir, readdir, rm, stat, writeFile } from 'fs/promises'; @@ -15,12 +17,20 @@ const REGISTRY_PORT = 6001; type PackageName = keyof typeof versions; type Result = { + package: PackageName; + dependencies: number; + selfSize: number; + dependencySize: number; +}; +type HumanReadableResult = { package: PackageName; dependencies: number; selfSize: string; dependencySize: string; totalSize: string; }; +type ResultMap = Record; +type HumanReadableResultMap = Record; /** * This script is used to bench the size of Storybook packages and their dependencies. For each * package, the steps are: @@ -79,11 +89,10 @@ export const benchPackage = async (packageName: PackageName) => { const result: Result = { package: packageName, dependencies: amountOfDependencies, - selfSize: formatBytes(selfSize), - dependencySize: formatBytes(dependencySize), - totalSize: formatBytes(nodeModulesSize), + selfSize, + dependencySize, }; - console.log(result); + console.log(toHumanReadable(result)); return result; }; @@ -100,9 +109,19 @@ const getDirSize = async (path: string) => { return stats.reduce((acc, { size }) => acc + size, 0); }; +const toHumanReadable = (result: Result): HumanReadableResult => { + return { + package: result.package, + dependencies: result.dependencies, + selfSize: formatBytes(result.selfSize), + dependencySize: formatBytes(result.dependencySize), + totalSize: formatBytes(result.selfSize + result.dependencySize), + }; +}; + const formatBytes = (bytes: number) => { const units = ['B', 'KB', 'MB', 'GB', 'TB']; - let size = bytes; + let size = Math.abs(bytes); let unitIndex = 0; while (size >= 1000 && unitIndex < units.length - 1) { @@ -113,30 +132,93 @@ const formatBytes = (bytes: number) => { // B, KB = 0 decimal places // MB, GB, TB = 2 decimal places const decimals = unitIndex < 2 ? 0 : 2; - return `${size.toFixed(decimals)} ${units[unitIndex]}`; + const formattedSize = `${size.toFixed(decimals)} ${units[unitIndex]}`; + + return bytes < 0 ? `-${formattedSize}` : formattedSize; }; -const saveResults = async (results: Result[]) => { - const resultPath = join(BENCH_PACKAGES_PATH, 'results.json'); +const saveResultsLocally = async ({ + results, + filename, +}: { + results: ResultMap; + filename: string; +}) => { + const resultPath = join(BENCH_PACKAGES_PATH, filename); console.log(`Saving results to ${resultPath}...`); - const allResults: Record> = {}; - for (const result of results) { - const { package: packageName, ...withoutPackage } = result; - allResults[result.package] = withoutPackage; + + const humanReadableResults = Object.entries(results).reduce((acc, [packageName, result]) => { + acc[packageName] = toHumanReadable(result); + return acc; + }, {} as HumanReadableResultMap); + await writeFile(resultPath, JSON.stringify(humanReadableResults, null, 2)); +}; + +const compareResults = async ({ results, base }: { results: ResultMap; base: string }) => { + // const GCP_CREDENTIALS = JSON.parse(process.env.GCP_CREDENTIALS || '{}'); + + // const store = new BigQuery({ + // projectId: GCP_CREDENTIALS.project_id, + // credentials: GCP_CREDENTIALS, + // }); + // const dataset = store.dataset('benchmark_results'); + // const appTable = dataset.table('bench2'); + + // const [baseResults] = await appTable.query({ + // query: ` + // WITH latest_packages AS ( + // SELECT branch, package, timestamp, + // ROW_NUMBER() OVER (PARTITION BY branch, package ORDER BY timestamp DESC) as rownumber + // FROM \`storybook-benchmark.benchmark_results.bench2\` + // WHERE branch = @base + // AND package IN UNNEST(@packages) + // AND timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) + // ) + // SELECT branch, package, timestamp + // FROM latest_packages + // WHERE rownumber = 1 + // ORDER BY package;`, + // params: { base, packages: Object.keys(results) }, + // }); + // console.log(baseResults); + + const baseResults = [ + { + package: '@storybook/react', + dependencies: 4, + selfSize: 900_000, + dependencySize: 50_000, + }, + ]; + + const comparisonResults = {} as ResultMap; + for (const [packageName, result] of Object.entries(results)) { + const baseResult = baseResults.find((row) => row.package === packageName); + if (!baseResult) { + console.warn(`No base result found for ${packageName}, skipping comparison.`); + continue; + } + comparisonResults[packageName] = { + package: packageName, + dependencies: result.dependencies - baseResult.dependencies, + selfSize: result.selfSize - baseResult.selfSize, + dependencySize: result.dependencySize - baseResult.dependencySize, + }; } - await writeFile(resultPath, JSON.stringify(allResults, null, 2)); + return comparisonResults; }; const run = async () => { - program.argument( - '[packages...]', - 'which packages to bench. If omitted, all packages are benched' - ); + program + .option('-b, --base ', 'The base branch to compare the results with') + .option('-p, --pull-request ', 'The PR number to comment comparions on') + .argument('[packages...]', 'which packages to bench. If omitted, all packages are benched'); program.parse(process.argv); const packages = ( program.args.length > 0 ? program.args : Object.keys(versions) ) as PackageName[]; + const options = program.opts<{ pullRequest?: string; base?: string }>(); packages.forEach((packageName) => { if (!Object.keys(versions).includes(packageName)) { @@ -165,10 +247,29 @@ const run = async () => { `Currently benching ${limit.activeCount} packages, ${limit.pendingCount} pending, ${doneCount} done...` ); }, 2_000); - const results = await Promise.all( + const resultsArray = await Promise.all( packages.map((packageName) => limit(() => benchPackage(packageName))) ); - await saveResults(results); + const results = resultsArray.reduce((acc, result) => { + acc[result.package] = result; + return acc; + }, {} as ResultMap); + await saveResultsLocally({ + filename: `results.json`, + results, + }); + + if (options.base) { + const comparisonResults = await compareResults({ results, base: options.base }); + await saveResultsLocally({ + filename: `compare-with-${options.base}.json`, + results: comparisonResults, + }); + + if (options.pullRequest) { + // send to github bot + } + } console.log('Done benching all packages'); registryController?.abort(); From fcd2d968cb0fea47cbd669bd4eca36432f662667 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 16 Oct 2024 12:35:32 +0200 Subject: [PATCH 11/40] cleanup --- .circleci/config.yml | 2 +- scripts/bench/bench-package.ts | 40 +++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 30d46b4f098c..e7e39471e3d6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -223,7 +223,7 @@ jobs: - run: name: Benchmarking Packages working_directory: scripts - command: yarn bench-package --base << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> + command: yarn bench-package --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> - store_artifacts: path: bench/packages/results.json - store_artifacts: diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index b00b22daa512..84517e370a30 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -31,18 +31,18 @@ type HumanReadableResult = { }; type ResultMap = Record; type HumanReadableResultMap = Record; + /** - * This script is used to bench the size of Storybook packages and their dependencies. For each - * package, the steps are: + * This function benchmarks the size of Storybook packages and their dependencies. For each package, + * the steps are: * * 1. Create a temporary directory in /bench/packages and create a package.json file that only depends * on that one package * 2. Install the package and its dependencies, without peer dependencies * 3. Measure the size of the package and its dependencies, and count the number of dependencies * (including transitive) - * 4. Print the results + * 4. Print and return the results */ - export const benchPackage = async (packageName: PackageName) => { console.log(`Benching ${packageName}...`); const tmpBenchPackagePath = join(BENCH_PACKAGES_PATH, packageName.replace('@storybook', '')); @@ -154,7 +154,13 @@ const saveResultsLocally = async ({ await writeFile(resultPath, JSON.stringify(humanReadableResults, null, 2)); }; -const compareResults = async ({ results, base }: { results: ResultMap; base: string }) => { +const compareResults = async ({ + results, + baseBranch, +}: { + results: ResultMap; + baseBranch: string; +}) => { // const GCP_CREDENTIALS = JSON.parse(process.env.GCP_CREDENTIALS || '{}'); // const store = new BigQuery({ @@ -170,7 +176,7 @@ const compareResults = async ({ results, base }: { results: ResultMap; base: str // SELECT branch, package, timestamp, // ROW_NUMBER() OVER (PARTITION BY branch, package ORDER BY timestamp DESC) as rownumber // FROM \`storybook-benchmark.benchmark_results.bench2\` - // WHERE branch = @base + // WHERE branch = @baseBranch // AND package IN UNNEST(@packages) // AND timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) // ) @@ -178,7 +184,7 @@ const compareResults = async ({ results, base }: { results: ResultMap; base: str // FROM latest_packages // WHERE rownumber = 1 // ORDER BY package;`, - // params: { base, packages: Object.keys(results) }, + // params: { baseBranch, packages: Object.keys(results) }, // }); // console.log(baseResults); @@ -192,14 +198,14 @@ const compareResults = async ({ results, base }: { results: ResultMap; base: str ]; const comparisonResults = {} as ResultMap; - for (const [packageName, result] of Object.entries(results)) { - const baseResult = baseResults.find((row) => row.package === packageName); + for (const result of Object.values(results)) { + const baseResult = baseResults.find((row) => row.package === result.package); if (!baseResult) { - console.warn(`No base result found for ${packageName}, skipping comparison.`); + console.warn(`No base result found for ${result.package}, skipping comparison.`); continue; } - comparisonResults[packageName] = { - package: packageName, + comparisonResults[result.package] = { + package: result.package, dependencies: result.dependencies - baseResult.dependencies, selfSize: result.selfSize - baseResult.selfSize, dependencySize: result.dependencySize - baseResult.dependencySize, @@ -210,7 +216,7 @@ const compareResults = async ({ results, base }: { results: ResultMap; base: str const run = async () => { program - .option('-b, --base ', 'The base branch to compare the results with') + .option('-b, --baseBranch ', 'The base branch to compare the results with') .option('-p, --pull-request ', 'The PR number to comment comparions on') .argument('[packages...]', 'which packages to bench. If omitted, all packages are benched'); program.parse(process.argv); @@ -218,7 +224,7 @@ const run = async () => { const packages = ( program.args.length > 0 ? program.args : Object.keys(versions) ) as PackageName[]; - const options = program.opts<{ pullRequest?: string; base?: string }>(); + const options = program.opts<{ pullRequest?: string; baseBranch?: string }>(); packages.forEach((packageName) => { if (!Object.keys(versions).includes(packageName)) { @@ -259,10 +265,10 @@ const run = async () => { results, }); - if (options.base) { - const comparisonResults = await compareResults({ results, base: options.base }); + if (options.baseBranch) { + const comparisonResults = await compareResults({ results, baseBranch: options.baseBranch }); await saveResultsLocally({ - filename: `compare-with-${options.base}.json`, + filename: `compare-with-${options.baseBranch}.json`, results: comparisonResults, }); From 8a40fd3b6dc4f7d760ea9286f81d34736823c9b5 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Wed, 16 Oct 2024 14:00:27 +0200 Subject: [PATCH 12/40] start upload benches --- scripts/bench/bench-package.ts | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 84517e370a30..5a672c5adfd5 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -14,6 +14,13 @@ import { esMain } from '../utils/esmain'; const BENCH_PACKAGES_PATH = join(__dirname, '..', '..', 'bench', 'packages'); const REGISTRY_PORT = 6001; +const GCP_CREDENTIALS = JSON.parse(process.env.GCP_CREDENTIALS || '{}'); +const bigQueryBenchTable = new BigQuery({ + projectId: GCP_CREDENTIALS.project_id, + credentials: GCP_CREDENTIALS, +}) + .dataset('benchmark_results') + .table('bench2'); type PackageName = keyof typeof versions; type Result = { @@ -161,16 +168,7 @@ const compareResults = async ({ results: ResultMap; baseBranch: string; }) => { - // const GCP_CREDENTIALS = JSON.parse(process.env.GCP_CREDENTIALS || '{}'); - - // const store = new BigQuery({ - // projectId: GCP_CREDENTIALS.project_id, - // credentials: GCP_CREDENTIALS, - // }); - // const dataset = store.dataset('benchmark_results'); - // const appTable = dataset.table('bench2'); - - // const [baseResults] = await appTable.query({ + // const [baseResults] = await bigQueryBenchTable.query({ // query: ` // WITH latest_packages AS ( // SELECT branch, package, timestamp, @@ -214,6 +212,18 @@ const compareResults = async ({ return comparisonResults; }; +const uploadResultsToBigQuery = async (results: ResultMap) => { + const row = { + branch: + process.env.CIRCLE_BRANCH || + (await x('git', 'rev-parse --abbrev-ref HEAD'.split(' '))).stdout.trim(), + commit: process.env.CIRCLE_SHA1 || (await x('git', 'rev-parse HEAD'.split(' '))).stdout.trim(), + timestamp: new Date().toISOString(), + results, + }; + +}; + const run = async () => { program .option('-b, --baseBranch ', 'The base branch to compare the results with') From 738c6bbbfb62d933aa1cc59a541486d20b319adb Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 17 Oct 2024 15:00:05 +0200 Subject: [PATCH 13/40] upload to BigQuery --- scripts/bench/bench-package.ts | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 5a672c5adfd5..d87e0da598c8 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -20,7 +20,7 @@ const bigQueryBenchTable = new BigQuery({ credentials: GCP_CREDENTIALS, }) .dataset('benchmark_results') - .table('bench2'); + .table('package_bench'); type PackageName = keyof typeof versions; type Result = { @@ -155,7 +155,7 @@ const saveResultsLocally = async ({ console.log(`Saving results to ${resultPath}...`); const humanReadableResults = Object.entries(results).reduce((acc, [packageName, result]) => { - acc[packageName] = toHumanReadable(result); + acc[packageName as PackageName] = toHumanReadable(result); return acc; }, {} as HumanReadableResultMap); await writeFile(resultPath, JSON.stringify(humanReadableResults, null, 2)); @@ -213,15 +213,26 @@ const compareResults = async ({ }; const uploadResultsToBigQuery = async (results: ResultMap) => { - const row = { + if (!GCP_CREDENTIALS.project_id) { + console.warn('No GCP credentials found, skipping upload to BigQuery'); + return; + } + const commonFields = { branch: process.env.CIRCLE_BRANCH || (await x('git', 'rev-parse --abbrev-ref HEAD'.split(' '))).stdout.trim(), commit: process.env.CIRCLE_SHA1 || (await x('git', 'rev-parse HEAD'.split(' '))).stdout.trim(), - timestamp: new Date().toISOString(), - results, + benchmarkedAt: new Date(), }; + const rows = Object.values(results).map((result) => ({ + ...commonFields, + package: result.package, + selfSize: result.selfSize, + dependencySize: result.dependencySize, + dependencyCount: result.dependencies, + })); + await bigQueryBenchTable.insert(rows); }; const run = async () => { @@ -277,10 +288,13 @@ const run = async () => { if (options.baseBranch) { const comparisonResults = await compareResults({ results, baseBranch: options.baseBranch }); - await saveResultsLocally({ - filename: `compare-with-${options.baseBranch}.json`, - results: comparisonResults, - }); + await Promise.all([ + saveResultsLocally({ + filename: `compare-with-${options.baseBranch}.json`, + results: comparisonResults, + }), + uploadResultsToBigQuery(results), + ]); if (options.pullRequest) { // send to github bot From caf693acd2e1f4db350ab8f7b04beb5b2f4f4402 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 18 Oct 2024 10:43:09 +0200 Subject: [PATCH 14/40] compare with base branch from bigquery --- .circleci/config.yml | 2 +- scripts/bench/bench-package.ts | 110 +++++++++++++++++++-------------- 2 files changed, 63 insertions(+), 49 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e7e39471e3d6..2acd362190f2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -223,7 +223,7 @@ jobs: - run: name: Benchmarking Packages working_directory: scripts - command: yarn bench-package --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> + command: yarn bench-package --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> --upload - store_artifacts: path: bench/packages/results.json - store_artifacts: diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index d87e0da598c8..64c511265717 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -25,13 +25,13 @@ const bigQueryBenchTable = new BigQuery({ type PackageName = keyof typeof versions; type Result = { package: PackageName; - dependencies: number; + dependencyCount: number; selfSize: number; dependencySize: number; }; type HumanReadableResult = { package: PackageName; - dependencies: number; + dependencyCount: number; selfSize: string; dependencySize: string; totalSize: string; @@ -39,6 +39,8 @@ type HumanReadableResult = { type ResultMap = Record; type HumanReadableResultMap = Record; +let registryController: AbortController | undefined; + /** * This function benchmarks the size of Storybook packages and their dependencies. For each package, * the steps are: @@ -87,7 +89,7 @@ export const benchPackage = async (packageName: PackageName) => { // the first line is the temporary benching package itself, don't count it // the second line is the package we're benching, don't count it - const amountOfDependencies = npmLsResult.stdout.trim().split('\n').length - 2; + const dependencyCount = npmLsResult.stdout.trim().split('\n').length - 2; const nodeModulesSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules')); const selfSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules', packageName)); @@ -95,7 +97,7 @@ export const benchPackage = async (packageName: PackageName) => { const result: Result = { package: packageName, - dependencies: amountOfDependencies, + dependencyCount, selfSize, dependencySize, }; @@ -119,7 +121,7 @@ const getDirSize = async (path: string) => { const toHumanReadable = (result: Result): HumanReadableResult => { return { package: result.package, - dependencies: result.dependencies, + dependencyCount: result.dependencyCount, selfSize: formatBytes(result.selfSize), dependencySize: formatBytes(result.dependencySize), totalSize: formatBytes(result.selfSize + result.dependencySize), @@ -168,32 +170,24 @@ const compareResults = async ({ results: ResultMap; baseBranch: string; }) => { - // const [baseResults] = await bigQueryBenchTable.query({ - // query: ` - // WITH latest_packages AS ( - // SELECT branch, package, timestamp, - // ROW_NUMBER() OVER (PARTITION BY branch, package ORDER BY timestamp DESC) as rownumber - // FROM \`storybook-benchmark.benchmark_results.bench2\` - // WHERE branch = @baseBranch - // AND package IN UNNEST(@packages) - // AND timestamp > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) - // ) - // SELECT branch, package, timestamp - // FROM latest_packages - // WHERE rownumber = 1 - // ORDER BY package;`, - // params: { baseBranch, packages: Object.keys(results) }, - // }); - // console.log(baseResults); - - const baseResults = [ - { - package: '@storybook/react', - dependencies: 4, - selfSize: 900_000, - dependencySize: 50_000, - }, - ]; + console.log(`Comparing results with base branch ${baseBranch}...`); + const [baseResults] = await bigQueryBenchTable.query({ + query: ` + WITH + latest_packages AS ( + SELECT *, + ROW_NUMBER() OVER (PARTITION BY package ORDER BY benchmarkedAt DESC) AS row_number + FROM + \`storybook-benchmark.benchmark_results.package_bench\` + WHERE + branch = @baseBranch + AND package IN UNNEST(@packages) + AND benchmarkedAt > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY) ) + SELECT * + FROM latest_packages + WHERE row_number = 1;`, + params: { baseBranch, packages: Object.keys(results) }, + }); const comparisonResults = {} as ResultMap; for (const result of Object.values(results)) { @@ -204,19 +198,17 @@ const compareResults = async ({ } comparisonResults[result.package] = { package: result.package, - dependencies: result.dependencies - baseResult.dependencies, + dependencyCount: result.dependencyCount - baseResult.dependencyCount, selfSize: result.selfSize - baseResult.selfSize, dependencySize: result.dependencySize - baseResult.dependencySize, }; } + console.log('LOG: comparisonResults', comparisonResults); return comparisonResults; }; const uploadResultsToBigQuery = async (results: ResultMap) => { - if (!GCP_CREDENTIALS.project_id) { - console.warn('No GCP credentials found, skipping upload to BigQuery'); - return; - } + console.log('Uploading results to BigQuery...'); const commonFields = { branch: process.env.CIRCLE_BRANCH || @@ -229,7 +221,7 @@ const uploadResultsToBigQuery = async (results: ResultMap) => { package: result.package, selfSize: result.selfSize, dependencySize: result.dependencySize, - dependencyCount: result.dependencies, + dependencyCount: result.dependencyCount, })); await bigQueryBenchTable.insert(rows); @@ -237,15 +229,30 @@ const uploadResultsToBigQuery = async (results: ResultMap) => { const run = async () => { program - .option('-b, --baseBranch ', 'The base branch to compare the results with') - .option('-p, --pull-request ', 'The PR number to comment comparions on') + .option( + '-b, --baseBranch ', + 'The base branch to compare the results with. Requires GCP_CREDENTIALS env var' + ) + .option( + '-p, --pull-request ', + 'The PR number to add compare results to. Only used together with --baseBranch' + ) + .option('-u, --upload', 'Upload results to BigQuery. Requires GCP_CREDENTIALS env var') .argument('[packages...]', 'which packages to bench. If omitted, all packages are benched'); program.parse(process.argv); const packages = ( program.args.length > 0 ? program.args : Object.keys(versions) ) as PackageName[]; - const options = program.opts<{ pullRequest?: string; baseBranch?: string }>(); + const options = program.opts<{ pullRequest?: string; baseBranch?: string; upload?: boolean }>(); + + if (options.upload || options.baseBranch) { + if (!GCP_CREDENTIALS.project_id) { + throw new Error( + 'GCP_CREDENTIALS env var is required to upload to BigQuery or compare against a base branch' + ); + } + } packages.forEach((packageName) => { if (!Object.keys(versions).includes(packageName)) { @@ -253,7 +260,6 @@ const run = async () => { } }); - let registryController: AbortController | undefined; if ((await detectFreePort(REGISTRY_PORT)) === REGISTRY_PORT) { console.log('Starting local registry...'); registryController = await runRegistry({ dryRun: false, debug: false }); @@ -285,16 +291,16 @@ const run = async () => { filename: `results.json`, results, }); + if (options.upload) { + await uploadResultsToBigQuery(results); + } if (options.baseBranch) { const comparisonResults = await compareResults({ results, baseBranch: options.baseBranch }); - await Promise.all([ - saveResultsLocally({ - filename: `compare-with-${options.baseBranch}.json`, - results: comparisonResults, - }), - uploadResultsToBigQuery(results), - ]); + await saveResultsLocally({ + filename: `compare-with-${options.baseBranch}.json`, + results: comparisonResults, + }); if (options.pullRequest) { // send to github bot @@ -307,7 +313,15 @@ const run = async () => { if (esMain(import.meta.url)) { run().catch((err) => { + registryController?.abort(); console.error(err); process.exit(1); }); } + +// TODO: +// compile no-link +// upload results as "next" branch +// set up threshold for comparisons +// send to github bot +// make github bot comment PRs From c99cb88daee7317fdab35a6acb6149c94bd9147c Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 21 Oct 2024 09:27:28 +0200 Subject: [PATCH 15/40] upload comparisons to github --- scripts/bench/bench-package.ts | 133 +++++++++++++++++++++++++-------- 1 file changed, 103 insertions(+), 30 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 64c511265717..a79b963f4cad 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -1,6 +1,5 @@ import { BigQuery } from '@google-cloud/bigquery'; -import { request } from '@octokit/request'; -import { program } from 'commander'; +import { InvalidArgumentError, program } from 'commander'; import detectFreePort from 'detect-port'; import { mkdir, readdir, rm, stat, writeFile } from 'fs/promises'; import pLimit from 'p-limit'; @@ -12,6 +11,14 @@ import { runRegistry } from '../tasks/run-registry'; import { maxConcurrentTasks } from '../utils/concurrency'; import { esMain } from '../utils/esmain'; +const Thresholds = { + SELF_SIZE_RATIO: 0.1, + SELF_SIZE_ABSOLUTE: 10_000, + DEPS_SIZE_RATIO: 0.1, + DEPS_SIZE_ABSOLUTE: 10_000, + DEPS_COUNT_ABSOLUTE: 1, +} as const; + const BENCH_PACKAGES_PATH = join(__dirname, '..', '..', 'bench', 'packages'); const REGISTRY_PORT = 6001; const GCP_CREDENTIALS = JSON.parse(process.env.GCP_CREDENTIALS || '{}'); @@ -73,7 +80,7 @@ export const benchPackage = async (packageName: PackageName) => { ) ); - await x( + const npmInstallResult = await x( 'npm', `install --save-exact --registry http://localhost:6001 --omit peer ${packageName}@${versions[packageName]}`.split( ' ' @@ -83,13 +90,9 @@ export const benchPackage = async (packageName: PackageName) => { } ); - const npmLsResult = await x('npm', `ls --all --parseable`.split(' '), { - nodeOptions: { cwd: tmpBenchPackagePath }, - }); - - // the first line is the temporary benching package itself, don't count it - // the second line is the package we're benching, don't count it - const dependencyCount = npmLsResult.stdout.trim().split('\n').length - 2; + // -1 of reported packages added because we shouldn't count the actual package as a dependency + const dependencyCount = + Number.parseInt(npmInstallResult.stdout.match(/added (\d+) packages?/)?.[1] ?? '') - 1; const nodeModulesSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules')); const selfSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules', packageName)); @@ -101,7 +104,7 @@ export const benchPackage = async (packageName: PackageName) => { selfSize, dependencySize, }; - console.log(toHumanReadable(result)); + console.log(`Done benching ${packageName}`); return result; }; @@ -146,11 +149,11 @@ const formatBytes = (bytes: number) => { return bytes < 0 ? `-${formattedSize}` : formattedSize; }; -const saveResultsLocally = async ({ +const saveLocally = async ({ results, filename, }: { - results: ResultMap; + results: Partial; filename: string; }) => { const resultPath = join(BENCH_PACKAGES_PATH, filename); @@ -203,11 +206,38 @@ const compareResults = async ({ dependencySize: result.dependencySize - baseResult.dependencySize, }; } - console.log('LOG: comparisonResults', comparisonResults); + console.log('Done comparing results'); return comparisonResults; }; -const uploadResultsToBigQuery = async (results: ResultMap) => { +const filterResultsByThresholds = ({ + currentResults, + comparisonResults, +}: { + currentResults: ResultMap; + comparisonResults: ResultMap; +}) => { + const filteredResults: Partial = {}; + for (const comparisonResult of Object.values(comparisonResults)) { + const currentResult = currentResults[comparisonResult.package]; + + const exceedsThresholds = + Math.abs(comparisonResult.selfSize) > Thresholds.SELF_SIZE_ABSOLUTE || + Math.abs(comparisonResult.selfSize) / currentResult.selfSize > Thresholds.SELF_SIZE_RATIO || + Math.abs(comparisonResult.dependencySize) > Thresholds.DEPS_SIZE_ABSOLUTE || + Math.abs(comparisonResult.dependencySize) / currentResult.dependencySize > + Thresholds.DEPS_SIZE_RATIO || + Math.abs(comparisonResult.dependencyCount) > Thresholds.DEPS_COUNT_ABSOLUTE; + + if (exceedsThresholds) { + filteredResults[comparisonResult.package] = comparisonResult; + } + } + console.log(`${Object.keys(filteredResults).length} packages exceeded the thresholds`); + return filteredResults; +}; + +const uploadToBigQuery = async (results: ResultMap) => { console.log('Uploading results to BigQuery...'); const commonFields = { branch: @@ -227,6 +257,30 @@ const uploadResultsToBigQuery = async (results: ResultMap) => { await bigQueryBenchTable.insert(rows); }; +const uploadToGithub = async ({ + results, + pullRequest, +}: { + results: Partial; + pullRequest: number; +}) => { + if (Object.keys(results).length === 0) { + console.log('No results to upload to GitHub, skipping.'); + return; + } + + console.log('Uploading results to GitHub...'); + await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { + method: 'POST', + body: JSON.stringify({ + owner: 'storybookjs', + repo: 'storybook', + issueNumber: pullRequest, + results, + }), + }); +}; + const run = async () => { program .option( @@ -235,16 +289,35 @@ const run = async () => { ) .option( '-p, --pull-request ', - 'The PR number to add compare results to. Only used together with --baseBranch' + 'The PR number to add compare results to. Only used together with --baseBranch', + function parseInt(value) { + const parsedValue = Number.parseInt(value); + if (Number.isNaN(parsedValue)) { + throw new InvalidArgumentError('Must be a number'); + } + return parsedValue; + } ) .option('-u, --upload', 'Upload results to BigQuery. Requires GCP_CREDENTIALS env var') - .argument('[packages...]', 'which packages to bench. If omitted, all packages are benched'); + .argument( + '[packages...]', + 'which packages to bench. If omitted, all packages are benched', + function parsePackages(value) { + const parsedValue = value.split(' '); + parsedValue.forEach((packageName) => { + if (!Object.keys(versions).includes(packageName)) { + throw new InvalidArgumentError(`Package '${packageName}' not found in the monorepo`); + } + }); + return parsedValue; + } + ); program.parse(process.argv); const packages = ( program.args.length > 0 ? program.args : Object.keys(versions) ) as PackageName[]; - const options = program.opts<{ pullRequest?: string; baseBranch?: string; upload?: boolean }>(); + const options = program.opts<{ pullRequest?: number; baseBranch?: string; upload?: boolean }>(); if (options.upload || options.baseBranch) { if (!GCP_CREDENTIALS.project_id) { @@ -287,23 +360,30 @@ const run = async () => { acc[result.package] = result; return acc; }, {} as ResultMap); - await saveResultsLocally({ + await saveLocally({ filename: `results.json`, results, }); if (options.upload) { - await uploadResultsToBigQuery(results); + await uploadToBigQuery(results); } if (options.baseBranch) { const comparisonResults = await compareResults({ results, baseBranch: options.baseBranch }); - await saveResultsLocally({ + await saveLocally({ filename: `compare-with-${options.baseBranch}.json`, results: comparisonResults, }); - + const resultsAboveThreshold = filterResultsByThresholds({ + currentResults: results, + comparisonResults, + }); + await saveLocally({ + filename: `comparisons-above-threshold-with-${options.baseBranch}.json`, + results: resultsAboveThreshold, + }); if (options.pullRequest) { - // send to github bot + await uploadToGithub({ results: resultsAboveThreshold, pullRequest: options.pullRequest }); } } @@ -318,10 +398,3 @@ if (esMain(import.meta.url)) { process.exit(1); }); } - -// TODO: -// compile no-link -// upload results as "next" branch -// set up threshold for comparisons -// send to github bot -// make github bot comment PRs From 00be90c8aa344a1659ba487eaece47b2dbc9f07a Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 21 Oct 2024 10:06:42 +0200 Subject: [PATCH 16/40] better logging --- scripts/bench/bench-package.ts | 80 +++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index a79b963f4cad..94e81d987428 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -4,6 +4,7 @@ import detectFreePort from 'detect-port'; import { mkdir, readdir, rm, stat, writeFile } from 'fs/promises'; import pLimit from 'p-limit'; import { join } from 'path'; +import picocolors from 'picocolors'; import { x } from 'tinyexec'; import versions from '../../code/core/src/common/versions'; @@ -38,7 +39,7 @@ type Result = { }; type HumanReadableResult = { package: PackageName; - dependencyCount: number; + dependencyCount: string; selfSize: string; dependencySize: string; totalSize: string; @@ -60,7 +61,7 @@ let registryController: AbortController | undefined; * 4. Print and return the results */ export const benchPackage = async (packageName: PackageName) => { - console.log(`Benching ${packageName}...`); + console.log(`Benching ${picocolors.blue(packageName)}...`); const tmpBenchPackagePath = join(BENCH_PACKAGES_PATH, packageName.replace('@storybook', '')); await rm(tmpBenchPackagePath, { recursive: true }).catch(() => {}); @@ -104,7 +105,7 @@ export const benchPackage = async (packageName: PackageName) => { selfSize, dependencySize, }; - console.log(`Done benching ${packageName}`); + console.log(`Done benching ${picocolors.blue(packageName)}`); return result; }; @@ -121,17 +122,17 @@ const getDirSize = async (path: string) => { return stats.reduce((acc, { size }) => acc + size, 0); }; -const toHumanReadable = (result: Result): HumanReadableResult => { +const toHumanReadable = (result: Result, diff = false): HumanReadableResult => { return { package: result.package, - dependencyCount: result.dependencyCount, - selfSize: formatBytes(result.selfSize), - dependencySize: formatBytes(result.dependencySize), - totalSize: formatBytes(result.selfSize + result.dependencySize), + dependencyCount: `${diff && result.dependencyCount > 0 ? '+' : ''}${result.dependencyCount}`, + selfSize: formatBytes(result.selfSize, diff), + dependencySize: formatBytes(result.dependencySize, diff), + totalSize: formatBytes(result.selfSize + result.dependencySize, diff), }; }; -const formatBytes = (bytes: number) => { +const formatBytes = (bytes: number, diff = false) => { const units = ['B', 'KB', 'MB', 'GB', 'TB']; let size = Math.abs(bytes); let unitIndex = 0; @@ -146,21 +147,29 @@ const formatBytes = (bytes: number) => { const decimals = unitIndex < 2 ? 0 : 2; const formattedSize = `${size.toFixed(decimals)} ${units[unitIndex]}`; - return bytes < 0 ? `-${formattedSize}` : formattedSize; + if (bytes < 0) { + return `-${formattedSize}`; + } + if (diff) { + return `+${formattedSize}`; + } + return formattedSize; }; const saveLocally = async ({ results, filename, + diff = false, }: { results: Partial; filename: string; + diff?: boolean; }) => { const resultPath = join(BENCH_PACKAGES_PATH, filename); - console.log(`Saving results to ${resultPath}...`); + console.log(`Saving results to ${picocolors.magenta(resultPath)}...`); const humanReadableResults = Object.entries(results).reduce((acc, [packageName, result]) => { - acc[packageName as PackageName] = toHumanReadable(result); + acc[packageName as PackageName] = toHumanReadable(result, diff); return acc; }, {} as HumanReadableResultMap); await writeFile(resultPath, JSON.stringify(humanReadableResults, null, 2)); @@ -173,7 +182,7 @@ const compareResults = async ({ results: ResultMap; baseBranch: string; }) => { - console.log(`Comparing results with base branch ${baseBranch}...`); + console.log(`Comparing results with base branch ${picocolors.magenta(baseBranch)}...`); const [baseResults] = await bigQueryBenchTable.query({ query: ` WITH @@ -194,11 +203,23 @@ const compareResults = async ({ const comparisonResults = {} as ResultMap; for (const result of Object.values(results)) { - const baseResult = baseResults.find((row) => row.package === result.package); + let baseResult = baseResults.find((row) => row.package === result.package); if (!baseResult) { - console.warn(`No base result found for ${result.package}, skipping comparison.`); + console.warn( + `No base result found for ${picocolors.blue(result.package)}, skipping comparison.` + ); continue; } + if (Math.random() > 0.5) { + console.log('LOG: faking base results', baseResult.package); + baseResult = { + package: baseResult.package, + dependencyCount: Math.floor(baseResult.dependencyCount * Math.random()), + selfSize: Math.floor(baseResult.selfSize * Math.random()), + dependencySize: Math.floor(baseResult.dependencySize * Math.random()), + }; + } + comparisonResults[result.package] = { package: result.package, dependencyCount: result.dependencyCount - baseResult.dependencyCount, @@ -206,7 +227,7 @@ const compareResults = async ({ dependencySize: result.dependencySize - baseResult.dependencySize, }; } - console.log('Done comparing results'); + console.log(picocolors.green('Done comparing results')); return comparisonResults; }; @@ -233,7 +254,11 @@ const filterResultsByThresholds = ({ filteredResults[comparisonResult.package] = comparisonResult; } } - console.log(`${Object.keys(filteredResults).length} packages exceeded the thresholds`); + + const amountAboveThreshold = Object.keys(filteredResults).length; + const color = amountAboveThreshold === 0 ? picocolors.green : picocolors.red; + console.log(color(`${amountAboveThreshold} packages exceeded the thresholds`)); + return filteredResults; }; @@ -270,7 +295,7 @@ const uploadToGithub = async ({ } console.log('Uploading results to GitHub...'); - await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { + const response = await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { method: 'POST', body: JSON.stringify({ owner: 'storybookjs', @@ -279,6 +304,13 @@ const uploadToGithub = async ({ results, }), }); + if (response.status < 200 || response.status >= 400) { + const body = await response.text(); + throw new Error(`Failed to upload results to GitHub. + STATUS: ${response.status} - ${response.statusText} + BODY: + ${body}`); + } }; const run = async () => { @@ -327,12 +359,6 @@ const run = async () => { } } - packages.forEach((packageName) => { - if (!Object.keys(versions).includes(packageName)) { - throw new Error(`Package '${packageName}' not found`); - } - }); - if ((await detectFreePort(REGISTRY_PORT)) === REGISTRY_PORT) { console.log('Starting local registry...'); registryController = await runRegistry({ dryRun: false, debug: false }); @@ -350,7 +376,7 @@ const run = async () => { return; } console.log( - `Currently benching ${limit.activeCount} packages, ${limit.pendingCount} pending, ${doneCount} done...` + `Benching status: ${picocolors.red(limit.pendingCount)} pending, ${picocolors.yellow(limit.activeCount)} running, ${picocolors.green(doneCount)} done...` ); }, 2_000); const resultsArray = await Promise.all( @@ -373,6 +399,7 @@ const run = async () => { await saveLocally({ filename: `compare-with-${options.baseBranch}.json`, results: comparisonResults, + diff: true, }); const resultsAboveThreshold = filterResultsByThresholds({ currentResults: results, @@ -381,13 +408,14 @@ const run = async () => { await saveLocally({ filename: `comparisons-above-threshold-with-${options.baseBranch}.json`, results: resultsAboveThreshold, + diff: true, }); if (options.pullRequest) { await uploadToGithub({ results: resultsAboveThreshold, pullRequest: options.pullRequest }); } } - console.log('Done benching all packages'); + console.log(picocolors.green('Done benching all packages')); registryController?.abort(); }; From 8b3d1cf486a77d0a54461f7c9e4665ac6be1331c Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 22 Oct 2024 10:27:34 +0200 Subject: [PATCH 17/40] refactor comparison result structure --- scripts/bench/bench-package.ts | 263 ++++++++++++++++++++++----------- 1 file changed, 174 insertions(+), 89 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 94e81d987428..2f7d026a0b6c 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -37,15 +37,26 @@ type Result = { selfSize: number; dependencySize: number; }; -type HumanReadableResult = { +type ComparisonResult = { package: PackageName; - dependencyCount: string; - selfSize: string; - dependencySize: string; - totalSize: string; + dependencyCount: { + base: number; + new: number; + diff: number; + }; + selfSize: { + base: number; + new: number; + diff: number; + }; + dependencySize: { + base: number; + new: number; + diff: number; + }; }; type ResultMap = Record; -type HumanReadableResultMap = Record; +type ComparisonResultMap = Record; let registryController: AbortController | undefined; @@ -95,6 +106,19 @@ export const benchPackage = async (packageName: PackageName) => { const dependencyCount = Number.parseInt(npmInstallResult.stdout.match(/added (\d+) packages?/)?.[1] ?? '') - 1; + const getDirSize = async (path: string) => { + const entities = await readdir(path, { + recursive: true, + withFileTypes: true, + }); + const stats = await Promise.all( + entities + .filter((entity) => entity.isFile()) + .map((entity) => stat(join(entity.parentPath, entity.name))) + ); + return stats.reduce((acc, { size }) => acc + size, 0); + }; + const nodeModulesSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules')); const selfSize = await getDirSize(join(tmpBenchPackagePath, 'node_modules', packageName)); const dependencySize = nodeModulesSize - selfSize; @@ -109,69 +133,86 @@ export const benchPackage = async (packageName: PackageName) => { return result; }; -const getDirSize = async (path: string) => { - const entities = await readdir(path, { - recursive: true, - withFileTypes: true, - }); - const stats = await Promise.all( - entities - .filter((entity) => entity.isFile()) - .map((entity) => stat(join(entity.parentPath, entity.name))) - ); - return stats.reduce((acc, { size }) => acc + size, 0); -}; - -const toHumanReadable = (result: Result, diff = false): HumanReadableResult => { - return { - package: result.package, - dependencyCount: `${diff && result.dependencyCount > 0 ? '+' : ''}${result.dependencyCount}`, - selfSize: formatBytes(result.selfSize, diff), - dependencySize: formatBytes(result.dependencySize, diff), - totalSize: formatBytes(result.selfSize + result.dependencySize, diff), - }; -}; +const toHumanReadable = (result: Partial | Partial) => { + const formatBytes = (bytes: number, diff = false) => { + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + let size = Math.abs(bytes); + let unitIndex = 0; -const formatBytes = (bytes: number, diff = false) => { - const units = ['B', 'KB', 'MB', 'GB', 'TB']; - let size = Math.abs(bytes); - let unitIndex = 0; + while (size >= 1000 && unitIndex < units.length - 1) { + size /= 1000; + unitIndex++; + } - while (size >= 1000 && unitIndex < units.length - 1) { - size /= 1000; - unitIndex++; - } + // B, KB = 0 decimal places + // MB, GB, TB = 2 decimal places + const decimals = unitIndex < 2 ? 0 : 2; + const formattedSize = `${size.toFixed(decimals)} ${units[unitIndex]}`; - // B, KB = 0 decimal places - // MB, GB, TB = 2 decimal places - const decimals = unitIndex < 2 ? 0 : 2; - const formattedSize = `${size.toFixed(decimals)} ${units[unitIndex]}`; + if (bytes < 0) { + return `-${formattedSize}`; + } + if (diff && bytes > 0) { + return `+${formattedSize}`; + } + return formattedSize; + }; - if (bytes < 0) { - return `-${formattedSize}`; - } - if (diff) { - return `+${formattedSize}`; + if (typeof result.dependencyCount === 'number') { + const { dependencyCount, selfSize, dependencySize } = result as Result; + return { + package: result.package, + dependencyCount: dependencyCount.toString(), + selfSize: formatBytes(selfSize), + dependencySize: formatBytes(dependencySize), + totalSize: formatBytes(selfSize + dependencySize), + }; } - return formattedSize; + const { dependencyCount, selfSize, dependencySize } = result as ComparisonResult; + + return { + package: result.package, + dependencyCount: { + base: dependencyCount.base.toString(), + current: dependencyCount.new.toString(), + diff: `${dependencyCount.diff > 0 ? '+' : dependencyCount.diff < 0 ? '-' : ''}${dependencyCount.diff}`, + }, + selfSize: { + base: formatBytes(selfSize.base), + current: formatBytes(selfSize.new), + diff: formatBytes(selfSize.diff, true), + }, + dependencySize: { + base: formatBytes(dependencySize.base), + current: formatBytes(dependencySize.new), + diff: formatBytes(dependencySize.diff, true), + }, + totalSize: { + base: formatBytes(selfSize.base + dependencySize.base), + current: formatBytes(selfSize.new + dependencySize.new), + diff: formatBytes(selfSize.diff + dependencySize.diff, true), + }, + }; }; const saveLocally = async ({ results, filename, - diff = false, }: { - results: Partial; + results: Partial; filename: string; diff?: boolean; }) => { const resultPath = join(BENCH_PACKAGES_PATH, filename); console.log(`Saving results to ${picocolors.magenta(resultPath)}...`); - const humanReadableResults = Object.entries(results).reduce((acc, [packageName, result]) => { - acc[packageName as PackageName] = toHumanReadable(result, diff); - return acc; - }, {} as HumanReadableResultMap); + const humanReadableResults = Object.entries(results).reduce( + (acc, [packageName, result]) => { + acc[packageName as PackageName] = toHumanReadable(result); + return acc; + }, + {} as Record> + ); await writeFile(resultPath, JSON.stringify(humanReadableResults, null, 2)); }; @@ -201,7 +242,7 @@ const compareResults = async ({ params: { baseBranch, packages: Object.keys(results) }, }); - const comparisonResults = {} as ResultMap; + const comparisonResults = {} as ComparisonResultMap; for (const result of Object.values(results)) { let baseResult = baseResults.find((row) => row.package === result.package); if (!baseResult) { @@ -222,33 +263,38 @@ const compareResults = async ({ comparisonResults[result.package] = { package: result.package, - dependencyCount: result.dependencyCount - baseResult.dependencyCount, - selfSize: result.selfSize - baseResult.selfSize, - dependencySize: result.dependencySize - baseResult.dependencySize, + dependencyCount: { + base: baseResult.dependencyCount, + new: result.dependencyCount, + diff: result.dependencyCount - baseResult.dependencyCount, + }, + selfSize: { + base: baseResult.selfSize, + new: result.selfSize, + diff: result.selfSize - baseResult.selfSize, + }, + dependencySize: { + base: baseResult.dependencySize, + new: result.dependencySize, + diff: result.dependencySize - baseResult.dependencySize, + }, }; } console.log(picocolors.green('Done comparing results')); return comparisonResults; }; -const filterResultsByThresholds = ({ - currentResults, - comparisonResults, -}: { - currentResults: ResultMap; - comparisonResults: ResultMap; -}) => { - const filteredResults: Partial = {}; +const filterResultsByThresholds = (comparisonResults: ComparisonResultMap) => { + const filteredResults: Partial = {}; for (const comparisonResult of Object.values(comparisonResults)) { - const currentResult = currentResults[comparisonResult.package]; - const exceedsThresholds = - Math.abs(comparisonResult.selfSize) > Thresholds.SELF_SIZE_ABSOLUTE || - Math.abs(comparisonResult.selfSize) / currentResult.selfSize > Thresholds.SELF_SIZE_RATIO || - Math.abs(comparisonResult.dependencySize) > Thresholds.DEPS_SIZE_ABSOLUTE || - Math.abs(comparisonResult.dependencySize) / currentResult.dependencySize > + Math.abs(comparisonResult.selfSize.diff) > Thresholds.SELF_SIZE_ABSOLUTE || + Math.abs(comparisonResult.selfSize.diff) / comparisonResult.selfSize.new > + Thresholds.SELF_SIZE_RATIO || + Math.abs(comparisonResult.dependencySize.diff) > Thresholds.DEPS_SIZE_ABSOLUTE || + Math.abs(comparisonResult.dependencySize.diff) / comparisonResult.dependencySize.new > Thresholds.DEPS_SIZE_RATIO || - Math.abs(comparisonResult.dependencyCount) > Thresholds.DEPS_COUNT_ABSOLUTE; + Math.abs(comparisonResult.dependencyCount.diff) > Thresholds.DEPS_COUNT_ABSOLUTE; if (exceedsThresholds) { filteredResults[comparisonResult.package] = comparisonResult; @@ -262,17 +308,22 @@ const filterResultsByThresholds = ({ return filteredResults; }; -const uploadToBigQuery = async (results: ResultMap) => { +const uploadToBigQuery = async ({ + results, + branch, + commit, + benchmarkedAt, +}: { + results: ResultMap; + branch: string; + commit: string; + benchmarkedAt: Date; +}) => { console.log('Uploading results to BigQuery...'); - const commonFields = { - branch: - process.env.CIRCLE_BRANCH || - (await x('git', 'rev-parse --abbrev-ref HEAD'.split(' '))).stdout.trim(), - commit: process.env.CIRCLE_SHA1 || (await x('git', 'rev-parse HEAD'.split(' '))).stdout.trim(), - benchmarkedAt: new Date(), - }; const rows = Object.values(results).map((result) => ({ - ...commonFields, + branch, + commit, + benchmarkedAt, package: result.package, selfSize: result.selfSize, dependencySize: result.dependencySize, @@ -284,24 +335,46 @@ const uploadToBigQuery = async (results: ResultMap) => { const uploadToGithub = async ({ results, + headBranch, + baseBranch, + commit, + benchmarkedAt, pullRequest, }: { - results: Partial; + results: Partial; + headBranch: string; + baseBranch: string; + commit: string; + benchmarkedAt: Date; pullRequest: number; }) => { if (Object.keys(results).length === 0) { + // TODO: no, we need to update the table when results are good again console.log('No results to upload to GitHub, skipping.'); return; } + const humanReadableResults = Object.values(results).reduce( + (acc, result) => { + acc[result.package] = toHumanReadable(result); + return acc; + }, + {} as Record> + ); + console.log('Uploading results to GitHub...'); - const response = await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { + const response = await fetch('http://localhost:3000/package-bench', { + // const response = await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { method: 'POST', body: JSON.stringify({ owner: 'storybookjs', repo: 'storybook', issueNumber: pullRequest, - results, + headBranch, + baseBranch, + commit, + benchmarkedAt: benchmarkedAt.toISOString(), + results: humanReadableResults, }), }); if (response.status < 200 || response.status >= 400) { @@ -390,28 +463,40 @@ const run = async () => { filename: `results.json`, results, }); + + const headBranch = + process.env.CIRCLE_BRANCH || + (await x('git', 'rev-parse --abbrev-ref HEAD'.split(' '))).stdout.trim(); + const commit = + process.env.CIRCLE_SHA1 || (await x('git', 'rev-parse HEAD'.split(' '))).stdout.trim(); + const benchmarkedAt = new Date(); + if (options.upload) { - await uploadToBigQuery(results); + await uploadToBigQuery({ results, branch: headBranch, commit, benchmarkedAt }); } if (options.baseBranch) { const comparisonResults = await compareResults({ results, baseBranch: options.baseBranch }); + const resultsAboveThreshold = filterResultsByThresholds(comparisonResults); await saveLocally({ filename: `compare-with-${options.baseBranch}.json`, results: comparisonResults, diff: true, }); - const resultsAboveThreshold = filterResultsByThresholds({ - currentResults: results, - comparisonResults, - }); await saveLocally({ filename: `comparisons-above-threshold-with-${options.baseBranch}.json`, results: resultsAboveThreshold, diff: true, }); if (options.pullRequest) { - await uploadToGithub({ results: resultsAboveThreshold, pullRequest: options.pullRequest }); + await uploadToGithub({ + results: resultsAboveThreshold, + pullRequest: options.pullRequest, + baseBranch: options.baseBranch, + headBranch, + commit, + benchmarkedAt, + }); } } From 6af79dda7de9427220c992de38f72a0643d0492e Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 22 Oct 2024 12:36:12 +0200 Subject: [PATCH 18/40] fix results sent to github --- scripts/bench/bench-package.ts | 40 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 24 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 2f7d026a0b6c..054033ee13f2 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -174,22 +174,22 @@ const toHumanReadable = (result: Partial | Partial) => package: result.package, dependencyCount: { base: dependencyCount.base.toString(), - current: dependencyCount.new.toString(), + new: dependencyCount.new.toString(), diff: `${dependencyCount.diff > 0 ? '+' : dependencyCount.diff < 0 ? '-' : ''}${dependencyCount.diff}`, }, selfSize: { base: formatBytes(selfSize.base), - current: formatBytes(selfSize.new), + new: formatBytes(selfSize.new), diff: formatBytes(selfSize.diff, true), }, dependencySize: { base: formatBytes(dependencySize.base), - current: formatBytes(dependencySize.new), + new: formatBytes(dependencySize.new), diff: formatBytes(dependencySize.diff, true), }, totalSize: { base: formatBytes(selfSize.base + dependencySize.base), - current: formatBytes(selfSize.new + dependencySize.new), + new: formatBytes(selfSize.new + dependencySize.new), diff: formatBytes(selfSize.diff + dependencySize.diff, true), }, }; @@ -244,22 +244,20 @@ const compareResults = async ({ const comparisonResults = {} as ComparisonResultMap; for (const result of Object.values(results)) { - let baseResult = baseResults.find((row) => row.package === result.package); + const baseResult = baseResults.find((row) => row.package === result.package); if (!baseResult) { console.warn( `No base result found for ${picocolors.blue(result.package)}, skipping comparison.` ); continue; } - if (Math.random() > 0.5) { - console.log('LOG: faking base results', baseResult.package); - baseResult = { - package: baseResult.package, - dependencyCount: Math.floor(baseResult.dependencyCount * Math.random()), - selfSize: Math.floor(baseResult.selfSize * Math.random()), - dependencySize: Math.floor(baseResult.dependencySize * Math.random()), - }; - } + // console.log('LOG: faking base results', baseResult.package); + // baseResult = { + // package: baseResult.package, + // dependencyCount: Math.floor(baseResult.dependencyCount * Math.random()), + // selfSize: Math.floor(baseResult.selfSize * Math.random()), + // dependencySize: Math.floor(baseResult.dependencySize * Math.random()), + // }; comparisonResults[result.package] = { package: result.package, @@ -289,10 +287,10 @@ const filterResultsByThresholds = (comparisonResults: ComparisonResultMap) => { for (const comparisonResult of Object.values(comparisonResults)) { const exceedsThresholds = Math.abs(comparisonResult.selfSize.diff) > Thresholds.SELF_SIZE_ABSOLUTE || - Math.abs(comparisonResult.selfSize.diff) / comparisonResult.selfSize.new > + Math.abs(comparisonResult.selfSize.diff) / comparisonResult.selfSize.base > Thresholds.SELF_SIZE_RATIO || Math.abs(comparisonResult.dependencySize.diff) > Thresholds.DEPS_SIZE_ABSOLUTE || - Math.abs(comparisonResult.dependencySize.diff) / comparisonResult.dependencySize.new > + Math.abs(comparisonResult.dependencySize.diff) / comparisonResult.dependencySize.base > Thresholds.DEPS_SIZE_RATIO || Math.abs(comparisonResult.dependencyCount.diff) > Thresholds.DEPS_COUNT_ABSOLUTE; @@ -348,12 +346,6 @@ const uploadToGithub = async ({ benchmarkedAt: Date; pullRequest: number; }) => { - if (Object.keys(results).length === 0) { - // TODO: no, we need to update the table when results are good again - console.log('No results to upload to GitHub, skipping.'); - return; - } - const humanReadableResults = Object.values(results).reduce( (acc, result) => { acc[result.package] = toHumanReadable(result); @@ -363,8 +355,8 @@ const uploadToGithub = async ({ ); console.log('Uploading results to GitHub...'); - const response = await fetch('http://localhost:3000/package-bench', { - // const response = await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { + // const response = await fetch('http://localhost:3000/package-bench', { + const response = await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { method: 'POST', body: JSON.stringify({ owner: 'storybookjs', From d1f0385e4011a2c660399bf2b42ef91f96cbb8d3 Mon Sep 17 00:00:00 2001 From: dohi0512 Date: Tue, 29 Oct 2024 13:13:23 +0900 Subject: [PATCH 19/40] Remove duplicate comments --- code/frameworks/nextjs/src/routing/app-router-provider.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/code/frameworks/nextjs/src/routing/app-router-provider.tsx b/code/frameworks/nextjs/src/routing/app-router-provider.tsx index d21fdc8382cf..881bb98a172f 100644 --- a/code/frameworks/nextjs/src/routing/app-router-provider.tsx +++ b/code/frameworks/nextjs/src/routing/app-router-provider.tsx @@ -41,8 +41,6 @@ function getSelectedParams(currentTree: FlightRouterState, params: Params = {}): continue; } - // Ensure catchAll and optional catchall are turned into an array - // Ensure catchAll and optional catchall are turned into an array const isCatchAll = isDynamicParameter && (segment[2] === 'c' || segment[2] === 'oc'); From 4871e902fa22cd388df7ee48f142c12e03342263 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 29 Oct 2024 12:38:34 +0100 Subject: [PATCH 20/40] use --json for npm install --- scripts/bench/bench-package.ts | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index 054033ee13f2..ccb841179954 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -84,6 +84,9 @@ export const benchPackage = async (packageName: PackageName) => { { name: `${packageName}-bench`, version: '1.0.0', + dependencies: { + [packageName]: versions[packageName], + }, // Overrides ensures that Storybook packages outside the monorepo are using the versions we have in the monorepo overrides: versions, }, @@ -94,17 +97,15 @@ export const benchPackage = async (packageName: PackageName) => { const npmInstallResult = await x( 'npm', - `install --save-exact --registry http://localhost:6001 --omit peer ${packageName}@${versions[packageName]}`.split( - ' ' - ), + `install --registry http://localhost:6001 --omit peer --json`.split(' '), { nodeOptions: { cwd: tmpBenchPackagePath }, } ); + const { added } = JSON.parse(npmInstallResult.stdout) as { added: number }; // -1 of reported packages added because we shouldn't count the actual package as a dependency - const dependencyCount = - Number.parseInt(npmInstallResult.stdout.match(/added (\d+) packages?/)?.[1] ?? '') - 1; + const dependencyCount = added - 1; const getDirSize = async (path: string) => { const entities = await readdir(path, { @@ -249,6 +250,7 @@ const compareResults = async ({ console.warn( `No base result found for ${picocolors.blue(result.package)}, skipping comparison.` ); + // TODO: keep this in the report, comparing it to 0 continue; } // console.log('LOG: faking base results', baseResult.package); @@ -346,6 +348,7 @@ const uploadToGithub = async ({ benchmarkedAt: Date; pullRequest: number; }) => { + // TODO: send raw data instead const humanReadableResults = Object.values(results).reduce( (acc, result) => { acc[result.package] = toHumanReadable(result); @@ -411,7 +414,7 @@ const run = async () => { ); program.parse(process.argv); - const packages = ( + const packageNames = ( program.args.length > 0 ? program.args : Object.keys(versions) ) as PackageName[]; const options = program.opts<{ pullRequest?: number; baseBranch?: string; upload?: boolean }>(); @@ -435,8 +438,8 @@ const run = async () => { const limit = pLimit(concurrentLimt); const progressIntervalId = setInterval(() => { - const doneCount = packages.length - limit.activeCount - limit.pendingCount; - if (doneCount === packages.length) { + const doneCount = packageNames.length - limit.activeCount - limit.pendingCount; + if (doneCount === packageNames.length) { clearInterval(progressIntervalId); return; } @@ -445,7 +448,7 @@ const run = async () => { ); }, 2_000); const resultsArray = await Promise.all( - packages.map((packageName) => limit(() => benchPackage(packageName))) + packageNames.map((packageName) => limit(() => benchPackage(packageName))) ); const results = resultsArray.reduce((acc, result) => { acc[result.package] = result; From be33759ec69f9f402d3f00015c056b2f67f44e9c Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 29 Oct 2024 12:40:16 +0100 Subject: [PATCH 21/40] compare with zero when package not found in base --- scripts/bench/bench-package.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index ccb841179954..e2c8a555ad6b 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -245,21 +245,18 @@ const compareResults = async ({ const comparisonResults = {} as ComparisonResultMap; for (const result of Object.values(results)) { - const baseResult = baseResults.find((row) => row.package === result.package); + let baseResult = baseResults.find((row) => row.package === result.package); if (!baseResult) { console.warn( - `No base result found for ${picocolors.blue(result.package)}, skipping comparison.` + `No base result found for ${picocolors.blue(result.package)}, comparing with zero values.` ); - // TODO: keep this in the report, comparing it to 0 - continue; + baseResult = { + package: result.package, + dependencyCount: 0, + selfSize: 0, + dependencySize: 0, + }; } - // console.log('LOG: faking base results', baseResult.package); - // baseResult = { - // package: baseResult.package, - // dependencyCount: Math.floor(baseResult.dependencyCount * Math.random()), - // selfSize: Math.floor(baseResult.selfSize * Math.random()), - // dependencySize: Math.floor(baseResult.dependencySize * Math.random()), - // }; comparisonResults[result.package] = { package: result.package, From de8f3d248e6f21ebef00951779defa96b5a75dba Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 29 Oct 2024 13:41:19 +0100 Subject: [PATCH 22/40] send raw results to github bot --- scripts/bench/bench-package.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-package.ts index e2c8a555ad6b..210812b5ba61 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-package.ts @@ -345,15 +345,6 @@ const uploadToGithub = async ({ benchmarkedAt: Date; pullRequest: number; }) => { - // TODO: send raw data instead - const humanReadableResults = Object.values(results).reduce( - (acc, result) => { - acc[result.package] = toHumanReadable(result); - return acc; - }, - {} as Record> - ); - console.log('Uploading results to GitHub...'); // const response = await fetch('http://localhost:3000/package-bench', { const response = await fetch('https://storybook-benchmark-bot.vercel.app/package-bench', { @@ -366,7 +357,7 @@ const uploadToGithub = async ({ baseBranch, commit, benchmarkedAt: benchmarkedAt.toISOString(), - results: humanReadableResults, + results, }), }); if (response.status < 200 || response.status >= 400) { From 76079d0646bcf839a6b70fd2c862c2180aadf6f9 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 29 Oct 2024 13:54:51 +0100 Subject: [PATCH 23/40] fix lock-file --- scripts/yarn.lock | 7 ------- 1 file changed, 7 deletions(-) diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 02ec8d3d3410..aadc9d8c181b 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -13452,13 +13452,6 @@ __metadata: languageName: node linkType: hard -"tinyexec@npm:^0.3.0": - version: 0.3.1 - resolution: "tinyexec@npm:0.3.1" - checksum: 10c0/11e7a7c5d8b3bddf8b5cbe82a9290d70a6fad84d528421d5d18297f165723cb53d2e737d8f58dcce5ca56f2e4aa2d060f02510b1f8971784f97eb3e9aec28f09 - languageName: node - linkType: hard - "tinyexec@npm:^0.3.0": version: 0.3.0 resolution: "tinyexec@npm:0.3.0" From a2a479441e26409ad3712fb6af2ca2b58650a9be Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 29 Oct 2024 21:47:00 +0100 Subject: [PATCH 24/40] remove auto handling of the registry --- .circleci/config.yml | 2 +- scripts/bench/{bench-package.ts => bench-packages.ts} | 11 ++++------- scripts/package.json | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) rename scripts/bench/{bench-package.ts => bench-packages.ts} (97%) diff --git a/.circleci/config.yml b/.circleci/config.yml index b64dbeea2571..52f6c5ebd734 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -223,7 +223,7 @@ jobs: - run: name: Benchmarking Packages working_directory: scripts - command: yarn bench-package --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> --upload + command: yarn bench-packages --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> --upload - store_artifacts: path: bench/packages/results.json - store_artifacts: diff --git a/scripts/bench/bench-package.ts b/scripts/bench/bench-packages.ts similarity index 97% rename from scripts/bench/bench-package.ts rename to scripts/bench/bench-packages.ts index 210812b5ba61..309e30095fb3 100644 --- a/scripts/bench/bench-package.ts +++ b/scripts/bench/bench-packages.ts @@ -6,9 +6,9 @@ import pLimit from 'p-limit'; import { join } from 'path'; import picocolors from 'picocolors'; import { x } from 'tinyexec'; +import dedent from 'ts-dedent'; import versions from '../../code/core/src/common/versions'; -import { runRegistry } from '../tasks/run-registry'; import { maxConcurrentTasks } from '../utils/concurrency'; import { esMain } from '../utils/esmain'; @@ -58,8 +58,6 @@ type ComparisonResult = { type ResultMap = Record; type ComparisonResultMap = Record; -let registryController: AbortController | undefined; - /** * This function benchmarks the size of Storybook packages and their dependencies. For each package, * the steps are: @@ -416,8 +414,9 @@ const run = async () => { } if ((await detectFreePort(REGISTRY_PORT)) === REGISTRY_PORT) { - console.log('Starting local registry...'); - registryController = await runRegistry({ dryRun: false, debug: false }); + throw new Error(dedent`The local verdaccio registry must be running in the background for package benching to work, + and packages must be published to it in --no-link mode with 'yarn --task publish --no-link' + Then runn the registry with 'yarn --task run-registry --no-link'`); } // The amount of VCPUs for this task in CI is 2 (medium resource) @@ -484,12 +483,10 @@ const run = async () => { } console.log(picocolors.green('Done benching all packages')); - registryController?.abort(); }; if (esMain(import.meta.url)) { run().catch((err) => { - registryController?.abort(); console.error(err); process.exit(1); }); diff --git a/scripts/package.json b/scripts/package.json index b3e0e4d46e57..e8903525a4f3 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "bench-package": "jiti ./bench/bench-package.ts", + "bench-packages": "jiti ./bench/bench-packages.ts", "build-package": "jiti ./build-package.ts", "check": "jiti ./prepare/check-scripts.ts", "check-package": "jiti ./check-package.ts", From 909297a014e4d53fa470c91fcab57c6300f112d1 Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Mon, 4 Nov 2024 12:15:45 +0100 Subject: [PATCH 25/40] Prevent clipping box shadow on file search modal --- code/core/src/manager/components/sidebar/FileSearchModal.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/code/core/src/manager/components/sidebar/FileSearchModal.tsx b/code/core/src/manager/components/sidebar/FileSearchModal.tsx index 469493744d43..043abffb5107 100644 --- a/code/core/src/manager/components/sidebar/FileSearchModal.tsx +++ b/code/core/src/manager/components/sidebar/FileSearchModal.tsx @@ -13,6 +13,7 @@ const MODAL_HEIGHT = 418; const ModalStyled = styled(Modal)(() => ({ boxShadow: 'none', background: 'transparent', + overflow: 'visible', })); const ModalChild = styled.div<{ height?: number }>(({ theme, height }) => ({ From 39a13d1355fbbc5494ee8d19b491cddcfc089c99 Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Mon, 4 Nov 2024 12:21:35 +0100 Subject: [PATCH 26/40] Addon Test: Enhance post-install logic for Next.js Vite framework support --- code/addons/test/src/postinstall.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/addons/test/src/postinstall.ts b/code/addons/test/src/postinstall.ts index f7b5efe8521c..90595b0e15d6 100644 --- a/code/addons/test/src/postinstall.ts +++ b/code/addons/test/src/postinstall.ts @@ -58,7 +58,9 @@ export default async function postInstall(options: PostinstallOptions) { '@storybook/experimental-nextjs-vite', '@storybook/sveltekit', ].includes(info.frameworkPackageName) - ? info.frameworkPackageName + ? info.frameworkPackageName === '@storybook/nextjs' + ? '@storybook/experimental-nextjs-vite' + : info.frameworkPackageName : info.rendererPackageName && ['@storybook/react', '@storybook/svelte', '@storybook/vue3'].includes( info.rendererPackageName @@ -431,7 +433,7 @@ const getVitestPluginInfo = (framework: string) => { let frameworkPluginCall = ''; let frameworkPluginDocs = ''; - if (framework === '@storybook/nextjs') { + if (framework === '@storybook/nextjs' || framework === '@storybook/experimental-nextjs-vite') { frameworkPluginImport = "import { storybookNextJsPlugin } from '@storybook/experimental-nextjs-vite/vite-plugin';"; frameworkPluginDocs = From ef5bde7179813f9a8c1451d834cc5b2a23f739a0 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 4 Nov 2024 16:17:14 +0100 Subject: [PATCH 27/40] add section about relesing changes to older minor versions --- CONTRIBUTING/RELEASING.md | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/CONTRIBUTING/RELEASING.md b/CONTRIBUTING/RELEASING.md index afc1bc377451..b6cff1205a7a 100644 --- a/CONTRIBUTING/RELEASING.md +++ b/CONTRIBUTING/RELEASING.md @@ -19,6 +19,7 @@ - [5. Make Manual Changes](#5-make-manual-changes) - [6. Merge](#6-merge) - [7. See the "Publish" Workflow Finish](#7-see-the-publish-workflow-finish) +- [Releasing changes to older minor versions](#releasing-changes-to-older-minor-versions) - [Releasing Locally in an Emergency 🚨](#releasing-locally-in-an-emergency-) - [Canary Releases](#canary-releases) - [With GitHub UI](#with-github-ui) @@ -330,6 +331,59 @@ Merging the pull request will trigger [the publish workflow](https://github.com/ Done! 🚀 +## Releasing changes to older minor versions + +If you need to release a change to an older minor version that is not the latest, you have to do it manually, locally. The process is described below, with an example of releasing a new `v8.3.7` in a situation where `8.4.0` is currently the latest version. + +1. Checkout the _existing_ tag that matches the latest minor release you want to bump, and create a new branch from it. In this case, we want to do: + 1. `git fetch --all --tags` + 2. `git checkout tags/v8.3.6 -b patch-8-3-7` +2. Make the changes you need to, most likely cherry-picking commits from the fix you need to back-port. +3. Run `yarn install` in `scripts` and `code` +4. Build all packages in `code` with `yarn task --task compile --no-link` +5. Commit and push your changes. +6. Trigger _daily_ CI manually on your branch: + 1. Open https://app.circleci.com/pipelines/github/storybookjs/storybook + 2. Click "Trigger Pipeline", top right corner + 3. Pipeline: _"storybook default"_ + 4. Config Source: _"storybook"_ + 5. Branch: Your branch, eg. `patch-8-3-7` + 6. Add a parameter, with _"name"_ `workflow`, _"value"_ `daily` +7. Wait for CI to finish successfully. +8. Bump all package versions: + 1. `cd scripts` + 2. `yarn release:version --release-type patch` +9. Commit with `git commit -m "Bump version from to MANUALLY"` +10. Add a new entry to `CHANGELOG.md`, describing your changes +11. Commit with `git commit -m "Update CHANGELOG.md with MANUALLY"` +12. Ensure you have the correct write permissions to all the Storybook npm packages. You need to be an admin of the _storybook_ org, as well as the packages not in the org. The simplest way to check this, is to ensure you can see the _"Settings"_ tab in the follwing packages: + 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite/access) + 2. [`storybook`](https://www.npmjs.com/package/storybook/access) + 3. [`sb`](https://www.npmjs.com/package/sb/access) + 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook/access) +13. Get your npm access token or generate a new one at https://www.npmjs.com/settings/jreinhold/tokens. Remember to not only give it access to the `storybook` org, but also the packages not in the org as listed above. +14. Publish all packages with `YARN_NPM_AUTH_TOKEN= yarn release:publish --tag tag-for-publishing-older-releases --verbose` + - It goes through all packages and publishes them. If any number of packages fails to publish, it will retry 5 times, skipping those that have already been published. +15. Confirm the new version has been released on npmjs with the tag `tag-for-publishing-older-releases`: + 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite?activeTab=versions) + 2. [`storybook`](https://www.npmjs.com/package/storybook?activeTab=versions) + 3. [`sb`](phttps://www.npmjs.com/package/sb?activeTab=versions) + 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook?activeTab=versions) +16. Push +17. Manually create a GitHub Release at https://github.com/storybookjs/storybook/releases/new with: + 1. Create new tag: `v`, eg. `v8.3.7` + 2. Target: your branch, eg. `patch-8-3-7` + 3. Previous tag: `v`, eg. `v8.3.6` + 4. Title: `v`, eg. `v8.3.7` + 5. Description: The content you added to `CHANGELOG.md` + 6. Untick _"Set as the latest release"_ +18. Cherry-pick your changelog changes into `next`, so they are actually visible + 1. Checkout the `next` branch + 2. Cherry-pick the commit you created with your changelog modifications + 3. Push + +Done. 🎉 + ## Releasing Locally in an Emergency 🚨 Things can fail, code can break, and bugs can exist. When automation is broken, there may be a need for an emergency escape hatch to release new fixes. In such a situation, it's valid to run the whole release process locally instead of relying on pull requests and workflows. You don't need to create pull requests or split preparation and publishing; you can do it all at once, but make sure you still follow the correct branching strategy. From 9aa2f867d0fe3ca5ff9af933cf167d9982b9ba4f Mon Sep 17 00:00:00 2001 From: Gert Hengeveld Date: Mon, 4 Nov 2024 16:29:31 +0100 Subject: [PATCH 28/40] Fix type errors --- .../manager/components/sidebar/Heading.stories.tsx | 8 +++++--- .../src/manager/components/sidebar/Menu.stories.tsx | 11 ++++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/code/core/src/manager/components/sidebar/Heading.stories.tsx b/code/core/src/manager/components/sidebar/Heading.stories.tsx index 678a6c8e2ae5..81436bfc0a1d 100644 --- a/code/core/src/manager/components/sidebar/Heading.stories.tsx +++ b/code/core/src/manager/components/sidebar/Heading.stories.tsx @@ -24,9 +24,11 @@ export default { } as Meta; const menuItems = [ - { title: 'Menu Item 1', onClick: action('onActivateMenuItem'), id: '1' }, - { title: 'Menu Item 2', onClick: action('onActivateMenuItem'), id: '2' }, - { title: 'Menu Item 3', onClick: action('onActivateMenuItem'), id: '3' }, + [ + { title: 'Menu Item 1', onClick: action('onActivateMenuItem'), id: '1' }, + { title: 'Menu Item 2', onClick: action('onActivateMenuItem'), id: '2' }, + { title: 'Menu Item 3', onClick: action('onActivateMenuItem'), id: '3' }, + ], ]; export const MenuHighlighted: Story = () => ( diff --git a/code/core/src/manager/components/sidebar/Menu.stories.tsx b/code/core/src/manager/components/sidebar/Menu.stories.tsx index 663bd4caa3b4..d5bf90dc2a60 100644 --- a/code/core/src/manager/components/sidebar/Menu.stories.tsx +++ b/code/core/src/manager/components/sidebar/Menu.stories.tsx @@ -1,4 +1,3 @@ -import type { ComponentProps } from 'react'; import React from 'react'; import { TooltipLinkList } from '@storybook/core/components'; @@ -11,11 +10,13 @@ import type { State } from '@storybook/core/manager-api'; import { useMenu } from '../../container/Menu'; import { LayoutProvider } from '../layout/LayoutProvider'; -import { SidebarMenu } from './Menu'; +import { type MenuList, SidebarMenu } from './Menu'; -const fakemenu: ComponentProps['links'] = [ - { title: 'has icon', icon: , id: 'icon' }, - { title: 'has no icon', id: 'non' }, +const fakemenu: MenuList = [ + [ + { title: 'has icon', icon: , id: 'icon' }, + { title: 'has no icon', id: 'non' }, + ], ]; const meta = { From c7ee4a675b9b8150d846a5f039d04384875abaaf Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Mon, 4 Nov 2024 16:45:33 +0100 Subject: [PATCH 29/40] fix typo --- CONTRIBUTING/RELEASING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING/RELEASING.md b/CONTRIBUTING/RELEASING.md index b6cff1205a7a..cc08a0ad9b4c 100644 --- a/CONTRIBUTING/RELEASING.md +++ b/CONTRIBUTING/RELEASING.md @@ -367,7 +367,7 @@ If you need to release a change to an older minor version that is not the latest 15. Confirm the new version has been released on npmjs with the tag `tag-for-publishing-older-releases`: 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite?activeTab=versions) 2. [`storybook`](https://www.npmjs.com/package/storybook?activeTab=versions) - 3. [`sb`](phttps://www.npmjs.com/package/sb?activeTab=versions) + 3. [`sb`](https://www.npmjs.com/package/sb?activeTab=versions) 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook?activeTab=versions) 16. Push 17. Manually create a GitHub Release at https://github.com/storybookjs/storybook/releases/new with: From e9d6e2968b813004c258bc3a8c495b406ffc9afb Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Tue, 5 Nov 2024 02:32:55 +0000 Subject: [PATCH 30/40] Write changelog for 8.5.0-alpha.3 [skip ci] --- CHANGELOG.prerelease.md | 5 +++++ code/package.json | 3 ++- docs/versions/next.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.prerelease.md b/CHANGELOG.prerelease.md index f9f62e7c79d9..597322a9ce2a 100644 --- a/CHANGELOG.prerelease.md +++ b/CHANGELOG.prerelease.md @@ -1,3 +1,8 @@ +## 8.5.0-alpha.3 + +- Addon Test: Fix post-install logic for Next.js Vite framework support - [#29524](https://github.com/storybookjs/storybook/pull/29524), thanks @valentinpalkovic! +- Core: Prevent clipping box shadow on file search modal - [#29523](https://github.com/storybookjs/storybook/pull/29523), thanks @ghengeveld! + ## 8.5.0-alpha.2 - Addon Test: Only render the TestingModule component in development mode - [#29501](https://github.com/storybookjs/storybook/pull/29501), thanks @yannbf! diff --git a/code/package.json b/code/package.json index 78ec34d4fafe..3612783dda03 100644 --- a/code/package.json +++ b/code/package.json @@ -293,5 +293,6 @@ "Dependency Upgrades" ] ] - } + }, + "deferredNextVersion": "8.5.0-alpha.3" } diff --git a/docs/versions/next.json b/docs/versions/next.json index 641189d11f4c..617b3b564f76 100644 --- a/docs/versions/next.json +++ b/docs/versions/next.json @@ -1 +1 @@ -{"version":"8.5.0-alpha.2","info":{"plain":"- Addon Test: Only render the TestingModule component in development mode - [#29501](https://github.com/storybookjs/storybook/pull/29501), thanks @yannbf!\n- CLI: Fix Solid init by installing `@storybook/test` - [#29514](https://github.com/storybookjs/storybook/pull/29514), thanks @shilman!\n- Core: Add bun support with npm fallback - [#29267](https://github.com/storybookjs/storybook/pull/29267), thanks @stephenjason89!\n- Core: Shim CJS-only globals in ESM output - [#29157](https://github.com/storybookjs/storybook/pull/29157), thanks @valentinpalkovic!\n- Next.js: Fix bundled react and react-dom in monorepos - [#29444](https://github.com/storybookjs/storybook/pull/29444), thanks @sentience!\n- Next.js: Upgrade sass-loader from ^13.2.0 to ^14.2.1 - [#29264](https://github.com/storybookjs/storybook/pull/29264), thanks @HoncharenkoZhenya!\n- UI: Add support for groups to `TooltipLinkList` and use it in main menu - [#29507](https://github.com/storybookjs/storybook/pull/29507), thanks @ghengeveld!"}} +{"version":"8.5.0-alpha.3","info":{"plain":"- Addon Test: Fix post-install logic for Next.js Vite framework support - [#29524](https://github.com/storybookjs/storybook/pull/29524), thanks @valentinpalkovic!\n- Core: Prevent clipping box shadow on file search modal - [#29523](https://github.com/storybookjs/storybook/pull/29523), thanks @ghengeveld!"}} From 85055fa4544625f84da65ca355f9136ea023a18e Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Tue, 5 Nov 2024 05:41:54 +0000 Subject: [PATCH 31/40] Bump version from "8.5.0-alpha.2" to "8.5.0-alpha.3" [skip ci] --- code/addons/a11y/package.json | 2 +- code/addons/actions/package.json | 2 +- code/addons/backgrounds/package.json | 2 +- code/addons/controls/package.json | 2 +- code/addons/docs/package.json | 2 +- code/addons/essentials/package.json | 2 +- code/addons/gfm/package.json | 2 +- code/addons/highlight/package.json | 2 +- code/addons/interactions/package.json | 2 +- code/addons/jest/package.json | 2 +- code/addons/links/package.json | 2 +- code/addons/measure/package.json | 2 +- code/addons/onboarding/package.json | 2 +- code/addons/outline/package.json | 2 +- code/addons/storysource/package.json | 2 +- code/addons/test/package.json | 2 +- code/addons/themes/package.json | 2 +- code/addons/toolbars/package.json | 2 +- code/addons/viewport/package.json | 2 +- code/builders/builder-vite/package.json | 2 +- code/builders/builder-webpack5/package.json | 2 +- code/core/package.json | 2 +- code/core/src/common/versions.ts | 168 +++++++++--------- code/core/src/manager-api/version.ts | 2 +- code/deprecated/builder-manager/package.json | 2 +- code/deprecated/channels/package.json | 2 +- code/deprecated/client-logger/package.json | 2 +- code/deprecated/components/package.json | 2 +- code/deprecated/core-common/package.json | 2 +- code/deprecated/core-events/package.json | 2 +- code/deprecated/core-server/package.json | 2 +- code/deprecated/csf-tools/package.json | 2 +- code/deprecated/docs-tools/package.json | 2 +- code/deprecated/manager-api/package.json | 2 +- code/deprecated/manager/package.json | 2 +- code/deprecated/node-logger/package.json | 2 +- code/deprecated/preview-api/package.json | 2 +- code/deprecated/preview/package.json | 2 +- code/deprecated/router/package.json | 2 +- code/deprecated/telemetry/package.json | 2 +- code/deprecated/theming/package.json | 2 +- code/deprecated/types/package.json | 2 +- code/frameworks/angular/package.json | 2 +- code/frameworks/ember/package.json | 2 +- .../experimental-nextjs-vite/package.json | 2 +- code/frameworks/html-vite/package.json | 2 +- code/frameworks/html-webpack5/package.json | 2 +- code/frameworks/nextjs/package.json | 2 +- code/frameworks/preact-vite/package.json | 2 +- code/frameworks/preact-webpack5/package.json | 2 +- code/frameworks/react-vite/package.json | 2 +- code/frameworks/react-webpack5/package.json | 2 +- code/frameworks/server-webpack5/package.json | 2 +- code/frameworks/svelte-vite/package.json | 2 +- code/frameworks/svelte-webpack5/package.json | 2 +- code/frameworks/sveltekit/package.json | 2 +- code/frameworks/vue3-vite/package.json | 2 +- code/frameworks/vue3-webpack5/package.json | 2 +- .../web-components-vite/package.json | 2 +- .../web-components-webpack5/package.json | 2 +- code/lib/blocks/package.json | 2 +- code/lib/cli-sb/package.json | 2 +- code/lib/cli-storybook/package.json | 2 +- code/lib/cli/package.json | 2 +- code/lib/codemod/package.json | 2 +- code/lib/core-webpack/package.json | 2 +- code/lib/create-storybook/package.json | 2 +- code/lib/csf-plugin/package.json | 2 +- code/lib/instrumenter/package.json | 2 +- code/lib/react-dom-shim/package.json | 2 +- code/lib/source-loader/package.json | 2 +- code/lib/test/package.json | 2 +- code/package.json | 5 +- code/presets/create-react-app/package.json | 2 +- code/presets/html-webpack/package.json | 2 +- code/presets/preact-webpack/package.json | 2 +- code/presets/react-webpack/package.json | 2 +- code/presets/server-webpack/package.json | 2 +- code/presets/svelte-webpack/package.json | 2 +- code/presets/vue3-webpack/package.json | 2 +- code/renderers/html/package.json | 2 +- code/renderers/preact/package.json | 2 +- code/renderers/react/package.json | 2 +- code/renderers/server/package.json | 2 +- code/renderers/svelte/package.json | 2 +- code/renderers/vue3/package.json | 2 +- code/renderers/web-components/package.json | 2 +- 87 files changed, 171 insertions(+), 172 deletions(-) diff --git a/code/addons/a11y/package.json b/code/addons/a11y/package.json index 65b230ec6feb..750e10416ed8 100644 --- a/code/addons/a11y/package.json +++ b/code/addons/a11y/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-a11y", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Test component compliance with web accessibility standards", "keywords": [ "a11y", diff --git a/code/addons/actions/package.json b/code/addons/actions/package.json index d2ae93c9cd9f..d8e3c09e3677 100644 --- a/code/addons/actions/package.json +++ b/code/addons/actions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-actions", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Get UI feedback when an action is performed on an interactive element", "keywords": [ "storybook", diff --git a/code/addons/backgrounds/package.json b/code/addons/backgrounds/package.json index a355399d4bda..ed8837847325 100644 --- a/code/addons/backgrounds/package.json +++ b/code/addons/backgrounds/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-backgrounds", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Switch backgrounds to view components in different settings", "keywords": [ "addon", diff --git a/code/addons/controls/package.json b/code/addons/controls/package.json index 15b7e876cb18..429aa10bfe5c 100644 --- a/code/addons/controls/package.json +++ b/code/addons/controls/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-controls", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Interact with component inputs dynamically in the Storybook UI", "keywords": [ "addon", diff --git a/code/addons/docs/package.json b/code/addons/docs/package.json index 075aa9042ed4..cd8352d5247a 100644 --- a/code/addons/docs/package.json +++ b/code/addons/docs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-docs", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Document component usage and properties in Markdown", "keywords": [ "addon", diff --git a/code/addons/essentials/package.json b/code/addons/essentials/package.json index d6f4c2d06a18..d83ad0bd8a3e 100644 --- a/code/addons/essentials/package.json +++ b/code/addons/essentials/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-essentials", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Curated addons to bring out the best of Storybook", "keywords": [ "addon", diff --git a/code/addons/gfm/package.json b/code/addons/gfm/package.json index 357c459512a1..8e4c51ba31d1 100644 --- a/code/addons/gfm/package.json +++ b/code/addons/gfm/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-mdx-gfm", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "GitHub Flavored Markdown in Storybook", "keywords": [ "addon", diff --git a/code/addons/highlight/package.json b/code/addons/highlight/package.json index f367c8522194..8fefc078ae48 100644 --- a/code/addons/highlight/package.json +++ b/code/addons/highlight/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-highlight", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Highlight DOM nodes within your stories", "keywords": [ "storybook-addons", diff --git a/code/addons/interactions/package.json b/code/addons/interactions/package.json index 8d6f8316d346..6611a51119bb 100644 --- a/code/addons/interactions/package.json +++ b/code/addons/interactions/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-interactions", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Automate, test and debug user interactions", "keywords": [ "storybook-addons", diff --git a/code/addons/jest/package.json b/code/addons/jest/package.json index 3f533d0630a8..4bbbd808658a 100644 --- a/code/addons/jest/package.json +++ b/code/addons/jest/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-jest", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "React storybook addon that show component jest report", "keywords": [ "addon", diff --git a/code/addons/links/package.json b/code/addons/links/package.json index 3f6041e32c8e..7811c108d2a7 100644 --- a/code/addons/links/package.json +++ b/code/addons/links/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-links", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Link stories together to build demos and prototypes with your UI components", "keywords": [ "storybook-addons", diff --git a/code/addons/measure/package.json b/code/addons/measure/package.json index 2b9b42f0817b..1f662322a90e 100644 --- a/code/addons/measure/package.json +++ b/code/addons/measure/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-measure", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Inspect layouts by visualizing the box model", "keywords": [ "storybook-addons", diff --git a/code/addons/onboarding/package.json b/code/addons/onboarding/package.json index 8f1c3dd69c6c..0913e5da9cc5 100644 --- a/code/addons/onboarding/package.json +++ b/code/addons/onboarding/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-onboarding", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook Addon Onboarding - Introduces a new onboarding experience", "keywords": [ "storybook-addons", diff --git a/code/addons/outline/package.json b/code/addons/outline/package.json index f891ea68483c..bef947388da9 100644 --- a/code/addons/outline/package.json +++ b/code/addons/outline/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-outline", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Outline all elements with CSS to help with layout placement and alignment", "keywords": [ "storybook-addons", diff --git a/code/addons/storysource/package.json b/code/addons/storysource/package.json index 9d5ea44b0a93..374e797bc5ea 100644 --- a/code/addons/storysource/package.json +++ b/code/addons/storysource/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-storysource", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "View a story’s source code to see how it works and paste into your app", "keywords": [ "addon", diff --git a/code/addons/test/package.json b/code/addons/test/package.json index ca9cac69fbb5..b778853351e5 100644 --- a/code/addons/test/package.json +++ b/code/addons/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/experimental-addon-test", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Integrate Vitest with Storybook", "keywords": [ "storybook-addons", diff --git a/code/addons/themes/package.json b/code/addons/themes/package.json index c6d1cfcd6d08..5fd65ba89a0c 100644 --- a/code/addons/themes/package.json +++ b/code/addons/themes/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-themes", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Switch between multiple themes for you components in Storybook", "keywords": [ "css", diff --git a/code/addons/toolbars/package.json b/code/addons/toolbars/package.json index dba8b60e73e9..b99a65fe8cad 100644 --- a/code/addons/toolbars/package.json +++ b/code/addons/toolbars/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-toolbars", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Create your own toolbar items that control story rendering", "keywords": [ "addon", diff --git a/code/addons/viewport/package.json b/code/addons/viewport/package.json index d51f0b158663..9bcdf2aff652 100644 --- a/code/addons/viewport/package.json +++ b/code/addons/viewport/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/addon-viewport", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Build responsive components by adjusting Storybook’s viewport size and orientation", "keywords": [ "addon", diff --git a/code/builders/builder-vite/package.json b/code/builders/builder-vite/package.json index 685e347dbd11..594e1c57e74e 100644 --- a/code/builders/builder-vite/package.json +++ b/code/builders/builder-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "A plugin to run and build Storybooks with Vite", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/builders/builder-vite/#readme", "bugs": { diff --git a/code/builders/builder-webpack5/package.json b/code/builders/builder-webpack5/package.json index fb7cf6b47f5f..6a122437e617 100644 --- a/code/builders/builder-webpack5/package.json +++ b/code/builders/builder-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/core/package.json b/code/core/package.json index 005e21f72afb..919e462ebd30 100644 --- a/code/core/package.json +++ b/code/core/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/core/src/common/versions.ts b/code/core/src/common/versions.ts index 68001af0ed44..9d0225f6f352 100644 --- a/code/core/src/common/versions.ts +++ b/code/core/src/common/versions.ts @@ -1,87 +1,87 @@ // auto generated file, do not edit export default { - '@storybook/addon-a11y': '8.5.0-alpha.2', - '@storybook/addon-actions': '8.5.0-alpha.2', - '@storybook/addon-backgrounds': '8.5.0-alpha.2', - '@storybook/addon-controls': '8.5.0-alpha.2', - '@storybook/addon-docs': '8.5.0-alpha.2', - '@storybook/addon-essentials': '8.5.0-alpha.2', - '@storybook/addon-mdx-gfm': '8.5.0-alpha.2', - '@storybook/addon-highlight': '8.5.0-alpha.2', - '@storybook/addon-interactions': '8.5.0-alpha.2', - '@storybook/addon-jest': '8.5.0-alpha.2', - '@storybook/addon-links': '8.5.0-alpha.2', - '@storybook/addon-measure': '8.5.0-alpha.2', - '@storybook/addon-onboarding': '8.5.0-alpha.2', - '@storybook/addon-outline': '8.5.0-alpha.2', - '@storybook/addon-storysource': '8.5.0-alpha.2', - '@storybook/experimental-addon-test': '8.5.0-alpha.2', - '@storybook/addon-themes': '8.5.0-alpha.2', - '@storybook/addon-toolbars': '8.5.0-alpha.2', - '@storybook/addon-viewport': '8.5.0-alpha.2', - '@storybook/builder-vite': '8.5.0-alpha.2', - '@storybook/builder-webpack5': '8.5.0-alpha.2', - '@storybook/core': '8.5.0-alpha.2', - '@storybook/builder-manager': '8.5.0-alpha.2', - '@storybook/channels': '8.5.0-alpha.2', - '@storybook/client-logger': '8.5.0-alpha.2', - '@storybook/components': '8.5.0-alpha.2', - '@storybook/core-common': '8.5.0-alpha.2', - '@storybook/core-events': '8.5.0-alpha.2', - '@storybook/core-server': '8.5.0-alpha.2', - '@storybook/csf-tools': '8.5.0-alpha.2', - '@storybook/docs-tools': '8.5.0-alpha.2', - '@storybook/manager': '8.5.0-alpha.2', - '@storybook/manager-api': '8.5.0-alpha.2', - '@storybook/node-logger': '8.5.0-alpha.2', - '@storybook/preview': '8.5.0-alpha.2', - '@storybook/preview-api': '8.5.0-alpha.2', - '@storybook/router': '8.5.0-alpha.2', - '@storybook/telemetry': '8.5.0-alpha.2', - '@storybook/theming': '8.5.0-alpha.2', - '@storybook/types': '8.5.0-alpha.2', - '@storybook/angular': '8.5.0-alpha.2', - '@storybook/ember': '8.5.0-alpha.2', - '@storybook/experimental-nextjs-vite': '8.5.0-alpha.2', - '@storybook/html-vite': '8.5.0-alpha.2', - '@storybook/html-webpack5': '8.5.0-alpha.2', - '@storybook/nextjs': '8.5.0-alpha.2', - '@storybook/preact-vite': '8.5.0-alpha.2', - '@storybook/preact-webpack5': '8.5.0-alpha.2', - '@storybook/react-vite': '8.5.0-alpha.2', - '@storybook/react-webpack5': '8.5.0-alpha.2', - '@storybook/server-webpack5': '8.5.0-alpha.2', - '@storybook/svelte-vite': '8.5.0-alpha.2', - '@storybook/svelte-webpack5': '8.5.0-alpha.2', - '@storybook/sveltekit': '8.5.0-alpha.2', - '@storybook/vue3-vite': '8.5.0-alpha.2', - '@storybook/vue3-webpack5': '8.5.0-alpha.2', - '@storybook/web-components-vite': '8.5.0-alpha.2', - '@storybook/web-components-webpack5': '8.5.0-alpha.2', - '@storybook/blocks': '8.5.0-alpha.2', - storybook: '8.5.0-alpha.2', - sb: '8.5.0-alpha.2', - '@storybook/cli': '8.5.0-alpha.2', - '@storybook/codemod': '8.5.0-alpha.2', - '@storybook/core-webpack': '8.5.0-alpha.2', - 'create-storybook': '8.5.0-alpha.2', - '@storybook/csf-plugin': '8.5.0-alpha.2', - '@storybook/instrumenter': '8.5.0-alpha.2', - '@storybook/react-dom-shim': '8.5.0-alpha.2', - '@storybook/source-loader': '8.5.0-alpha.2', - '@storybook/test': '8.5.0-alpha.2', - '@storybook/preset-create-react-app': '8.5.0-alpha.2', - '@storybook/preset-html-webpack': '8.5.0-alpha.2', - '@storybook/preset-preact-webpack': '8.5.0-alpha.2', - '@storybook/preset-react-webpack': '8.5.0-alpha.2', - '@storybook/preset-server-webpack': '8.5.0-alpha.2', - '@storybook/preset-svelte-webpack': '8.5.0-alpha.2', - '@storybook/preset-vue3-webpack': '8.5.0-alpha.2', - '@storybook/html': '8.5.0-alpha.2', - '@storybook/preact': '8.5.0-alpha.2', - '@storybook/react': '8.5.0-alpha.2', - '@storybook/server': '8.5.0-alpha.2', - '@storybook/svelte': '8.5.0-alpha.2', - '@storybook/vue3': '8.5.0-alpha.2', - '@storybook/web-components': '8.5.0-alpha.2', + '@storybook/addon-a11y': '8.5.0-alpha.3', + '@storybook/addon-actions': '8.5.0-alpha.3', + '@storybook/addon-backgrounds': '8.5.0-alpha.3', + '@storybook/addon-controls': '8.5.0-alpha.3', + '@storybook/addon-docs': '8.5.0-alpha.3', + '@storybook/addon-essentials': '8.5.0-alpha.3', + '@storybook/addon-mdx-gfm': '8.5.0-alpha.3', + '@storybook/addon-highlight': '8.5.0-alpha.3', + '@storybook/addon-interactions': '8.5.0-alpha.3', + '@storybook/addon-jest': '8.5.0-alpha.3', + '@storybook/addon-links': '8.5.0-alpha.3', + '@storybook/addon-measure': '8.5.0-alpha.3', + '@storybook/addon-onboarding': '8.5.0-alpha.3', + '@storybook/addon-outline': '8.5.0-alpha.3', + '@storybook/addon-storysource': '8.5.0-alpha.3', + '@storybook/experimental-addon-test': '8.5.0-alpha.3', + '@storybook/addon-themes': '8.5.0-alpha.3', + '@storybook/addon-toolbars': '8.5.0-alpha.3', + '@storybook/addon-viewport': '8.5.0-alpha.3', + '@storybook/builder-vite': '8.5.0-alpha.3', + '@storybook/builder-webpack5': '8.5.0-alpha.3', + '@storybook/core': '8.5.0-alpha.3', + '@storybook/builder-manager': '8.5.0-alpha.3', + '@storybook/channels': '8.5.0-alpha.3', + '@storybook/client-logger': '8.5.0-alpha.3', + '@storybook/components': '8.5.0-alpha.3', + '@storybook/core-common': '8.5.0-alpha.3', + '@storybook/core-events': '8.5.0-alpha.3', + '@storybook/core-server': '8.5.0-alpha.3', + '@storybook/csf-tools': '8.5.0-alpha.3', + '@storybook/docs-tools': '8.5.0-alpha.3', + '@storybook/manager': '8.5.0-alpha.3', + '@storybook/manager-api': '8.5.0-alpha.3', + '@storybook/node-logger': '8.5.0-alpha.3', + '@storybook/preview': '8.5.0-alpha.3', + '@storybook/preview-api': '8.5.0-alpha.3', + '@storybook/router': '8.5.0-alpha.3', + '@storybook/telemetry': '8.5.0-alpha.3', + '@storybook/theming': '8.5.0-alpha.3', + '@storybook/types': '8.5.0-alpha.3', + '@storybook/angular': '8.5.0-alpha.3', + '@storybook/ember': '8.5.0-alpha.3', + '@storybook/experimental-nextjs-vite': '8.5.0-alpha.3', + '@storybook/html-vite': '8.5.0-alpha.3', + '@storybook/html-webpack5': '8.5.0-alpha.3', + '@storybook/nextjs': '8.5.0-alpha.3', + '@storybook/preact-vite': '8.5.0-alpha.3', + '@storybook/preact-webpack5': '8.5.0-alpha.3', + '@storybook/react-vite': '8.5.0-alpha.3', + '@storybook/react-webpack5': '8.5.0-alpha.3', + '@storybook/server-webpack5': '8.5.0-alpha.3', + '@storybook/svelte-vite': '8.5.0-alpha.3', + '@storybook/svelte-webpack5': '8.5.0-alpha.3', + '@storybook/sveltekit': '8.5.0-alpha.3', + '@storybook/vue3-vite': '8.5.0-alpha.3', + '@storybook/vue3-webpack5': '8.5.0-alpha.3', + '@storybook/web-components-vite': '8.5.0-alpha.3', + '@storybook/web-components-webpack5': '8.5.0-alpha.3', + '@storybook/blocks': '8.5.0-alpha.3', + storybook: '8.5.0-alpha.3', + sb: '8.5.0-alpha.3', + '@storybook/cli': '8.5.0-alpha.3', + '@storybook/codemod': '8.5.0-alpha.3', + '@storybook/core-webpack': '8.5.0-alpha.3', + 'create-storybook': '8.5.0-alpha.3', + '@storybook/csf-plugin': '8.5.0-alpha.3', + '@storybook/instrumenter': '8.5.0-alpha.3', + '@storybook/react-dom-shim': '8.5.0-alpha.3', + '@storybook/source-loader': '8.5.0-alpha.3', + '@storybook/test': '8.5.0-alpha.3', + '@storybook/preset-create-react-app': '8.5.0-alpha.3', + '@storybook/preset-html-webpack': '8.5.0-alpha.3', + '@storybook/preset-preact-webpack': '8.5.0-alpha.3', + '@storybook/preset-react-webpack': '8.5.0-alpha.3', + '@storybook/preset-server-webpack': '8.5.0-alpha.3', + '@storybook/preset-svelte-webpack': '8.5.0-alpha.3', + '@storybook/preset-vue3-webpack': '8.5.0-alpha.3', + '@storybook/html': '8.5.0-alpha.3', + '@storybook/preact': '8.5.0-alpha.3', + '@storybook/react': '8.5.0-alpha.3', + '@storybook/server': '8.5.0-alpha.3', + '@storybook/svelte': '8.5.0-alpha.3', + '@storybook/vue3': '8.5.0-alpha.3', + '@storybook/web-components': '8.5.0-alpha.3', }; diff --git a/code/core/src/manager-api/version.ts b/code/core/src/manager-api/version.ts index fa52a67d9c1f..238310acedb1 100644 --- a/code/core/src/manager-api/version.ts +++ b/code/core/src/manager-api/version.ts @@ -1 +1 @@ -export const version = '8.5.0-alpha.2'; +export const version = '8.5.0-alpha.3'; diff --git a/code/deprecated/builder-manager/package.json b/code/deprecated/builder-manager/package.json index 998fe199cf3c..4ad08c09b4a3 100644 --- a/code/deprecated/builder-manager/package.json +++ b/code/deprecated/builder-manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/builder-manager", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook manager builder", "keywords": [ "storybook" diff --git a/code/deprecated/channels/package.json b/code/deprecated/channels/package.json index c3cc42c5ef5a..688873156e9e 100644 --- a/code/deprecated/channels/package.json +++ b/code/deprecated/channels/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/channels", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/deprecated/client-logger/package.json b/code/deprecated/client-logger/package.json index 81487c759bae..384ad1432a6a 100644 --- a/code/deprecated/client-logger/package.json +++ b/code/deprecated/client-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/client-logger", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/deprecated/components/package.json b/code/deprecated/components/package.json index f191a7353819..d1750b8c4f81 100644 --- a/code/deprecated/components/package.json +++ b/code/deprecated/components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/components", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/deprecated/core-common/package.json b/code/deprecated/core-common/package.json index dfb292656181..d5818575ff0f 100644 --- a/code/deprecated/core-common/package.json +++ b/code/deprecated/core-common/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-common", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/deprecated/core-events/package.json b/code/deprecated/core-events/package.json index 5b14bb545db8..de869d70f4aa 100644 --- a/code/deprecated/core-events/package.json +++ b/code/deprecated/core-events/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-events", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Event names used in storybook core", "keywords": [ "storybook" diff --git a/code/deprecated/core-server/package.json b/code/deprecated/core-server/package.json index 063fcde26a4c..e3ec83f93258 100644 --- a/code/deprecated/core-server/package.json +++ b/code/deprecated/core-server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-server", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/deprecated/csf-tools/package.json b/code/deprecated/csf-tools/package.json index f62c3d3879f2..bace85c54878 100644 --- a/code/deprecated/csf-tools/package.json +++ b/code/deprecated/csf-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-tools", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Parse and manipulate CSF and Storybook config files", "keywords": [ "storybook" diff --git a/code/deprecated/docs-tools/package.json b/code/deprecated/docs-tools/package.json index e36ab11070f3..9ab05de3b587 100644 --- a/code/deprecated/docs-tools/package.json +++ b/code/deprecated/docs-tools/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/docs-tools", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Shared utility functions for frameworks to implement docs", "keywords": [ "storybook" diff --git a/code/deprecated/manager-api/package.json b/code/deprecated/manager-api/package.json index 5c7afd53accf..f7c8cf3a6a61 100644 --- a/code/deprecated/manager-api/package.json +++ b/code/deprecated/manager-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager-api", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Core Storybook Manager API & Context", "keywords": [ "storybook" diff --git a/code/deprecated/manager/package.json b/code/deprecated/manager/package.json index 136dc63a9d44..83213deaa9e1 100644 --- a/code/deprecated/manager/package.json +++ b/code/deprecated/manager/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/manager", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Core Storybook UI", "keywords": [ "storybook" diff --git a/code/deprecated/node-logger/package.json b/code/deprecated/node-logger/package.json index fe00d6cb9e88..9c151e1d8bdf 100644 --- a/code/deprecated/node-logger/package.json +++ b/code/deprecated/node-logger/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/node-logger", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/deprecated/preview-api/package.json b/code/deprecated/preview-api/package.json index 954b77c87a65..528f533d8c30 100644 --- a/code/deprecated/preview-api/package.json +++ b/code/deprecated/preview-api/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview-api", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/deprecated/preview/package.json b/code/deprecated/preview/package.json index 33e8aa8811ad..a2d6f5c49da8 100644 --- a/code/deprecated/preview/package.json +++ b/code/deprecated/preview/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preview", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/deprecated/router/package.json b/code/deprecated/router/package.json index 15f0838f0d6e..9550874baceb 100644 --- a/code/deprecated/router/package.json +++ b/code/deprecated/router/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/router", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Core Storybook Router", "keywords": [ "storybook" diff --git a/code/deprecated/telemetry/package.json b/code/deprecated/telemetry/package.json index 487a120c5037..320be1c21042 100644 --- a/code/deprecated/telemetry/package.json +++ b/code/deprecated/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/telemetry", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Telemetry logging for crash reports and usage statistics", "keywords": [ "storybook" diff --git a/code/deprecated/theming/package.json b/code/deprecated/theming/package.json index 1324ccfba9d4..e47ea4acac35 100644 --- a/code/deprecated/theming/package.json +++ b/code/deprecated/theming/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/theming", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Core Storybook Components", "keywords": [ "storybook" diff --git a/code/deprecated/types/package.json b/code/deprecated/types/package.json index 72f199a21205..906b18452bce 100644 --- a/code/deprecated/types/package.json +++ b/code/deprecated/types/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/types", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Core Storybook TS Types", "keywords": [ "storybook" diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index 69fb329efb6d..58cd68aceb7f 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/angular", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.", "keywords": [ "storybook", diff --git a/code/frameworks/ember/package.json b/code/frameworks/ember/package.json index 80c1deada3bb..fa337ddf6016 100644 --- a/code/frameworks/ember/package.json +++ b/code/frameworks/ember/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/ember", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Ember: Develop Ember Component in isolation with Hot Reloading.", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/frameworks/ember", "bugs": { diff --git a/code/frameworks/experimental-nextjs-vite/package.json b/code/frameworks/experimental-nextjs-vite/package.json index 4d9a4c2049d3..b7e1d2dc4d1e 100644 --- a/code/frameworks/experimental-nextjs-vite/package.json +++ b/code/frameworks/experimental-nextjs-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/experimental-nextjs-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Next.js and Vite", "keywords": [ "storybook", diff --git a/code/frameworks/html-vite/package.json b/code/frameworks/html-vite/package.json index 084ee13115c0..1d2c28e55d49 100644 --- a/code/frameworks/html-vite/package.json +++ b/code/frameworks/html-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for HTML and Vite: Develop HTML in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/html-webpack5/package.json b/code/frameworks/html-webpack5/package.json index aab8040d3e7c..c906836614ac 100644 --- a/code/frameworks/html-webpack5/package.json +++ b/code/frameworks/html-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/nextjs/package.json b/code/frameworks/nextjs/package.json index b72f212c7e94..79bc3f6613ee 100644 --- a/code/frameworks/nextjs/package.json +++ b/code/frameworks/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/nextjs", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Next.js", "keywords": [ "storybook", diff --git a/code/frameworks/preact-vite/package.json b/code/frameworks/preact-vite/package.json index 3b606bf92a34..59b22b6fdb4f 100644 --- a/code/frameworks/preact-vite/package.json +++ b/code/frameworks/preact-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Preact and Vite: Develop Preact components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/preact-webpack5/package.json b/code/frameworks/preact-webpack5/package.json index c1f885bfa39d..9876abb7e945 100644 --- a/code/frameworks/preact-webpack5/package.json +++ b/code/frameworks/preact-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/frameworks/react-vite/package.json b/code/frameworks/react-vite/package.json index d0d456be57e5..878d130556a2 100644 --- a/code/frameworks/react-vite/package.json +++ b/code/frameworks/react-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for React and Vite: Develop React components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index 65010b37a395..f9b70c7df783 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/server-webpack5/package.json b/code/frameworks/server-webpack5/package.json index 715663b50985..d3d2cb9226c6 100644 --- a/code/frameworks/server-webpack5/package.json +++ b/code/frameworks/server-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-vite/package.json b/code/frameworks/svelte-vite/package.json index ffbb07aa227e..cc643fbf33d0 100644 --- a/code/frameworks/svelte-vite/package.json +++ b/code/frameworks/svelte-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Svelte and Vite: Develop Svelte components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/svelte-webpack5/package.json b/code/frameworks/svelte-webpack5/package.json index 9d7d2cd662b0..36d4ef03d897 100644 --- a/code/frameworks/svelte-webpack5/package.json +++ b/code/frameworks/svelte-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 229f4d355d13..05dd93345799 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/sveltekit", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for SvelteKit", "keywords": [ "storybook", diff --git a/code/frameworks/vue3-vite/package.json b/code/frameworks/vue3-vite/package.json index 56964dce742a..a5d3f892cb11 100644 --- a/code/frameworks/vue3-vite/package.json +++ b/code/frameworks/vue3-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Vue3 and Vite: Develop Vue3 components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/vue3-webpack5/package.json b/code/frameworks/vue3-webpack5/package.json index 1c25df9cefdf..82a84c308550 100644 --- a/code/frameworks/vue3-webpack5/package.json +++ b/code/frameworks/vue3-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-vite/package.json b/code/frameworks/web-components-vite/package.json index 03dc677da545..251e034cf036 100644 --- a/code/frameworks/web-components-vite/package.json +++ b/code/frameworks/web-components-vite/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-vite", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for web-components and Vite: Develop Web Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/frameworks/web-components-webpack5/package.json b/code/frameworks/web-components-webpack5/package.json index c59b0cf156d2..c269e1081a2a 100644 --- a/code/frameworks/web-components-webpack5/package.json +++ b/code/frameworks/web-components-webpack5/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components-webpack5", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for web-components: View web components snippets in isolation with Hot Reloading.", "keywords": [ "lit", diff --git a/code/lib/blocks/package.json b/code/lib/blocks/package.json index e3dd3c8f847f..d7206af15ab5 100644 --- a/code/lib/blocks/package.json +++ b/code/lib/blocks/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/blocks", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook Doc Blocks", "keywords": [ "storybook" diff --git a/code/lib/cli-sb/package.json b/code/lib/cli-sb/package.json index 0e6591ba8935..9d8bee7cecd6 100644 --- a/code/lib/cli-sb/package.json +++ b/code/lib/cli-sb/package.json @@ -1,6 +1,6 @@ { "name": "sb", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli-storybook/package.json b/code/lib/cli-storybook/package.json index 48a41fafddef..0e55f1743e5c 100644 --- a/code/lib/cli-storybook/package.json +++ b/code/lib/cli-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/cli", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook CLI", "keywords": [ "storybook" diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 7a9bff57f796..77a2a37ca516 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -1,6 +1,6 @@ { "name": "storybook", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook's CLI - install, dev, build, upgrade, and more", "keywords": [ "cli", diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index 9553b14af5f1..0ba9b276559b 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/codemod", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "A collection of codemod scripts written with JSCodeshift", "keywords": [ "storybook" diff --git a/code/lib/core-webpack/package.json b/code/lib/core-webpack/package.json index b9ef9cbb495a..77de45a9a7f6 100644 --- a/code/lib/core-webpack/package.json +++ b/code/lib/core-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/core-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook framework-agnostic API", "keywords": [ "storybook" diff --git a/code/lib/create-storybook/package.json b/code/lib/create-storybook/package.json index dd39ff420b2f..1fe15edaa81f 100644 --- a/code/lib/create-storybook/package.json +++ b/code/lib/create-storybook/package.json @@ -1,6 +1,6 @@ { "name": "create-storybook", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Initialize Storybook into your project", "homepage": "https://github.com/storybookjs/storybook/tree/next/code/lib/create-storybook", "bugs": { diff --git a/code/lib/csf-plugin/package.json b/code/lib/csf-plugin/package.json index 0fbb7c8753b1..13e3bfcc8551 100644 --- a/code/lib/csf-plugin/package.json +++ b/code/lib/csf-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/csf-plugin", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Enrich CSF files via static analysis", "keywords": [ "storybook" diff --git a/code/lib/instrumenter/package.json b/code/lib/instrumenter/package.json index b68c93b58238..b529f7b13571 100644 --- a/code/lib/instrumenter/package.json +++ b/code/lib/instrumenter/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/instrumenter", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/react-dom-shim/package.json b/code/lib/react-dom-shim/package.json index 5062005ce550..bd9c76c456ca 100644 --- a/code/lib/react-dom-shim/package.json +++ b/code/lib/react-dom-shim/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react-dom-shim", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index 2594917e51c9..126a0aa63551 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/source-loader", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Source loader", "keywords": [ "lib", diff --git a/code/lib/test/package.json b/code/lib/test/package.json index c5c5eff4d05f..036df428d0bc 100644 --- a/code/lib/test/package.json +++ b/code/lib/test/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/test", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "", "keywords": [ "storybook" diff --git a/code/package.json b/code/package.json index 3612783dda03..2fc645efc459 100644 --- a/code/package.json +++ b/code/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/root", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "private": true, "description": "Storybook root", "homepage": "https://storybook.js.org/", @@ -293,6 +293,5 @@ "Dependency Upgrades" ] ] - }, - "deferredNextVersion": "8.5.0-alpha.3" + } } diff --git a/code/presets/create-react-app/package.json b/code/presets/create-react-app/package.json index ad8bf6ceebd5..90bb70e95947 100644 --- a/code/presets/create-react-app/package.json +++ b/code/presets/create-react-app/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-create-react-app", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Create React App preset", "keywords": [ "storybook" diff --git a/code/presets/html-webpack/package.json b/code/presets/html-webpack/package.json index 226caa5c4cb1..764d9449507b 100644 --- a/code/presets/html-webpack/package.json +++ b/code/presets/html-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-html-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for HTML: View HTML snippets in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/preact-webpack/package.json b/code/presets/preact-webpack/package.json index 91ce4e06fd91..f3ebc5f6623b 100644 --- a/code/presets/preact-webpack/package.json +++ b/code/presets/preact-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-preact-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Preact: Develop Preact Component in isolation.", "keywords": [ "storybook" diff --git a/code/presets/react-webpack/package.json b/code/presets/react-webpack/package.json index 89c2463b2ec4..a49e9a4d33e1 100644 --- a/code/presets/react-webpack/package.json +++ b/code/presets/react-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-react-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for React: Develop React Component in isolation with Hot Reloading", "keywords": [ "storybook" diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index d52073589d33..8a0ec01169d8 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-server-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Server: View HTML snippets from a server in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/svelte-webpack/package.json b/code/presets/svelte-webpack/package.json index 355cc24fb73c..f29f438661cf 100644 --- a/code/presets/svelte-webpack/package.json +++ b/code/presets/svelte-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-svelte-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Svelte: Develop Svelte Component in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/presets/vue3-webpack/package.json b/code/presets/vue3-webpack/package.json index 43aa95c4096e..70941cba6d28 100644 --- a/code/presets/vue3-webpack/package.json +++ b/code/presets/vue3-webpack/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preset-vue3-webpack", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook for Vue 3: Develop Vue 3 Components in isolation with Hot Reloading.", "keywords": [ "storybook" diff --git a/code/renderers/html/package.json b/code/renderers/html/package.json index 9a0ae582dbf4..3f360e97fd3a 100644 --- a/code/renderers/html/package.json +++ b/code/renderers/html/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/html", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook HTML renderer", "keywords": [ "storybook" diff --git a/code/renderers/preact/package.json b/code/renderers/preact/package.json index 3a8f051740b1..935712d26f4f 100644 --- a/code/renderers/preact/package.json +++ b/code/renderers/preact/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/preact", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook Preact renderer", "keywords": [ "storybook" diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index ac97456262c7..6d3035da5dec 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/react", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook React renderer", "keywords": [ "storybook" diff --git a/code/renderers/server/package.json b/code/renderers/server/package.json index ee8e51e307e5..4881b9b86228 100644 --- a/code/renderers/server/package.json +++ b/code/renderers/server/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/server", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook Server renderer", "keywords": [ "storybook" diff --git a/code/renderers/svelte/package.json b/code/renderers/svelte/package.json index e3b836a21029..2747727902d4 100644 --- a/code/renderers/svelte/package.json +++ b/code/renderers/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/svelte", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook Svelte renderer", "keywords": [ "storybook" diff --git a/code/renderers/vue3/package.json b/code/renderers/vue3/package.json index 574463ddb23c..2bb6337b1cdf 100644 --- a/code/renderers/vue3/package.json +++ b/code/renderers/vue3/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/vue3", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook Vue 3 renderer", "keywords": [ "storybook" diff --git a/code/renderers/web-components/package.json b/code/renderers/web-components/package.json index eafd851c255b..dc2b034dc11a 100644 --- a/code/renderers/web-components/package.json +++ b/code/renderers/web-components/package.json @@ -1,6 +1,6 @@ { "name": "@storybook/web-components", - "version": "8.5.0-alpha.2", + "version": "8.5.0-alpha.3", "description": "Storybook web-components renderer", "keywords": [ "lit", From c1a87795c6538ebad9efacdf03d61f94125daf97 Mon Sep 17 00:00:00 2001 From: storybook-bot <32066757+storybook-bot@users.noreply.github.com> Date: Tue, 5 Nov 2024 05:49:52 +0000 Subject: [PATCH 32/40] Update CHANGELOG.md for v8.4.2 [skip ci] --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0b60008f0fb..06520612a48a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 8.4.2 + +- Addon Test: Fix post-install logic for Next.js Vite framework support - [#29524](https://github.com/storybookjs/storybook/pull/29524), thanks @valentinpalkovic! +- Addon Test: Only render the TestingModule component in development mode - [#29501](https://github.com/storybookjs/storybook/pull/29501), thanks @yannbf! +- CLI: Fix Solid init by installing `@storybook/test` - [#29514](https://github.com/storybookjs/storybook/pull/29514), thanks @shilman! +- Core: Shim CJS-only globals in ESM output - [#29157](https://github.com/storybookjs/storybook/pull/29157), thanks @valentinpalkovic! +- Next.js: Fix bundled react and react-dom in monorepos - [#29444](https://github.com/storybookjs/storybook/pull/29444), thanks @sentience! + ## 8.4.1 - Core: Relax peer dep constraint of shim packages - [#29503](https://github.com/storybookjs/storybook/pull/29503), thanks @kasperpeulen! From 81a5d077c2857eea6f139dfeaec301feafcf50e9 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Nov 2024 14:31:14 +0100 Subject: [PATCH 33/40] fix typos --- scripts/bench/bench-packages.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/bench/bench-packages.ts b/scripts/bench/bench-packages.ts index 309e30095fb3..fa12505e5d42 100644 --- a/scripts/bench/bench-packages.ts +++ b/scripts/bench/bench-packages.ts @@ -416,13 +416,13 @@ const run = async () => { if ((await detectFreePort(REGISTRY_PORT)) === REGISTRY_PORT) { throw new Error(dedent`The local verdaccio registry must be running in the background for package benching to work, and packages must be published to it in --no-link mode with 'yarn --task publish --no-link' - Then runn the registry with 'yarn --task run-registry --no-link'`); + Then run the registry with 'yarn --task run-registry --no-link'`); } // The amount of VCPUs for this task in CI is 2 (medium resource) const amountOfVCPUs = 2; - const concurrentLimt = process.env.CI ? amountOfVCPUs - 1 : maxConcurrentTasks; - const limit = pLimit(concurrentLimt); + const concurrentLimit = process.env.CI ? amountOfVCPUs - 1 : maxConcurrentTasks; + const limit = pLimit(concurrentLimit); const progressIntervalId = setInterval(() => { const doneCount = packageNames.length - limit.activeCount - limit.pendingCount; From f88eb05bf21eb63b0774572f05bcb3d486cde18d Mon Sep 17 00:00:00 2001 From: Alain Schaller Date: Tue, 5 Nov 2024 14:51:33 +0100 Subject: [PATCH 34/40] Correct addon-themes README to align text with code example --- code/addons/themes/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/addons/themes/README.md b/code/addons/themes/README.md index 68309d9054a0..1f58f259485c 100644 --- a/code/addons/themes/README.md +++ b/code/addons/themes/README.md @@ -36,7 +36,7 @@ Don't see your favorite tool listed? Don't worry! That doesn't mean this addon i ### ❗️ Overriding theme -If you want to override your theme for a particular component or story, you can use the `themes.themeOverride` parameter. +If you want to override your theme for a particular component or story, you can use the `globals.theme` parameter. ```js import React from 'react'; From 9cec767e66dd996fb3bd4265158c5f1fb6fbd077 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Nov 2024 21:20:15 +0100 Subject: [PATCH 35/40] Apply suggestions from code review Co-authored-by: jonniebigodes --- CONTRIBUTING/RELEASING.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING/RELEASING.md b/CONTRIBUTING/RELEASING.md index cc08a0ad9b4c..f011664a0b80 100644 --- a/CONTRIBUTING/RELEASING.md +++ b/CONTRIBUTING/RELEASING.md @@ -343,12 +343,12 @@ If you need to release a change to an older minor version that is not the latest 4. Build all packages in `code` with `yarn task --task compile --no-link` 5. Commit and push your changes. 6. Trigger _daily_ CI manually on your branch: - 1. Open https://app.circleci.com/pipelines/github/storybookjs/storybook - 2. Click "Trigger Pipeline", top right corner - 3. Pipeline: _"storybook default"_ - 4. Config Source: _"storybook"_ - 5. Branch: Your branch, eg. `patch-8-3-7` - 6. Add a parameter, with _"name"_ `workflow`, _"value"_ `daily` + 1. Open [CircleCI](https://app.circleci.com/pipelines/github/storybookjs/storybook) and click "Trigger Pipeline" on the top right corner of the page. + 2. Set the following configuration options: + - Pipeline: _"storybook default"_ + - Config Source: _"storybook"_ + - Branch: Your branch, eg. `patch-8-3-7` + 3. Add a parameter, with _"name"_ `workflow`, _"value"_ `daily` 7. Wait for CI to finish successfully. 8. Bump all package versions: 1. `cd scripts` @@ -356,25 +356,25 @@ If you need to release a change to an older minor version that is not the latest 9. Commit with `git commit -m "Bump version from to MANUALLY"` 10. Add a new entry to `CHANGELOG.md`, describing your changes 11. Commit with `git commit -m "Update CHANGELOG.md with MANUALLY"` -12. Ensure you have the correct write permissions to all the Storybook npm packages. You need to be an admin of the _storybook_ org, as well as the packages not in the org. The simplest way to check this, is to ensure you can see the _"Settings"_ tab in the follwing packages: +12. Ensure you have the correct write permissions for all the Storybook npm packages. You need to be an admin of the _storybook_ org, and the packages that are not in the org. The simplest way to check this is to ensure you can see the _"Settings"_ tab in the following packages: 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite/access) 2. [`storybook`](https://www.npmjs.com/package/storybook/access) 3. [`sb`](https://www.npmjs.com/package/sb/access) 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook/access) -13. Get your npm access token or generate a new one at https://www.npmjs.com/settings/jreinhold/tokens. Remember to not only give it access to the `storybook` org, but also the packages not in the org as listed above. +13. Get your npm access token or generate a new one at https://www.npmjs.com/settings/your-username/tokens. Remember to give it access to the `storybook` org and the packages not in the org, as listed above. 14. Publish all packages with `YARN_NPM_AUTH_TOKEN= yarn release:publish --tag tag-for-publishing-older-releases --verbose` - It goes through all packages and publishes them. If any number of packages fails to publish, it will retry 5 times, skipping those that have already been published. -15. Confirm the new version has been released on npmjs with the tag `tag-for-publishing-older-releases`: +15. Confirm the new version has been released on npm with the tag `tag-for-publishing-older-releases`: 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite?activeTab=versions) 2. [`storybook`](https://www.npmjs.com/package/storybook?activeTab=versions) 3. [`sb`](https://www.npmjs.com/package/sb?activeTab=versions) 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook?activeTab=versions) 16. Push 17. Manually create a GitHub Release at https://github.com/storybookjs/storybook/releases/new with: - 1. Create new tag: `v`, eg. `v8.3.7` - 2. Target: your branch, eg. `patch-8-3-7` - 3. Previous tag: `v`, eg. `v8.3.6` - 4. Title: `v`, eg. `v8.3.7` + 1. Create new tag: `v` (e.g., `v8.3.7`) + 2. Target: your branch (e.g., `patch-8-3-7`) + 3. Previous tag: `v` (e.g., `v8.3.6`) + 4. Title: `v` (e.g., `v8.3.7`) 5. Description: The content you added to `CHANGELOG.md` 6. Untick _"Set as the latest release"_ 18. Cherry-pick your changelog changes into `next`, so they are actually visible From 27191fda46e5fd9c686847e243e9a05a511a2c35 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Tue, 5 Nov 2024 21:29:07 +0100 Subject: [PATCH 36/40] fix nested lists --- CONTRIBUTING/RELEASING.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING/RELEASING.md b/CONTRIBUTING/RELEASING.md index f011664a0b80..33a74bfdc224 100644 --- a/CONTRIBUTING/RELEASING.md +++ b/CONTRIBUTING/RELEASING.md @@ -336,31 +336,31 @@ Done! 🚀 If you need to release a change to an older minor version that is not the latest, you have to do it manually, locally. The process is described below, with an example of releasing a new `v8.3.7` in a situation where `8.4.0` is currently the latest version. 1. Checkout the _existing_ tag that matches the latest minor release you want to bump, and create a new branch from it. In this case, we want to do: - 1. `git fetch --all --tags` - 2. `git checkout tags/v8.3.6 -b patch-8-3-7` + 1. `git fetch --all --tags` + 2. `git checkout tags/v8.3.6 -b patch-8-3-7` 2. Make the changes you need to, most likely cherry-picking commits from the fix you need to back-port. 3. Run `yarn install` in `scripts` and `code` 4. Build all packages in `code` with `yarn task --task compile --no-link` 5. Commit and push your changes. 6. Trigger _daily_ CI manually on your branch: - 1. Open [CircleCI](https://app.circleci.com/pipelines/github/storybookjs/storybook) and click "Trigger Pipeline" on the top right corner of the page. - 2. Set the following configuration options: - - Pipeline: _"storybook default"_ - - Config Source: _"storybook"_ - - Branch: Your branch, eg. `patch-8-3-7` - 3. Add a parameter, with _"name"_ `workflow`, _"value"_ `daily` + 1. Open [CircleCI](https://app.circleci.com/pipelines/github/storybookjs/storybook) and click "Trigger Pipeline" on the top right corner of the page. + 2. Set the following configuration options: + - Pipeline: _"storybook default"_ + - Config Source: _"storybook"_ + - Branch: Your branch, eg. `patch-8-3-7` + 3. Add a parameter, with _"name"_ `workflow`, _"value"_ `daily` 7. Wait for CI to finish successfully. 8. Bump all package versions: - 1. `cd scripts` - 2. `yarn release:version --release-type patch` + 1. `cd scripts` + 2. `yarn release:version --release-type patch` 9. Commit with `git commit -m "Bump version from to MANUALLY"` 10. Add a new entry to `CHANGELOG.md`, describing your changes 11. Commit with `git commit -m "Update CHANGELOG.md with MANUALLY"` 12. Ensure you have the correct write permissions for all the Storybook npm packages. You need to be an admin of the _storybook_ org, and the packages that are not in the org. The simplest way to check this is to ensure you can see the _"Settings"_ tab in the following packages: - 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite/access) - 2. [`storybook`](https://www.npmjs.com/package/storybook/access) - 3. [`sb`](https://www.npmjs.com/package/sb/access) - 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook/access) + 1. [`@storybook/react-vite`](https://www.npmjs.com/package/@storybook/react-vite/access) + 2. [`storybook`](https://www.npmjs.com/package/storybook/access) + 3. [`sb`](https://www.npmjs.com/package/sb/access) + 4. [`create-storybook`](https://www.npmjs.com/package/create-storybook/access) 13. Get your npm access token or generate a new one at https://www.npmjs.com/settings/your-username/tokens. Remember to give it access to the `storybook` org and the packages not in the org, as listed above. 14. Publish all packages with `YARN_NPM_AUTH_TOKEN= yarn release:publish --tag tag-for-publishing-older-releases --verbose` - It goes through all packages and publishes them. If any number of packages fails to publish, it will retry 5 times, skipping those that have already been published. From 9ed9d72f560cc1c6470a92ffac41ea7d58b5b234 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 6 Nov 2024 13:10:34 +0100 Subject: [PATCH 37/40] Fix type issues --- code/addons/backgrounds/src/components/Tool.tsx | 2 +- code/addons/viewport/src/components/Tool.tsx | 2 +- scripts/prepare/tools.ts | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/code/addons/backgrounds/src/components/Tool.tsx b/code/addons/backgrounds/src/components/Tool.tsx index 828cc3b3a3d4..0659d8360c70 100644 --- a/code/addons/backgrounds/src/components/Tool.tsx +++ b/code/addons/backgrounds/src/components/Tool.tsx @@ -124,7 +124,7 @@ const Pure = memo(function PureTool(props: PureProps) { onHide(); }, })), - ]} + ].flat()} /> ); }} diff --git a/code/addons/viewport/src/components/Tool.tsx b/code/addons/viewport/src/components/Tool.tsx index 52b8713c7919..cf3170a8c48a 100644 --- a/code/addons/viewport/src/components/Tool.tsx +++ b/code/addons/viewport/src/components/Tool.tsx @@ -139,7 +139,7 @@ const Pure = React.memo(function PureTool(props: PureProps) { onHide(); }, })), - ]} + ].flat()} /> )} closeOnOutsideClick diff --git a/scripts/prepare/tools.ts b/scripts/prepare/tools.ts index 6037f3cd301c..23213e25b004 100644 --- a/scripts/prepare/tools.ts +++ b/scripts/prepare/tools.ts @@ -118,7 +118,10 @@ export const nodeInternals = [ ...require('module').builtinModules.flatMap((m: string) => [m, `node:${m}`]), ]; -export const getWorkspace = async () => { +type PackageJson = typefest.PackageJson & + Required> & { path: string }; + +export const getWorkspace = async (): Promise => { const codePackage = await readJson(join(CODE_DIRECTORY, 'package.json')); const { workspaces: { packages: patterns }, @@ -142,8 +145,7 @@ export const getWorkspace = async () => { return null; } const pkg = await readJson(packageJsonPath); - return { ...pkg, path: packagePath } as typefest.PackageJson & - Required> & { path: string }; + return { ...pkg, path: packagePath } as PackageJson; }) ).then((packages) => packages.filter((p) => p !== null)); }; From 0f52dbba5d8d947b2e1acab4ad31041dcca0973e Mon Sep 17 00:00:00 2001 From: Valentin Palkovic Date: Thu, 7 Nov 2024 21:03:52 +0100 Subject: [PATCH 38/40] Vite Ecosystem CI: Additionally test on a built Storybook --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64a3e118ab67..0e6a462f4a88 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "upload-bench": "cd scripts; yarn upload-bench", "vite-ecosystem-ci:before-test": "node ./scripts/vite-ecosystem-ci/before-test.js && cd ./sandbox/react-vite-default-ts && yarn install", "vite-ecosystem-ci:build": "yarn task --task sandbox --template react-vite/default-ts --start-from=install", - "vite-ecosystem-ci:test": "yarn task --task test-runner-dev --template react-vite/default-ts --start-from=dev" + "vite-ecosystem-ci:test": "yarn task --task test-runner-dev --template react-vite/default-ts --start-from=dev && yarn task --task test-runner --template react-vite/default-ts --start-from=build" }, "packageManager": "yarn@4.4.0+sha512.91d93b445d9284e7ed52931369bc89a663414e5582d00eea45c67ddc459a2582919eece27c412d6ffd1bd0793ff35399381cb229326b961798ce4f4cc60ddfdb" } From a496226c8f578f2f5112e85943db422ee875c3fd Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Thu, 7 Nov 2024 21:54:56 +0100 Subject: [PATCH 39/40] run registry before package benching --- .circleci/config.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 52f6c5ebd734..c115003515a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -223,7 +223,9 @@ jobs: - run: name: Benchmarking Packages working_directory: scripts - command: yarn bench-packages --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> --upload + command: | + yarn local-registry --open & + yarn bench-packages --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> --upload - store_artifacts: path: bench/packages/results.json - store_artifacts: From fd821a36fd05ed47163fe8db21e03fd4e9414284 Mon Sep 17 00:00:00 2001 From: Jeppe Reinhold Date: Fri, 8 Nov 2024 09:09:24 +0100 Subject: [PATCH 40/40] wait for local registry --- .circleci/config.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index c115003515a0..51de43a71e69 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -225,6 +225,10 @@ jobs: working_directory: scripts command: | yarn local-registry --open & + until curl -s http://localhost:6001 > /dev/null; do + echo 'Waiting for local registry to be available...' + sleep 2 + done yarn bench-packages --baseBranch << pipeline.parameters.ghBaseBranch >> --pull-request << pipeline.parameters.ghPrNumber >> --upload - store_artifacts: path: bench/packages/results.json