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

Release: Patch 7.6.12 #25827

Merged
merged 5 commits into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 7.6.12

- CLI: Fix `upgrade` detecting the wrong version of existing Storybooks - [#25752](https://github.com/storybookjs/storybook/pull/25752), thanks [@JReinhold](https://github.com/JReinhold)!

## 7.6.11

- CLI: Update init for react native v7 - [#25780](https://github.com/storybookjs/storybook/pull/25780), thanks [@dannyhw](https://github.com/dannyhw)!
Expand Down
43 changes: 40 additions & 3 deletions code/lib/cli/src/upgrade.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { getStorybookCoreVersion } from '@storybook/telemetry';
import {
UpgradeStorybookToLowerVersionError,
UpgradeStorybookToSameVersionError,
Expand All @@ -16,6 +15,20 @@ jest.mock('./versions', () => {
};
});

const findInstallationsMock = jest.fn();

jest.mock('./js-package-manager', () => {
const originalModule = jest.requireActual('./js-package-manager');
return {
...originalModule,
JsPackageManagerFactory: {
getPackageManager: () => ({
findInstallations: findInstallationsMock,
}),
},
};
});

describe.each([
['│ │ │ ├── @babel/[email protected] deduped', null],
[
Expand All @@ -39,13 +52,37 @@ describe.each([

describe('Upgrade errors', () => {
it('should throw an error when upgrading to a lower version number', async () => {
jest.mocked(getStorybookCoreVersion).mockResolvedValue('8.1.0');
findInstallationsMock.mockResolvedValue({
dependencies: {
'@storybook/cli': [
{
version: '8.1.0',
},
],
},
duplicatedDependencies: {},
infoCommand: '',
dedupeCommand: '',
});

await expect(doUpgrade({} as any)).rejects.toThrowError(UpgradeStorybookToLowerVersionError);
expect(findInstallationsMock).toHaveBeenCalledWith(['storybook', '@storybook/cli']);
});
it('should throw an error when upgrading to the same version number', async () => {
jest.mocked(getStorybookCoreVersion).mockResolvedValue('8.0.0');
findInstallationsMock.mockResolvedValue({
dependencies: {
'@storybook/cli': [
{
version: '8.0.0',
},
],
},
duplicatedDependencies: {},
infoCommand: '',
dedupeCommand: '',
});

await expect(doUpgrade({} as any)).rejects.toThrowError(UpgradeStorybookToSameVersionError);
expect(findInstallationsMock).toHaveBeenCalledWith(['storybook', '@storybook/cli']);
});
});
40 changes: 27 additions & 13 deletions code/lib/cli/src/upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { sync as spawnSync } from 'cross-spawn';
import { telemetry, getStorybookCoreVersion } from '@storybook/telemetry';
import { telemetry } from '@storybook/telemetry';
import semver, { coerce, eq, lt } from 'semver';
import { deprecate, logger } from '@storybook/node-logger';
import { withTelemetry } from '@storybook/core-server';
Expand All @@ -11,7 +11,11 @@ import {
import chalk from 'chalk';
import dedent from 'ts-dedent';
import boxen from 'boxen';
import type { PackageJsonWithMaybeDeps, PackageManagerName } from './js-package-manager';
import type {
JsPackageManager,
PackageJsonWithMaybeDeps,
PackageManagerName,
} from './js-package-manager';
import { JsPackageManagerFactory, getPackageDetails, useNpmWarning } from './js-package-manager';
import { commandLog } from './helpers';
import { automigrate } from './automigrate';
Expand All @@ -34,6 +38,18 @@ export const getStorybookVersion = (line: string) => {
};
};

const getInstalledStorybookVersion = async (packageManager: JsPackageManager) => {
const installations = await packageManager.findInstallations(['storybook', '@storybook/cli']);
if (!installations) {
return undefined;
}
const cliVersion = installations.dependencies['@storybook/cli']?.[0].version;
if (cliVersion) {
return cliVersion;
}
return installations.dependencies['storybook']?.[0].version;
};

const deprecatedPackages = [
{
minVersion: '6.0.0-alpha.0',
Expand Down Expand Up @@ -91,9 +107,7 @@ export const checkVersionConsistency = () => {
});
};

/**
* DEPRECATED BEHAVIOR SECTION
*/
// #region DEPRECATED BEHAVIOR SECTION

type ExtraFlags = Record<string, string[]>;
const EXTRA_FLAGS: ExtraFlags = {
Expand Down Expand Up @@ -170,7 +184,8 @@ export const deprecatedUpgrade = async ({
}
const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr });

const beforeVersion = await getStorybookCoreVersion();
// If we can't determine the existing version fallback to v0.0.0 to not block the upgrade
const beforeVersion = (await getInstalledStorybookVersion(packageManager)) ?? '0.0.0';

commandLog(`Checking for latest versions of '@storybook/*' packages`);

Expand Down Expand Up @@ -221,7 +236,7 @@ export const deprecatedUpgrade = async ({
automigrationResults = await automigrate({ dryRun, yes, packageManager: pkgMgr, configDir });
}
if (!options.disableTelemetry) {
const afterVersion = await getStorybookCoreVersion();
const afterVersion = await getInstalledStorybookVersion(packageManager);
const { preCheckFailure, fixResults } = automigrationResults || {};
const automigrationTelemetry = {
automigrationResults: preCheckFailure ? null : fixResults,
Expand All @@ -237,9 +252,7 @@ export const deprecatedUpgrade = async ({
}
};

/**
* DEPRECATED BEHAVIOR SECTION END
*/
// #endregion DEPRECATED BEHAVIOR SECTION

export interface UpgradeOptions {
/**
Expand Down Expand Up @@ -292,8 +305,9 @@ export const doUpgrade = async ({

const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr });

// If we can't determine the existing version (Yarn PnP), fallback to v0.0.0 to not block the upgrade
const beforeVersion = (await getStorybookCoreVersion()) ?? '0.0.0';
// If we can't determine the existing version fallback to v0.0.0 to not block the upgrade
const beforeVersion = (await getInstalledStorybookVersion(packageManager)) ?? '0.0.0';

const currentVersion = versions['@storybook/cli'];
const isCanary = currentVersion.startsWith('0.0.0');

Expand Down Expand Up @@ -385,7 +399,7 @@ export const doUpgrade = async ({
automigrationResults = await automigrate({ dryRun, yes, packageManager: pkgMgr, configDir });
}
if (!options.disableTelemetry) {
const afterVersion = await getStorybookCoreVersion();
const afterVersion = await getInstalledStorybookVersion(packageManager);
const { preCheckFailure, fixResults } = automigrationResults || {};
const automigrationTelemetry = {
automigrationResults: preCheckFailure ? null : fixResults,
Expand Down
2 changes: 0 additions & 2 deletions code/lib/telemetry/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ export * from './storybook-metadata';

export * from './types';

export { getStorybookCoreVersion } from './package-json';

export { getPrecedingUpgrade } from './event-cache';

export { addToGlobalContext } from './telemetry';
Expand Down
6 changes: 0 additions & 6 deletions code/lib/telemetry/src/package-json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,3 @@ export const getActualPackageJson = async (packageName: string) => {
const packageJson = await fs.readJson(resolvedPackageJson);
return packageJson;
};

// Note that this probably doesn't work in Yarn PNP mode because @storybook/telemetry doesn't depend on @storybook/cli
export const getStorybookCoreVersion = async () => {
const { version } = await getActualPackageVersion('@storybook/cli');
return version;
};
3 changes: 2 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -329,5 +329,6 @@
"Dependency Upgrades"
]
]
}
},
"deferredNextVersion": "7.6.12"
}
154 changes: 152 additions & 2 deletions docs/api/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ Storybook collects completely anonymous data to help us improve user experience.

All of the following documentation is available in the CLI by running `storybook --help`.

<Callout variant="info" icon="💡">

Passing options to these commands works slightly differently if you're using npm instead of Yarn. You must prefix all of your options with `--`. For example, `npm run storybook build -- -o ./path/to/build --quiet`.

</Callout>

### `dev`

Compiles and serves a development build of your Storybook that reflects your source code changes in the browser in real time. Should be run from the root of your project.
Expand Down Expand Up @@ -76,8 +82,152 @@ Options include:
| `--disable-telemetry` | Disables Storybook's telemetry. Learn more about it [here](../configure/telemetry.md).<br/>`storybook build --disable-telemetry` |
| `--test` | Optimize Storybook's production build for performance and tests by removing unnecessary features with the `test` option. Learn more [here](../api/main-config-build.md).<br/>`storybook build --test` |

<Callout variant="info" icon="💡">
<!-- Re-read this for accuracy -->

### `init`

Installs and initializes the specified version (e.g., `@latest`, `@8`, `@next`) of Storybook into your project. Read more in the [installation guide](../get-started/install.md).

```shell
storybook[@version] init [options]
```

For example, `storybook@latest init` will install the latest version of Storybook into your project.

Options include:

| Option | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `-b`, `--builder` | Defines the [builder](../builders/index.md) to use for your Storybook instance<br/>`storybook init --builder webpack5` |
| `-f`,`--force` | Forcefully installs Storybook into your project, prompting you to overwrite existing files<br/>`storybook init --force` |
| `-s`, `--skip-install` | Skips the dependency installation step. Used only when you need to configure Storybook manually<br/>`storybook init --skip-install` |
| `-t`, `--type` | Defines the [framework](../configure/frameworks.md) to use for your Storybook instance<br/>`storybook init --type solid` |
| `-y`, `--yes` | Skips interactive prompts and automatically installs Storybook per specified version<br/>`storybook init --yes` |
| `--package-manager` | Sets the package manager to use when installing the addon.<br/> Available package managers include `npm`, `yarn`, and `pnpm`<br/>`storybook init --package-manager pnpm` |
| `--use-pnp` | Enables [Plug'n'Play](https://yarnpkg.com/features/pnp) support for Yarn. This option is only available when using Yarn as your package manager<br/>`storybook init --use-pnp` |

### `add`

Installs a Storybook addon and configures your project for it. Read more in the [addon installation guide](../addons/install-addons.md).

```shell
storybook add [addon] [options]
```

Options include:

| Option | Description |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--package-manager` | Sets the package manager to use when installing the addon.<br/> Available package managers include `npm`, `yarn`, and `pnpm`<br/>`storybook add [addon] --package-manager pnpm` |
| `-s`, `--skip-postinstall` | Skips post-install configuration. Used only when you need to configure the addon yourself<br/>`storybook add [addon] --skip-postinstall` |

### `remove`

Deletes a Storybook addon from your project. Read more in the [addon installation guide](../addons/install-addons.md#removing-addons).

```shell
storybook remove [addon] [options]
```

Options include:

| Option | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--package-manager` | Sets the package manager to use when removing the addon.<br/>Available package managers include `npm`, `yarn`, and `pnpm`<br/>`storybook remove [addon]--package-manager pnpm` |

### `upgrade`

Upgrades your Storybook instance to the specified version (e.g., `@latest`, `@8`, `@next`). Read more in the [upgrade guide](../configure/upgrading.md).

```shell
storybook[@version] upgrade [options]
```

For example, `storybook@latest upgrade --dry-run` will perform a dry run (no actual changes) of upgrading your project to the latest version of Storybook.

Options include:

| Option | Description |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-c`, `--config-dir` | Directory where to load Storybook configurations from<br/>`storybook upgrade --config-dir .storybook` |
| `-n`, `--dry-run` | Checks for version upgrades without installing them<br/>`storybook upgrade --dry-run` |
| `-s`, `--skip-check` | Skips the migration check step during the upgrade process<br/> `storybook upgrade --skip-check` |
| `-y`, `--yes` | Skips interactive prompts and automatically upgrades Storybook to the latest version<br/>`storybook upgrade --yes` |
| `--package-manager` | Sets the package manager to use when installing the addon.<br/> Available package managers include `npm`, `yarn`, and `pnpm`<br/>`storybook upgrade --package-manager pnpm` |

### `doctor`

Performs a health check on your Storybook project for common issues (e.g., duplicate dependencies, incompatible addons or mismatched versions) and provides suggestions on how to fix them. Applicable when [upgrading](../configure/upgrading.md#verifying-the-upgrade) Storybook versions.

```shell
storybook doctor [options]
```

Options include:

| Option | Description |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `-c`, `--config-dir` | Directory where to load Storybook configurations from<br/>`storybook doctor --config-dir .storybook` |
| `--package-manager` | Sets the package manager to use when running the health check.<br/>Available package managers include `npm`, `yarn`, and `pnpm`<br/>`storybook doctor --package-manager pnpm` |

### `info`

Reports useful debugging information about your environment. Helpful in providing information when opening an issue or a discussion.

```shell
storybook info
```

Example output:

```shell
Storybook Environment Info:

System:
OS: macOS 14.2
CPU: (8) arm64 Apple M3
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.19.0 - ~/.nvm/versions/node/v18.19.0/bin/node
npm: 10.2.3 - ~/.nvm/versions/node/v18.19.0/bin/npm <----- active
Browsers:
Chrome: 120.0.6099.199
npmPackages:
@storybook/addon-essentials: ^7.6.6 => 7.6.6
@storybook/addon-interactions: ^7.6.6 => 7.6.6
@storybook/addon-links: ^7.6.6 => 7.6.6
@storybook/addon-onboarding: ^1.0.10 => 1.0.10
@storybook/blocks: ^7.6.6 => 7.6.6
@storybook/preset-create-react-app: ^7.6.6 => 7.6.6
@storybook/react: ^7.6.6 => 7.6.6
@storybook/react-webpack5: ^7.6.6 => 7.6.6
@storybook/test: ^7.6.6 => 7.6.6
storybook: ^7.6.6 => 7.6.6
npmGlobalPackages:
chromatic: ^10.2.0 => 10.2.0
```

### `sandbox`

Generates a local sandbox project using the specified version (e.g., `@latest`, `@8`, `@next`) for testing Storybook features based on the list of supported [frameworks](../configure/frameworks.md). Useful for reproducing bugs when opening an issue or a discussion.

```shell
storybook[@version] sandbox [framework-filter] [options]
```

For example, `storybook@next sandbox` will generated sandboxes using the newest pre-release version of Storybook.

The `framework-filter` argument is optional and can filter the list of available frameworks. For example, `storybook@next sandbox react` will only offer to generate React-based sandboxes.

Options include:

| Option | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------------- |
| `-o`, `--output [dir-name]` | Configures the location of the sandbox project<br/>`storybook sandbox --output /my-sandbox-project` |
| `--no-init` | Generates a sandbox project without without initializing Storybook<br/>`storybook sandbox --no-init` |

<Callout variant="info">

If you're using npm instead of yarn to publish Storybook, the commands work slightly different. For example, `npm run storybook build -- -o ./path/to/build`.
If you're looking for a hosted version of the available sandboxes, see [storybook.new](https://storybook.new).

</Callout>
Loading
Loading