chore: convert bump script to js (#15820)
This commit is contained in:
parent
2845267c18
commit
1b8c11121f
10 changed files with 378 additions and 323 deletions
29
package-lock.json
generated
29
package-lock.json
generated
|
@ -7972,6 +7972,17 @@
|
|||
"find-up": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"plist": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
|
||||
"integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"base64-js": "^1.2.3",
|
||||
"xmlbuilder": "^9.0.7",
|
||||
"xmldom": "0.1.x"
|
||||
}
|
||||
},
|
||||
"plur": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz",
|
||||
|
@ -9419,9 +9430,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver-diff": {
|
||||
|
@ -12132,6 +12143,18 @@
|
|||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"xmlbuilder": {
|
||||
"version": "9.0.7",
|
||||
"resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
|
||||
"integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
|
||||
"dev": true
|
||||
},
|
||||
"xmldom": {
|
||||
"version": "0.1.27",
|
||||
"resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz",
|
||||
"integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=",
|
||||
"dev": true
|
||||
},
|
||||
"xtend": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||
|
|
|
@ -26,11 +26,12 @@
|
|||
"node-fetch": "^2.1.2",
|
||||
"nugget": "^2.0.1",
|
||||
"octicons": "^7.3.0",
|
||||
"plist": "^3.0.1",
|
||||
"recursive-readdir": "^2.2.2",
|
||||
"remark-cli": "^4.0.0",
|
||||
"remark-preset-lint-markdown-style-guide": "^2.1.1",
|
||||
"request": "^2.88.0",
|
||||
"semver": "^5.5.0",
|
||||
"semver": "^5.6.0",
|
||||
"serve": "^6.5.8",
|
||||
"standard-markdown": "^5.0.0",
|
||||
"sumchecker": "^2.0.2",
|
||||
|
|
184
script/bump-version.js
Normal file
184
script/bump-version.js
Normal file
|
@ -0,0 +1,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 }
|
|
@ -1,219 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
from lib.util import execute, get_electron_version, parse_version, scoped_cwd, \
|
||||
is_nightly, is_beta, is_stable, get_next_nightly, get_next_beta, \
|
||||
get_next_stable_from_pre, get_next_stable_from_stable, clean_parse_version
|
||||
|
||||
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Bump version numbers. Must specify at least one of the three'
|
||||
+' options:\n'
|
||||
+' --bump=patch to increment patch version, or\n'
|
||||
+' --stable to promote current beta to stable, or\n'
|
||||
+' --version={version} to set version number directly\n'
|
||||
+'Note that you can use both --bump and --stable '
|
||||
+'simultaneously.',
|
||||
formatter_class=argparse.RawTextHelpFormatter
|
||||
)
|
||||
parser.add_argument(
|
||||
'--version',
|
||||
default=None,
|
||||
dest='new_version',
|
||||
help='new version number'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--bump',
|
||||
action='store',
|
||||
default=None,
|
||||
dest='bump',
|
||||
help='increment [stable | beta | nightly]'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--dry-run',
|
||||
action='store_true',
|
||||
default= False,
|
||||
dest='dry_run',
|
||||
help='just to check that version number is correct'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
curr_version = get_electron_version()
|
||||
|
||||
if args.bump not in ['stable', 'beta', 'nightly']:
|
||||
raise Exception('bump must be set to either stable, beta or nightly')
|
||||
|
||||
if is_nightly(curr_version):
|
||||
if args.bump == 'nightly':
|
||||
version = get_next_nightly(curr_version)
|
||||
elif args.bump == 'beta':
|
||||
version = get_next_beta(curr_version)
|
||||
elif args.bump == 'stable':
|
||||
version = get_next_stable_from_pre(curr_version)
|
||||
else:
|
||||
not_reached()
|
||||
elif is_beta(curr_version):
|
||||
if args.bump == 'nightly':
|
||||
version = get_next_nightly(curr_version)
|
||||
elif args.bump == 'beta':
|
||||
version = get_next_beta(curr_version)
|
||||
elif args.bump == 'stable':
|
||||
version = get_next_stable_from_pre(curr_version)
|
||||
else:
|
||||
not_reached()
|
||||
elif is_stable(curr_version):
|
||||
if args.bump == 'nightly':
|
||||
version = get_next_nightly(curr_version)
|
||||
elif args.bump == 'beta':
|
||||
version = get_next_beta(curr_version)
|
||||
elif args.bump == 'stable':
|
||||
version = get_next_stable_from_stable(curr_version)
|
||||
else:
|
||||
not_reached()
|
||||
else:
|
||||
raise Exception("Invalid current version: " + curr_version)
|
||||
|
||||
if args.new_version is None and args.bump is None and not args.stable:
|
||||
parser.print_help()
|
||||
return 1
|
||||
|
||||
versions = clean_parse_version(version)
|
||||
suffix = ''
|
||||
if '-' in version:
|
||||
suffix = '-' + version.split('-')[1]
|
||||
versions[3] = parse_version(version)[3]
|
||||
version = version.split('-')[0]
|
||||
|
||||
if args.dry_run:
|
||||
print 'new version number would be: {0}\n'.format(version + suffix)
|
||||
return 0
|
||||
|
||||
with scoped_cwd(SOURCE_ROOT):
|
||||
update_version(version, suffix)
|
||||
update_win_rc(version, versions, args.bump == "nightly")
|
||||
update_version_h(versions, suffix)
|
||||
update_info_plist(version)
|
||||
update_package_json(version, suffix)
|
||||
tag_version(version, suffix)
|
||||
|
||||
print 'Bumped to version: {0}'.format(version + suffix)
|
||||
|
||||
def not_reached():
|
||||
raise Exception('Unreachable code was reached')
|
||||
|
||||
def increase_version(versions, index):
|
||||
for i in range(index + 1, 4):
|
||||
versions[i] = '0'
|
||||
versions[index] = str(int(versions[index]) + 1)
|
||||
return versions
|
||||
|
||||
|
||||
def update_version(version, suffix):
|
||||
with open('VERSION', 'w') as f:
|
||||
f.write(version + suffix)
|
||||
|
||||
|
||||
def update_win_rc(version, versions, is_nightly_version):
|
||||
pattern_fv = re.compile(' FILEVERSION [0-9,]+')
|
||||
pattern_pv = re.compile(' PRODUCTVERSION [0-9,]+')
|
||||
pattern_fvs = re.compile(' *VALUE "FileVersion", "[0-9.]+"')
|
||||
pattern_pvs = re.compile(' *VALUE "ProductVersion", "[0-9.]+"')
|
||||
|
||||
win_rc = os.path.join('atom', 'browser', 'resources', 'win', 'atom.rc')
|
||||
with open(win_rc, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
versions = [str(v) for v in versions]
|
||||
for i in range(0, len(lines)):
|
||||
line = lines[i]
|
||||
if pattern_fv.match(line):
|
||||
versions_64_bit = versions[::]
|
||||
if is_nightly_version:
|
||||
versions_64_bit[3] = '0'
|
||||
lines[i] = ' FILEVERSION {0}\r\n'.format(','.join(versions_64_bit))
|
||||
elif pattern_pv.match(line):
|
||||
lines[i] = ' PRODUCTVERSION {0}\r\n'.format(','.join(versions))
|
||||
elif pattern_fvs.match(line):
|
||||
lines[i] = ' VALUE "FileVersion", "{0}"\r\n'.format(version)
|
||||
elif pattern_pvs.match(line):
|
||||
lines[i] = ' VALUE "ProductVersion", "{0}"\r\n'.format(version)
|
||||
|
||||
with open(win_rc, 'w') as f:
|
||||
f.write(''.join(lines))
|
||||
|
||||
|
||||
def update_version_h(versions, suffix):
|
||||
version_h = os.path.join('atom', 'common', 'atom_version.h')
|
||||
with open(version_h, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for i in range(0, len(lines)):
|
||||
line = lines[i]
|
||||
if 'ATOM_MAJOR_VERSION' in line:
|
||||
lines[i] = '#define ATOM_MAJOR_VERSION {0}\n'.format(versions[0])
|
||||
lines[i + 1] = '#define ATOM_MINOR_VERSION {0}\n'.format(versions[1])
|
||||
lines[i + 2] = '#define ATOM_PATCH_VERSION {0}\n'.format(versions[2])
|
||||
|
||||
# We do +4 here to avoid the clang format comment
|
||||
if (suffix):
|
||||
lines[i + 4] = '#define ATOM_PRE_RELEASE_VERSION {0}\n'.format(suffix)
|
||||
else:
|
||||
lines[i + 4] = '// #define ATOM_PRE_RELEASE_VERSION\n'
|
||||
|
||||
with open(version_h, 'w') as f:
|
||||
f.write(''.join(lines))
|
||||
return
|
||||
|
||||
|
||||
def update_info_plist(version):
|
||||
info_plist = os.path.join('atom', 'browser', 'resources', 'mac', 'Info.plist')
|
||||
with open(info_plist, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for i in range(0, len(lines)):
|
||||
line = lines[i]
|
||||
if 'CFBundleVersion' in line:
|
||||
lines[i + 1] = ' <string>{0}</string>\n'.format(version)
|
||||
if 'CFBundleShortVersionString' in line:
|
||||
lines[i + 1] = ' <string>{0}</string>\n'.format(version)
|
||||
|
||||
with open(info_plist, 'w') as f:
|
||||
f.write(''.join(lines))
|
||||
|
||||
|
||||
def update_package_json(version, suffix):
|
||||
metadata_json_files = ['package.json', 'package-lock.json']
|
||||
for json_file in metadata_json_files:
|
||||
with open(json_file, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
for i in range(0, len(lines)):
|
||||
line = lines[i];
|
||||
if 'version' in line:
|
||||
lines[i] = ' "version": "{0}",\n'.format(version + suffix)
|
||||
break
|
||||
|
||||
with open(json_file, 'w') as f:
|
||||
f.write(''.join(lines))
|
||||
|
||||
|
||||
def tag_version(version, suffix):
|
||||
execute([
|
||||
'git',
|
||||
'commit',
|
||||
'-a',
|
||||
'-m',
|
||||
'Bump v{0}'.format(version + suffix),
|
||||
'-n'
|
||||
])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
|
@ -3,7 +3,7 @@ const path = require('path')
|
|||
const semver = require('semver')
|
||||
const gitDir = path.resolve(__dirname, '..')
|
||||
|
||||
async function determineNextMajorForMaster () {
|
||||
async function getLastMajorForMaster () {
|
||||
let branchNames
|
||||
const result = await GitProcess.exec(['branch', '-a', '--remote', '--list', 'origin/[0-9]-[0-9]-x'], gitDir)
|
||||
if (result.exitCode === 0) {
|
||||
|
@ -17,13 +17,7 @@ async function determineNextMajorForMaster () {
|
|||
|
||||
function getNextReleaseBranch (branches) {
|
||||
const converted = branches.map(b => b.replace(/-/g, '.').replace('x', '0'))
|
||||
const next = converted.reduce((v1, v2) => {
|
||||
return semver.gt(v1, v2) ? v1 : v2
|
||||
})
|
||||
return parseInt(next.split('.')[0], 10)
|
||||
return converted.reduce((v1, v2) => semver.gt(v1, v2) ? v1 : v2)
|
||||
}
|
||||
|
||||
determineNextMajorForMaster().then(console.info).catch((err) => {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
module.exports = { getLastMajorForMaster }
|
||||
|
|
|
@ -217,85 +217,6 @@ def s3put(bucket, access_key, secret_key, prefix, key_prefix, files):
|
|||
def add_exec_bit(filename):
|
||||
os.chmod(filename, os.stat(filename).st_mode | stat.S_IEXEC)
|
||||
|
||||
def parse_version(version):
|
||||
if version[0] == 'v':
|
||||
version = version[1:]
|
||||
|
||||
vs = version.split('.')
|
||||
if len(vs) > 4:
|
||||
return vs[0:4]
|
||||
else:
|
||||
return vs + ['0'] * (4 - len(vs))
|
||||
|
||||
def clean_parse_version(v):
|
||||
return parse_version(v.split("-")[0])
|
||||
|
||||
def is_stable(v):
|
||||
return len(v.split(".")) == 3
|
||||
|
||||
def is_beta(v):
|
||||
return 'beta' in v
|
||||
|
||||
def is_nightly(v):
|
||||
return 'nightly' in v
|
||||
|
||||
def get_nightly_date():
|
||||
return datetime.datetime.today().strftime('%Y%m%d')
|
||||
|
||||
def get_last_major():
|
||||
return execute(['node', 'script/get-last-major-for-master.js'])
|
||||
|
||||
def get_next_nightly(v):
|
||||
pv = clean_parse_version(v)
|
||||
(major, minor, patch) = pv[0:3]
|
||||
|
||||
if (is_stable(v)):
|
||||
patch = str(int(pv[2]) + 1)
|
||||
|
||||
if execute(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) == "master":
|
||||
major = str(get_last_major() + 1)
|
||||
minor = '0'
|
||||
patch = '0'
|
||||
|
||||
pre = 'nightly.' + get_nightly_date()
|
||||
return make_version(major, minor, patch, pre)
|
||||
|
||||
def non_empty(thing):
|
||||
return thing.strip() != ''
|
||||
|
||||
def beta_tag_compare(tag1, tag2):
|
||||
p1 = parse_version(tag1)
|
||||
p2 = parse_version(tag2)
|
||||
return int(p1[3]) - int(p2[3])
|
||||
|
||||
def get_next_beta(v):
|
||||
pv = clean_parse_version(v)
|
||||
tag_pattern = 'v' + pv[0] + '.' + pv[1] + '.' + pv[2] + '-beta.*'
|
||||
tag_list = sorted(filter(
|
||||
non_empty,
|
||||
execute(['git', 'tag', '--list', '-l', tag_pattern]).strip().split('\n')
|
||||
), cmp=beta_tag_compare)
|
||||
if len(tag_list) == 0:
|
||||
return make_version(pv[0] , pv[1], pv[2], 'beta.1')
|
||||
|
||||
lv = parse_version(tag_list[-1])
|
||||
return make_version(pv[0] , pv[1], pv[2], 'beta.' + str(int(lv[3]) + 1))
|
||||
|
||||
def get_next_stable_from_pre(v):
|
||||
pv = clean_parse_version(v)
|
||||
(major, minor, patch) = pv[0:3]
|
||||
return make_version(major, minor, patch)
|
||||
|
||||
def get_next_stable_from_stable(v):
|
||||
pv = clean_parse_version(v)
|
||||
(major, minor, patch) = pv[0:3]
|
||||
return make_version(major, minor, str(int(patch) + 1))
|
||||
|
||||
def make_version(major, minor, patch, pre = None):
|
||||
if pre is None:
|
||||
return major + '.' + minor + '.' + patch
|
||||
return major + "." + minor + "." + patch + '-' + pre
|
||||
|
||||
def get_out_dir():
|
||||
out_dir = 'Debug'
|
||||
override = os.environ.get('ELECTRON_OUT_DIR')
|
||||
|
|
73
script/lib/version-utils.js
Normal file
73
script/lib/version-utils.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const semver = require('semver')
|
||||
const { getLastMajorForMaster } = require('../get-last-major-for-master')
|
||||
const { GitProcess } = require('dugite')
|
||||
const { promisify } = require('util')
|
||||
|
||||
const readFile = promisify(fs.readFile)
|
||||
const gitDir = path.resolve(__dirname, '..', '..')
|
||||
|
||||
const getCurrentDate = () => {
|
||||
const d = new Date()
|
||||
const dd = `${d.getDate()}`.padStart(2, '0')
|
||||
const mm = `${d.getMonth() + 1}`.padStart(2, '0')
|
||||
const yyyy = d.getFullYear()
|
||||
return `${yyyy}${mm}${dd}`
|
||||
}
|
||||
|
||||
const isNightly = v => v.includes('nightly')
|
||||
const isBeta = v => v.includes('beta')
|
||||
const isStable = v => {
|
||||
const parsed = semver.parse(v)
|
||||
return !!(parsed && parsed.prerelease.length === 0)
|
||||
}
|
||||
|
||||
const makeVersion = (components, delim, withPre = false) => {
|
||||
let version = [components.major, components.minor, components.patch].join(delim)
|
||||
if (withPre) {
|
||||
version += `-${components.pre[0]}${delim}${components.pre[1]}`
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
async function nextBeta (v) {
|
||||
const next = semver.coerce(semver.clean(v))
|
||||
|
||||
const tagBlob = await GitProcess.exec(['tag', '--list', '-l', `v${next}-beta.*`], gitDir)
|
||||
const tags = tagBlob.stdout.split('\n').filter(e => e !== '')
|
||||
tags.sort((t1, t2) => semver.gt(t1, t2))
|
||||
|
||||
// increment the latest existing beta tag or start at beta.1 if it's a new beta line
|
||||
return tags.length === 0 ? semver.inc(next, 'beta', 'prerelease') : semver.inc(tags.pop(), 'prerelease')
|
||||
}
|
||||
|
||||
async function getElectronVersion () {
|
||||
const versionPath = path.join(__dirname, '..', '..', 'VERSION')
|
||||
const version = await readFile(versionPath, 'utf8')
|
||||
return version.trim()
|
||||
}
|
||||
|
||||
async function nextNightly (v) {
|
||||
let next = semver.valid(semver.coerce(v))
|
||||
const pre = `nightly.${getCurrentDate()}`
|
||||
|
||||
const branch = await GitProcess.exec(['rev-parse', '--abbrev-ref', 'HEAD'], gitDir)
|
||||
if (branch === 'master') {
|
||||
next = semver.inc(await getLastMajorForMaster(), 'major')
|
||||
} else if (isStable(v)) {
|
||||
next = semver.inc(next, 'patch')
|
||||
}
|
||||
|
||||
return `${next}-${pre}`
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
isStable,
|
||||
isBeta,
|
||||
isNightly,
|
||||
nextBeta,
|
||||
makeVersion,
|
||||
getElectronVersion,
|
||||
nextNightly
|
||||
}
|
|
@ -13,8 +13,8 @@ const path = require('path')
|
|||
const readline = require('readline')
|
||||
const releaseNotesGenerator = require('./release-notes/index.js')
|
||||
const { getCurrentBranch } = require('./lib/utils.js')
|
||||
const versionType = args._[0]
|
||||
const targetRepo = versionType === 'nightly' ? 'nightlies' : 'electron'
|
||||
const bumpType = args._[0]
|
||||
const targetRepo = bumpType === 'nightly' ? 'nightlies' : 'electron'
|
||||
|
||||
require('colors')
|
||||
const pass = '\u2713'.green
|
||||
|
@ -23,8 +23,8 @@ const fail = '\u2717'.red
|
|||
// TODO (future) automatically determine version based on conventional commits
|
||||
// via conventional-recommended-bump
|
||||
|
||||
if (!versionType && !args.notesOnly) {
|
||||
console.log(`Usage: prepare-release versionType [stable | beta | nightly]` +
|
||||
if (!bumpType && !args.notesOnly) {
|
||||
console.log(`Usage: prepare-release [stable | beta | nightly]` +
|
||||
` (--stable) (--notesOnly) (--automaticRelease) (--branch)`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
@ -35,13 +35,11 @@ github.authenticate({ type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN })
|
|||
|
||||
async function getNewVersion (dryRun) {
|
||||
if (!dryRun) {
|
||||
console.log(`Bumping for new "${versionType}" version.`)
|
||||
}
|
||||
const bumpScript = path.join(__dirname, 'bump-version.py')
|
||||
const scriptArgs = [bumpScript, '--bump', versionType]
|
||||
if (dryRun) {
|
||||
scriptArgs.push('--dry-run')
|
||||
console.log(`Bumping for new "${bumpType}" version.`)
|
||||
}
|
||||
const bumpScript = path.join(__dirname, 'bump-version.js')
|
||||
const scriptArgs = ['node', bumpScript, `--bump=${bumpType}`]
|
||||
if (dryRun) scriptArgs.push('--dry-run')
|
||||
try {
|
||||
let bumpVersion = execSync(scriptArgs.join(' '), { encoding: 'UTF-8' })
|
||||
bumpVersion = bumpVersion.substr(bumpVersion.indexOf(':') + 1).trim()
|
||||
|
@ -57,7 +55,7 @@ async function getNewVersion (dryRun) {
|
|||
}
|
||||
|
||||
async function getReleaseNotes (currentBranch) {
|
||||
if (versionType === 'nightly') {
|
||||
if (bumpType === 'nightly') {
|
||||
return 'Nightlies do not get release notes, please compare tags for info'
|
||||
}
|
||||
console.log(`Generating release notes for ${currentBranch}.`)
|
||||
|
|
|
@ -15,7 +15,7 @@ from io import StringIO
|
|||
from lib.config import PLATFORM, get_target_arch, get_env_var, s3_config, \
|
||||
get_zip_name
|
||||
from lib.util import get_electron_branding, execute, get_electron_version, \
|
||||
parse_version, scoped_cwd, s3put, get_electron_exec, \
|
||||
scoped_cwd, s3put, get_electron_exec, \
|
||||
get_out_dir, SRC_DIR
|
||||
|
||||
|
||||
|
|
80
spec/version-bump-spec.js
Normal file
80
spec/version-bump-spec.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
const { expect } = require('chai')
|
||||
const { nextVersion } = require('../script/bump-version')
|
||||
|
||||
describe('bump-version script', () => {
|
||||
const nightlyPattern = /[0-9.]*(-nightly.(\d{4})(\d{2})(\d{2}))$/g
|
||||
const betaPattern = /[0-9.]*(-beta[0-9.]*)/g
|
||||
|
||||
it('bumps to nightly from stable', async () => {
|
||||
const version = 'v2.0.0'
|
||||
const next = await nextVersion('nightly', version)
|
||||
const matches = next.match(nightlyPattern)
|
||||
expect(matches).to.have.lengthOf(1)
|
||||
})
|
||||
|
||||
it('bumps to nightly from beta', async () => {
|
||||
const version = 'v2.0.0-beta.1'
|
||||
const next = await nextVersion('nightly', version)
|
||||
const matches = next.match(nightlyPattern)
|
||||
expect(matches).to.have.lengthOf(1)
|
||||
})
|
||||
|
||||
it('bumps to nightly from nightly', async () => {
|
||||
const version = 'v2.0.0-nightly.19950901'
|
||||
const next = await nextVersion('nightly', version)
|
||||
const matches = next.match(nightlyPattern)
|
||||
expect(matches).to.have.lengthOf(1)
|
||||
})
|
||||
|
||||
it('throws error when bumping to beta from stable', () => {
|
||||
const version = 'v2.0.0'
|
||||
return expect(
|
||||
nextVersion('beta', version)
|
||||
).to.be.rejectedWith('Cannot bump to beta from stable.')
|
||||
})
|
||||
|
||||
it('bumps to beta from nightly', async () => {
|
||||
const version = 'v2.0.0-nightly.19950901'
|
||||
const next = await nextVersion('beta', version)
|
||||
const matches = next.match(betaPattern)
|
||||
expect(matches).to.have.lengthOf(1)
|
||||
})
|
||||
|
||||
it('bumps to beta from beta', async () => {
|
||||
const version = 'v2.0.0-beta.8'
|
||||
const next = await nextVersion('beta', version)
|
||||
expect(next).to.equal('2.0.0-beta.9')
|
||||
})
|
||||
|
||||
it('bumps to stable from beta', async () => {
|
||||
const version = 'v2.0.0-beta.1'
|
||||
const next = await nextVersion('stable', version)
|
||||
expect(next).to.equal('2.0.0')
|
||||
})
|
||||
|
||||
it('bumps to stable from stable', async () => {
|
||||
const version = 'v2.0.0'
|
||||
const next = await nextVersion('stable', version)
|
||||
expect(next).to.equal('2.0.1')
|
||||
})
|
||||
|
||||
it('bumps to stable from nightly', async () => {
|
||||
const version = 'v2.0.0-nightly.19950901'
|
||||
const next = await nextVersion('stable', version)
|
||||
expect(next).to.equal('2.0.0')
|
||||
})
|
||||
|
||||
it('throws on an invalid version', () => {
|
||||
const version = 'vI.AM.INVALID'
|
||||
return expect(
|
||||
nextVersion('beta', version)
|
||||
).to.be.rejectedWith(`Invalid current version: ${version}`)
|
||||
})
|
||||
|
||||
it('throws on an invalid bump type', () => {
|
||||
const version = 'v2.0.0'
|
||||
return expect(
|
||||
nextVersion('WRONG', version)
|
||||
).to.be.rejectedWith('Invalid bump type.')
|
||||
})
|
||||
})
|
Loading…
Add table
Reference in a new issue