Skip to content

Commit b6a127c

Browse files
chore(release): 🚀 add custom workspace publish and version sync scripts
* Introduce `publish-workspace.js` to handle npm publishing for workspaces, including dry-run support and version syncing. * Add `sync-workspace-versions.js` to synchronize root version to workspace packages post-bump. * Update `.release-it.json` to integrate new scripts into release workflow and improve workspace publishing reliability. Signed-off-by: Justin Wiegmann <wiegmann@e-spirit.com>
1 parent 69dc8bc commit b6a127c

3 files changed

Lines changed: 111 additions & 5 deletions

File tree

‎.release-it.json‎

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"npm run test"
2323
],
2424
"after:bump": [
25+
"node scripts/sync-workspace-versions.js",
2526
"npm run build"
2627
],
2728
"after:release": "echo Successfully released ${name} v${version} to ${repo.repository}."
@@ -38,11 +39,8 @@
3839
"proxy"
3940
],
4041
"publish": true,
41-
"additionalManifests": {
42-
"versionUpdates": [
43-
"proxy/package.json"
44-
]
45-
}
42+
"skipChecks": true,
43+
"publishCommand": "node scripts/publish-workspace.js"
4644
}
4745
}
4846
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Custom publish script for workspace packages.
5+
* This script handles the actual npm publish for workspaces,
6+
* and correctly handles dry-run mode by syncing versions first.
7+
*
8+
* Environment variables provided by @release-it-plugins/workspaces:
9+
* - RELEASE_IT_WORKSPACES_PATH_TO_WORKSPACE: relative path to workspace
10+
* - RELEASE_IT_WORKSPACES_TAG: npm dist-tag (e.g., 'latest')
11+
* - RELEASE_IT_WORKSPACES_ACCESS: access level ('public' or 'restricted')
12+
* - RELEASE_IT_WORKSPACES_OTP: one-time password for 2FA (optional)
13+
* - RELEASE_IT_WORKSPACES_DRY_RUN: 'true' if this is a dry run
14+
*/
15+
16+
const { execSync } = require('child_process');
17+
const fs = require('fs');
18+
const path = require('path');
19+
20+
const workspacePath = process.env.RELEASE_IT_WORKSPACES_PATH_TO_WORKSPACE;
21+
const tag = process.env.RELEASE_IT_WORKSPACES_TAG || 'latest';
22+
const access = process.env.RELEASE_IT_WORKSPACES_ACCESS || 'public';
23+
const otp = process.env.RELEASE_IT_WORKSPACES_OTP;
24+
const isDryRun = process.env.RELEASE_IT_WORKSPACES_DRY_RUN === 'true';
25+
26+
if (!workspacePath) {
27+
console.error('Error: RELEASE_IT_WORKSPACES_PATH_TO_WORKSPACE not set');
28+
process.exit(1);
29+
}
30+
31+
// Sync version from root package.json to workspace package.json
32+
// This is needed because in dry-run mode, the after:bump hook doesn't execute
33+
const rootPackagePath = path.join(__dirname, '..', 'package.json');
34+
const workspacePackagePath = path.join(__dirname, '..', workspacePath, 'package.json');
35+
36+
try {
37+
const rootPackage = JSON.parse(fs.readFileSync(rootPackagePath, 'utf8'));
38+
const workspacePackage = JSON.parse(fs.readFileSync(workspacePackagePath, 'utf8'));
39+
40+
if (rootPackage.version !== workspacePackage.version) {
41+
console.log(`Syncing version: ${workspacePackage.version} -> ${rootPackage.version}`);
42+
workspacePackage.version = rootPackage.version;
43+
fs.writeFileSync(workspacePackagePath, JSON.stringify(workspacePackage, null, 2) + '\n');
44+
}
45+
} catch (error) {
46+
console.error('Error syncing version:', error.message);
47+
process.exit(1);
48+
}
49+
50+
// Build the npm publish command
51+
let command = `npm publish ./${workspacePath} --tag ${tag} --access ${access}`;
52+
if (otp) {
53+
command += ` --otp ${otp}`;
54+
}
55+
if (isDryRun) {
56+
command += ' --dry-run';
57+
}
58+
59+
console.log(`Publishing ${workspacePath}...`);
60+
console.log(`Command: ${command}`);
61+
62+
try {
63+
execSync(command, { stdio: 'inherit' });
64+
console.log(`Successfully published ${workspacePath}`);
65+
} catch (error) {
66+
console.error(`Failed to publish ${workspacePath}:`, error.message);
67+
process.exit(1);
68+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Synchronizes the version from root package.json to all workspace package.json files.
5+
* Used as a release-it hook after version bump.
6+
*/
7+
8+
const fs = require('fs');
9+
const path = require('path');
10+
11+
const rootPackagePath = path.join(__dirname, '..', 'package.json');
12+
const workspaces = ['proxy'];
13+
14+
try {
15+
const rootPackage = JSON.parse(fs.readFileSync(rootPackagePath, 'utf8'));
16+
const newVersion = rootPackage.version;
17+
18+
console.log(`Syncing version ${newVersion} to workspaces...`);
19+
20+
workspaces.forEach((workspace) => {
21+
const workspacePackagePath = path.join(__dirname, '..', workspace, 'package.json');
22+
23+
if (fs.existsSync(workspacePackagePath)) {
24+
const workspacePackage = JSON.parse(fs.readFileSync(workspacePackagePath, 'utf8'));
25+
const oldVersion = workspacePackage.version;
26+
27+
workspacePackage.version = newVersion;
28+
fs.writeFileSync(workspacePackagePath, JSON.stringify(workspacePackage, null, 2) + '\n');
29+
30+
console.log(` ${workspace}/package.json: ${oldVersion} -> ${newVersion}`);
31+
} else {
32+
console.warn(` Warning: ${workspacePackagePath} not found`);
33+
}
34+
});
35+
36+
console.log('Version sync complete.');
37+
} catch (error) {
38+
console.error('Error syncing versions:', error.message);
39+
process.exit(1);
40+
}

0 commit comments

Comments
 (0)