-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrelease.js
More file actions
135 lines (115 loc) · 4.48 KB
/
release.js
File metadata and controls
135 lines (115 loc) · 4.48 KB
1
2
3
4
5
6
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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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
import { execSync } from 'child_process';
import { readFileSync } from 'fs';
import readline from 'readline/promises';
import { stdin as input, stdout as output } from 'process';
const rl = readline.createInterface({ input, output });
/**
* Platform-independent release script written in Node.js
*/
async function run() {
console.log('\x1b[36m%s\x1b[0m', '--- List Dock Release Assistant ---');
// 1. Check if there are uncommitted changes
try {
const status = execSync('git status --porcelain', { encoding: 'utf8' }).trim();
if (status) {
console.log('\x1b[31m%s\x1b[0m', 'Error: You have uncommitted changes. Please commit or stash them first.');
console.log(execSync('git status', { encoding: 'utf8' }));
process.exit(1);
}
} catch (error) {
console.error('Failed to check git status:', error.message);
process.exit(1);
}
// 2. Get current version info
const pkgPath = './package.json';
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
let currentVersion = pkg.version;
let latestTag = 'None';
try {
latestTag = execSync('git describe --tags --abbrev=0', {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'ignore']
}).trim();
} catch (e) {
// No tags found yet
}
const tagVersion = latestTag.replace(/^v/, '');
console.log('\x1b[90m%s\x1b[0m', `Current Package Version: v${currentVersion}`);
console.log('\x1b[90m%s\x1b[0m', `Latest Git Tag: ${latestTag}`);
// 3. Handle Version Mismatch
if (latestTag !== 'None' && currentVersion !== tagVersion) {
console.log('\x1b[33m%s\x1b[0m', 'VERSION MISMATCH DETECTED!');
console.log(`Package version (v${currentVersion}) does not match Git tag (${latestTag}).`);
console.log('\x1b[33m%s\x1b[0m', 'Which version should be used as the base for this release?');
console.log(`1) Use Package Version (v${currentVersion})`);
console.log(`2) Use Git Tag Version (${latestTag})`);
console.log('q) Quit');
const syncChoice = await rl.question('Choice: ');
if (syncChoice === '2') {
console.log('\x1b[36m%s\x1b[0m', `Syncing package.json to match Git tag (${latestTag})...`);
execSync(`pnpm version ${tagVersion} --no-git-tag-version --allow-same-version`, { stdio: 'inherit' });
currentVersion = tagVersion;
} else if (syncChoice === 'q') {
console.log('Cancelled.');
process.exit(0);
} else {
console.log('\x1b[90m%s\x1b[0m', 'Proceeding with Package Version as base.');
}
}
// 4. Ask for release type
console.log('\n\x1b[33m%s\x1b[0m', 'Select release type:');
console.log('1) Patch (0.0.x)');
console.log('2) Minor (0.x.0)');
console.log('3) Major (x.0.0)');
console.log('q) Quit');
const choice = await rl.question('Choice: ');
let type = '';
switch (choice) {
case '1': type = 'patch'; break;
case '2': type = 'minor'; break;
case '3': type = 'major'; break;
case 'q':
console.log('Cancelled.');
rl.close();
process.exit(0);
default:
console.log('Invalid choice.');
rl.close();
process.exit(1);
}
// 5. Ask for custom commit message
console.log('\n\x1b[33m%s\x1b[0m', `Enter commit message (leave blank for auto: '${type} release vX.X.X'):`);
const customMsg = await rl.question('Message: ');
// 6. Final Confirmation
console.log('\n\x1b[36m%s\x1b[0m', `Ready to release ${type}...`);
const confirmation = await rl.question('Proceed? (y/n) ');
if (confirmation.toLowerCase() !== 'y') {
console.log('\x1b[90m%s\x1b[0m', 'Release cancelled.');
rl.close();
process.exit(0);
}
console.log('\n\x1b[36m%s\x1b[0m', 'Bumping version...');
// 7. Run pnpm version
try {
let command = `pnpm version ${type}`;
if (customMsg) {
// Escape double quotes in message
const escapedMsg = customMsg.replace(/"/g, '\\"');
command += ` -m "${escapedMsg}"`;
}
const newVersion = execSync(command, { encoding: 'utf8' }).trim();
console.log('\x1b[32m%s\x1b[0m', `New Version: ${newVersion}`);
// 8. Push to origin
console.log('\n\x1b[36m%s\x1b[0m', 'Pushing changes and tags to origin...');
execSync('git push', { stdio: 'inherit' });
execSync('git push --tags', { stdio: 'inherit' });
console.log('\n\x1b[32m%s\x1b[0m', `✨ Release ${newVersion} successful! GitHub Actions check has started.`);
} catch (error) {
console.log('\x1b[31m%s\x1b[0m', 'Error: Release failed.');
console.error(error.message);
process.exit(1);
} finally {
rl.close();
}
}
run();