diff --git a/script/bump-version.py b/script/bump-version.py index 28424aaa8ee6..403bb88a80ed 100755 --- a/script/bump-version.py +++ b/script/bump-version.py @@ -72,10 +72,17 @@ def main(): versions[3] = '0' if args.new_version != None: - versions = parse_version(re.sub('-beta', '', args.new_version)) + 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 = '' if versions[3] == '0' else '-beta.' + versions[3] + suffix = '' + + if args.new_version != None and '-nightly' in args.new_version: + suffix = '-nightly.' + versions[3] + elif versions[3] != '0': + suffix = '-beta.' + versions[3] if args.dry_run: print 'new version number would be: {0}\n'.format(version + suffix) @@ -192,7 +199,14 @@ def update_package_json(version, suffix): def tag_version(version, suffix): - execute(['git', 'commit', '-a', '-m', 'Bump v{0}'.format(version + suffix)]) + execute([ + 'git', + 'commit', + '-a', + '-m', + 'Bump v{0}'.format(version + suffix), + '-n' + ]) if __name__ == '__main__': diff --git a/script/find-release.js b/script/find-release.js index 27812fe12385..d8cfb2be8af1 100644 --- a/script/find-release.js +++ b/script/find-release.js @@ -14,7 +14,7 @@ async function findRelease () { github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) let releases = await github.repos.getReleases({ owner: 'electron', - repo: 'electron' + repo: version.indexOf('nightly') > 0 ? 'nightlies' : 'electron' }) let targetRelease = releases.data.find(release => { return release.tag_name === version diff --git a/script/prepare-release.js b/script/prepare-release.js index 34e500e46b34..d6cde6285d94 100755 --- a/script/prepare-release.js +++ b/script/prepare-release.js @@ -14,13 +14,14 @@ const pass = '\u2713'.green const path = require('path') const pkg = require('../package.json') const readline = require('readline') +const semver = require('semver') const versionType = args._[0] // TODO (future) automatically determine version based on conventional commits // via conventional-recommended-bump if (!versionType && !args.notesOnly) { - console.log(`Usage: prepare-release versionType [major | minor | patch | beta]` + + console.log(`Usage: prepare-release versionType [major | minor | patch | beta | nightly]` + ` (--stable) (--notesOnly) (--automaticRelease) (--branch)`) process.exit(1) } @@ -29,10 +30,15 @@ const github = new GitHub() const gitDir = path.resolve(__dirname, '..') github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) -function getNewVersion (dryRun) { +async function getNewVersion (dryRun) { console.log(`Bumping for new "${versionType}" version.`) let bumpScript = path.join(__dirname, 'bump-version.py') - let scriptArgs = [bumpScript, `--bump ${versionType}`] + let scriptArgs = [bumpScript] + if (versionType === 'nightly') { + scriptArgs.push(`--version ${await determineNextNightly(await getCurrentBranch())}`) + } else { + scriptArgs.push(`--bump ${versionType}`) + } if (args.stable) { scriptArgs.push('--stable') } @@ -49,9 +55,47 @@ function getNewVersion (dryRun) { return newVersion } catch (err) { console.log(`${fail} Could not bump version, error was:`, err) + throw err } } +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) { console.log(`Determining current git branch`) let gitArgs = ['rev-parse', '--abbrev-ref', 'HEAD'] @@ -70,6 +114,9 @@ async function getCurrentBranch (gitDir) { } async function getReleaseNotes (currentBranch) { + if (versionType === 'nightly') { + return 'Nightlies do not get release notes, please compare tags for info' + } console.log(`Generating release notes for ${currentBranch}.`) let githubOpts = { owner: 'electron', @@ -135,7 +182,7 @@ async function getReleaseNotes (currentBranch) { async function createRelease (branchToTarget, isBeta) { let releaseNotes = await getReleaseNotes(branchToTarget) - let newVersion = getNewVersion() + let newVersion = await getNewVersion() await tagRelease(newVersion) const githubOpts = { owner: 'electron', @@ -208,7 +255,7 @@ async function tagRelease (version) { } async function verifyNewVersion () { - let newVersion = getNewVersion(true) + let newVersion = await getNewVersion(true) let response if (args.automaticRelease) { response = 'y' @@ -238,8 +285,8 @@ async function promptForVersion (version) { async function prepareRelease (isBeta, notesOnly) { if (args.automaticRelease && (pkg.version.indexOf('beta') === -1 || - versionType !== 'beta')) { - console.log(`${fail} Automatic release is only supported for beta releases`) + versionType !== 'beta') && versionType !== 'nightly') { + console.log(`${fail} Automatic release is only supported for beta and nightly releases`) process.exit(1) } let currentBranch diff --git a/script/publish-to-npm.js b/script/publish-to-npm.js index eb0702ff5ef2..3139e29a5f24 100644 --- a/script/publish-to-npm.js +++ b/script/publish-to-npm.js @@ -68,7 +68,7 @@ new Promise((resolve, reject) => { return github.repos.getReleases({ owner: 'electron', - repo: 'electron' + repo: rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron' }) }) .then((releases) => { diff --git a/script/release.js b/script/release.js index 9048d759d947..af9723eb1788 100755 --- a/script/release.js +++ b/script/release.js @@ -16,6 +16,7 @@ const fail = '\u2717'.red const sumchecker = require('sumchecker') const temp = require('temp').track() const { URL } = require('url') +const targetRepo = pkgVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron' let failureCount = 0 const github = new GitHub({ @@ -24,7 +25,7 @@ const github = new GitHub({ github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) async function getDraftRelease (version, skipValidation) { - let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: 'electron'}) + let releaseInfo = await github.repos.getReleases({owner: 'electron', repo: targetRepo}) let drafts let versionToCheck if (version) { @@ -197,7 +198,7 @@ async function createReleaseShasums (release) { console.log(`${fileName} already exists on GitHub; deleting before creating new file.`) await github.repos.deleteAsset({ owner: 'electron', - repo: 'electron', + repo: targetRepo, id: existingAssets[0].id }).catch(err => { console.log(`${fail} Error deleting ${fileName} on GitHub:`, err) @@ -216,7 +217,7 @@ async function createReleaseShasums (release) { async function uploadShasumFile (filePath, fileName, release) { let githubOpts = { owner: 'electron', - repo: 'electron', + repo: targetRepo, id: release.id, filePath, name: fileName @@ -251,7 +252,7 @@ function saveShaSumFile (checksums, fileName) { async function publishRelease (release) { let githubOpts = { owner: 'electron', - repo: 'electron', + repo: targetRepo, id: release.id, tag_name: release.tag_name, draft: false @@ -305,7 +306,7 @@ async function verifyAssets (release) { let downloadDir = await makeTempDir() let githubOpts = { owner: 'electron', - repo: 'electron', + repo: targetRepo, headers: { Accept: 'application/octet-stream' } diff --git a/script/upload-to-github.js b/script/upload-to-github.js index 0d42b8d9e1c9..2facda2daa1b 100644 --- a/script/upload-to-github.js +++ b/script/upload-to-github.js @@ -4,17 +4,20 @@ const GitHub = require('github') const github = new GitHub() github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN}) -if (process.argv.length < 5) { +if (process.argv.length < 6) { console.log('Usage: upload-to-github filePath fileName releaseId') process.exit(1) } let filePath = process.argv[2] let fileName = process.argv[3] let releaseId = process.argv[4] +let releaseVersion = process.argv[5] + +const targetRepo = releaseVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron' let githubOpts = { owner: 'electron', - repo: 'electron', + repo: targetRepo, id: releaseId, filePath: filePath, name: fileName @@ -36,7 +39,7 @@ function uploadToGitHub () { console.log(`${fileName} already exists; will delete before retrying upload.`) github.repos.deleteAsset({ owner: 'electron', - repo: 'electron', + repo: targetRepo, id: existingAssets[0].id }).then(uploadToGitHub).catch(uploadToGitHub) } else { diff --git a/script/upload.py b/script/upload.py index 7809d65dd738..2d9eaa201265 100755 --- a/script/upload.py +++ b/script/upload.py @@ -165,17 +165,18 @@ def upload_electron(release, file_path, args): return # Upload the file. - upload_io_to_github(release, filename, file_path) + upload_io_to_github(release, filename, file_path, args.version) # Upload the checksum file. upload_sha256_checksum(args.version, file_path) -def upload_io_to_github(release, filename, filepath): +def upload_io_to_github(release, filename, filepath, version): print 'Uploading %s to Github' % \ (filename) script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-to-github.js') - execute(['node', script_path, filepath, filename, str(release['id'])]) + execute(['node', script_path, filepath, filename, str(release['id']), + version]) def upload_sha256_checksum(version, file_path, key_prefix=None):