forked from electron/electron
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathversion-bumper.js
188 lines (164 loc) · 5.92 KB
/
version-bumper.js
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/env node
const { GitProcess } = require('dugite');
const { promises: fs } = require('fs');
const semver = require('semver');
const path = require('path');
const minimist = require('minimist');
const { ELECTRON_DIR } = require('../lib/utils');
const versionUtils = require('./version-utils');
const supported = path.resolve(ELECTRON_DIR, 'docs', 'tutorial', 'support.md');
const writeFile = fs.writeFile;
const readFile = fs.readFile;
function parseCommandLine () {
let help;
const opts = minimist(process.argv.slice(2), {
string: ['bump', 'version'],
boolean: ['dryRun', 'help'],
alias: { version: ['v'] },
unknown: arg => { help = true; }
});
if (help || opts.help || !opts.bump) {
console.log(`
Bump release version number. Possible arguments:\n
--bump=patch to increment patch version\n
--version={version} to set version number directly\n
--dryRun to print the next version without updating files
Note that you can use both --bump and --stable simultaneously.
`);
process.exit(0);
}
return opts;
}
// run the script
async function main () {
const opts = parseCommandLine();
const currentVersion = await versionUtils.getElectronVersion();
const version = await nextVersion(opts.bump, currentVersion);
const parsed = semver.parse(version);
const components = {
major: parsed.major,
minor: parsed.minor,
patch: parsed.patch,
pre: parsed.prerelease
};
// print would-be new version and exit early
if (opts.dryRun) {
console.log(`new version number would be: ${version}\n`);
return 0;
}
if (shouldUpdateSupported(opts.bump, currentVersion, version)) {
await updateSupported(version, supported);
}
// update all version-related files
await Promise.all([
updateVersion(version),
updatePackageJSON(version),
updateWinRC(components)
]);
// commit all updated version-related files
await commitVersionBump(version);
console.log(`Bumped to version: ${version}`);
}
// get next version for release based on [nightly, beta, stable]
async function nextVersion (bumpType, version) {
if (versionUtils.isNightly(version) || versionUtils.isBeta(version)) {
switch (bumpType) {
case 'nightly':
version = await versionUtils.nextNightly(version);
break;
case 'beta':
version = await versionUtils.nextBeta(version);
break;
case 'stable':
version = semver.valid(semver.coerce(version));
break;
default:
throw new Error('Invalid bump type.');
}
} else if (versionUtils.isStable(version)) {
switch (bumpType) {
case 'nightly':
version = versionUtils.nextNightly(version);
break;
case 'beta':
throw new Error('Cannot bump to beta from stable.');
case 'minor':
version = semver.inc(version, 'minor');
break;
case 'stable':
version = semver.inc(version, 'patch');
break;
default:
throw new Error('Invalid bump type.');
}
} else {
throw new Error(`Invalid current version: ${version}`);
}
return version;
}
function shouldUpdateSupported (bump, current, version) {
return isMajorStable(bump, current) || isMajorNightly(version, current);
}
function isMajorStable (bump, currentVersion) {
if (versionUtils.isBeta(currentVersion) && (bump === 'stable')) return true;
return false;
}
function isMajorNightly (version, currentVersion) {
const parsed = semver.parse(version);
const current = semver.parse(currentVersion);
if (versionUtils.isNightly(currentVersion) && (parsed.major > current.major)) return true;
return false;
}
// update VERSION file with latest release info
async function updateVersion (version) {
const versionPath = path.resolve(ELECTRON_DIR, 'ELECTRON_VERSION');
await writeFile(versionPath, version, 'utf8');
}
// update package metadata files with new version
async function updatePackageJSON (version) {
const filePath = path.resolve(ELECTRON_DIR, 'package.json');
const file = require(filePath);
file.version = version;
await writeFile(filePath, JSON.stringify(file, null, 2));
}
// push bump commit to release branch
async function commitVersionBump (version) {
const gitArgs = ['commit', '-a', '-m', `Bump v${version}`, '-n'];
await GitProcess.exec(gitArgs, ELECTRON_DIR);
}
// updates electron.rc file with new semver values
async function updateWinRC (components) {
const filePath = path.resolve(ELECTRON_DIR, 'shell', 'browser', 'resources', 'win', 'electron.rc');
const data = await readFile(filePath, 'utf8');
const arr = data.split('\n');
arr.forEach((line, idx) => {
if (line.includes('FILEVERSION')) {
arr[idx] = ` FILEVERSION ${versionUtils.makeVersion(components, ',', versionUtils.preType.PARTIAL)}`;
arr[idx + 1] = ` PRODUCTVERSION ${versionUtils.makeVersion(components, ',', versionUtils.preType.PARTIAL)}`;
} else if (line.includes('FileVersion')) {
arr[idx] = ` VALUE "FileVersion", "${versionUtils.makeVersion(components, '.')}"`;
arr[idx + 5] = ` VALUE "ProductVersion", "${versionUtils.makeVersion(components, '.')}"`;
}
});
await writeFile(filePath, arr.join('\n'));
}
// updates support.md file with new semver values (stable only)
async function updateSupported (version, filePath) {
const v = parseInt(version);
const newVersions = [`* ${v}.x.y`, `* ${v - 1}.x.y`, `* ${v - 2}.x.y`];
const contents = await readFile(filePath, 'utf8');
const previousVersions = contents.split('\n').filter((elem) => {
return (/[^\n]*\.x\.y[^\n]*/).test(elem);
}, []);
const newContents = previousVersions.reduce((contents, current, i) => {
return contents.replace(current, newVersions[i]);
}, contents);
await writeFile(filePath, newContents, 'utf8');
}
if (process.mainModule === module) {
main().catch((error) => {
console.error(error);
process.exit(1);
});
}
module.exports = { nextVersion, shouldUpdateSupported, updateSupported };