forked from electron/electron
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbump-version.js
184 lines (163 loc) · 5.83 KB
/
bump-version.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
#!/usr/bin/env node
const { GitProcess } = require('dugite')
const utils = require('./lib/version-utils')
const plist = require('plist')
const fs = require('fs')
const semver = require('semver')
const path = require('path')
const { promisify } = require('util')
const minimist = require('minimist')
const writeFile = promisify(fs.writeFile)
const readFile = promisify(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 utils.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
}
// update all version-related files
await Promise.all([
updateVersion(version),
updateInfoPlist(version),
updatePackageJSON(version),
updateVersionH(components),
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 (utils.isNightly(version) || utils.isBeta(version)) {
switch (bumpType) {
case 'nightly':
version = await utils.nextNightly(version)
break
case 'beta':
version = await utils.nextBeta(version)
break
case 'stable':
version = semver.valid(semver.coerce(version))
break
default:
throw new Error('Invalid bump type.')
}
} else if (utils.isStable(version)) {
switch (bumpType) {
case 'nightly':
version = utils.nextNightly(version)
break
case 'beta':
throw new Error('Cannot bump to beta from stable.')
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
}
// update VERSION file with latest release info
async function updateVersion (version) {
const versionPath = path.resolve(__dirname, '..', 'VERSION')
await writeFile(versionPath, version, 'utf8')
}
// update package metadata files with new version
async function updatePackageJSON (version) {
['package.json', 'package-lock.json'].forEach(async fileName => {
const filePath = path.resolve(__dirname, '..', fileName)
const file = require(filePath)
file.version = version
await writeFile(filePath, JSON.stringify(file, null, 2))
})
}
// update CFBundle version information and overwrite pre-existing file
// TODO(codebytere): provide these version fields at GN build time
async function updateInfoPlist (version) {
const filePath = path.resolve(__dirname, '..', 'atom', 'browser', 'resources', 'mac', 'Info.plist')
const file = plist.parse(await readFile(filePath, { encoding: 'utf8' }))
file.CFBundleVersion = version
file.CFBundleShortVersionString = version
await writeFile(filePath, plist.build(file))
}
// push bump commit to release branch
async function commitVersionBump (version) {
const gitDir = path.resolve(__dirname, '..')
const gitArgs = ['commit', '-a', '-m', `Bump v${version}`, '-n']
await GitProcess.exec(gitArgs, gitDir)
}
// updates atom_version.h file with new semver values
// TODO(codebytere): auto-generate this
async function updateVersionH (components) {
const filePath = path.resolve(__dirname, '..', 'atom', 'common', 'atom_version.h')
const data = await readFile(filePath, 'utf8')
const arr = data.split('\n')
const pre = components.pre != null ? `-${components.pre[0]}.${components.pre[1]}` : null
arr.forEach((item, idx) => {
if (item.includes('#define ATOM_MAJOR_VERSION')) {
arr[idx] = `#define ATOM_MAJOR_VERSION ${components.major}`
arr[idx + 1] = `#define ATOM_MINOR_VERSION ${components.minor}`
arr[idx + 2] = `#define ATOM_PATCH_VERSION ${components.patch}`
arr[idx + 4] = pre ? `#define ATOM_PRE_RELEASE_VERSION ${pre}` : '// #define ATOM_PRE_RELEASE_VERSION'
}
})
await writeFile(filePath, arr.join('\n'))
}
// updates atom.rc file with new semver values
async function updateWinRC (components) {
const filePath = path.resolve(__dirname, '..', 'atom', 'browser', 'resources', 'win', 'atom.rc')
const data = await readFile(filePath, 'utf8')
const arr = data.split('\n')
arr.forEach((line, idx) => {
if (line.includes('FILEVERSION')) {
arr[idx] = ` FILEVERSION ${utils.makeVersion(components, ',', true)}`
arr[idx + 1] = ` PRODUCTVERSION ${utils.makeVersion(components, ',', true)}`
} else if (line.includes('FileVersion')) {
arr[idx] = ` VALUE "FileVersion", "${utils.makeVersion(components, '.')}"`
arr[idx + 5] = ` VALUE "ProductVersion", "${utils.makeVersion(components, '.')}"`
}
})
await writeFile(filePath, arr.join('\n'))
}
if (process.mainModule === module) {
main().catch((error) => {
console.error(error)
process.exit(1)
})
}
module.exports = { nextVersion }