Skip to content

Commit

Permalink
Merge branch 'jeppe/upgrade-versioned-main' into norbert/cli-sandbox-…
Browse files Browse the repository at this point in the history
…versioned-main
  • Loading branch information
ndelangen authored Jan 12, 2024
2 parents 3f48968 + a89b141 commit 6dff347
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 5 deletions.
5 changes: 5 additions & 0 deletions code/lib/cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ command('upgrade')
.option('-N --use-npm', 'Use NPM to install dependencies (deprecated)')
.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) (deprecated)'
)
.option('-p --prerelease', 'Upgrade to the pre-release packages (deprecated)')
.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
185 changes: 180 additions & 5 deletions code/lib/cli/src/upgrade.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { sync as spawnSync } from 'cross-spawn';
import { telemetry, getStorybookCoreVersion } from '@storybook/telemetry';
import semver, { coerce, eq, lt, prerelease } from 'semver';
import { logger } from '@storybook/node-logger';
import semver, { coerce, eq, lt } from 'semver';
import { deprecate, logger } from '@storybook/node-logger';
import { withTelemetry } from '@storybook/core-server';
import {
UpgradeStorybookToLowerVersionError,
Expand All @@ -11,8 +11,8 @@ import {
import chalk from 'chalk';
import dedent from 'ts-dedent';
import boxen from 'boxen';
import type { PackageManagerName } from './js-package-manager';
import { JsPackageManagerFactory, useNpmWarning } from './js-package-manager';
import type { PackageJsonWithMaybeDeps, PackageManagerName } from './js-package-manager';
import { JsPackageManagerFactory, getPackageDetails, useNpmWarning } from './js-package-manager';
import { commandLog } from './helpers';
import { automigrate } from './automigrate';
import { isCorePackage } from './utils';
Expand Down Expand Up @@ -91,7 +91,165 @@ export const checkVersionConsistency = () => {
});
};

/**
* DEPRECATED BEHAVIOR SECTION
*/

type ExtraFlags = Record<string, string[]>;
const EXTRA_FLAGS: ExtraFlags = {
'react-scripts@<5': ['--reject', '/preset-create-react-app/'],
};

export const addExtraFlags = (
extraFlags: ExtraFlags,
flags: string[],
{ dependencies, devDependencies }: PackageJsonWithMaybeDeps
) => {
return Object.entries(extraFlags).reduce(
(acc, entry) => {
const [pattern, extra] = entry;
const [pkg, specifier] = getPackageDetails(pattern);
const pkgVersion = dependencies[pkg] || devDependencies[pkg];

if (pkgVersion && semver.satisfies(semver.coerce(pkgVersion), specifier)) {
return [...acc, ...extra];
}

return acc;
},
[...flags]
);
};

export const addNxPackagesToReject = (flags: string[]) => {
const newFlags = [...flags];
const index = flags.indexOf('--reject');
if (index > -1) {
// Try to understand if it's in the format of a regex pattern
if (newFlags[index + 1].endsWith('/') && newFlags[index + 1].startsWith('/')) {
// Remove last and first slash so that I can add the parentheses
newFlags[index + 1] = newFlags[index + 1].substring(1, newFlags[index + 1].length - 1);
newFlags[index + 1] = `/(${newFlags[index + 1]}|@nrwl/storybook|@nx/storybook)/`;
} else {
// Adding the two packages as comma-separated values
// If the existing rejects are in regex format, they will be ignored.
// Maybe we need to find a more robust way to treat rejects?
newFlags[index + 1] = `${newFlags[index + 1]},@nrwl/storybook,@nx/storybook`;
}
} else {
newFlags.push('--reject');
newFlags.push('@nrwl/storybook,@nx/storybook');
}
return newFlags;
};

export const deprecatedUpgrade = async ({
tag,
prerelease,
skipCheck,
useNpm,
packageManager: pkgMgr,
dryRun,
configDir,
yes,
...options
}: UpgradeOptions) => {
if (useNpm) {
useNpmWarning();
// eslint-disable-next-line no-param-reassign
pkgMgr = 'npm';
}
if (tag) {
deprecate(
'The --tag flag is deprecated. Specify the version you want to upgrade to with `npx storybook@<version> upgrade` instead'
);
} else if (prerelease) {
deprecate(
'The --prerelease flag is deprecated. Specify the version you want to upgrade to with `npx storybook@<version> upgrade` instead'
);
}
const packageManager = JsPackageManagerFactory.getPackageManager({ force: pkgMgr });

const beforeVersion = await getStorybookCoreVersion();

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

if (tag && prerelease) {
throw new Error(
`Cannot set both --tag and --prerelease. Use --tag next to get the latest prereleae`
);
}

let target = 'latest';
if (prerelease) {
// '@next' is storybook's convention for the latest prerelease tag.
// This used to be 'greatest', but that was not reliable and could pick canaries, etc.
// and random releases of other packages with storybook in their name.
target = '@next';
} else if (tag) {
target = `@${tag}`;
}

let flags = [];
if (!dryRun) flags.push('--upgrade');
flags.push('--target');
flags.push(target);
flags = addExtraFlags(EXTRA_FLAGS, flags, await packageManager.retrievePackageJson());
flags = addNxPackagesToReject(flags);
const check = spawnSync('npx', ['npm-check-updates@latest', '/storybook/', ...flags], {
stdio: 'pipe',
shell: true,
});
logger.info(check.stdout.toString());
logger.info(check.stderr.toString());

const checkSb = spawnSync('npx', ['npm-check-updates@latest', 'sb', ...flags], {
stdio: 'pipe',
shell: true,
});
logger.info(checkSb.stdout.toString());
logger.info(checkSb.stderr.toString());

if (!dryRun) {
commandLog(`Installing upgrades`);
await packageManager.installDependencies();
}

let automigrationResults;
if (!skipCheck) {
checkVersionConsistency();
automigrationResults = await automigrate({ dryRun, yes, packageManager: pkgMgr, configDir });
}
if (!options.disableTelemetry) {
const afterVersion = await getStorybookCoreVersion();
const { preCheckFailure, fixResults } = automigrationResults || {};
const automigrationTelemetry = {
automigrationResults: preCheckFailure ? null : fixResults,
automigrationPreCheckFailure: preCheckFailure || null,
};
telemetry('upgrade', {
prerelease,
tag,
beforeVersion,
afterVersion,
...automigrationTelemetry,
});
}
};

/**
* DEPRECATED BEHAVIOR SECTION END
*/

export interface UpgradeOptions {
/**
* @deprecated
*/
tag: string;
/**
* @deprecated
*/
prerelease: boolean;
skipCheck: boolean;
useNpm: boolean;
packageManager: PackageManagerName;
Expand All @@ -102,6 +260,8 @@ export interface UpgradeOptions {
}

export const doUpgrade = async ({
tag,
prerelease,
skipCheck,
useNpm,
packageManager: pkgMgr,
Expand All @@ -115,6 +275,21 @@ export const doUpgrade = async ({
// eslint-disable-next-line no-param-reassign
pkgMgr = 'npm';
}
if (tag || prerelease) {
await deprecatedUpgrade({
tag,
prerelease,
skipCheck,
useNpm,
packageManager: pkgMgr,
dryRun,
configDir,
yes,
...options,
});
return;
}

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

const currentVersion = versions['@storybook/cli'];
Expand All @@ -129,7 +304,7 @@ export const doUpgrade = async ({

const latestVersion = await packageManager.latestVersion('@storybook/cli');
const isOutdated = lt(currentVersion, latestVersion);
const isPrerelease = prerelease(currentVersion) !== null;
const isPrerelease = semver.prerelease(currentVersion) !== null;

const borderColor = isOutdated ? '#FC521F' : '#F1618C';

Expand Down
1 change: 1 addition & 0 deletions code/lib/cli/src/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export default {
'@storybook/svelte-webpack5': '7.6.7',
'@storybook/sveltekit': '7.6.7',
'@storybook/telemetry': '7.6.7',
'@storybook/test': '7.6.7',
'@storybook/theming': '7.6.7',
'@storybook/types': '7.6.7',
'@storybook/vue': '7.6.7',
Expand Down

0 comments on commit 6dff347

Please sign in to comment.