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

[Request]: Add version checksum in main.js #28600

Open
yannbf opened this issue Jul 15, 2024 · 1 comment
Open

[Request]: Add version checksum in main.js #28600

yannbf opened this issue Jul 15, 2024 · 1 comment

Comments

@yannbf
Copy link
Member

yannbf commented Jul 15, 2024

Problem

We're having trouble figuring out if Storybook users are using the npx storybook@latest upgrade to upgrade Storybook, or if they do it manually or via other ways. If we could know for sure whether they've upgraded Storybook correctly, we could provide much better help to fix their issues.

Solution

Every time someone runs the Storybook upgrade command, we'll track the old and new versions, create a checksum with that info, and add it to .storybook/main.ts. This checksum will help us with telemetry so we know if users are using the upgrade command, and we can also use it to check at runtime if Storybook is installed correctly. If some packages don't match the expected version, we'll prompt users to run the upgrade command to fix the issue and update the checksum.

When users run npx storybook@latest upgrade, detect the from and to versions, create a checksum string with this info. Here's an example with base64 encoding:

const encodeChecksum = (fromVersion: string, toVersion: string): string => {
  return Buffer.from(`${fromVersion}|${toVersion}`).toString('base64');
};

const decodeChecksum = (checksum: string): { fromVersion: string, toVersion: string } => {
  const [fromVersion, toVersion] = Buffer.from(checksum, 'base64').toString('utf8').split('|');
  return { fromVersion, toVersion };
};

Then add it to .storybook/main.ts e.g.:

import { StorybookConfig } from '@storybook/react-vite'

const config: StorybookConfig = {
  //...
  checksum: 'OC4xLjF8OC4yLjA=' // '8.1.1|8.2.0'
}
export default config

Later on, at runtime, the checksum will be parsed to extract the target version.
The extracted version will be compared against the installed Storybook packages.
If discrepancies are found (e.g., some packages match the version while others do not), an error will be thrown, prompting users to run the upgrade command again.

Copy link
Contributor

greptile-apps bot commented Jul 15, 2024

** Disclaimer** This information might be inaccurate, due to it being generated automatically

Implementation Steps

  1. Generate the Checksum:

    • Add the following functions to /code/lib/cli/src/upgrade.ts:
    const encodeChecksum = (fromVersion: string, toVersion: string): string => {
      return Buffer.from(`${fromVersion}|${toVersion}`).toString('base64');
    };
    
    const decodeChecksum = (checksum: string): { fromVersion: string, toVersion: string } => {
      const [fromVersion, toVersion] = Buffer.from(checksum, 'base64').toString('utf8').split('|');
      return { fromVersion, toVersion };
    };
  2. Modify the Upgrade Command:

    • In the doUpgrade function in /code/lib/cli/src/upgrade.ts, after the upgrade process, generate the checksum and add it to .storybook/main.ts:
    const checksum = encodeChecksum(beforeVersion, currentCLIVersion);
    const mainConfigPath = path.resolve(configDir, 'main.ts');
    const mainConfigContent = await fs.promises.readFile(mainConfigPath, 'utf8');
    const updatedMainConfigContent = mainConfigContent.replace(/(export default config;)/, `config.checksum = '${checksum}';

$1`);
await fs.promises.writeFile(mainConfigPath, updatedMainConfigContent);


3. **Validate Checksum at Runtime:**
- Add a validation step in the Storybook initialization process to decode and compare the checksum with the installed versions. This can be done in a new utility file, e.g., `/code/lib/cli/src/validateChecksum.ts`:
```ts
import { decodeChecksum } from './upgrade';
import { getInstalledStorybookVersion } from './helpers';

export const validateChecksum = async (configDir: string) => {
  const mainConfigPath = path.resolve(configDir, 'main.ts');
  const mainConfigContent = await fs.promises.readFile(mainConfigPath, 'utf8');
  const checksumMatch = mainConfigContent.match(/checksum: '([^']+)'/);
  if (checksumMatch) {
    const { fromVersion, toVersion } = decodeChecksum(checksumMatch[1]);
    const installedVersion = await getInstalledStorybookVersion();
    if (installedVersion !== toVersion) {
      throw new Error(`Storybook version mismatch. Expected: ${toVersion}, Found: ${installedVersion}. Please run 'npx storybook@latest upgrade'.`);
    }
  }
};

References

/code/lib/cli/src/upgrade.ts
/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.ts
/code/lib/cli/src/automigrate/fixes/upgrade-storybook-related-dependencies.test.ts
/code/core/src/core-server/utils/update-check.ts

About Greptile

This response provides a starting point for your research, not a precise solution.

Help us improve! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

Ask Greptile · Edit Issue Bot Settings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant