Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI: Versioned upgrade of monorepo packages #25553

Merged
merged 11 commits into from
Jan 12, 2024
2 changes: 1 addition & 1 deletion code/frameworks/nextjs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ npx storybook@latest init
This framework is designed to work with Storybook 7. If you’re not already using v7, upgrade with this command:

```bash
npx storybook@latest upgrade --prerelease
npx storybook@latest upgrade
```

#### Automatic migration
Expand Down
2 changes: 1 addition & 1 deletion code/frameworks/preact-vite/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ npx storybook@latest init
This framework is designed to work with Storybook 7. If you’re not already using v7, upgrade with this command:

```bash
npx storybook@latest upgrade --prerelease
npx storybook@latest upgrade
```

#### Manual migration
Expand Down
3 changes: 1 addition & 2 deletions code/frameworks/sveltekit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ Check out our [Frameworks API](https://storybook.js.org/blog/framework-api/) ann
- [Mocking links](#mocking-links)
- [Troubleshooting](#troubleshooting)
- [Error: `ERR! SyntaxError: Identifier '__esbuild_register_import_meta_url__' has already been declared` when starting Storybook](#error-err-syntaxerror-identifier-__esbuild_register_import_meta_url__-has-already-been-declared-when-starting-storybook)
- [Error: `Cannot read properties of undefined (reading 'disable_scroll_handling')` in preview](#error-cannot-read-properties-of-undefined-reading-disable_scroll_handling-in-preview)
- [Acknowledgements](#acknowledgements)

## Supported features
Expand Down Expand Up @@ -64,7 +63,7 @@ npx storybook@latest init
This framework is designed to work with Storybook 7. If you’re not already using v7, upgrade with this command:

```bash
npx storybook@latest upgrade --prerelease
npx storybook@latest upgrade
```

#### Automatic migration
Expand Down
6 changes: 5 additions & 1 deletion code/lib/cli/src/automigrate/fixes/builder-vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { writeConfig } from '@storybook/csf-tools';
import type { Fix } from '../types';
import type { PackageJson } from '../../js-package-manager';
import { updateMainConfig } from '../helpers/mainConfigFile';
import { getStorybookVersionSpecifier } from '../../helpers';

const logger = console;

Expand Down Expand Up @@ -68,8 +69,11 @@ export const builderVite: Fix<BuilderViteOptions> = {

logger.info(`✅ Adding '@storybook/builder-vite' as dev dependency`);
if (!dryRun) {
const versionToInstall = getStorybookVersionSpecifier(
await packageManager.retrievePackageJson()
);
await packageManager.addDependencies({ installAsDevDependencies: true }, [
'@storybook/builder-vite',
`@storybook/builder-vite@${versionToInstall}`,
]);
}

Expand Down
6 changes: 4 additions & 2 deletions code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ export const checkWebpack5Builder = async ({

To upgrade to the latest stable release, run this from your project directory:

${chalk.cyan('npx storybook upgrade')}
${chalk.cyan('npx storybook@latest upgrade')}

Add the ${chalk.cyan('--prerelease')} flag to get the latest prerelease.
To upgrade to the latest pre-release, run this from your project directory:

${chalk.cyan('npx storybook@next upgrade')}
`.trim()
);
return null;
Expand Down
4 changes: 1 addition & 3 deletions code/lib/cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,13 @@ command('remove <addon>')
.action((addonName: string, options: any) => remove(addonName, options));

command('upgrade')
.description('Upgrade your Storybook packages to the latest')
.description(`Upgrade your Storybook packages to v${versions.storybook}`)
.option(
'--package-manager <npm|pnpm|yarn1|yarn2>',
'Force package manager for installing dependencies'
)
.option('-y --yes', 'Skip prompting the user')
.option('-n --dry-run', 'Only check for upgrades, do not install')
.option('-t --tag <tag>', 'Upgrade to a certain npm dist-tag (e.g. next, prerelease)')
.option('-p --prerelease', 'Upgrade to the pre-release packages')
.option('-s --skip-check', 'Skip postinstall version and automigration checks')
.option('-c, --config-dir <dir-name>', 'Directory where to load Storybook configurations from')
.action(async (options: UpgradeOptions) => upgrade(options).catch(() => process.exit(1)));
Expand Down
2 changes: 2 additions & 0 deletions code/lib/cli/src/js-package-manager/JsPackageManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ export abstract class JsPackageManager {

done = commandLog('Installing dependencies');

logger.log();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this adds a newline so that the package manager's install logs are not written to the same line


try {
await this.runInstall();
done();
Expand Down
90 changes: 27 additions & 63 deletions code/lib/cli/src/upgrade.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import { describe, it, expect } from 'vitest';
import { addExtraFlags, addNxPackagesToReject, getStorybookVersion } from './upgrade';
import { describe, it, expect, vi } from 'vitest';
import { getStorybookCoreVersion } from '@storybook/telemetry';
import {
UpgradeStorybookToLowerVersionError,
UpgradeStorybookToSameVersionError,
} from '@storybook/core-events/server-errors';
import { doUpgrade, getStorybookVersion } from './upgrade';
import type versions from './versions';

vi.mock('@storybook/telemetry');
vi.mock('./versions', async (importOriginal) => {
const originalVersions = ((await importOriginal()) as { default: typeof versions }).default;
return {
default: Object.keys(originalVersions).reduce((acc, key) => {
acc[key] = '8.0.0';
return acc;
}, {} as Record<string, string>),
};
});

describe.each([
['│ │ │ ├── @babel/[email protected] deduped', null],
Expand All @@ -22,68 +39,15 @@ describe.each([
});
});

describe('extra flags', () => {
const extraFlags = {
'react-scripts@<5': ['--foo'],
};
const devDependencies = {};
it('package matches constraints', () => {
expect(
addExtraFlags(extraFlags, [], { dependencies: { 'react-scripts': '4' }, devDependencies })
).toEqual(['--foo']);
});
it('package prerelease matches constraints', () => {
expect(
addExtraFlags(extraFlags, [], {
dependencies: { 'react-scripts': '4.0.0-alpha.0' },
devDependencies,
})
).toEqual(['--foo']);
});
it('package not matches constraints', () => {
expect(
addExtraFlags(extraFlags, [], {
dependencies: { 'react-scripts': '5.0.0-alpha.0' },
devDependencies,
})
).toEqual([]);
});
it('no package not matches constraints', () => {
expect(
addExtraFlags(extraFlags, [], {
dependencies: {},
devDependencies,
})
).toEqual([]);
});
});
describe('Upgrade errors', () => {
it('should throw an error when upgrading to a lower version number', async () => {
vi.mocked(getStorybookCoreVersion).mockResolvedValue('8.1.0');

describe('addNxPackagesToReject', () => {
it('reject exists and is in regex pattern', () => {
const flags = ['--reject', '/preset-create-react-app/', '--some-flag', 'hello'];
expect(addNxPackagesToReject(flags)).toMatchObject([
'--reject',
'"/(preset-create-react-app|@nrwl/storybook|@nx/storybook)/"',
'--some-flag',
'hello',
]);
await expect(doUpgrade({} as any)).rejects.toThrowError(UpgradeStorybookToLowerVersionError);
});
it('reject exists and is in unknown pattern', () => {
const flags = ['--some-flag', 'hello', '--reject', '@storybook/preset-create-react-app'];
expect(addNxPackagesToReject(flags)).toMatchObject([
'--some-flag',
'hello',
'--reject',
'@storybook/preset-create-react-app,@nrwl/storybook,@nx/storybook',
]);
});
it('reject does not exist', () => {
const flags = ['--some-flag', 'hello'];
expect(addNxPackagesToReject(flags)).toMatchObject([
'--some-flag',
'hello',
'--reject',
'@nrwl/storybook,@nx/storybook',
]);
it('should throw an error when upgrading to the same version number', async () => {
vi.mocked(getStorybookCoreVersion).mockResolvedValue('8.0.0');

await expect(doUpgrade({} as any)).rejects.toThrowError(UpgradeStorybookToSameVersionError);
});
});
Loading