mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 02:54:21 +08:00
ci: rebase PRs on target branch
This commit is contained in:
parent
b32ad328cf
commit
efac7b61ba
@ -9,6 +9,13 @@ skip_branch_with_pr: true
|
|||||||
|
|
||||||
install:
|
install:
|
||||||
- ps: Install-Product node $env:nodejs_version
|
- ps: Install-Product node $env:nodejs_version
|
||||||
|
- ps: |
|
||||||
|
if (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) {
|
||||||
|
# user is required for rebase.
|
||||||
|
git config user.name "angular-ci"
|
||||||
|
git config user.email "angular-ci"
|
||||||
|
# Rebase on target branch.
|
||||||
|
node tools\rebase-pr.js angular/angular-cli $env:APPVEYOR_PULL_REQUEST_NUMBER }
|
||||||
# --network-timeout is a workaround for https://github.com/yarnpkg/yarn/issues/6221
|
# --network-timeout is a workaround for https://github.com/yarnpkg/yarn/issues/6221
|
||||||
- yarn --frozen-lockfile --network-timeout=500000
|
- yarn --frozen-lockfile --network-timeout=500000
|
||||||
- yarn webdriver-update
|
- yarn webdriver-update
|
||||||
|
@ -25,26 +25,19 @@ anchor_1: &defaults
|
|||||||
docker:
|
docker:
|
||||||
- image: *docker_image
|
- image: *docker_image
|
||||||
|
|
||||||
# After checkout, rebase on top of master.
|
# After checkout, rebase on top of target branch.
|
||||||
# Similar to travis behavior, but not quite the same.
|
|
||||||
# See https://discuss.circleci.com/t/1662
|
|
||||||
anchor_2: &post_checkout
|
anchor_2: &post_checkout
|
||||||
run:
|
run:
|
||||||
name: Post checkout step
|
name: Rebase PR on target branch
|
||||||
command: >
|
command: >
|
||||||
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
|
if [[ -n "${CIRCLE_PR_NUMBER}" ]]; then
|
||||||
# Fetch the head and merge commits for this PR.
|
# User is required for rebase.
|
||||||
git fetch origin +refs/pull/$CIRCLE_PR_NUMBER/head:pr/$CIRCLE_PR_NUMBER/head
|
git config user.name "angular-ci"
|
||||||
git fetch origin +refs/pull/$CIRCLE_PR_NUMBER/merge:pr/$CIRCLE_PR_NUMBER/merge
|
git config user.email "angular-ci"
|
||||||
# Checkout the merged PR for testing as CircleCI will just use the PR head otherwise.
|
# Rebase PR on top of target branch.
|
||||||
git checkout -qf pr/$CIRCLE_PR_NUMBER/merge
|
node tools/rebase-pr.js angular/angular-cli ${CIRCLE_PR_NUMBER}
|
||||||
# Reset the merge commit into its PR head.
|
else
|
||||||
git reset pr/$CIRCLE_PR_NUMBER/head
|
echo "This build is not over a PR, nothing to do."
|
||||||
# Commit the merge changes into the head of the PR.
|
|
||||||
# This way we keep the last commit message.
|
|
||||||
git config user.name "angular-ci"
|
|
||||||
git config user.email "angular-ci"
|
|
||||||
git commit . --amend --no-edit
|
|
||||||
fi
|
fi
|
||||||
anchor_3: &restore_cache
|
anchor_3: &restore_cache
|
||||||
restore_cache:
|
restore_cache:
|
||||||
|
92
tools/rebase-pr.js
Normal file
92
tools/rebase-pr.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google Inc. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by an MIT-style license that can be
|
||||||
|
* found in the LICENSE file at https://angular.io/license
|
||||||
|
*/
|
||||||
|
|
||||||
|
// tslint:disable:no-console
|
||||||
|
// ** IMPORTANT **
|
||||||
|
// This script cannot use external dependencies because it needs to run before they are installed.
|
||||||
|
|
||||||
|
const util = require('util');
|
||||||
|
const https = require('https');
|
||||||
|
const child_process = require('child_process');
|
||||||
|
const exec = util.promisify(child_process.exec);
|
||||||
|
|
||||||
|
function determineTargetBranch(repository, prNumber) {
|
||||||
|
const pullsUrl = `https://api.github.com/repos/${repository}/pulls/${prNumber}`;
|
||||||
|
// GitHub requires a user agent: https://developer.github.com/v3/#user-agent-required
|
||||||
|
const options = { headers: { 'User-Agent': repository } };
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
https.get(pullsUrl, options, (res) => {
|
||||||
|
const { statusCode } = res;
|
||||||
|
const contentType = res.headers['content-type'];
|
||||||
|
|
||||||
|
let error;
|
||||||
|
if (statusCode !== 200) {
|
||||||
|
error = new Error(`Request Failed.\nStatus Code: ${statusCode}.\nResponse: ${res}.\n' +`);
|
||||||
|
} else if (!/^application\/json/.test(contentType)) {
|
||||||
|
error = new Error('Invalid content-type.\n' +
|
||||||
|
`Expected application/json but received ${contentType}`);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
res.resume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setEncoding('utf8');
|
||||||
|
let rawData = '';
|
||||||
|
res.on('data', (chunk) => { rawData += chunk; });
|
||||||
|
res.on('end', () => {
|
||||||
|
try {
|
||||||
|
const parsedData = JSON.parse(rawData);
|
||||||
|
resolve(parsedData['base']['ref']);
|
||||||
|
} catch (e) {
|
||||||
|
reject(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).on('error', (e) => {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.argv.length != 4) {
|
||||||
|
console.error(`This script requires the GitHub repository and PR number as arguments.`);
|
||||||
|
console.error(`Example: node scripts/rebase-pr.js angular/angular 123`);
|
||||||
|
process.exitCode = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const repository = process.argv[2];
|
||||||
|
const prNumber = process.argv[3];
|
||||||
|
let targetBranch;
|
||||||
|
|
||||||
|
|
||||||
|
return Promise.resolve()
|
||||||
|
.then(() => {
|
||||||
|
console.log(`Determining target branch for PR ${prNumber} on ${repository}.`);
|
||||||
|
return determineTargetBranch(repository, prNumber);
|
||||||
|
})
|
||||||
|
.then(target => {
|
||||||
|
targetBranch = target;
|
||||||
|
console.log(`Target branch is ${targetBranch}.`);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
console.log(`Fetching ${targetBranch} from origin.`);
|
||||||
|
return exec(`git fetch origin ${targetBranch}`);
|
||||||
|
})
|
||||||
|
.then(target => {
|
||||||
|
console.log(`Rebasing current branch on ${targetBranch}.`);
|
||||||
|
return exec(`git rebase origin/${targetBranch}`);
|
||||||
|
})
|
||||||
|
.then(() => console.log('Rebase successfull.'))
|
||||||
|
.catch(err => {
|
||||||
|
console.log('Failed to rebase on top or target branch.\n');
|
||||||
|
console.error(err);
|
||||||
|
process.exitCode = 1;
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user