semver#prerelease TypeScript Examples

The following examples show how to use semver#prerelease. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: publish-packages.ts    From react-celo with MIT License 4 votes vote down vote up
// This is an async IIFE so that we can use `aync/await`
void (async function () {
  start();

  // `getAnswers` will either prompt the user for a version and whether
  // or not to publish or it will use an existing failedPublish.json file.
  const { packages, version, publish } = await getAnswers();

  if (version && !valid(version) && !VERSIONS.includes(version)) {
    console.error(
      red(
        'Invalid version given. Version must be major, minor, patch, or a semantic version.'
      )
    );
    process.exit(1);
  }

  const shouldPublish =
    publish.toLowerCase() === 'y' || publish.toLowerCase() === 'dry-run';

  if (!shouldPublish && !version) {
    console.error(red('Either a version or --publish must be given'));
    process.exit(1);
  }

  let tag = 'latest';
  const prereleaseArr = prerelease(version);
  if (prereleaseArr) {
    tag = (prereleaseArr[0] + '').trim();

    if (!['alpha', 'beta', 'canary', 'rc'].includes(tag)) {
      const errorPrompt = [
        {
          name: 'confirmTag',
          description: red(
            `Unknown prerelease keyword given, do you really want to publish ${version} with tag ${tag}? Y/N`
          ),
        },
      ];
      const { confirmTag } = await get(errorPrompt);
      if (confirmTag !== 'Y') {
        process.exit(1);
      }
    }
  }

  const packagePaths = findPackagePaths(path.join(__dirname, '..', 'packages'));
  const packageJsons = packagePaths.map(readPackageJson);

  // We need all the names before we go through and update the
  // `package.json` dependencies.
  const packageNames = packageJsons.map(({ name }) => name);

  const currentVersion = removeDevSuffix(packageJsons[0].version);

  let newVersion: string;
  if (!version) {
    newVersion = currentVersion;
  } else {
    newVersion = VERSIONS.includes(version)
      ? incrementVersion(currentVersion, version)
      : version;
  }
  // Here we update the `package.json` objects with updated
  // versions and dependencies.
  packageJsons.forEach((json, index) => {
    json.version = newVersion;

    if (shouldPublish) {
      for (const depName in json.dependencies) {
        if (packageNames.includes(depName)) {
          json.dependencies[depName] = newVersion;
        }
      }
      for (const depName in json.devDependencies) {
        if (packageNames.includes(depName)) {
          json.devDependencies[depName] = newVersion;
        }
      }
    }

    writePackageJson(packagePaths[index], json);
  });

  const otpPrompt = [
    {
      name: 'otp',
      description: green(`Enter 2FA code`),
    },
  ];

  const successfulPackages: string[] = [];
  if (shouldPublish) {
    // Here we build and publish all the packages
    for (let index = 0; index < packagePaths.length; index++) {
      const path = packagePaths[index];
      const packageJson = packageJsons[index];
      if (packages.length && !packages.includes(packageJson.name)) {
        console.log(`Skipping ${packageJson.name}`);
        successfulPackages.push(packageJson.name);
        continue;
      }
      const packageFolderPath = path.replace('package.json', '');
      try {
        console.log(`Building ${packageJson.name}`);
        child_process.execSync('yarn build', {
          cwd: packageFolderPath,
          stdio: 'ignore',
        });

        console.info(
          `Publishing ${packageJson.name}@${packageJson.version} tagged as ${tag}...`
        );
        // Here you enter the 2FA code for npm
        let { otp } = await get<{ otp: string }>(otpPrompt);
        if (!otp) {
          console.error(red('OTP is required. Can be anything for dry run'));
        }

        // Here is the actual publishing
        child_process.execSync(
          `npm publish --access public --otp ${otp} ${
            publish === 'dry-run' ? '--dry-run' : ''
          } --tag ${tag}`,
          { cwd: packageFolderPath, stdio: 'ignore' }
        );
        successfulPackages.push(packageJson.name);
      } catch (e) {
        const errorPrompt = [
          {
            name: 'retry',
            description: red(
              `${packageJson.name} failed to publish. Error message: ${
                (e as Error).message
              } Retry? Y/N`
            ),
          },
        ];
        const { retry } = await get(errorPrompt);
        if (retry === 'Y') {
          index--;
        }
      }
    }
  }

  // This means some packages were not successfully published
  // but some were published so we need to track the failed ones
  // to keep them in sync.
  if (
    successfulPackages.length &&
    successfulPackages.length !== packageNames.length
  ) {
    const failedPackages = packageNames.filter(
      (name) => !successfulPackages.includes(name)
    );
    console.error(
      red(
        `The following packages failed to publish ${failedPackages.join(', ')}.`
      )
    );
    console.error(red('Creating failed packages file.'));
    fs.writeFileSync(
      path.join(__dirname, 'failedPackages.json'),
      JSON.stringify({ packages: failedPackages, version: undefined, publish })
    );
    console.error(red(`Fix failed packages and try again.`));
    process.exit(1);
  }

  const failedJsonPath = path.join(__dirname, 'failedPackages.json');
  if (fs.existsSync(failedJsonPath)) {
    fs.unlinkSync(failedJsonPath);
  }

  const allPackagePaths = findPackagePaths(
    path.join(__dirname, '..', 'packages')
  );

  const newDevVersion = getNewDevVersion(newVersion);

  // Finally we update all the packages across the monorepo
  // to use the most recent packages.
  allPackagePaths.forEach((path) => {
    const json = readPackageJson(path);

    json.version = `${newVersion}-dev`;

    for (const depName in json.dependencies) {
      if (packageNames.includes(depName)) {
        const versionUpdate = json.dependencies[depName].includes('-dev')
          ? `${newDevVersion}-dev`
          : newVersion;
        json.dependencies[depName] = versionUpdate;
      }
    }
    for (const depName in json.devDependencies) {
      if (packageNames.includes(depName)) {
        const versionUpdate = json.devDependencies[depName].includes('-dev')
          ? `${newDevVersion}-dev`
          : newVersion;
        json.devDependencies[depName] = versionUpdate;
      }
    }
    writePackageJson(path, json);
  });
})();