chore: allow nightlies from release branches (#14157)
* chore: allow nightlies from release branches * keep current version from beta to nightly * move version bump logic to bump-versi.py
This commit is contained in:
parent
ba98ef382d
commit
6861c10183
4 changed files with 143 additions and 81 deletions
|
@ -5,12 +5,12 @@ import re
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
from lib.util import execute, get_electron_version, parse_version, scoped_cwd
|
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__)))
|
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
|
@ -34,14 +34,7 @@ def main():
|
||||||
action='store',
|
action='store',
|
||||||
default=None,
|
default=None,
|
||||||
dest='bump',
|
dest='bump',
|
||||||
help='increment [major | minor | patch | beta]'
|
help='increment [stable | beta | nightly]'
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
'--stable',
|
|
||||||
action='store_true',
|
|
||||||
default= False,
|
|
||||||
dest='stable',
|
|
||||||
help='promote to stable (i.e. remove `-beta.x` suffix)'
|
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--dry-run',
|
'--dry-run',
|
||||||
|
@ -52,43 +45,55 @@ def main():
|
||||||
)
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
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':
|
||||||
|
raise Exception("You can\'t bump to a beta from stable")
|
||||||
|
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 == None and args.bump == None and args.stable == False:
|
if args.new_version == None and args.bump == None and args.stable == False:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
increments = ['major', 'minor', 'patch', 'beta']
|
versions = clean_parse_version(version)
|
||||||
|
|
||||||
curr_version = get_electron_version()
|
|
||||||
versions = parse_version(re.sub('-beta', '', curr_version))
|
|
||||||
|
|
||||||
if args.bump in increments:
|
|
||||||
versions = increase_version(versions, increments.index(args.bump))
|
|
||||||
if versions[3] == '0':
|
|
||||||
# beta starts at 1
|
|
||||||
versions = increase_version(versions, increments.index('beta'))
|
|
||||||
|
|
||||||
if args.stable == True:
|
|
||||||
versions[3] = '0'
|
|
||||||
|
|
||||||
if args.new_version != None:
|
|
||||||
clean_version = re.sub('-beta', '', args.new_version)
|
|
||||||
clean_version = re.sub('-nightly', '', clean_version)
|
|
||||||
versions = parse_version(clean_version)
|
|
||||||
|
|
||||||
version = '.'.join(versions[:3])
|
|
||||||
suffix = ''
|
suffix = ''
|
||||||
|
if '-' in version:
|
||||||
if args.new_version != None and '-nightly' in args.new_version:
|
suffix = '-' + version.split('-')[1]
|
||||||
suffix = '-nightly.' + versions[3]
|
version = version.split('-')[0]
|
||||||
elif versions[3] != '0':
|
|
||||||
suffix = '-beta.' + versions[3]
|
|
||||||
|
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
print 'new version number would be: {0}\n'.format(version + suffix)
|
print 'new version number would be: {0}\n'.format(version + suffix)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
with scoped_cwd(SOURCE_ROOT):
|
with scoped_cwd(SOURCE_ROOT):
|
||||||
update_electron_gyp(version, suffix)
|
update_electron_gyp(version, suffix)
|
||||||
update_win_rc(version, versions)
|
update_win_rc(version, versions)
|
||||||
|
@ -99,6 +104,9 @@ def main():
|
||||||
|
|
||||||
print 'Bumped to version: {0}'.format(version + suffix)
|
print 'Bumped to version: {0}'.format(version + suffix)
|
||||||
|
|
||||||
|
def not_reached():
|
||||||
|
raise Exception('Unreachable code was reached')
|
||||||
|
|
||||||
def increase_version(versions, index):
|
def increase_version(versions, index):
|
||||||
for i in range(index + 1, 4):
|
for i in range(index + 1, 4):
|
||||||
versions[i] = '0'
|
versions[i] = '0'
|
||||||
|
|
29
script/get-last-major-for-master.js
Normal file
29
script/get-last-major-for-master.js
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
const { GitProcess } = require('dugite')
|
||||||
|
const path = require('path')
|
||||||
|
const semver = require('semver')
|
||||||
|
const gitDir = path.resolve(__dirname, '..')
|
||||||
|
|
||||||
|
async function determineNextMajorForMaster () {
|
||||||
|
let branchNames
|
||||||
|
let result = await GitProcess.exec(['branch', '-a', '--remote', '--list', 'origin/[0-9]-[0-9]-x'], gitDir)
|
||||||
|
if (result.exitCode === 0) {
|
||||||
|
branchNames = result.stdout.trim().split('\n')
|
||||||
|
const filtered = branchNames.map(b => b.replace('origin/', ''))
|
||||||
|
return getNextReleaseBranch(filtered)
|
||||||
|
} else {
|
||||||
|
throw new Error('Release branches could not be fetched.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
determineNextMajorForMaster().then(console.info).catch((err) => {
|
||||||
|
console.error(err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import contextlib
|
import contextlib
|
||||||
|
import datetime
|
||||||
import errno
|
import errno
|
||||||
import platform
|
import platform
|
||||||
import re
|
import re
|
||||||
|
@ -293,3 +294,67 @@ def update_node_modules(dirname, env=None):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
execute_stdout(args, env)
|
execute_stdout(args, env)
|
||||||
|
|
||||||
|
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 = pv[0]; minor = pv[1]; patch = pv[2]
|
||||||
|
|
||||||
|
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 get_next_beta(v):
|
||||||
|
pv = clean_parse_version(v)
|
||||||
|
tag_pattern = 'v' + pv[0] + '.' + pv[1] + '.' + pv[2] + '-beta.*'
|
||||||
|
tag_list = filter(
|
||||||
|
non_empty,
|
||||||
|
execute(['git', 'tag', '--list', '-l', tag_pattern]).strip().split('\n')
|
||||||
|
)
|
||||||
|
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(lv[0] , lv[1], lv[2], str(int(lv[3]) + 1))
|
||||||
|
|
||||||
|
def get_next_stable_from_pre(v):
|
||||||
|
pv = clean_parse_version(v)
|
||||||
|
major = pv[0]; minor = pv[1]; patch = pv[2]
|
||||||
|
return make_version(major, minor, patch)
|
||||||
|
|
||||||
|
def get_next_stable_from_stable(v):
|
||||||
|
pv = clean_parse_version(v)
|
||||||
|
major = pv[0]; minor = pv[1]; patch = pv[2]
|
||||||
|
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
|
||||||
|
|
|
@ -14,7 +14,6 @@ const pass = '\u2713'.green
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const pkg = require('../package.json')
|
const pkg = require('../package.json')
|
||||||
const readline = require('readline')
|
const readline = require('readline')
|
||||||
const semver = require('semver')
|
|
||||||
const versionType = args._[0]
|
const versionType = args._[0]
|
||||||
const targetRepo = versionType === 'nightly' ? 'nightlies' : 'electron'
|
const targetRepo = versionType === 'nightly' ? 'nightlies' : 'electron'
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ const targetRepo = versionType === 'nightly' ? 'nightlies' : 'electron'
|
||||||
// via conventional-recommended-bump
|
// via conventional-recommended-bump
|
||||||
|
|
||||||
if (!versionType && !args.notesOnly) {
|
if (!versionType && !args.notesOnly) {
|
||||||
console.log(`Usage: prepare-release versionType [major | minor | patch | beta | nightly]` +
|
console.log(`Usage: prepare-release versionType [stable | beta | nightly]` +
|
||||||
` (--stable) (--notesOnly) (--automaticRelease) (--branch)`)
|
` (--stable) (--notesOnly) (--automaticRelease) (--branch)`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
@ -35,9 +34,7 @@ async function getNewVersion (dryRun) {
|
||||||
console.log(`Bumping for new "${versionType}" version.`)
|
console.log(`Bumping for new "${versionType}" version.`)
|
||||||
let bumpScript = path.join(__dirname, 'bump-version.py')
|
let bumpScript = path.join(__dirname, 'bump-version.py')
|
||||||
let scriptArgs = [bumpScript]
|
let scriptArgs = [bumpScript]
|
||||||
if (versionType === 'nightly') {
|
if (args.bump) {
|
||||||
scriptArgs.push(`--version ${await determineNextNightly(await getCurrentBranch())}`)
|
|
||||||
} else {
|
|
||||||
scriptArgs.push(`--bump ${versionType}`)
|
scriptArgs.push(`--bump ${versionType}`)
|
||||||
}
|
}
|
||||||
if (args.stable) {
|
if (args.stable) {
|
||||||
|
@ -60,43 +57,6 @@ async function getNewVersion (dryRun) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function determineNextNightly (currentBranch) {
|
|
||||||
const twoPad = (n) => n < 10 ? `0${n}` : `${n}`
|
|
||||||
const d = new Date()
|
|
||||||
const date = `${d.getFullYear()}${twoPad(d.getMonth() + 1)}${twoPad(d.getDate())}`
|
|
||||||
|
|
||||||
let version
|
|
||||||
|
|
||||||
if (currentBranch === 'master') {
|
|
||||||
version = await determineNextNightlyForMaster()
|
|
||||||
}
|
|
||||||
if (!version) {
|
|
||||||
throw new Error(`not yet implemented for release branch: ${currentBranch}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${version}-nightly.${date}`
|
|
||||||
}
|
|
||||||
|
|
||||||
async function determineNextNightlyForMaster () {
|
|
||||||
let branchNames
|
|
||||||
let result = await GitProcess.exec(['branch', '-a', '--remote', '--list', 'origin/[0-9]-[0-9]-x'], gitDir)
|
|
||||||
if (result.exitCode === 0) {
|
|
||||||
branchNames = result.stdout.trim().split('\n')
|
|
||||||
const filtered = branchNames.map(b => b.replace('origin/', ''))
|
|
||||||
return getNextReleaseBranch(filtered)
|
|
||||||
} else {
|
|
||||||
throw new Error('Release branches could not be fetched.')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) + 1}.0.0`
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getCurrentBranch (gitDir) {
|
async function getCurrentBranch (gitDir) {
|
||||||
console.log(`Determining current git branch`)
|
console.log(`Determining current git branch`)
|
||||||
let gitArgs = ['rev-parse', '--abbrev-ref', 'HEAD']
|
let gitArgs = ['rev-parse', '--abbrev-ref', 'HEAD']
|
||||||
|
@ -205,7 +165,7 @@ async function createRelease (branchToTarget, isBeta) {
|
||||||
githubOpts.draft = true
|
githubOpts.draft = true
|
||||||
githubOpts.name = `electron ${newVersion}`
|
githubOpts.name = `electron ${newVersion}`
|
||||||
if (isBeta) {
|
if (isBeta) {
|
||||||
if (versionType === 'nightly') {
|
if (newVersion.indexOf('nightly') > 0) {
|
||||||
githubOpts.body = `Note: This is a nightly release. Please file new issues ` +
|
githubOpts.body = `Note: This is a nightly release. Please file new issues ` +
|
||||||
`for any bugs you find in it.\n \n This release is published to npm ` +
|
`for any bugs you find in it.\n \n This release is published to npm ` +
|
||||||
`under the nightly tag and can be installed via npm install electron@nightly, ` +
|
`under the nightly tag and can be installed via npm install electron@nightly, ` +
|
||||||
|
@ -293,7 +253,7 @@ async function promptForVersion (version) {
|
||||||
|
|
||||||
async function prepareRelease (isBeta, notesOnly) {
|
async function prepareRelease (isBeta, notesOnly) {
|
||||||
if (args.automaticRelease && (pkg.version.indexOf('beta') === -1 ||
|
if (args.automaticRelease && (pkg.version.indexOf('beta') === -1 ||
|
||||||
versionType !== 'beta') && versionType !== 'nightly') {
|
versionType !== 'beta') && versionType !== 'nightly' && versionType !== 'stable') {
|
||||||
console.log(`${fail} Automatic release is only supported for beta and nightly releases`)
|
console.log(`${fail} Automatic release is only supported for beta and nightly releases`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue