backport
Version:
A CLI tool that automates the process of backporting commits
361 lines (352 loc) • 14.7 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const os_1 = __importDefault(require("os"));
const nock_1 = __importDefault(require("nock"));
const nockHelpers_1 = require("../../test/nockHelpers");
const childProcess = __importStar(require("../child-process-promisified"));
const logger = __importStar(require("../logger"));
const oraModule = __importStar(require("../ora"));
const autoMergeNowOrLater = __importStar(require("./autoMergeNowOrLater"));
const cherrypickAndCreateTargetPullRequest_1 = require("./cherrypickAndCreateTargetPullRequest");
describe('cherrypickAndCreateTargetPullRequest', () => {
let execSpy;
let addLabelsScope;
let consoleLogSpy;
let autoMergeSpy;
beforeEach(() => {
jest.spyOn(os_1.default, 'homedir').mockReturnValue('/myHomeDir');
autoMergeSpy = jest.spyOn(autoMergeNowOrLater, 'autoMergeNowOrLater');
execSpy = jest
.spyOn(childProcess, 'spawnPromise')
// mock all spawn commands to respond without errors
.mockResolvedValue({ stdout: '', stderr: '', code: 0, cmdArgs: [] });
consoleLogSpy = jest.spyOn(logger, 'consoleLog');
// ensure labels are added
addLabelsScope = (0, nock_1.default)('https://api.github.com')
.post('/repos/elastic/kibana/issues/1337/labels', {
labels: ['backport'],
})
.reply(200);
});
afterEach(() => {
jest.clearAllMocks();
addLabelsScope.done();
nock_1.default.cleanAll();
});
describe('when commit has a pull request reference', () => {
let res;
let createPullRequestCalls;
let oraSpy;
beforeEach(async () => {
const options = {
assignees: [],
authenticatedUsername: 'sqren_authenticated',
author: 'sorenlouv',
autoMerge: true,
autoMergeMethod: 'squash',
fork: true,
gitAuthorEmail: 'soren@louv.dk',
gitAuthorName: 'Soren L',
githubApiBaseUrlV4: 'http://localhost/graphql',
interactive: false,
prTitle: '[{{targetBranch}}] {{commitMessages}}',
repoForkOwner: 'sorenlouv',
repoName: 'kibana',
repoOwner: 'elastic',
reviewers: [],
sourceBranch: 'myDefaultSourceBranch',
sourcePRLabels: [],
targetPRLabels: ['backport'],
};
const commits = [
{
author: {
email: 'soren.louv@elastic.co',
name: 'Søren Louv-Jansen',
},
sourceBranch: '7.x',
suggestedTargetBranches: [],
sourceCommit: {
branchLabelMapping: {},
committedDate: 'fff',
sha: 'mySha',
message: 'My original commit message (#1000)',
},
sourcePullRequest: {
labels: [],
url: 'foo',
number: 1000,
title: 'My original commit message',
mergeCommit: {
sha: 'mySha',
message: 'My original commit message (#1000)',
},
},
targetPullRequestStates: [],
},
{
author: {
email: 'soren.louv@elastic.co',
name: 'Søren Louv-Jansen',
},
sourceBranch: '7.x',
suggestedTargetBranches: [],
sourceCommit: {
branchLabelMapping: {},
committedDate: 'ggg',
sha: 'mySha2',
message: 'My other commit message (#2000)',
},
sourcePullRequest: {
labels: [],
url: 'foo',
number: 2000,
title: 'My other commit message',
mergeCommit: {
sha: 'mySha2',
message: 'My other commit message (#2000)',
},
},
targetPullRequestStates: [],
},
];
(0, nockHelpers_1.mockUrqlRequest)({
operationName: 'GetBranchId',
body: { data: { repository: { ref: { id: 'foo' } } } },
});
const scope = (0, nock_1.default)('https://api.github.com')
.post('/repos/elastic/kibana/pulls')
.reply(200, { number: 1337, html_url: 'myHtmlUrl' });
createPullRequestCalls = (0, nockHelpers_1.listenForCallsToNockScope)(scope);
oraSpy = jest.spyOn(oraModule, 'ora');
res = await (0, cherrypickAndCreateTargetPullRequest_1.cherrypickAndCreateTargetPullRequest)({
options,
commits,
targetBranch: '6.x',
});
scope.done();
nock_1.default.cleanAll();
});
it('creates the pull request with multiple PR references', () => {
expect(createPullRequestCalls).toMatchInlineSnapshot(`
[
{
"base": "6.x",
"body": "# Backport
This will backport the following commits from \`7.x\` to \`6.x\`:
- [My original commit message (#1000)](foo)
- [My other commit message (#2000)](foo)
<!--- Backport version: 1.2.3-mocked -->
### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport)",
"head": "sorenlouv:backport/6.x/pr-1000_pr-2000",
"title": "[6.x] My original commit message (#1000) | My other commit message (#2000)",
},
]
`);
});
it('calls autoMergeNowOrLater', () => {
expect(autoMergeSpy).toHaveBeenCalledWith(expect.any(Object), 1337);
});
it('returns the expected response', () => {
expect(res).toEqual({ didUpdate: false, url: 'myHtmlUrl', number: 1337 });
});
it('should make correct git commands', () => {
expect(execSpy.mock.calls).toMatchSnapshot();
});
it('logs correctly', () => {
expect(consoleLogSpy.mock.calls.length).toBe(2);
expect(consoleLogSpy.mock.calls[0][0]).toMatchInlineSnapshot(`
"
Backporting to 6.x:"
`);
expect(consoleLogSpy.mock.calls[1][0]).toMatchInlineSnapshot(`"View pull request: myHtmlUrl"`);
});
it('should start the spinner with the correct text', () => {
expect(oraSpy.mock.calls.map(([, text]) => text)).toMatchInlineSnapshot(`
[
"",
"Pulling latest changes",
"Cherry-picking: My original commit message (#1000)",
"Cherry-picking: My other commit message (#2000)",
"Pushing branch "sorenlouv:backport/6.x/pr-1000_pr-2000"",
undefined,
"Creating pull request",
"Adding labels: backport",
"Auto-merge: Enabling via "squash"",
]
`);
});
});
describe('when commit does not have a pull request reference', () => {
let res;
let createPullRequestCalls;
beforeEach(async () => {
const options = {
assignees: [],
authenticatedUsername: 'sqren_authenticated',
author: 'sorenlouv',
fork: true,
prTitle: '[{{targetBranch}}] {{commitMessages}}',
repoForkOwner: 'the_fork_owner',
repoName: 'kibana',
repoOwner: 'elastic',
reviewers: [],
sourcePRLabels: [],
targetPRLabels: ['backport'],
githubApiBaseUrlV4: 'http://localhost/graphql',
};
const commits = [
{
author: {
email: 'soren.louv@elastic.co',
name: 'Søren Louv-Jansen',
},
suggestedTargetBranches: [],
sourceCommit: {
branchLabelMapping: {},
committedDate: 'hhh',
sha: 'mySha',
message: 'My original commit message',
},
sourceBranch: '7.x',
targetPullRequestStates: [],
},
];
(0, nockHelpers_1.mockUrqlRequest)({
operationName: 'GetBranchId',
body: { data: { repository: { ref: { id: 'foo' } } } },
});
const scope = (0, nock_1.default)('https://api.github.com')
.post('/repos/elastic/kibana/pulls')
.reply(200, { number: 1337, html_url: 'myHtmlUrl' });
createPullRequestCalls = (0, nockHelpers_1.listenForCallsToNockScope)(scope);
res = await (0, cherrypickAndCreateTargetPullRequest_1.cherrypickAndCreateTargetPullRequest)({
options,
commits,
targetBranch: '6.x',
});
scope.done();
nock_1.default.cleanAll();
});
it('creates the pull request with commit reference', () => {
expect(createPullRequestCalls).toMatchInlineSnapshot(`
[
{
"base": "6.x",
"body": "# Backport
This will backport the following commits from \`7.x\` to \`6.x\`:
- My original commit message (mySha)
<!--- Backport version: 1.2.3-mocked -->
### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport)",
"head": "the_fork_owner:backport/6.x/commit-mySha",
"title": "[6.x] My original commit message",
},
]
`);
});
it('returns the expected response', () => {
expect(res).toEqual({ didUpdate: false, url: 'myHtmlUrl', number: 1337 });
});
});
describe('when cherry-picking fails', () => {
let res;
let createPullRequestCalls;
beforeEach(async () => {
const options = {
assignees: [],
authenticatedUsername: 'sqren_authenticated',
author: 'sorenlouv',
fork: true,
githubApiBaseUrlV4: 'http://localhost/graphql',
prTitle: '[{{targetBranch}}] {{commitMessages}}',
repoForkOwner: 'sorenlouv',
repoName: 'kibana',
repoOwner: 'elastic',
reviewers: [],
sourceBranch: 'myDefaultSourceBranch',
sourcePRLabels: [],
targetPRLabels: ['backport'],
};
(0, nockHelpers_1.mockUrqlRequest)({
operationName: 'GetBranchId',
body: { data: { repository: { ref: { id: 'foo' } } } },
});
const scope = (0, nock_1.default)('https://api.github.com')
.post('/repos/elastic/kibana/pulls')
.reply(200, { number: 1337, html_url: 'myHtmlUrl' });
createPullRequestCalls = (0, nockHelpers_1.listenForCallsToNockScope)(scope);
res = await (0, cherrypickAndCreateTargetPullRequest_1.cherrypickAndCreateTargetPullRequest)({
options,
commits: [
{
author: {
email: 'soren.louv@elastic.co',
name: 'Søren Louv-Jansen',
},
suggestedTargetBranches: [],
sourceCommit: {
branchLabelMapping: {},
committedDate: '2021-08-18T16:11:38Z',
sha: 'mySha',
message: 'My original commit message',
},
sourceBranch: '7.x',
targetPullRequestStates: [],
},
],
targetBranch: '6.x',
});
scope.done();
nock_1.default.cleanAll();
});
it('creates the pull request with commit reference', () => {
expect(createPullRequestCalls).toMatchInlineSnapshot(`
[
{
"base": "6.x",
"body": "# Backport
This will backport the following commits from \`7.x\` to \`6.x\`:
- My original commit message (mySha)
<!--- Backport version: 1.2.3-mocked -->
### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport)",
"head": "sorenlouv:backport/6.x/commit-mySha",
"title": "[6.x] My original commit message",
},
]
`);
});
it('returns the expected response', () => {
expect(res).toEqual({ didUpdate: false, url: 'myHtmlUrl', number: 1337 });
});
});
});
//# sourceMappingURL=cherrypickAndCreateTargetPullRequest.test.js.map