release.js 4.54 KB
Newer Older
dengxiaofeng's avatar
dengxiaofeng committed
1 2 3 4 5
const { utils } = require('umi');
const { join } = require('path');
const exec = require('./utils/exec');
const getPackages = require('./utils/getPackages');
const isNextVersion = require('./utils/isNextVersion');
叶飞's avatar
叶飞 committed
6
const { error } = require('console');
dengxiaofeng's avatar
dengxiaofeng committed
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

const { yParser, execa, chalk } = utils;
const cwd = process.cwd();
const args = yParser(process.argv);
const lernaCli = require.resolve('lerna/cli');

function printErrorAndExit(message) {
  console.error(chalk.red(message));
  process.exit(1);
}

function logStep(name) {
  console.log(`${chalk.gray('>> Release:')} ${chalk.magenta.bold(name)}`);
}

function packageExists({ name, version }) {
  const { stdout } = execa.sync('npm', ['info', `${name}@${version}`]);
  return stdout.length > 0;
}

async function release() {
  // Check git status
  if (!args.skipGitStatusCheck) {
    const gitStatus = execa.sync('git', ['status', '--porcelain']).stdout;
    if (gitStatus.length) {
      printErrorAndExit(`Your git status is not clean. Aborting.`);
    }
  } else {
    logStep('git status check is skipped, since --skip-git-status-check is supplied');
  }

  // Check npm registry
  logStep('check npm registry');
  const userRegistry = execa.sync('npm', ['config', 'get', 'registry']).stdout;
  if (userRegistry.includes('https://registry.yarnpkg.com/')) {
    printErrorAndExit(`Release failed, please use ${chalk.blue('npm run release')}.`);
  }
邓晓峰's avatar
邓晓峰 committed
44 45 46 47 48 49 50 51
  //https://g.civnet.cn:4873
  // if (!userRegistry.includes('https://registry.npmjs.org/')) {
  //   const registry = chalk.blue('https://registry.npmjs.org/');
  //   printErrorAndExit(`Release failed, npm registry must be ${registry}.`);
  // }

  if (!userRegistry.includes('https://g.civnet.cn:4873/')) {
    const registry = chalk.blue('https://g.civnet.cn:4873/');
dengxiaofeng's avatar
dengxiaofeng committed
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
    printErrorAndExit(`Release failed, npm registry must be ${registry}.`);
  }
  let updated = null;

  if (!args.publishOnly) {
    // Get updated packages
    logStep('check updated packages');
    const updatedStdout = execa.sync(lernaCli, ['changed']).stdout;
    updated = updatedStdout
      .split('\n')
      .map((pkg) => {
        return pkg.split('/')[1];
      })
      .filter(Boolean);
    if (!updated.length) {
      printErrorAndExit('Release failed, no updated package is updated.');
    }

    // Clean
    logStep('clean');

    // Build
    if (!args.skipBuild) {
      logStep('build');
叶飞's avatar
叶飞 committed
76 77
      try {
        await exec('npm', ['run', 'build']);
叶飞's avatar
叶飞 committed
78
      } catch(error) {
叶飞's avatar
叶飞 committed
79
        console.log(error)
叶飞's avatar
叶飞 committed
80
      }
叶飞's avatar
叶飞 committed
81
      
dengxiaofeng's avatar
dengxiaofeng committed
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
    } else {
      logStep('build is skipped, since args.skipBuild is supplied');
    }

    // Bump version
    // Commit
    // Git Tag
    // Push
    logStep('bump version with lerna version');
    const conventionalGraduate = args.conventionalGraduate
      ? ['--conventional-graduate'].concat(
          Array.isArray(args.conventionalGraduate) ? args.conventionalGraduate.join(',') : [],
        )
      : [];
    const conventionalPrerelease = args.conventionalPrerelease
      ? ['--conventional-prerelease'].concat(
          Array.isArray(args.conventionalPrerelease) ? args.conventionalPrerelease.join(',') : [],
        )
      : [];
    await exec(
      lernaCli,
      [
        'version',
        '--exact',
        // '--no-commit-hooks',
        // '--no-git-tag-version',
        // '--no-push',
        '--message',
        '🎨 chore(release): Publish',
        '--conventional-commits',
      ]
        .concat(conventionalGraduate)
        .concat(conventionalPrerelease),
    );
  }

  // Publish
  // Umi must be the latest.
  const pkgs = args.publishOnly ? getPackages() : updated;
  logStep(`publish packages: ${chalk.blue(pkgs.join(', '))}`);

  pkgs.forEach((pkg, index) => {
    const pkgPath = join(cwd, 'packages', pkg.replace('pro-', ''));
    const { name, version } = require(join(pkgPath, 'package.json'));
    const isNext = isNextVersion(version);
    let isPackageExist = null;
    if (args.publishOnly) {
      isPackageExist = packageExists({ name, version });
      if (isPackageExist) {
        console.log(`package ${name}@${version} is already exists on npm, skip.`);
      }
    }
    if (!args.publishOnly || !isPackageExist) {
      console.log(
        `[${index + 1}/${pkgs.length}] Publish package ${name} ${isNext ? 'with next tag' : ''}`,
      );
      const cliArgs = isNext ? ['publish', '--tag', 'next'] : ['publish'];
      const { stdout } = execa.sync('npm', cliArgs, {
        cwd: pkgPath,
      });
      console.log(stdout);
    }
  });

  await exec('npm', ['run', 'prettier']);

  logStep('done');
}

release().catch((err) => {
  console.error(err);
  process.exit(1);
邓晓峰's avatar
邓晓峰 committed
154
});