chore: introduce concept of nightly builds to release scripts (#14130)
* chore: introduce concept of nightly builds to release scripts * build: publish nightly releases to dedicated repo
This commit is contained in:
parent
22a2d9bd44
commit
b9afc68c35
7 changed files with 89 additions and 23 deletions
|
@ -72,10 +72,17 @@ def main():
|
||||||
versions[3] = '0'
|
versions[3] = '0'
|
||||||
|
|
||||||
if args.new_version != None:
|
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])
|
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:
|
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)
|
||||||
|
@ -192,7 +199,14 @@ def update_package_json(version, suffix):
|
||||||
|
|
||||||
|
|
||||||
def tag_version(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__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -14,7 +14,7 @@ async function findRelease () {
|
||||||
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
||||||
let releases = await github.repos.getReleases({
|
let releases = await github.repos.getReleases({
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron'
|
repo: version.indexOf('nightly') > 0 ? 'nightlies' : 'electron'
|
||||||
})
|
})
|
||||||
let targetRelease = releases.data.find(release => {
|
let targetRelease = releases.data.find(release => {
|
||||||
return release.tag_name === version
|
return release.tag_name === version
|
||||||
|
|
|
@ -14,13 +14,14 @@ 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]
|
||||||
|
|
||||||
// TODO (future) automatically determine version based on conventional commits
|
// TODO (future) automatically determine version based on conventional commits
|
||||||
// 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]` +
|
console.log(`Usage: prepare-release versionType [major | minor | patch | beta | nightly]` +
|
||||||
` (--stable) (--notesOnly) (--automaticRelease) (--branch)`)
|
` (--stable) (--notesOnly) (--automaticRelease) (--branch)`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
@ -29,10 +30,15 @@ const github = new GitHub()
|
||||||
const gitDir = path.resolve(__dirname, '..')
|
const gitDir = path.resolve(__dirname, '..')
|
||||||
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
||||||
|
|
||||||
function getNewVersion (dryRun) {
|
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, `--bump ${versionType}`]
|
let scriptArgs = [bumpScript]
|
||||||
|
if (versionType === 'nightly') {
|
||||||
|
scriptArgs.push(`--version ${await determineNextNightly(await getCurrentBranch())}`)
|
||||||
|
} else {
|
||||||
|
scriptArgs.push(`--bump ${versionType}`)
|
||||||
|
}
|
||||||
if (args.stable) {
|
if (args.stable) {
|
||||||
scriptArgs.push('--stable')
|
scriptArgs.push('--stable')
|
||||||
}
|
}
|
||||||
|
@ -49,9 +55,47 @@ function getNewVersion (dryRun) {
|
||||||
return newVersion
|
return newVersion
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(`${fail} Could not bump version, error was:`, 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) {
|
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']
|
||||||
|
@ -70,6 +114,9 @@ async function getCurrentBranch (gitDir) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getReleaseNotes (currentBranch) {
|
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}.`)
|
console.log(`Generating release notes for ${currentBranch}.`)
|
||||||
let githubOpts = {
|
let githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
|
@ -135,7 +182,7 @@ async function getReleaseNotes (currentBranch) {
|
||||||
|
|
||||||
async function createRelease (branchToTarget, isBeta) {
|
async function createRelease (branchToTarget, isBeta) {
|
||||||
let releaseNotes = await getReleaseNotes(branchToTarget)
|
let releaseNotes = await getReleaseNotes(branchToTarget)
|
||||||
let newVersion = getNewVersion()
|
let newVersion = await getNewVersion()
|
||||||
await tagRelease(newVersion)
|
await tagRelease(newVersion)
|
||||||
const githubOpts = {
|
const githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
|
@ -208,7 +255,7 @@ async function tagRelease (version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifyNewVersion () {
|
async function verifyNewVersion () {
|
||||||
let newVersion = getNewVersion(true)
|
let newVersion = await getNewVersion(true)
|
||||||
let response
|
let response
|
||||||
if (args.automaticRelease) {
|
if (args.automaticRelease) {
|
||||||
response = 'y'
|
response = 'y'
|
||||||
|
@ -238,8 +285,8 @@ 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 !== 'beta') && versionType !== 'nightly') {
|
||||||
console.log(`${fail} Automatic release is only supported for beta releases`)
|
console.log(`${fail} Automatic release is only supported for beta and nightly releases`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
let currentBranch
|
let currentBranch
|
||||||
|
|
|
@ -68,7 +68,7 @@ new Promise((resolve, reject) => {
|
||||||
|
|
||||||
return github.repos.getReleases({
|
return github.repos.getReleases({
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron'
|
repo: rootPackageJson.version.indexOf('nightly') > 0 ? 'nightlies' : 'electron'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.then((releases) => {
|
.then((releases) => {
|
||||||
|
|
|
@ -16,6 +16,7 @@ const fail = '\u2717'.red
|
||||||
const sumchecker = require('sumchecker')
|
const sumchecker = require('sumchecker')
|
||||||
const temp = require('temp').track()
|
const temp = require('temp').track()
|
||||||
const { URL } = require('url')
|
const { URL } = require('url')
|
||||||
|
const targetRepo = pkgVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron'
|
||||||
let failureCount = 0
|
let failureCount = 0
|
||||||
|
|
||||||
const github = new GitHub({
|
const github = new GitHub({
|
||||||
|
@ -24,7 +25,7 @@ const github = new GitHub({
|
||||||
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
||||||
|
|
||||||
async function getDraftRelease (version, skipValidation) {
|
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 drafts
|
||||||
let versionToCheck
|
let versionToCheck
|
||||||
if (version) {
|
if (version) {
|
||||||
|
@ -197,7 +198,7 @@ async function createReleaseShasums (release) {
|
||||||
console.log(`${fileName} already exists on GitHub; deleting before creating new file.`)
|
console.log(`${fileName} already exists on GitHub; deleting before creating new file.`)
|
||||||
await github.repos.deleteAsset({
|
await github.repos.deleteAsset({
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron',
|
repo: targetRepo,
|
||||||
id: existingAssets[0].id
|
id: existingAssets[0].id
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(`${fail} Error deleting ${fileName} on GitHub:`, err)
|
console.log(`${fail} Error deleting ${fileName} on GitHub:`, err)
|
||||||
|
@ -216,7 +217,7 @@ async function createReleaseShasums (release) {
|
||||||
async function uploadShasumFile (filePath, fileName, release) {
|
async function uploadShasumFile (filePath, fileName, release) {
|
||||||
let githubOpts = {
|
let githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron',
|
repo: targetRepo,
|
||||||
id: release.id,
|
id: release.id,
|
||||||
filePath,
|
filePath,
|
||||||
name: fileName
|
name: fileName
|
||||||
|
@ -251,7 +252,7 @@ function saveShaSumFile (checksums, fileName) {
|
||||||
async function publishRelease (release) {
|
async function publishRelease (release) {
|
||||||
let githubOpts = {
|
let githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron',
|
repo: targetRepo,
|
||||||
id: release.id,
|
id: release.id,
|
||||||
tag_name: release.tag_name,
|
tag_name: release.tag_name,
|
||||||
draft: false
|
draft: false
|
||||||
|
@ -305,7 +306,7 @@ async function verifyAssets (release) {
|
||||||
let downloadDir = await makeTempDir()
|
let downloadDir = await makeTempDir()
|
||||||
let githubOpts = {
|
let githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron',
|
repo: targetRepo,
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/octet-stream'
|
Accept: 'application/octet-stream'
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,20 @@ const GitHub = require('github')
|
||||||
const github = new GitHub()
|
const github = new GitHub()
|
||||||
github.authenticate({type: 'token', token: process.env.ELECTRON_GITHUB_TOKEN})
|
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')
|
console.log('Usage: upload-to-github filePath fileName releaseId')
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
let filePath = process.argv[2]
|
let filePath = process.argv[2]
|
||||||
let fileName = process.argv[3]
|
let fileName = process.argv[3]
|
||||||
let releaseId = process.argv[4]
|
let releaseId = process.argv[4]
|
||||||
|
let releaseVersion = process.argv[5]
|
||||||
|
|
||||||
|
const targetRepo = releaseVersion.indexOf('nightly') > 0 ? 'nightlies' : 'electron'
|
||||||
|
|
||||||
let githubOpts = {
|
let githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron',
|
repo: targetRepo,
|
||||||
id: releaseId,
|
id: releaseId,
|
||||||
filePath: filePath,
|
filePath: filePath,
|
||||||
name: fileName
|
name: fileName
|
||||||
|
@ -36,7 +39,7 @@ function uploadToGitHub () {
|
||||||
console.log(`${fileName} already exists; will delete before retrying upload.`)
|
console.log(`${fileName} already exists; will delete before retrying upload.`)
|
||||||
github.repos.deleteAsset({
|
github.repos.deleteAsset({
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron',
|
repo: targetRepo,
|
||||||
id: existingAssets[0].id
|
id: existingAssets[0].id
|
||||||
}).then(uploadToGitHub).catch(uploadToGitHub)
|
}).then(uploadToGitHub).catch(uploadToGitHub)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -165,17 +165,18 @@ def upload_electron(release, file_path, args):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Upload the file.
|
# 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 the checksum file.
|
||||||
upload_sha256_checksum(args.version, file_path)
|
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' % \
|
print 'Uploading %s to Github' % \
|
||||||
(filename)
|
(filename)
|
||||||
script_path = os.path.join(SOURCE_ROOT, 'script', 'upload-to-github.js')
|
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):
|
def upload_sha256_checksum(version, file_path, key_prefix=None):
|
||||||
|
|
Loading…
Reference in a new issue