forked from electron/electron
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: convert bump script to js (electron#15820)
- Loading branch information
1 parent
2845267
commit 1b8c111
Showing
10 changed files
with
378 additions
and
323 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } |
Oops, something went wrong.