Merge pull request #11903 from electron/update-release-for2
Change release process for 2.0
This commit is contained in:
commit
546bd6da5e
5 changed files with 24 additions and 164 deletions
|
@ -167,27 +167,10 @@ This release is published to [npm](https://www.npmjs.com/package/electron) under
|
||||||
1. You can run `npm run release -- --validateRelease` to verify that all of the
|
1. You can run `npm run release -- --validateRelease` to verify that all of the
|
||||||
required files have been created for the release.
|
required files have been created for the release.
|
||||||
|
|
||||||
## Merge temporary branch
|
|
||||||
Once the release builds have finished, merge the `release` branch back into
|
|
||||||
the source release branch using the `merge-release` script.
|
|
||||||
If the branch cannot be successfully merged back this script will automatically
|
|
||||||
rebase the `release` branch and push the changes which will trigger the release
|
|
||||||
builds again, which means you will need to wait for the release builds to run
|
|
||||||
again before proceeding.
|
|
||||||
|
|
||||||
### Merging back into master
|
|
||||||
```sh
|
|
||||||
npm run merge-release -- master
|
|
||||||
```
|
|
||||||
|
|
||||||
### Merging back into old release branch
|
|
||||||
```sh
|
|
||||||
npm run merge-release -- 1-7-x
|
|
||||||
```
|
|
||||||
|
|
||||||
## Publish the release
|
## Publish the release
|
||||||
|
|
||||||
Once the merge has finished successfully, run the `release` script
|
Once the release builds have finished, run the `release` script
|
||||||
via `npm run release` to finish the release process. This script will do the
|
via `npm run release` to finish the release process. This script will do the
|
||||||
following:
|
following:
|
||||||
1. Build the project to validate that the correct version number is being released.
|
1. Build the project to validate that the correct version number is being released.
|
||||||
|
|
|
@ -55,7 +55,6 @@
|
||||||
"lint-js-in-markdown": "standard-markdown docs",
|
"lint-js-in-markdown": "standard-markdown docs",
|
||||||
"create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version",
|
"create-api-json": "electron-docs-linter docs --outfile=out/electron-api.json --version=$npm_package_version",
|
||||||
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts",
|
"create-typescript-definitions": "npm run create-api-json && electron-typescript-definitions --in=out/electron-api.json --out=out/electron.d.ts",
|
||||||
"merge-release": "node ./script/merge-release.js",
|
|
||||||
"mock-release": "node ./script/ci-release-build.js",
|
"mock-release": "node ./script/ci-release-build.js",
|
||||||
"preinstall": "node -e 'process.exit(0)'",
|
"preinstall": "node -e 'process.exit(0)'",
|
||||||
"publish-to-npm": "node ./script/publish-to-npm.js",
|
"publish-to-npm": "node ./script/publish-to-npm.js",
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
require('colors')
|
|
||||||
const assert = require('assert')
|
|
||||||
const branchToRelease = process.argv[2]
|
|
||||||
const fail = '\u2717'.red
|
|
||||||
const { GitProcess, GitError } = require('dugite')
|
|
||||||
const pass = '\u2713'.green
|
|
||||||
const path = require('path')
|
|
||||||
const pkg = require('../package.json')
|
|
||||||
|
|
||||||
assert(process.env.ELECTRON_GITHUB_TOKEN, 'ELECTRON_GITHUB_TOKEN not found in environment')
|
|
||||||
if (!branchToRelease) {
|
|
||||||
console.log(`Usage: merge-release branch`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
const gitDir = path.resolve(__dirname, '..')
|
|
||||||
|
|
||||||
async function callGit (args, errorMessage, successMessage) {
|
|
||||||
let gitResult = await GitProcess.exec(args, gitDir)
|
|
||||||
if (gitResult.exitCode === 0) {
|
|
||||||
console.log(`${pass} ${successMessage}`)
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
console.log(`${fail} ${errorMessage} ${gitResult.stderr}`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkoutBranch (branchName) {
|
|
||||||
console.log(`Checking out ${branchName}.`)
|
|
||||||
let errorMessage = `Error checking out branch ${branchName}:`
|
|
||||||
let successMessage = `Successfully checked out branch ${branchName}.`
|
|
||||||
return callGit(['checkout', branchName], errorMessage, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function commitMerge () {
|
|
||||||
console.log(`Committing the merge for v${pkg.version}`)
|
|
||||||
let errorMessage = `Error committing merge:`
|
|
||||||
let successMessage = `Successfully committed the merge for v${pkg.version}`
|
|
||||||
let gitArgs = ['commit', '-m', `v${pkg.version}`]
|
|
||||||
return callGit(gitArgs, errorMessage, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function mergeReleaseIntoBranch (branchName) {
|
|
||||||
console.log(`Merging release branch into ${branchName}.`)
|
|
||||||
let mergeArgs = ['merge', 'release', '--squash']
|
|
||||||
let mergeDetails = await GitProcess.exec(mergeArgs, gitDir)
|
|
||||||
if (mergeDetails.exitCode === 0) {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
const error = GitProcess.parseError(mergeDetails.stderr)
|
|
||||||
if (error === GitError.MergeConflicts) {
|
|
||||||
console.log(`${fail} Could not merge release branch into ${branchName} ` +
|
|
||||||
`due to merge conflicts.`)
|
|
||||||
return false
|
|
||||||
} else {
|
|
||||||
console.log(`${fail} Could not merge release branch into ${branchName} ` +
|
|
||||||
`due to an error: ${mergeDetails.stderr}.`)
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function pushBranch (branchName) {
|
|
||||||
console.log(`Pushing branch ${branchName}.`)
|
|
||||||
let pushArgs = ['push', 'origin', branchName]
|
|
||||||
let errorMessage = `Could not push branch ${branchName} due to an error:`
|
|
||||||
let successMessage = `Successfully pushed branch ${branchName}.`
|
|
||||||
return callGit(pushArgs, errorMessage, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function pull () {
|
|
||||||
console.log(`Performing a git pull`)
|
|
||||||
let errorMessage = `Could not pull due to an error:`
|
|
||||||
let successMessage = `Successfully performed a git pull`
|
|
||||||
return callGit(['pull'], errorMessage, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function rebase (targetBranch) {
|
|
||||||
console.log(`Rebasing release branch from ${targetBranch}`)
|
|
||||||
let errorMessage = `Could not rebase due to an error:`
|
|
||||||
let successMessage = `Successfully rebased release branch from ` +
|
|
||||||
`${targetBranch}`
|
|
||||||
return callGit(['rebase', targetBranch], errorMessage, successMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function mergeRelease () {
|
|
||||||
await checkoutBranch(branchToRelease)
|
|
||||||
let mergeSuccess = await mergeReleaseIntoBranch(branchToRelease)
|
|
||||||
if (mergeSuccess) {
|
|
||||||
console.log(`${pass} Successfully merged release branch into ` +
|
|
||||||
`${branchToRelease}.`)
|
|
||||||
await commitMerge()
|
|
||||||
let pushSuccess = await pushBranch(branchToRelease)
|
|
||||||
if (pushSuccess) {
|
|
||||||
console.log(`${pass} Success!!! ${branchToRelease} now has the latest release!`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log(`Trying rebase of ${branchToRelease} into release branch.`)
|
|
||||||
await pull()
|
|
||||||
await checkoutBranch('release')
|
|
||||||
let rebaseResult = await rebase(branchToRelease)
|
|
||||||
if (rebaseResult) {
|
|
||||||
let pushResult = pushBranch('HEAD')
|
|
||||||
if (pushResult) {
|
|
||||||
console.log(`Rebase of ${branchToRelease} into release branch was ` +
|
|
||||||
`successful. Let release builds run and then try this step again.`)
|
|
||||||
}
|
|
||||||
// Exit as failure so release doesn't continue
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mergeRelease()
|
|
|
@ -6,7 +6,7 @@ const assert = require('assert')
|
||||||
const ciReleaseBuild = require('./ci-release-build')
|
const ciReleaseBuild = require('./ci-release-build')
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
const fail = '\u2717'.red
|
const fail = '\u2717'.red
|
||||||
const { GitProcess, GitError } = require('dugite')
|
const { GitProcess } = require('dugite')
|
||||||
const GitHub = require('github')
|
const GitHub = require('github')
|
||||||
const pass = '\u2713'.green
|
const pass = '\u2713'.green
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
@ -28,24 +28,6 @@ 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})
|
||||||
|
|
||||||
async function createReleaseBranch () {
|
|
||||||
console.log(`Creating release branch.`)
|
|
||||||
let checkoutDetails = await GitProcess.exec([ 'checkout', '-b', 'release' ], gitDir)
|
|
||||||
if (checkoutDetails.exitCode === 0) {
|
|
||||||
console.log(`${pass} Successfully created the release branch.`)
|
|
||||||
} else {
|
|
||||||
const error = GitProcess.parseError(checkoutDetails.stderr)
|
|
||||||
if (error === GitError.BranchAlreadyExists) {
|
|
||||||
console.log(`${fail} Release branch already exists, aborting prepare ` +
|
|
||||||
`release process.`)
|
|
||||||
} else {
|
|
||||||
console.log(`${fail} Error creating release branch: ` +
|
|
||||||
`${checkoutDetails.stderr}`)
|
|
||||||
}
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getNewVersion (dryRun) {
|
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')
|
||||||
|
@ -98,7 +80,7 @@ async function getReleaseNotes (currentBranch) {
|
||||||
console.log(`Checking for commits from ${pkg.version} to ${currentBranch}`)
|
console.log(`Checking for commits from ${pkg.version} to ${currentBranch}`)
|
||||||
let commitComparison = await github.repos.compareCommits(githubOpts)
|
let commitComparison = await github.repos.compareCommits(githubOpts)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(`{$fail} Error checking for commits from ${pkg.version} to ` +
|
console.log(`${fail} Error checking for commits from ${pkg.version} to ` +
|
||||||
`${currentBranch}`, err)
|
`${currentBranch}`, err)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
})
|
})
|
||||||
|
@ -116,6 +98,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 = getNewVersion()
|
||||||
|
await tagRelease(newVersion)
|
||||||
const githubOpts = {
|
const githubOpts = {
|
||||||
owner: 'electron',
|
owner: 'electron',
|
||||||
repo: 'electron'
|
repo: 'electron'
|
||||||
|
@ -156,25 +139,37 @@ async function createRelease (branchToTarget, isBeta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pushRelease () {
|
async function pushRelease () {
|
||||||
let pushDetails = await GitProcess.exec(['push', 'origin', 'HEAD'], gitDir)
|
let pushDetails = await GitProcess.exec(['push', 'origin', 'HEAD', '--follow-tags'], gitDir)
|
||||||
if (pushDetails.exitCode === 0) {
|
if (pushDetails.exitCode === 0) {
|
||||||
console.log(`${pass} Successfully pushed the release branch. Wait for ` +
|
console.log(`${pass} Successfully pushed the release. Wait for ` +
|
||||||
`release builds to finish before running "npm run release".`)
|
`release builds to finish before running "npm run release".`)
|
||||||
} else {
|
} else {
|
||||||
console.log(`${fail} Error pushing the release branch: ` +
|
console.log(`${fail} Error pushing the release: ` +
|
||||||
`${pushDetails.stderr}`)
|
`${pushDetails.stderr}`)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runReleaseBuilds () {
|
async function runReleaseBuilds (branch) {
|
||||||
await ciReleaseBuild('release', {
|
await ciReleaseBuild(branch, {
|
||||||
ghRelease: true
|
ghRelease: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function tagRelease (version) {
|
||||||
|
console.log(`Tagging release ${version}.`)
|
||||||
|
let checkoutDetails = await GitProcess.exec([ 'tag', '-a', '-m', version, version ], gitDir)
|
||||||
|
if (checkoutDetails.exitCode === 0) {
|
||||||
|
console.log(`${pass} Successfully tagged ${version}.`)
|
||||||
|
} else {
|
||||||
|
console.log(`${fail} Error tagging ${version}: ` +
|
||||||
|
`${checkoutDetails.stderr}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function verifyNewVersion () {
|
async function verifyNewVersion () {
|
||||||
let newVersion = await getNewVersion(true)
|
let newVersion = getNewVersion(true)
|
||||||
let response = await promptForVersion(newVersion)
|
let response = await promptForVersion(newVersion)
|
||||||
if (response.match(/^y/i)) {
|
if (response.match(/^y/i)) {
|
||||||
console.log(`${pass} Starting release of ${newVersion}`)
|
console.log(`${pass} Starting release of ${newVersion}`)
|
||||||
|
@ -204,10 +199,9 @@ async function prepareRelease (isBeta, notesOnly) {
|
||||||
console.log(`Draft release notes are: ${releaseNotes}`)
|
console.log(`Draft release notes are: ${releaseNotes}`)
|
||||||
} else {
|
} else {
|
||||||
await verifyNewVersion()
|
await verifyNewVersion()
|
||||||
await createReleaseBranch()
|
|
||||||
await createRelease(currentBranch, isBeta)
|
await createRelease(currentBranch, isBeta)
|
||||||
await pushRelease()
|
await pushRelease()
|
||||||
await runReleaseBuilds()
|
await runReleaseBuilds(currentBranch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ new Promise((resolve, reject) => {
|
||||||
tempDir = dirPath
|
tempDir = dirPath
|
||||||
// copy files from `/npm` to temp directory
|
// copy files from `/npm` to temp directory
|
||||||
files.forEach((name) => {
|
files.forEach((name) => {
|
||||||
const noThirdSegment = name === 'README.md' || 'LICENSE'
|
const noThirdSegment = name === 'README.md' || name === 'LICENSE'
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.join(tempDir, name),
|
path.join(tempDir, name),
|
||||||
fs.readFileSync(path.join(__dirname, '..', noThirdSegment ? '' : 'npm', name))
|
fs.readFileSync(path.join(__dirname, '..', noThirdSegment ? '' : 'npm', name))
|
||||||
|
|
Loading…
Reference in a new issue