Skip to content

Commit 976a29a

Browse files
committed
chore: add release script
1 parent ebf5843 commit 976a29a

File tree

7 files changed

+187
-1
lines changed

7 files changed

+187
-1
lines changed

CONTRIBUTING.md

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ $ yarn test --package core
4343
$ yarn test --coverage
4444
```
4545

46+
## Release
47+
48+
```bash
49+
$ npm run release
50+
$ npm run release -- --publish-only
51+
$ npm run release -- --skip-git-status-check
52+
$ npm run release -- --skip-build
53+
```
54+
4655
## Create new package
4756

4857
Such as creating package `foo`.

lerna.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,12 @@
1212
"pr(chore)": ":turtle: Chore"
1313
},
1414
"cacheDir": ".changelog"
15-
}
15+
},
16+
"ignoreChanges": [
17+
"**/*.md",
18+
"**/*.test.ts",
19+
"**/*.e2e.ts",
20+
"**/fixtures/**",
21+
"**/test/**"
22+
]
1623
}

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"build": "father-build",
99
"prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
1010
"link": "yarn link umi && yarn link @umijs/test && yarn link @umijs/utils && yarn link @umijs/types",
11+
"release": "node ./scripts/release.js",
1112
"test": "umi-test",
1213
"test:coverage": "umi-test --coverage",
1314
"test:update": "umi-test --updateSnapshot"

scripts/release.js

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
const { utils } = require('umi');
2+
const { join } = require('path');
3+
const exec = require('./utils/exec');
4+
const getPackages = require('./utils/getPackages');
5+
const isNextVersion = require('./utils/isNextVersion');
6+
7+
const { yParser, execa, chalk } = utils;
8+
const cwd = process.cwd();
9+
const args = yParser(process.argv);
10+
const lernaCli = require.resolve('lerna/cli');
11+
12+
function printErrorAndExit(message) {
13+
console.error(chalk.red(message));
14+
process.exit(1);
15+
}
16+
17+
function logStep(name) {
18+
console.log(`${chalk.gray('>> Release:')} ${chalk.magenta.bold(name)}`);
19+
}
20+
21+
async function release() {
22+
// Check git status
23+
if (!args.skipGitStatusCheck) {
24+
const gitStatus = execa.sync('git', ['status', '--porcelain']).stdout;
25+
if (gitStatus.length) {
26+
printErrorAndExit(`Your git status is not clean. Aborting.`);
27+
}
28+
} else {
29+
logStep(
30+
'git status check is skipped, since --skip-git-status-check is supplied',
31+
);
32+
}
33+
34+
// Check npm registry
35+
logStep('check npm registry');
36+
const userRegistry = execa.sync('npm', ['config', 'get', 'registry']).stdout;
37+
if (userRegistry.includes('https://registry.yarnpkg.com/')) {
38+
printErrorAndExit(
39+
`Release failed, please use ${chalk.blue('npm run release')}.`,
40+
);
41+
}
42+
if (!userRegistry.includes('https://registry.npmjs.org/')) {
43+
const registry = chalk.blue('https://registry.npmjs.org/');
44+
printErrorAndExit(`Release failed, npm registry must be ${registry}.`);
45+
}
46+
47+
let updated = null;
48+
49+
if (!args.publishOnly) {
50+
// Get updated packages
51+
logStep('check updated packages');
52+
const updatedStdout = execa.sync(lernaCli, ['changed']).stdout;
53+
updated = updatedStdout
54+
.split('\n')
55+
.map(pkg => {
56+
return pkg.split('/')[1];
57+
})
58+
.filter(Boolean);
59+
if (!updated.length) {
60+
printErrorAndExit('Release failed, no updated package is updated.');
61+
}
62+
63+
// Clean
64+
logStep('clean');
65+
66+
// Build
67+
if (!args.skipBuild) {
68+
logStep('build');
69+
await exec('npm', ['run', 'build']);
70+
} else {
71+
logStep('build is skipped, since args.skipBuild is supplied');
72+
}
73+
74+
// Bump version
75+
// Commit
76+
// Git Tag
77+
// Push
78+
logStep('bump version with lerna version');
79+
const conventionalGraduate = args.conventionalGraduate
80+
? ['--conventional-graduate'].concat(
81+
Array.isArray(args.conventionalGraduate)
82+
? args.conventionalGraduate.join(',')
83+
: [],
84+
)
85+
: [];
86+
const conventionalPrerelease = args.conventionalPrerelease
87+
? ['--conventional-prerelease'].concat(
88+
Array.isArray(args.conventionalPrerelease)
89+
? args.conventionalPrerelease.join(',')
90+
: [],
91+
)
92+
: [];
93+
await exec(
94+
lernaCli,
95+
[
96+
'version',
97+
'--exact',
98+
// '--no-commit-hooks',
99+
// '--no-git-tag-version',
100+
// '--no-push',
101+
'--conventional-commits',
102+
]
103+
.concat(conventionalGraduate)
104+
.concat(conventionalPrerelease),
105+
);
106+
107+
logStep('done');
108+
return;
109+
}
110+
111+
// Publish
112+
// Umi must be the latest.
113+
const pkgs = args.publishOnly ? getPackages() : updated;
114+
logStep(`publish packages: ${chalk.blue(pkgs.join(', '))}`);
115+
116+
pkgs.forEach(pkg => {
117+
const pkgPath = join(cwd, 'packages', pkg);
118+
const { name, version } = require(join(pkgPath, 'package.json'));
119+
const isNext = isNextVersion(version);
120+
console.log(`Publish package ${name} ${isNext ? 'with next tag' : ''}`);
121+
const cliArgs = isNext ? ['publish', '--tag', 'next'] : ['publish'];
122+
const { stdout } = execa.sync('npm', cliArgs, {
123+
cwd: pkgPath,
124+
});
125+
console.log(stdout);
126+
});
127+
}
128+
129+
release().catch(err => {
130+
console.error(err);
131+
process.exit(1);
132+
});

scripts/utils/exec.js

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const { spawn } = require('child_process');
2+
3+
module.exports = function exec(command, args, opts) {
4+
return new Promise((resolve, reject) => {
5+
const child = spawn(
6+
command,
7+
args,
8+
Object.assign({ stdio: 'inherit', env: process.env }, opts),
9+
);
10+
child.once('error', err => {
11+
console.log(err);
12+
reject(err);
13+
});
14+
child.once('close', code => {
15+
if (code === 1) {
16+
process.exit(1);
17+
} else {
18+
resolve();
19+
}
20+
});
21+
});
22+
};

scripts/utils/getPackages.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const { readdirSync } = require('fs');
2+
const { join } = require('path');
3+
4+
module.exports = function getPackages() {
5+
return readdirSync(join(__dirname, '../../packages')).filter(
6+
pkg => pkg.charAt(0) !== '.',
7+
);
8+
};

scripts/utils/isNextVersion.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = function(version) {
2+
return (
3+
version.includes('-rc.') ||
4+
version.includes('-beta.') ||
5+
version.includes('-alpha.')
6+
);
7+
};

0 commit comments

Comments
 (0)