@fecommunity/reactpress 2.0.0-beta-4-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +122 -0
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/client/bin/reactpress-client.js +190 -0
- package/package.json +92 -0
- package/scripts/reactpress-cli.js +90 -0
- package/scripts/reactpress-deploy.sh +47 -0
- package/scripts/reactpress-dev.js +39 -0
- package/scripts/reactpress-publish.js +945 -0
- package/scripts/reactpress.js +90 -0
- package/server/bin/reactpress-server.js +203 -0
|
@@ -0,0 +1,945 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
const inquirer = require('inquirer');
|
|
8
|
+
const crypto = require('crypto');
|
|
9
|
+
|
|
10
|
+
// Package build order (dependencies first)
|
|
11
|
+
const packages = [
|
|
12
|
+
{
|
|
13
|
+
name: '@fecommunity/reactpress',
|
|
14
|
+
path: '.',
|
|
15
|
+
description: 'Main ReactPress package'
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: '@fecommunity/reactpress-server',
|
|
19
|
+
path: 'server',
|
|
20
|
+
description: 'Backend API server package'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: '@fecommunity/reactpress-client',
|
|
24
|
+
path: 'client',
|
|
25
|
+
description: 'Frontend application package'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: '@fecommunity/reactpress-toolkit',
|
|
29
|
+
path: 'toolkit',
|
|
30
|
+
description: 'API client and utilities toolkit'
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: '@fecommunity/reactpress-template-hello-world',
|
|
34
|
+
path: 'templates/hello-world',
|
|
35
|
+
description: 'Hello World template for ReactPress'
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: '@fecommunity/reactpress-template-twentytwentyfive',
|
|
39
|
+
path: 'templates/twentytwentyfive',
|
|
40
|
+
description: 'Twenty Twenty Five blog template for ReactPress'
|
|
41
|
+
}
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// Generate a hash for a file or directory
|
|
45
|
+
function generateHash(filePath) {
|
|
46
|
+
try {
|
|
47
|
+
if (fs.statSync(filePath).isDirectory()) {
|
|
48
|
+
const files = fs.readdirSync(filePath);
|
|
49
|
+
const hashes = files
|
|
50
|
+
.filter(file => !file.startsWith('.') && file !== 'node_modules' && file !== 'dist' && file !== '.next') // Ignore hidden files and build directories
|
|
51
|
+
.map(file => generateHash(path.join(filePath, file)))
|
|
52
|
+
.sort();
|
|
53
|
+
return crypto.createHash('md5').update(hashes.join('')).digest('hex');
|
|
54
|
+
} else {
|
|
55
|
+
const content = fs.readFileSync(filePath);
|
|
56
|
+
return crypto.createHash('md5').update(content).digest('hex');
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Get package content hash
|
|
64
|
+
function getPackageHash(packagePath) {
|
|
65
|
+
const fullPath = path.join(process.cwd(), packagePath);
|
|
66
|
+
return generateHash(fullPath);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check if package has meaningful changes (for build)
|
|
70
|
+
function hasMeaningfulChangesForBuild(packagePath, packageName) {
|
|
71
|
+
try {
|
|
72
|
+
// Create a hash file path to store previous hash in node_modules
|
|
73
|
+
const hashFilePath = path.join(process.cwd(), 'node_modules', '.build-cache', `${packageName.replace('/', '_')}.hash`);
|
|
74
|
+
|
|
75
|
+
// Generate current hash
|
|
76
|
+
const currentHash = getPackageHash(packagePath);
|
|
77
|
+
|
|
78
|
+
// Check if we have a previous hash
|
|
79
|
+
if (fs.existsSync(hashFilePath)) {
|
|
80
|
+
const previousHash = fs.readFileSync(hashFilePath, 'utf8').trim();
|
|
81
|
+
return currentHash !== previousHash;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// If no previous hash, consider it as having changes
|
|
85
|
+
return true;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.log(chalk.yellow(`ā ļø Could not check changes for ${packageName}, assuming changes exist`));
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Check if package has meaningful changes (for publish)
|
|
93
|
+
function hasMeaningfulChangesForPublish(packagePath, packageName) {
|
|
94
|
+
try {
|
|
95
|
+
// Create a hash file path to store previous hash in node_modules
|
|
96
|
+
const hashFilePath = path.join(process.cwd(), 'node_modules', '.publish-cache', `${packageName.replace('/', '_')}.hash`);
|
|
97
|
+
|
|
98
|
+
// Generate current hash
|
|
99
|
+
const currentHash = getPackageHash(packagePath);
|
|
100
|
+
|
|
101
|
+
// Check if we have a previous hash
|
|
102
|
+
if (fs.existsSync(hashFilePath)) {
|
|
103
|
+
const previousHash = fs.readFileSync(hashFilePath, 'utf8').trim();
|
|
104
|
+
return currentHash !== previousHash;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// If no previous hash, consider it as having changes
|
|
108
|
+
return true;
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.log(chalk.yellow(`ā ļø Could not check changes for ${packageName}, assuming changes exist`));
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Save package hash (for build)
|
|
116
|
+
function savePackageHashForBuild(packagePath, packageName) {
|
|
117
|
+
try {
|
|
118
|
+
const hashFilePath = path.join(process.cwd(), 'node_modules', '.build-cache', `${packageName.replace('/', '_')}.hash`);
|
|
119
|
+
|
|
120
|
+
// Ensure cache directory exists
|
|
121
|
+
const cacheDir = path.dirname(hashFilePath);
|
|
122
|
+
if (!fs.existsSync(cacheDir)) {
|
|
123
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Generate and save current hash
|
|
127
|
+
const currentHash = getPackageHash(packagePath);
|
|
128
|
+
fs.writeFileSync(hashFilePath, currentHash);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.log(chalk.yellow(`ā ļø Could not save hash for ${packageName}`));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Save package hash (for publish)
|
|
135
|
+
function savePackageHashForPublish(packagePath, packageName) {
|
|
136
|
+
try {
|
|
137
|
+
const hashFilePath = path.join(process.cwd(), 'node_modules', '.publish-cache', `${packageName.replace('/', '_')}.hash`);
|
|
138
|
+
|
|
139
|
+
// Ensure cache directory exists
|
|
140
|
+
const cacheDir = path.dirname(hashFilePath);
|
|
141
|
+
if (!fs.existsSync(cacheDir)) {
|
|
142
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Generate and save current hash
|
|
146
|
+
const currentHash = getPackageHash(packagePath);
|
|
147
|
+
fs.writeFileSync(hashFilePath, currentHash);
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.log(chalk.yellow(`ā ļø Could not save hash for ${packageName}`));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Get current versions
|
|
154
|
+
function getCurrentVersion(packagePath) {
|
|
155
|
+
try {
|
|
156
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
157
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
158
|
+
return pkg.version;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
return 'unknown';
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Increment version based on type
|
|
165
|
+
function incrementVersion(version, type) {
|
|
166
|
+
const parts = version.split('-')[0].split('.');
|
|
167
|
+
const major = parseInt(parts[0]);
|
|
168
|
+
const minor = parseInt(parts[1]);
|
|
169
|
+
const patch = parseInt(parts[2]);
|
|
170
|
+
|
|
171
|
+
switch (type) {
|
|
172
|
+
case 'major':
|
|
173
|
+
return `${major + 1}.0.0`;
|
|
174
|
+
case 'minor':
|
|
175
|
+
return `${major}.${minor + 1}.0`;
|
|
176
|
+
case 'patch':
|
|
177
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
178
|
+
case 'beta':
|
|
179
|
+
// For beta, we increment the beta number or add beta.1 if not present
|
|
180
|
+
const match = version.match(/^(.*)-beta\.(\d+)$/);
|
|
181
|
+
if (match) {
|
|
182
|
+
const baseVersion = match[1];
|
|
183
|
+
const betaNumber = parseInt(match[2]);
|
|
184
|
+
return `${baseVersion}-beta.${betaNumber + 1}`;
|
|
185
|
+
} else {
|
|
186
|
+
// If no beta version exists, add beta.1
|
|
187
|
+
return `${version}-beta.1`;
|
|
188
|
+
}
|
|
189
|
+
case 'alpha':
|
|
190
|
+
// For alpha, we increment the alpha number or add alpha.1 if not present
|
|
191
|
+
const alphaMatch = version.match(/^(.*)-alpha\.(\d+)$/);
|
|
192
|
+
if (alphaMatch) {
|
|
193
|
+
const baseVersion = alphaMatch[1];
|
|
194
|
+
const alphaNumber = parseInt(alphaMatch[2]);
|
|
195
|
+
return `${baseVersion}-alpha.${alphaNumber + 1}`;
|
|
196
|
+
} else {
|
|
197
|
+
// If no alpha version exists, add alpha.1
|
|
198
|
+
return `${version}-alpha.1`;
|
|
199
|
+
}
|
|
200
|
+
default:
|
|
201
|
+
return version;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Get next available version from npm registry
|
|
206
|
+
function getNextAvailableVersion(packageName, currentVersion, versionType) {
|
|
207
|
+
try {
|
|
208
|
+
// First, increment the version locally
|
|
209
|
+
let nextVersion = incrementVersion(currentVersion, versionType);
|
|
210
|
+
|
|
211
|
+
// Check if this version already exists on npm
|
|
212
|
+
let versionExists = true;
|
|
213
|
+
let attempts = 0;
|
|
214
|
+
const maxAttempts = 100; // Prevent infinite loop
|
|
215
|
+
|
|
216
|
+
while (versionExists && attempts < maxAttempts) {
|
|
217
|
+
try {
|
|
218
|
+
execSync(`npm view ${packageName}@${nextVersion} version`, { stdio: 'ignore' });
|
|
219
|
+
// If we get here, the version exists, so we need to increment again
|
|
220
|
+
nextVersion = incrementVersion(nextVersion, versionType);
|
|
221
|
+
attempts++;
|
|
222
|
+
} catch (error) {
|
|
223
|
+
// If we get an error, the version doesn't exist, which is what we want
|
|
224
|
+
versionExists = false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (attempts >= maxAttempts) {
|
|
229
|
+
throw new Error('Too many attempts to find available version');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return nextVersion;
|
|
233
|
+
} catch (error) {
|
|
234
|
+
// Fallback to simple increment if npm view fails
|
|
235
|
+
console.log(chalk.yellow(`ā ļø Could not check npm registry, using local increment for ${packageName}`));
|
|
236
|
+
return incrementVersion(currentVersion, versionType);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Update package version
|
|
241
|
+
function updateVersion(packagePath, newVersion) {
|
|
242
|
+
console.log(chalk.blue(`\nāļø Updating version to ${newVersion}...`));
|
|
243
|
+
|
|
244
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
245
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
246
|
+
|
|
247
|
+
const oldVersion = pkg.version;
|
|
248
|
+
pkg.version = newVersion;
|
|
249
|
+
|
|
250
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
251
|
+
console.log(chalk.green(`ā
Version updated from ${oldVersion} to ${newVersion}`));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Fix workspace dependencies for build
|
|
255
|
+
function fixWorkspaceDependenciesForBuild(packagePath) {
|
|
256
|
+
console.log(chalk.blue(`š§ Fixing workspace dependencies for build: ${packagePath}...`));
|
|
257
|
+
|
|
258
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
259
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
260
|
+
|
|
261
|
+
// Fix dependencies
|
|
262
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
263
|
+
|
|
264
|
+
depTypes.forEach(depType => {
|
|
265
|
+
if (pkg[depType]) {
|
|
266
|
+
Object.keys(pkg[depType]).forEach(depName => {
|
|
267
|
+
// Check if it's a workspace dependency
|
|
268
|
+
if (pkg[depType][depName] === 'workspace:*' || pkg[depType][depName].startsWith('workspace:')) {
|
|
269
|
+
// For build purposes, we'll use the file: protocol to reference local packages
|
|
270
|
+
const depPackage = packages.find(p => p.name === depName);
|
|
271
|
+
if (depPackage) {
|
|
272
|
+
console.log(chalk.gray(` Replacing ${depName} workspace dependency with file reference`));
|
|
273
|
+
pkg[depType][depName] = `file:../${depPackage.path}`;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Write the updated package.json
|
|
281
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
282
|
+
console.log(chalk.green(`ā
Workspace dependencies fixed for build: ${packagePath}`));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Restore workspace dependencies after build
|
|
286
|
+
function restoreWorkspaceDependenciesAfterBuild(packagePath) {
|
|
287
|
+
console.log(chalk.blue(`š Restoring workspace dependencies after build: ${packagePath}...`));
|
|
288
|
+
|
|
289
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
290
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
291
|
+
|
|
292
|
+
// Restore dependencies
|
|
293
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
294
|
+
|
|
295
|
+
depTypes.forEach(depType => {
|
|
296
|
+
if (pkg[depType]) {
|
|
297
|
+
Object.keys(pkg[depType]).forEach(depName => {
|
|
298
|
+
// Check if this is one of our internal packages referenced with file:
|
|
299
|
+
const depPackage = packages.find(p => p.name === depName);
|
|
300
|
+
if (depPackage && pkg[depType][depName].startsWith('file:')) {
|
|
301
|
+
console.log(chalk.gray(` Restoring ${depName} to workspace dependency`));
|
|
302
|
+
pkg[depType][depName] = 'workspace:*';
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
// Write the updated package.json
|
|
309
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
310
|
+
console.log(chalk.green(`ā
Workspace dependencies restored after build: ${packagePath}`));
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Fix workspace dependencies for publish
|
|
314
|
+
function fixWorkspaceDependenciesForPublish(packagePath, packageVersions) {
|
|
315
|
+
console.log(chalk.blue(`š§ Fixing workspace dependencies for publish: ${packagePath}...`));
|
|
316
|
+
|
|
317
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
318
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
319
|
+
|
|
320
|
+
// Fix dependencies
|
|
321
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
322
|
+
|
|
323
|
+
depTypes.forEach(depType => {
|
|
324
|
+
if (pkg[depType]) {
|
|
325
|
+
Object.keys(pkg[depType]).forEach(depName => {
|
|
326
|
+
// Check if it's a workspace dependency
|
|
327
|
+
if (pkg[depType][depName] === 'workspace:*' || pkg[depType][depName].startsWith('workspace:')) {
|
|
328
|
+
// Replace with actual version
|
|
329
|
+
const depPackage = packages.find(p => p.name === depName);
|
|
330
|
+
if (depPackage && packageVersions[depName]) {
|
|
331
|
+
console.log(chalk.gray(` Replacing ${depName} workspace dependency with version ${packageVersions[depName]}`));
|
|
332
|
+
pkg[depType][depName] = packageVersions[depName];
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// Write the updated package.json
|
|
340
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
341
|
+
console.log(chalk.green(`ā
Workspace dependencies fixed for publish: ${packagePath}`));
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Restore workspace dependencies after publish
|
|
345
|
+
function restoreWorkspaceDependenciesAfterPublish(packagePath) {
|
|
346
|
+
console.log(chalk.blue(`š Restoring workspace dependencies for ${packagePath}...`));
|
|
347
|
+
|
|
348
|
+
const pkgPath = path.join(process.cwd(), packagePath, 'package.json');
|
|
349
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
350
|
+
|
|
351
|
+
// Restore dependencies
|
|
352
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies'];
|
|
353
|
+
|
|
354
|
+
depTypes.forEach(depType => {
|
|
355
|
+
if (pkg[depType]) {
|
|
356
|
+
Object.keys(pkg[depType]).forEach(depName => {
|
|
357
|
+
// Check if this is one of our internal packages
|
|
358
|
+
const depPackage = packages.find(p => p.name === depName);
|
|
359
|
+
if (depPackage) {
|
|
360
|
+
console.log(chalk.gray(` Restoring ${depName} to workspace dependency`));
|
|
361
|
+
pkg[depType][depName] = 'workspace:*';
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
// Write the updated package.json
|
|
368
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
|
|
369
|
+
console.log(chalk.green(`ā
Workspace dependencies restored for ${packagePath}`));
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Build package
|
|
373
|
+
function buildPackage(pkg) {
|
|
374
|
+
console.log(chalk.blue(`\nšØ Building ${pkg.name} (${pkg.description})...`));
|
|
375
|
+
|
|
376
|
+
try {
|
|
377
|
+
// Fix workspace dependencies for build
|
|
378
|
+
fixWorkspaceDependenciesForBuild(pkg.path);
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
if (pkg.path === 'config') {
|
|
382
|
+
execSync('pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
383
|
+
} else if (pkg.path === 'server') {
|
|
384
|
+
execSync('pnpm run prebuild && pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
385
|
+
} else if (pkg.path === 'client') {
|
|
386
|
+
execSync('pnpm run prebuild && pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
387
|
+
} else if (pkg.path === 'toolkit') {
|
|
388
|
+
execSync('pnpm run build', { cwd: path.join(process.cwd(), pkg.path), stdio: 'inherit' });
|
|
389
|
+
} else if (pkg.path === 'templates/hello-world' || pkg.path === 'templates/twentytwentyfive') {
|
|
390
|
+
// Templates don't need to be built, just validate package.json
|
|
391
|
+
console.log(chalk.gray(' Templates do not require building, skipping...'));
|
|
392
|
+
}
|
|
393
|
+
console.log(chalk.green(`ā
${pkg.name} built successfully`));
|
|
394
|
+
} finally {
|
|
395
|
+
// Always restore workspace dependencies
|
|
396
|
+
restoreWorkspaceDependenciesAfterBuild(pkg.path);
|
|
397
|
+
}
|
|
398
|
+
} catch (error) {
|
|
399
|
+
console.log(chalk.red(`ā Failed to build ${pkg.name}`));
|
|
400
|
+
throw error;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Publish package
|
|
405
|
+
function publishPackage(packagePath, packageName, tag = 'latest') {
|
|
406
|
+
console.log(chalk.blue(`\nš Publishing ${packageName} with tag ${tag}...`));
|
|
407
|
+
|
|
408
|
+
try {
|
|
409
|
+
const command = `pnpm publish --access public --tag ${tag} --registry https://registry.npmjs.org --no-git-checks`;
|
|
410
|
+
execSync(command, { cwd: path.join(process.cwd(), packagePath), stdio: 'inherit' });
|
|
411
|
+
console.log(chalk.green(`ā
${packageName} published successfully!`));
|
|
412
|
+
} catch (error) {
|
|
413
|
+
console.log(chalk.red(`ā Failed to publish ${packageName}`));
|
|
414
|
+
throw error;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Create GitHub release
|
|
419
|
+
function createGitHubRelease(tagName, releaseNotes) {
|
|
420
|
+
console.log(chalk.blue(`\nš Creating GitHub release ${tagName}...`));
|
|
421
|
+
|
|
422
|
+
try {
|
|
423
|
+
// Create release using GitHub CLI if available
|
|
424
|
+
const command = `gh release create ${tagName} --title "${tagName}" --notes "${releaseNotes}"`;
|
|
425
|
+
execSync(command, { stdio: 'inherit' });
|
|
426
|
+
console.log(chalk.green(`ā
GitHub release ${tagName} created successfully!`));
|
|
427
|
+
} catch (error) {
|
|
428
|
+
console.log(chalk.yellow(`ā ļø Failed to create GitHub release (GitHub CLI may not be installed or configured)`));
|
|
429
|
+
console.log(chalk.gray('You can manually create the release at: https://github.com/fecommunity/reactpress/releases/new'));
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// Check environment
|
|
434
|
+
function checkEnvironment() {
|
|
435
|
+
// Check if pnpm is installed
|
|
436
|
+
try {
|
|
437
|
+
execSync('pnpm --version', { stdio: 'ignore' });
|
|
438
|
+
} catch (error) {
|
|
439
|
+
console.log(chalk.red('ā pnpm is not installed. Please install pnpm first.'));
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Check if logged in to npm
|
|
444
|
+
try {
|
|
445
|
+
execSync('pnpm whoami --registry https://registry.npmjs.org', { stdio: 'ignore' });
|
|
446
|
+
} catch (error) {
|
|
447
|
+
console.log(chalk.red('ā Not logged in to npm. Please run "pnpm login --registry https://registry.npmjs.org" first.'));
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
return true;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Build packages function
|
|
455
|
+
async function buildPackages() {
|
|
456
|
+
console.log(chalk.blue('šļø ReactPress Package Builder\n'));
|
|
457
|
+
|
|
458
|
+
// Show current versions
|
|
459
|
+
console.log(chalk.cyan('š Current package versions:'));
|
|
460
|
+
packages.forEach(pkg => {
|
|
461
|
+
const version = getCurrentVersion(pkg.path);
|
|
462
|
+
console.log(chalk.gray(` ${pkg.name}: ${version}`));
|
|
463
|
+
});
|
|
464
|
+
console.log();
|
|
465
|
+
|
|
466
|
+
try {
|
|
467
|
+
// Track which packages actually need to be built
|
|
468
|
+
const packagesToBuild = [];
|
|
469
|
+
|
|
470
|
+
// Check for meaningful changes in each package
|
|
471
|
+
for (const pkg of packages) {
|
|
472
|
+
if (fs.existsSync(path.join(process.cwd(), pkg.path))) {
|
|
473
|
+
if (hasMeaningfulChangesForBuild(pkg.path, pkg.name)) {
|
|
474
|
+
packagesToBuild.push(pkg);
|
|
475
|
+
console.log(chalk.blue(`\nš¦ ${pkg.name} has changes, will be built`));
|
|
476
|
+
} else {
|
|
477
|
+
console.log(chalk.gray(`\nāļø ${pkg.name} has no meaningful changes, skipping...`));
|
|
478
|
+
}
|
|
479
|
+
} else {
|
|
480
|
+
console.log(chalk.yellow(`ā ļø Package ${pkg.name} directory not found, skipping...`));
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (packagesToBuild.length === 0) {
|
|
485
|
+
console.log(chalk.green('\nā
No packages have meaningful changes. Nothing to build!'));
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// Build packages that have changes
|
|
490
|
+
for (const pkg of packagesToBuild) {
|
|
491
|
+
await buildPackage(pkg);
|
|
492
|
+
// Save the hash after successful build
|
|
493
|
+
savePackageHashForBuild(pkg.path, pkg.name);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
console.log(chalk.green(`\nš ${packagesToBuild.length} package(s) built successfully!`));
|
|
497
|
+
} catch (error) {
|
|
498
|
+
console.error(chalk.red('ā Build failed:'), error);
|
|
499
|
+
process.exit(1);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Publish packages function
|
|
504
|
+
async function publishPackages() {
|
|
505
|
+
// Check if called with --no-build flag
|
|
506
|
+
const noBuild = process.argv.includes('--no-build');
|
|
507
|
+
|
|
508
|
+
console.log(chalk.blue('š¦ ReactPress Package Publisher\n'));
|
|
509
|
+
|
|
510
|
+
// Run environment checks
|
|
511
|
+
if (!checkEnvironment()) {
|
|
512
|
+
process.exit(1);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Show current versions
|
|
516
|
+
console.log(chalk.cyan('š Current package versions:'));
|
|
517
|
+
packages.forEach(pkg => {
|
|
518
|
+
const version = getCurrentVersion(pkg.path);
|
|
519
|
+
console.log(chalk.gray(` ${pkg.name}: ${version}`));
|
|
520
|
+
});
|
|
521
|
+
console.log();
|
|
522
|
+
|
|
523
|
+
// Ask for publishing options
|
|
524
|
+
const { action } = await inquirer.prompt([
|
|
525
|
+
{
|
|
526
|
+
type: 'list',
|
|
527
|
+
name: 'action',
|
|
528
|
+
message: 'What would you like to do?',
|
|
529
|
+
choices: [
|
|
530
|
+
{ name: 'š Publish all packages with version bump', value: 'publish-all' },
|
|
531
|
+
{ name: 'š¦ Publish specific package', value: 'publish-one' },
|
|
532
|
+
{ name: 'šØ Build all packages only', value: 'build-all' },
|
|
533
|
+
{ name: 'š·ļø Publish as beta/alpha', value: 'publish-prerelease' },
|
|
534
|
+
{ name: 'ā Cancel', value: 'cancel' }
|
|
535
|
+
]
|
|
536
|
+
}
|
|
537
|
+
]);
|
|
538
|
+
|
|
539
|
+
if (action === 'cancel') {
|
|
540
|
+
console.log(chalk.yellow('Operation cancelled.'));
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
if (action === 'build-all') {
|
|
545
|
+
console.log(chalk.blue('šØ Building all packages...\n'));
|
|
546
|
+
|
|
547
|
+
// Track which packages actually need to be built
|
|
548
|
+
const packagesToBuild = [];
|
|
549
|
+
|
|
550
|
+
// Check for meaningful changes in each package
|
|
551
|
+
for (const pkg of packages) {
|
|
552
|
+
if (fs.existsSync(path.join(process.cwd(), pkg.path))) {
|
|
553
|
+
if (hasMeaningfulChangesForPublish(pkg.path, pkg.name)) {
|
|
554
|
+
packagesToBuild.push(pkg);
|
|
555
|
+
console.log(chalk.blue(`\nš¦ ${pkg.name} has changes, will be built`));
|
|
556
|
+
} else {
|
|
557
|
+
console.log(chalk.gray(`\nāļø ${pkg.name} has no meaningful changes, skipping...`));
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
console.log(chalk.yellow(`ā ļø Package ${pkg.name} directory not found, skipping...`));
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (packagesToBuild.length === 0) {
|
|
565
|
+
console.log(chalk.green('\nā
No packages have meaningful changes. Nothing to build!'));
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// Build packages that have changes
|
|
570
|
+
for (const pkg of packagesToBuild) {
|
|
571
|
+
buildPackage(pkg);
|
|
572
|
+
// Save the hash after successful build
|
|
573
|
+
savePackageHashForPublish(pkg.path, pkg.name);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
console.log(chalk.green(`\nš ${packagesToBuild.length} package(s) built successfully!`));
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (action === 'publish-one') {
|
|
581
|
+
const { selectedPackage } = await inquirer.prompt([
|
|
582
|
+
{
|
|
583
|
+
type: 'list',
|
|
584
|
+
name: 'selectedPackage',
|
|
585
|
+
message: 'Which package would you like to publish?',
|
|
586
|
+
choices: packages.map(pkg => ({
|
|
587
|
+
name: `${pkg.name} (${pkg.description})`,
|
|
588
|
+
value: pkg
|
|
589
|
+
}))
|
|
590
|
+
}
|
|
591
|
+
]);
|
|
592
|
+
|
|
593
|
+
// Check if the selected package has meaningful changes
|
|
594
|
+
if (!hasMeaningfulChangesForPublish(selectedPackage.path, selectedPackage.name)) {
|
|
595
|
+
console.log(chalk.gray(`\nāļø ${selectedPackage.name} has no meaningful changes, skipping...`));
|
|
596
|
+
console.log(chalk.green('ā
Nothing to publish!'));
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
const { versionType } = await inquirer.prompt([
|
|
601
|
+
{
|
|
602
|
+
type: 'list',
|
|
603
|
+
name: 'versionType',
|
|
604
|
+
message: 'Version bump type:',
|
|
605
|
+
choices: [
|
|
606
|
+
{ name: 'Beta (1.0.0-beta.1 -> 1.0.0-beta.2)', value: 'beta' },
|
|
607
|
+
{ name: 'Patch (1.0.0 -> 1.0.1)', value: 'patch' },
|
|
608
|
+
{ name: 'Minor (1.0.0 -> 1.1.0)', value: 'minor' },
|
|
609
|
+
{ name: 'Major (1.0.0 -> 2.0.0)', value: 'major' },
|
|
610
|
+
{ name: 'Custom version', value: 'custom' }
|
|
611
|
+
]
|
|
612
|
+
}
|
|
613
|
+
]);
|
|
614
|
+
|
|
615
|
+
let newVersion;
|
|
616
|
+
const currentVersion = getCurrentVersion(selectedPackage.path);
|
|
617
|
+
|
|
618
|
+
if (versionType === 'custom') {
|
|
619
|
+
const { customVersion } = await inquirer.prompt([
|
|
620
|
+
{
|
|
621
|
+
type: 'input',
|
|
622
|
+
name: 'customVersion',
|
|
623
|
+
message: `Enter new version for ${selectedPackage.name} (current: ${currentVersion}):`,
|
|
624
|
+
validate: (input) => {
|
|
625
|
+
const semverRegex = /^\d+\.\d+\.\d+(-[a-zA-Z0-9.-]+)?$/;
|
|
626
|
+
return semverRegex.test(input) || 'Please enter a valid semver version (e.g., 1.0.0)';
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
]);
|
|
630
|
+
newVersion = customVersion;
|
|
631
|
+
} else {
|
|
632
|
+
newVersion = getNextAvailableVersion(selectedPackage.name, currentVersion, versionType);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Get all package versions for dependency resolution
|
|
636
|
+
const packageVersions = {};
|
|
637
|
+
packages.forEach(pkg => {
|
|
638
|
+
packageVersions[pkg.name] = getCurrentVersion(pkg.path);
|
|
639
|
+
});
|
|
640
|
+
// Update the selected package version
|
|
641
|
+
packageVersions[selectedPackage.name] = newVersion;
|
|
642
|
+
|
|
643
|
+
// Fix workspace dependencies before publishing
|
|
644
|
+
fixWorkspaceDependenciesForPublish(selectedPackage.path, packageVersions);
|
|
645
|
+
|
|
646
|
+
try {
|
|
647
|
+
updateVersion(selectedPackage.path, newVersion);
|
|
648
|
+
// Only build if not disabled
|
|
649
|
+
if (!noBuild) {
|
|
650
|
+
buildPackage(selectedPackage);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// Determine tag based on version type
|
|
654
|
+
const tag = versionType === 'beta' ? 'beta' : 'latest';
|
|
655
|
+
publishPackage(selectedPackage.path, selectedPackage.name, tag);
|
|
656
|
+
|
|
657
|
+
// Save the hash after successful publish
|
|
658
|
+
savePackageHashForPublish(selectedPackage.path, selectedPackage.name);
|
|
659
|
+
|
|
660
|
+
console.log(chalk.green(`\nš ${selectedPackage.name} v${newVersion} published successfully!`));
|
|
661
|
+
} finally {
|
|
662
|
+
// Always restore workspace dependencies
|
|
663
|
+
restoreWorkspaceDependenciesAfterPublish(selectedPackage.path);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (action === 'publish-prerelease') {
|
|
670
|
+
const { tag } = await inquirer.prompt([
|
|
671
|
+
{
|
|
672
|
+
type: 'list',
|
|
673
|
+
name: 'tag',
|
|
674
|
+
message: 'Select prerelease tag:',
|
|
675
|
+
choices: ['beta', 'alpha', 'rc', 'next']
|
|
676
|
+
}
|
|
677
|
+
]);
|
|
678
|
+
|
|
679
|
+
const { versionType } = await inquirer.prompt([
|
|
680
|
+
{
|
|
681
|
+
type: 'list',
|
|
682
|
+
name: 'versionType',
|
|
683
|
+
message: 'Version bump type:',
|
|
684
|
+
choices: [
|
|
685
|
+
{ name: `Prerelease (${tag})`, value: tag },
|
|
686
|
+
{ name: 'Patch (1.0.0 -> 1.0.1)', value: 'patch' },
|
|
687
|
+
{ name: 'Minor (1.0.0 -> 1.1.0)', value: 'minor' },
|
|
688
|
+
{ name: 'Major (1.0.0 -> 2.0.0)', value: 'major' },
|
|
689
|
+
{ name: 'Custom version', value: 'custom' }
|
|
690
|
+
]
|
|
691
|
+
}
|
|
692
|
+
]);
|
|
693
|
+
|
|
694
|
+
// Get all package versions for dependency resolution
|
|
695
|
+
const packageVersions = {};
|
|
696
|
+
packages.forEach(pkg => {
|
|
697
|
+
const currentVersion = getCurrentVersion(pkg.path);
|
|
698
|
+
packageVersions[pkg.name] = currentVersion;
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
// Track which packages actually need to be published
|
|
702
|
+
const packagesToPublish = [];
|
|
703
|
+
|
|
704
|
+
// Check for meaningful changes in each package
|
|
705
|
+
for (const pkg of packages) {
|
|
706
|
+
if (!fs.existsSync(path.join(process.cwd(), pkg.path))) {
|
|
707
|
+
console.log(chalk.yellow(`ā ļø Package ${pkg.name} directory not found, skipping...`));
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
if (hasMeaningfulChangesForPublish(pkg.path, pkg.name)) {
|
|
712
|
+
packagesToPublish.push(pkg);
|
|
713
|
+
console.log(chalk.blue(`\nš¦ ${pkg.name} has changes, will be published`));
|
|
714
|
+
} else {
|
|
715
|
+
console.log(chalk.gray(`\nāļø ${pkg.name} has no meaningful changes, skipping...`));
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
if (packagesToPublish.length === 0) {
|
|
720
|
+
console.log(chalk.green('\nā
No packages have meaningful changes. Nothing to publish!'));
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
// Process each package that has changes
|
|
725
|
+
for (const pkg of packagesToPublish) {
|
|
726
|
+
let newVersion;
|
|
727
|
+
const currentVersion = getCurrentVersion(pkg.path);
|
|
728
|
+
|
|
729
|
+
if (versionType === 'custom') {
|
|
730
|
+
const { customVersion } = await inquirer.prompt([
|
|
731
|
+
{
|
|
732
|
+
type: 'input',
|
|
733
|
+
name: 'customVersion',
|
|
734
|
+
message: `Enter version for ${pkg.name} (current: ${currentVersion}):`,
|
|
735
|
+
default: currentVersion
|
|
736
|
+
}
|
|
737
|
+
]);
|
|
738
|
+
newVersion = customVersion;
|
|
739
|
+
} else {
|
|
740
|
+
newVersion = getNextAvailableVersion(pkg.name, currentVersion, versionType);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// Update package version in our tracking
|
|
744
|
+
packageVersions[pkg.name] = newVersion;
|
|
745
|
+
|
|
746
|
+
// Fix workspace dependencies before publishing
|
|
747
|
+
fixWorkspaceDependenciesForPublish(pkg.path, packageVersions);
|
|
748
|
+
|
|
749
|
+
try {
|
|
750
|
+
updateVersion(pkg.path, newVersion);
|
|
751
|
+
// Only build if not disabled
|
|
752
|
+
if (!noBuild) {
|
|
753
|
+
buildPackage(pkg);
|
|
754
|
+
}
|
|
755
|
+
publishPackage(pkg.path, pkg.name, tag);
|
|
756
|
+
|
|
757
|
+
// Save the hash after successful publish
|
|
758
|
+
savePackageHashForPublish(pkg.path, pkg.name);
|
|
759
|
+
} finally {
|
|
760
|
+
// Always restore workspace dependencies
|
|
761
|
+
restoreWorkspaceDependenciesAfterPublish(pkg.path);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
console.log(chalk.green(`\nš ${packagesToPublish.length} package(s) published with ${tag} tag!`));
|
|
766
|
+
return;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
if (action === 'publish-all') {
|
|
770
|
+
// Check if we're on master branch for final release
|
|
771
|
+
let isMasterBranch = false;
|
|
772
|
+
try {
|
|
773
|
+
const branch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();
|
|
774
|
+
isMasterBranch = branch === 'master' || branch === 'main';
|
|
775
|
+
} catch (error) {
|
|
776
|
+
console.log(chalk.yellow('ā ļø Unable to determine current branch'));
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const { versionType } = await inquirer.prompt([
|
|
780
|
+
{
|
|
781
|
+
type: 'list',
|
|
782
|
+
name: 'versionType',
|
|
783
|
+
message: 'Version bump type:',
|
|
784
|
+
choices: [
|
|
785
|
+
{ name: `Beta ${isMasterBranch ? '(will publish as final)' : '(will publish as beta)'}`, value: 'beta' },
|
|
786
|
+
{ name: 'Patch (1.0.0 -> 1.0.1)', value: 'patch' },
|
|
787
|
+
{ name: 'Minor (1.0.0 -> 1.1.0)', value: 'minor' },
|
|
788
|
+
{ name: 'Major (1.0.0 -> 2.0.0)', value: 'major' },
|
|
789
|
+
{ name: 'Custom version', value: 'custom' }
|
|
790
|
+
]
|
|
791
|
+
}
|
|
792
|
+
]);
|
|
793
|
+
|
|
794
|
+
// Get all package versions for dependency resolution
|
|
795
|
+
const packageVersions = {};
|
|
796
|
+
const originalVersions = {};
|
|
797
|
+
|
|
798
|
+
packages.forEach(pkg => {
|
|
799
|
+
const currentVersion = getCurrentVersion(pkg.path);
|
|
800
|
+
originalVersions[pkg.name] = currentVersion;
|
|
801
|
+
packageVersions[pkg.name] = currentVersion;
|
|
802
|
+
});
|
|
803
|
+
|
|
804
|
+
let baseVersion;
|
|
805
|
+
if (versionType === 'custom') {
|
|
806
|
+
const { customVersion } = await inquirer.prompt([
|
|
807
|
+
{
|
|
808
|
+
type: 'input',
|
|
809
|
+
name: 'customVersion',
|
|
810
|
+
message: 'Enter new version for all packages:',
|
|
811
|
+
validate: (input) => {
|
|
812
|
+
const semverRegex = /^\d+\.\d+\.\d+$/;
|
|
813
|
+
return semverRegex.test(input) || 'Please enter a valid semver version (e.g., 1.0.0)';
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
]);
|
|
817
|
+
baseVersion = customVersion;
|
|
818
|
+
} else {
|
|
819
|
+
// Use the highest current version as base and increment
|
|
820
|
+
const nextVersion = getNextAvailableVersion(packages[0].name, originalVersions[packages[0].name], versionType);
|
|
821
|
+
baseVersion = nextVersion;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
console.log(chalk.cyan(`\nš Will publish all packages with version: ${baseVersion}\n`));
|
|
825
|
+
|
|
826
|
+
const { confirm } = await inquirer.prompt([
|
|
827
|
+
{
|
|
828
|
+
type: 'confirm',
|
|
829
|
+
name: 'confirm',
|
|
830
|
+
message: 'Are you sure you want to proceed?',
|
|
831
|
+
default: false
|
|
832
|
+
}
|
|
833
|
+
]);
|
|
834
|
+
|
|
835
|
+
if (!confirm) {
|
|
836
|
+
console.log(chalk.yellow('Operation cancelled.'));
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
// Track which packages actually need to be published
|
|
841
|
+
const packagesToPublish = [];
|
|
842
|
+
|
|
843
|
+
// Check for meaningful changes in each package
|
|
844
|
+
for (const pkg of packages) {
|
|
845
|
+
if (!fs.existsSync(path.join(process.cwd(), pkg.path))) {
|
|
846
|
+
console.log(chalk.yellow(`ā ļø Package ${pkg.name} directory not found, skipping...`));
|
|
847
|
+
continue;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
if (hasMeaningfulChangesForPublish(pkg.path, pkg.name)) {
|
|
851
|
+
packagesToPublish.push(pkg);
|
|
852
|
+
console.log(chalk.blue(`\nš¦ ${pkg.name} has changes, will be published`));
|
|
853
|
+
} else {
|
|
854
|
+
console.log(chalk.gray(`\nāļø ${pkg.name} has no meaningful changes, skipping...`));
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
if (packagesToPublish.length === 0) {
|
|
859
|
+
console.log(chalk.green('\nā
No packages have meaningful changes. Nothing to publish!'));
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// Update versions, build and publish only packages with changes
|
|
864
|
+
for (const pkg of packagesToPublish) {
|
|
865
|
+
console.log(chalk.blue(`\nš¦ Processing ${pkg.name}...`));
|
|
866
|
+
|
|
867
|
+
// For publish-all, we use the same version for all packages
|
|
868
|
+
const pkgVersion = baseVersion;
|
|
869
|
+
packageVersions[pkg.name] = pkgVersion;
|
|
870
|
+
|
|
871
|
+
// Fix workspace dependencies before publishing
|
|
872
|
+
fixWorkspaceDependenciesForPublish(pkg.path, packageVersions);
|
|
873
|
+
|
|
874
|
+
try {
|
|
875
|
+
updateVersion(pkg.path, pkgVersion);
|
|
876
|
+
// Only build if not disabled
|
|
877
|
+
if (!noBuild) {
|
|
878
|
+
buildPackage(pkg);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// Determine tag based on version type and branch
|
|
882
|
+
const tag = (versionType === 'beta' && !isMasterBranch) ? 'beta' : 'latest';
|
|
883
|
+
publishPackage(pkg.path, pkg.name, tag);
|
|
884
|
+
|
|
885
|
+
// Save the hash after successful publish
|
|
886
|
+
savePackageHashForPublish(pkg.path, pkg.name);
|
|
887
|
+
} finally {
|
|
888
|
+
// Always restore workspace dependencies
|
|
889
|
+
restoreWorkspaceDependenciesAfterPublish(pkg.path);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
// Create GitHub release if on master and we actually published something
|
|
894
|
+
if (isMasterBranch && packagesToPublish.length > 0) {
|
|
895
|
+
const tagName = `v${baseVersion}`;
|
|
896
|
+
const releaseNotes = `Release ${baseVersion}
|
|
897
|
+
|
|
898
|
+
Packages released:
|
|
899
|
+
${Object.entries(packageVersions).map(([name, version]) => `- ${name}@${version}`).join('\n')}`;
|
|
900
|
+
createGitHubRelease(tagName, releaseNotes);
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
console.log(chalk.green(`\nš ${packagesToPublish.length} package(s) published successfully with version ${baseVersion}!`));
|
|
904
|
+
console.log(chalk.cyan('\nš Next steps:'));
|
|
905
|
+
console.log(chalk.gray('1. Create a git tag: git tag v' + baseVersion));
|
|
906
|
+
console.log(chalk.gray('2. Push changes: git push && git push --tags'));
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// Main function
|
|
911
|
+
async function main() {
|
|
912
|
+
// Check command line arguments
|
|
913
|
+
const args = process.argv.slice(2);
|
|
914
|
+
|
|
915
|
+
if (args.includes('--publish')) {
|
|
916
|
+
// When called with --publish, start the publish process
|
|
917
|
+
console.log(chalk.blue('šļø ReactPress Package Builder\n'));
|
|
918
|
+
|
|
919
|
+
// Show current versions
|
|
920
|
+
console.log(chalk.cyan('š Current package versions:'));
|
|
921
|
+
packages.forEach(pkg => {
|
|
922
|
+
const version = getCurrentVersion(pkg.path);
|
|
923
|
+
console.log(chalk.gray(` ${pkg.name}: ${version}`));
|
|
924
|
+
});
|
|
925
|
+
console.log();
|
|
926
|
+
|
|
927
|
+
// Start the publish process
|
|
928
|
+
await publishPackages();
|
|
929
|
+
} else if (args.includes('--build')) {
|
|
930
|
+
// When called with --build, just build packages
|
|
931
|
+
await buildPackages();
|
|
932
|
+
} else {
|
|
933
|
+
// Default behavior - show help
|
|
934
|
+
console.log(chalk.blue('šļø ReactPress CLI\n'));
|
|
935
|
+
console.log('Usage:');
|
|
936
|
+
console.log(' node scripts/reactpress-cli.js --build Build all packages');
|
|
937
|
+
console.log(' node scripts/reactpress-cli.js --publish Publish packages (interactive)');
|
|
938
|
+
console.log('');
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
main().catch(error => {
|
|
943
|
+
console.error(chalk.red('ā Operation failed:'), error);
|
|
944
|
+
process.exit(1);
|
|
945
|
+
});
|