build: upgrade Storybook to 8 beta (#13297)

* chore: upgrade Storybook to 8

* ci: restore Storybook workflow

* build: createRequire

* ci: TurboSnap life extension
This commit is contained in:
Acid Chicken (硫酸鶏) 2024-02-14 18:48:25 +09:00 committed by GitHub
parent 19e3753202
commit b8800b8b95
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 1362 additions and 2211 deletions

113
.github/workflows/storybook.yml vendored Normal file
View file

@ -0,0 +1,113 @@
name: Storybook
on:
push:
branches:
- master
- develop
- dev/storybook8 # for testing
pull_request_target:
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_OPTIONS: "--max_old_space_size=7168"
steps:
- uses: actions/checkout@v3.6.0
if: github.event_name != 'pull_request_target'
with:
fetch-depth: 0
submodules: true
- uses: actions/checkout@v3.6.0
if: github.event_name == 'pull_request_target'
with:
fetch-depth: 0
submodules: true
ref: "refs/pull/${{ github.event.number }}/merge"
- name: Checkout actual HEAD
if: github.event_name == 'pull_request_target'
id: rev
run: |
echo "base=$(git rev-list --parents -n1 HEAD | cut -d" " -f2)" >> $GITHUB_OUTPUT
git checkout $(git rev-list --parents -n1 HEAD | cut -d" " -f3)
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
run_install: false
- name: Use Node.js 20.x
uses: actions/setup-node@v3.8.1
with:
node-version-file: '.node-version'
cache: 'pnpm'
- run: corepack enable
- run: pnpm i --frozen-lockfile
- name: Check pnpm-lock.yaml
run: git diff --exit-code pnpm-lock.yaml
- name: Build misskey-js
run: pnpm --filter misskey-js build
- name: Build storybook
run: pnpm --filter frontend build-storybook
- name: Publish to Chromatic
if: github.event_name != 'pull_request_target' && github.ref == 'refs/heads/master'
run: pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- name: Publish to Chromatic
if: github.event_name != 'pull_request_target' && github.ref != 'refs/heads/master'
id: chromatic_push
run: |
DIFF="${{ github.event.before }} HEAD"
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
DIFF="HEAD"
fi
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
echo "skip=true" >> $GITHUB_OUTPUT
fi
if pnpm --filter frontend chromatic -d storybook-static $(echo "$CHROMATIC_PARAMETER"); then
echo "success=true" >> $GITHUB_OUTPUT
else
echo "success=false" >> $GITHUB_OUTPUT
fi
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- name: Publish to Chromatic
if: github.event_name == 'pull_request_target'
id: chromatic_pull_request
run: |
DIFF="${{ steps.rev.outputs.base }} HEAD"
if [ "$DIFF" = "0000000000000000000000000000000000000000 HEAD" ]; then
DIFF="HEAD"
fi
CHROMATIC_PARAMETER="$(node packages/frontend/.storybook/changes.js $(git diff-tree --no-commit-id --name-only -r $(echo "$DIFF") | xargs))"
if [ "$CHROMATIC_PARAMETER" = " --skip" ]; then
echo "skip=true" >> $GITHUB_OUTPUT
fi
BRANCH="${{ github.event.pull_request.head.user.login }}:${{ github.event.pull_request.head.ref }}"
if [ "$BRANCH" = "misskey-dev:${{ github.event.pull_request.head.ref }}" ]; then
BRANCH="${{ github.event.pull_request.head.ref }}"
fi
pnpm --filter frontend chromatic --exit-once-uploaded -d storybook-static --branch-name $BRANCH $(echo "$CHROMATIC_PARAMETER")
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
- name: Notify that Chromatic detects changes
uses: actions/github-script@v6.4.0
if: github.event_name != 'pull_request_target' && steps.chromatic_push.outputs.success == 'false'
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
github.rest.repos.createCommitComment({
owner: context.repo.owner,
repo: context.repo.repo,
commit_sha: context.sha,
body: 'Chromatic detects changes. Please [review the changes on Chromatic](https://www.chromatic.com/builds?appId=6428f7d7b962f0b79f97d6e4).'
})
- name: Upload Artifacts
uses: actions/upload-artifact@v3
with:
name: storybook
path: packages/frontend/storybook-static

View file

@ -3,25 +3,28 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { resolve } from 'node:path'; import { createRequire } from 'node:module';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url'; import { fileURLToPath } from 'node:url';
import type { StorybookConfig } from '@storybook/vue3-vite'; import type { StorybookConfig } from '@storybook/vue3-vite';
import { type Plugin, mergeConfig } from 'vite'; import { type Plugin, mergeConfig } from 'vite';
import turbosnap from 'vite-plugin-turbosnap'; import turbosnap from 'vite-plugin-turbosnap';
const dirname = fileURLToPath(new URL('.', import.meta.url)); const require = createRequire(import.meta.url);
const _dirname = fileURLToPath(new URL('.', import.meta.url));
const config = { const config = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [ addons: [
'@storybook/addon-essentials', getAbsolutePath('@storybook/addon-essentials'),
'@storybook/addon-interactions', getAbsolutePath('@storybook/addon-interactions'),
'@storybook/addon-links', getAbsolutePath('@storybook/addon-links'),
'@storybook/addon-storysource', getAbsolutePath('@storybook/addon-storysource'),
resolve(dirname, '../node_modules/storybook-addon-misskey-theme'), getAbsolutePath('@storybook/addon-mdx-gfm'),
resolve(_dirname, '../node_modules/storybook-addon-misskey-theme'),
], ],
framework: { framework: {
name: '@storybook/vue3-vite', name: getAbsolutePath('@storybook/vue3-vite') as '@storybook/vue3-vite',
options: {}, options: {},
}, },
docs: { docs: {
@ -37,10 +40,13 @@ const config = {
} }
return mergeConfig(config, { return mergeConfig(config, {
plugins: [ plugins: [
// XXX: https://github.com/IanVS/vite-plugin-turbosnap/issues/8 {
(turbosnap as any as typeof turbosnap['default'])({ // XXX: https://github.com/IanVS/vite-plugin-turbosnap/issues/8
rootDir: config.root ?? process.cwd(), ...(turbosnap as any as typeof turbosnap['default'])({
}), rootDir: config.root ?? process.cwd(),
}),
name: 'fake-turbosnap',
},
], ],
build: { build: {
target: [ target: [
@ -53,3 +59,7 @@ const config = {
}, },
} satisfies StorybookConfig; } satisfies StorybookConfig;
export default config; export default config;
function getAbsolutePath(value: string): string {
return dirname(require.resolve(join(value, 'package.json')));
}

View file

@ -3,8 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
import { addons } from '@storybook/addons';
import { FORCE_REMOUNT } from '@storybook/core-events'; import { FORCE_REMOUNT } from '@storybook/core-events';
import { addons } from '@storybook/preview-api';
import { type Preview, setup } from '@storybook/vue3'; import { type Preview, setup } from '@storybook/vue3';
import isChromatic from 'chromatic/isChromatic'; import isChromatic from 'chromatic/isChromatic';
import { initialize, mswDecorator } from 'msw-storybook-addon'; import { initialize, mswDecorator } from 'msw-storybook-addon';

View file

@ -8,7 +8,7 @@
"build": "vite build", "build": "vite build",
"storybook-dev": "nodemon --verbose --watch src --ext \"mdx,ts,vue\" --ignore \"*.stories.ts\" --exec \"pnpm build-storybook-pre && pnpm exec storybook dev -p 6006 --ci\"", "storybook-dev": "nodemon --verbose --watch src --ext \"mdx,ts,vue\" --ignore \"*.stories.ts\" --exec \"pnpm build-storybook-pre && pnpm exec storybook dev -p 6006 --ci\"",
"build-storybook-pre": "(tsc -p .storybook || echo done.) && node .storybook/generate.js && node .storybook/preload-locale.js && node .storybook/preload-theme.js", "build-storybook-pre": "(tsc -p .storybook || echo done.) && node .storybook/generate.js && node .storybook/preload-locale.js && node .storybook/preload-theme.js",
"build-storybook": "pnpm build-storybook-pre && storybook build", "build-storybook": "pnpm build-storybook-pre && storybook build --webpack-stats-json storybook-static",
"chromatic": "chromatic", "chromatic": "chromatic",
"test": "vitest --run --globals", "test": "vitest --run --globals",
"test-and-coverage": "vitest --run --coverage --globals", "test-and-coverage": "vitest --run --coverage --globals",
@ -78,24 +78,24 @@
"devDependencies": { "devDependencies": {
"@misskey-dev/eslint-plugin": "1.0.0", "@misskey-dev/eslint-plugin": "1.0.0",
"@misskey-dev/summaly": "5.0.3", "@misskey-dev/summaly": "5.0.3",
"@storybook/addon-actions": "7.6.10", "@storybook/addon-actions": "8.0.0-beta.2",
"@storybook/addon-essentials": "7.6.10", "@storybook/addon-essentials": "8.0.0-beta.2",
"@storybook/addon-interactions": "7.6.10", "@storybook/addon-interactions": "8.0.0-beta.2",
"@storybook/addon-links": "7.6.10", "@storybook/addon-links": "8.0.0-beta.2",
"@storybook/addon-storysource": "7.6.10", "@storybook/addon-mdx-gfm": "8.0.0-beta.2",
"@storybook/addons": "7.6.10", "@storybook/addon-storysource": "8.0.0-beta.2",
"@storybook/blocks": "7.6.10", "@storybook/blocks": "8.0.0-beta.2",
"@storybook/core-events": "7.6.10", "@storybook/components": "8.0.0-beta.2",
"@storybook/jest": "0.2.3", "@storybook/core-events": "8.0.0-beta.2",
"@storybook/manager-api": "7.6.10", "@storybook/manager-api": "8.0.0-beta.2",
"@storybook/preview-api": "7.6.10", "@storybook/preview-api": "8.0.0-beta.2",
"@storybook/react": "7.6.10", "@storybook/react": "8.0.0-beta.2",
"@storybook/react-vite": "7.6.10", "@storybook/react-vite": "8.0.0-beta.2",
"@storybook/testing-library": "0.2.2", "@storybook/test": "8.0.0-beta.2",
"@storybook/theming": "7.6.10", "@storybook/theming": "8.0.0-beta.2",
"@storybook/types": "7.6.10", "@storybook/types": "8.0.0-beta.2",
"@storybook/vue3": "7.6.10", "@storybook/vue3": "8.0.0-beta.2",
"@storybook/vue3-vite": "7.6.10", "@storybook/vue3-vite": "8.0.0-beta.2",
"@testing-library/vue": "8.0.2", "@testing-library/vue": "8.0.2",
"@types/escape-regexp": "0.0.3", "@types/escape-regexp": "0.0.3",
"@types/estree": "1.0.5", "@types/estree": "1.0.5",
@ -129,12 +129,12 @@
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"start-server-and-test": "2.0.3", "start-server-and-test": "2.0.3",
"storybook": "7.6.10", "storybook": "8.0.0-beta.2",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme", "storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"vite-plugin-turbosnap": "1.0.3", "vite-plugin-turbosnap": "1.0.3",
"vitest": "0.34.6", "vitest": "0.34.6",
"vitest-fetch-mock": "0.2.2", "vitest-fetch-mock": "0.2.2",
"vue-component-type-helpers": "^1.8.27", "vue-component-type-helpers": "1.8.27",
"vue-eslint-parser": "9.4.2", "vue-eslint-parser": "9.4.2",
"vue-tsc": "1.8.27" "vue-tsc": "1.8.27"
} }

View file

@ -5,8 +5,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import { expect } from '@storybook/jest'; import { expect, userEvent, waitFor, within } from '@storybook/test';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw'; import { HttpResponse, http } from 'msw';
import { userDetailed } from '../../.storybook/fakes.js'; import { userDetailed } from '../../.storybook/fakes.js';

View file

@ -4,8 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { expect } from '@storybook/jest'; import { expect, userEvent, waitFor, within } from '@storybook/test';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import { galleryPost } from '../../.storybook/fakes.js'; import { galleryPost } from '../../.storybook/fakes.js';
import MkGalleryPostPreview from './MkGalleryPostPreview.vue'; import MkGalleryPostPreview from './MkGalleryPostPreview.vue';

View file

@ -4,8 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { expect } from '@storybook/jest'; import { expect, userEvent, waitFor, within } from '@storybook/test';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import { onBeforeUnmount } from 'vue'; import { onBeforeUnmount } from 'vue';
import MkSignupServerRules from './MkSignupDialog.rules.vue'; import MkSignupServerRules from './MkSignupDialog.rules.vue';

View file

@ -4,8 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { expect } from '@storybook/jest'; import { expect, userEvent, within } from '@storybook/test';
import { userEvent, within } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import MkA from './MkA.vue'; import MkA from './MkA.vue';
import { tick } from '@/scripts/test-utils.js'; import { tick } from '@/scripts/test-utils.js';

View file

@ -5,8 +5,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { action } from '@storybook/addon-actions'; import { action } from '@storybook/addon-actions';
import { expect } from '@storybook/jest'; import { expect, waitFor } from '@storybook/test';
import { waitFor } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import MkError from './MkError.vue'; import MkError from './MkError.vue';
export const Default = { export const Default = {

View file

@ -5,8 +5,7 @@
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import { within } from '@storybook/testing-library'; import { expect, within } from '@storybook/test';
import { expect } from '@storybook/jest';
import MkMisskeyFlavoredMarkdown from './MkMisskeyFlavoredMarkdown.js'; import MkMisskeyFlavoredMarkdown from './MkMisskeyFlavoredMarkdown.js';
export const Default = { export const Default = {
render(args) { render(args) {

View file

@ -4,7 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { waitFor } from '@storybook/testing-library'; import { waitFor } from '@storybook/test';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import MkPageHeader from './MkPageHeader.vue'; import MkPageHeader from './MkPageHeader.vue';
export const Empty = { export const Empty = {

View file

@ -4,7 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { expect } from '@storybook/jest'; import { expect } from '@storybook/test';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import MkTime from './MkTime.vue'; import MkTime from './MkTime.vue';
import { i18n } from '@/i18n.js'; import { i18n } from '@/i18n.js';

View file

@ -4,8 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { expect } from '@storybook/jest'; import { expect, userEvent, waitFor, within } from '@storybook/test';
import { userEvent, waitFor, within } from '@storybook/testing-library';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import { HttpResponse, http } from 'msw'; import { HttpResponse, http } from 'msw';
import { commonHandlers } from '../../../.storybook/mocks.js'; import { commonHandlers } from '../../../.storybook/mocks.js';

View file

@ -4,7 +4,7 @@
*/ */
/* eslint-disable @typescript-eslint/explicit-function-return-type */ /* eslint-disable @typescript-eslint/explicit-function-return-type */
import { expect } from '@storybook/jest'; import { expect } from '@storybook/test';
import { StoryObj } from '@storybook/vue3'; import { StoryObj } from '@storybook/vue3';
import { userDetailed } from '../../../.storybook/fakes.js'; import { userDetailed } from '../../../.storybook/fakes.js';
import MkUserName from './MkUserName.vue'; import MkUserName from './MkUserName.vue';

File diff suppressed because it is too large Load diff