diff --git a/client/storybook/BUILD.bazel b/client/storybook/BUILD.bazel index a4853d19ca4..0e436515fb3 100644 --- a/client/storybook/BUILD.bazel +++ b/client/storybook/BUILD.bazel @@ -67,6 +67,7 @@ ts_project( "//:node_modules/focus-visible", "//:node_modules/open-color", "//:node_modules/react", + "//:node_modules/vite-plugin-turbosnap", ], ) diff --git a/client/storybook/src/main.ts b/client/storybook/src/main.ts index 34bf5057b1b..307f94fdb34 100644 --- a/client/storybook/src/main.ts +++ b/client/storybook/src/main.ts @@ -3,6 +3,7 @@ import path from 'path' import type { StorybookConfigVite } from '@storybook/builder-vite' import type { StorybookConfig as ReactViteStorybookConfig } from '@storybook/react-vite' import type { StorybookConfig } from '@storybook/types' +import turbosnap from 'vite-plugin-turbosnap' import { ROOT_PATH, STATIC_ASSETS_PATH, getEnvironmentBoolean } from '@sourcegraph/build-config' @@ -25,7 +26,12 @@ const getStoriesGlob = (): string[] => { } const config: StorybookConfig & StorybookConfigVite & ReactViteStorybookConfig = { - framework: '@storybook/react-vite', + // TODO: This has to be an object and not a string for now due to a bug in Chromatic + // that would cause the builder to not be identified correctly. + framework: { + name: '@storybook/react-vite', + options: {}, + }, staticDirs: [path.resolve(__dirname, '../assets'), STATIC_ASSETS_PATH], stories: getStoriesGlob(), @@ -37,18 +43,7 @@ const config: StorybookConfig & StorybookConfigVite & ReactViteStorybookConfig = '@storybook/addon-toolbars', '@storybook/addon-docs', '@storybook/addon-controls', - { - name: '@storybook/addon-storysource', - options: { - rule: { - test: /\.story\.tsx?$/, - }, - sourceLoaderOptions: { - injectStoryParameters: false, - prettierConfig: { printWidth: 80, singleQuote: false }, - }, - }, - }, + '@storybook/addon-storysource', ], core: { @@ -61,8 +56,15 @@ const config: StorybookConfig & StorybookConfigVite & ReactViteStorybookConfig = reactDocgen: false, }, - viteFinal: config => { - config.define = { ...config.define, 'process.env.CHROMATIC': getEnvironmentBoolean('CHROMATIC') } + viteFinal: (config, { configType }) => { + const isChromatic = getEnvironmentBoolean('CHROMATIC') + config.define = { ...config.define, 'process.env.CHROMATIC': isChromatic } + if (isChromatic && configType === 'PRODUCTION') { + // eslint-disable-next-line no-console + console.log('Using TurboSnap plugin!') + config.plugins = config.plugins ?? [] + config.plugins.push(turbosnap({ rootDir: config.root ?? ROOT_PATH })) + } config.build = { ...config.build, @@ -117,4 +119,23 @@ const config: StorybookConfig & StorybookConfigVite & ReactViteStorybookConfig = }, } +// TODO: We need to replace the @storybook/addon-storysource plugin with an object +// definition to supply options here because chromatic CLI does not properly understand +// the configured addons otherwise. +const idx = config.addons?.findIndex(addon => addon === '@storybook/addon-storysource') +if (idx !== undefined && idx >= 0) { + config.addons![idx] = { + name: '@storybook/addon-storysource', + options: { + rule: { + test: /\.story\.tsx?$/, + }, + sourceLoaderOptions: { + injectStoryParameters: false, + prettierConfig: { printWidth: 80, singleQuote: false }, + }, + }, + } +} + module.exports = config diff --git a/dev/ci/internal/ci/operations.go b/dev/ci/internal/ci/operations.go index 2ac13253fd8..48d4cc5cbb3 100644 --- a/dev/ci/internal/ci/operations.go +++ b/dev/ci/internal/ci/operations.go @@ -311,7 +311,7 @@ func clientChromaticTests(opts CoreTestOperationsOptions) operations.Operation { } // Upload storybook to Chromatic - chromaticCommand := "pnpm chromatic --exit-zero-on-changes --exit-once-uploaded --build-script-name=storybook:build" + chromaticCommand := "pnpm chromatic --exit-zero-on-changes --exit-once-uploaded" if opts.ChromaticShouldAutoAccept { chromaticCommand += " --auto-accept-changes" } else { diff --git a/package.json b/package.json index 13360f9d526..896ba3f1a41 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,9 @@ "release": "cd dev/release && pnpm run release", "docsite:serve": "./dev/docsite.sh -config doc/docsite.json serve -http=localhost:5080", "build-browser-extension": "pnpm --filter @sourcegraph/browser run build", - "optimize-svg-assets": "svgo --multipass --config=\"./svgo.config.js\"" + "optimize-svg-assets": "svgo --multipass --config=\"./svgo.config.js\"", + "chromatic": "CHROMATIC=true pnpm run _chromatic --storybook-config-dir client/storybook/src --build-script-name=storybook:build", + "_chromatic": "chromatic" }, "nyc": { "extends": "@istanbuljs/nyc-config-typescript", @@ -109,6 +111,7 @@ "@octokit/rest": "^16.36.0", "@percy/cli": "^1.24.0", "@percy/puppeteer": "^2.0.2", + "vite-plugin-turbosnap": "^1.0.3", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.10", "@pollyjs/adapter": "^5.0.0", "@pollyjs/core": "^5.1.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 178f8cb2284..dae4ab8a9a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1203,6 +1203,9 @@ importers: vite: specifier: ^4.1.4 version: 4.4.7(@types/node@18.17.15)(sass@1.32.4) + vite-plugin-turbosnap: + specifier: ^1.0.3 + version: 1.0.3 vsce: specifier: ^2.7.0 version: 2.7.0 @@ -31181,6 +31184,10 @@ packages: - supports-color dev: true + /vite-plugin-turbosnap@1.0.3: + resolution: {integrity: sha512-p4D8CFVhZS412SyQX125qxyzOgIFouwOcvjZWk6bQbNPR1wtaEzFT6jZxAjf1dejlGqa6fqHcuCvQea6EWUkUA==} + dev: true + /vite@4.4.7(@types/node@18.17.15)(sass@1.32.4): resolution: {integrity: sha512-6pYf9QJ1mHylfVh39HpuSfMPojPSKVxZvnclX1K1FyZ1PXDOcLBibdq5t1qxJSnL63ca8Wf4zts6mD8u8oc9Fw==} engines: {node: ^14.18.0 || >=16.0.0}