Skip to content

Commit d0ef1db

Browse files
committed
fix: make prerelease builds exit reliably
The alpha prerelease path hit a repeatable build hang after package artifacts were written. Release scripts now build tagged packages in dependency order. The bundler CLI also exits explicitly after non-watch builds complete. Constraint: publish scripts must not rely on a manual build workaround. Rejected: keep using rush build --only tag:package | it can hang before publish. Confidence: high Scope-risk: narrow Directive: keep TAGGED_PACKAGE_BUILD_ORDER in sync with rush.json package tags. Tested: node --check release script files. Tested: rush change --verify --no-fetch. Tested: buildTagPackages() completed all seven publishable package builds. Not-tested: node common/scripts/pre-release.js; it would publish packages.
1 parent 25875b5 commit d0ef1db

5 files changed

Lines changed: 91 additions & 21 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
const { spawnSync } = require('child_process');
2+
const path = require('path');
3+
const getPackageJson = require('./get-package-json');
4+
5+
const REPO_ROOT = path.join(__dirname, '../..');
6+
const RUSHX_SCRIPT = path.join(REPO_ROOT, 'common/scripts/install-run-rushx.js');
7+
8+
const TAGGED_PACKAGE_BUILD_ORDER = [
9+
'@visactor/vrender-core',
10+
'@visactor/vrender-animate',
11+
'@visactor/vrender-kits',
12+
'@visactor/vrender-components',
13+
'@visactor/vrender',
14+
'@visactor/react-vrender',
15+
'@visactor/react-vrender-utils'
16+
];
17+
18+
function assertTaggedPackageCoverage() {
19+
const rushJson = getPackageJson(path.join(REPO_ROOT, 'rush.json'));
20+
const taggedPackages = rushJson.projects
21+
.filter(project => Array.isArray(project.tags) && project.tags.includes('package'))
22+
.map(project => project.packageName);
23+
24+
const missing = taggedPackages.filter(packageName => !TAGGED_PACKAGE_BUILD_ORDER.includes(packageName));
25+
const extra = TAGGED_PACKAGE_BUILD_ORDER.filter(packageName => !taggedPackages.includes(packageName));
26+
27+
if (missing.length || extra.length) {
28+
throw new Error([
29+
'TAGGED_PACKAGE_BUILD_ORDER is out of sync with rush.json package tags.',
30+
missing.length ? `Missing: ${missing.join(', ')}` : '',
31+
extra.length ? `Extra: ${extra.join(', ')}` : ''
32+
].filter(Boolean).join('\n'));
33+
}
34+
35+
return rushJson.projects.reduce((projectByName, project) => {
36+
projectByName[project.packageName] = project;
37+
return projectByName;
38+
}, {});
39+
}
40+
41+
function runPackageBuild(project) {
42+
console.log(`\n[release-build] ${project.packageName}`);
43+
44+
// `--clean` avoids stale build handles that can keep some package builds open.
45+
const result = spawnSync(process.execPath, [RUSHX_SCRIPT, 'build', '--clean'], {
46+
cwd: path.join(REPO_ROOT, project.projectFolder),
47+
stdio: 'inherit',
48+
shell: false
49+
});
50+
51+
if (result.error) {
52+
throw result.error;
53+
}
54+
55+
if (result.status !== 0) {
56+
process.exit(result.status || 1);
57+
}
58+
}
59+
60+
function buildTagPackages() {
61+
const projectByName = assertTaggedPackageCoverage();
62+
63+
TAGGED_PACKAGE_BUILD_ORDER.forEach(packageName => {
64+
runPackageBuild(projectByName[packageName]);
65+
});
66+
}
67+
68+
module.exports = {
69+
buildTagPackages,
70+
TAGGED_PACKAGE_BUILD_ORDER
71+
};

common/scripts/hotfix-release.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const checkAndUpdateNextBump = require('./version-policies');
99
const getPackageJson = require('./get-package-json');
1010
const writePrereleaseVersion = require('./set-prerelease-version');
1111
const parseVersion = require('./parse-version');
12+
const { buildTagPackages } = require('./build-tag-packages');
1213

1314

1415
function run() {
@@ -60,10 +61,7 @@ function run() {
6061
writePrereleaseVersion('', '', currentVersion, hotfixName)
6162

6263
// 2. build all the packages
63-
spawnSync('sh', ['-c', `rush build --only tag:package`], {
64-
stdio: 'inherit',
65-
shell: false,
66-
});
64+
buildTagPackages();
6765

6866
// 3. publish to npm
6967
spawnSync('sh', ['-c', `rush publish --publish --include-all --tag ${hotfixType}`], {

common/scripts/pre-release.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const path = require('path')
88
const checkAndUpdateNextBump = require('./version-policies');
99
const getPackageJson = require('./get-package-json');
1010
const writePrereleaseVersion = require('./set-prerelease-version');
11+
const { buildTagPackages } = require('./build-tag-packages');
1112

1213

1314
const semverRegex = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(alpha|beta|rc)(?:\.(?:(0|[1-9])))*)$/;
@@ -57,10 +58,7 @@ function run() {
5758
writePrereleaseVersion(checkAndUpdateNextBump(process.argv.slice(2)[1]), preReleaseName)
5859

5960
// 2. build all the packages
60-
spawnSync('sh', ['-c', `rush build --only tag:package`], {
61-
stdio: 'inherit',
62-
shell: false,
63-
});
61+
buildTagPackages();
6462

6563
// 3. publish to npm
6664
spawnSync('sh', ['-c', `rush publish --publish --include-all --tag ${preReleaseType}`], {
@@ -94,4 +92,3 @@ function run() {
9492
}
9593

9694
run()
97-

common/scripts/release.js

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { spawnSync } = require('child_process')
77
const fs = require('fs')
88
const path = require('path')
99
const checkAndUpdateNextBump = require('./version-policies');
10+
const { buildTagPackages } = require('./build-tag-packages');
1011

1112
function getPackageJson(pkgJsonPath) {
1213
const pkgJson = fs.readFileSync(pkgJsonPath, { encoding: 'utf-8' })
@@ -28,10 +29,7 @@ function run() {
2829

2930

3031
// 2. build all the packages
31-
spawnSync('sh', ['-c', `rush build --only tag:package`], {
32-
stdio: 'inherit',
33-
shell: false,
34-
});
32+
buildTagPackages();
3533

3634
// 3. publish to npm
3735
spawnSync('sh', ['-c', 'rush publish --publish --include-all'], {
@@ -46,14 +44,14 @@ function run() {
4644
});
4745

4846
const rushJson = getPackageJson(path.join(__dirname, '../../rush.json'));
49-
const package = rushJson.projects.find((project) => project.name === '@visactor/vrender');
47+
const package = rushJson.projects.find((project) => project.packageName === '@visactor/vrender');
5048

5149
if (package) {
52-
const pkgJsonPath = path.join(__dirname, '../../', project.projectFolder, 'package.json')
50+
const pkgJsonPath = path.join(__dirname, '../../', package.projectFolder, 'package.json')
5351
const pkgJson = getPackageJson(pkgJsonPath)
5452

5553
// 5. add tag
56-
spawnSync('sh', ['-c', `git tag v${pkgJson.versopn}`], {
54+
spawnSync('sh', ['-c', `git tag v${pkgJson.version}`], {
5755
stdio: 'inherit',
5856
shell: false,
5957
});
@@ -79,4 +77,3 @@ function run() {
7977
}
8078

8179
run()
82-

tools/bundler/src/bootstrap.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,18 @@ async function bootstrap() {
151151
});
152152
return;
153153
}
154-
taker.series(taskList)(err => {
155-
if (err) {
156-
throw err;
157-
}
154+
await new Promise<void>((resolve, reject) => {
155+
taker.series(taskList)(err => {
156+
if (err) {
157+
reject(err);
158+
return;
159+
}
160+
161+
resolve();
162+
});
158163
});
164+
165+
process.exit(0);
159166
}
160167

161168
bootstrap().catch(err => {

0 commit comments

Comments
 (0)