backport
Version:
A CLI tool that automates the process of backporting commits
378 lines (369 loc) • 15 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const rest_1 = require("@octokit/rest");
const entrypoint_api_1 = require("../../../entrypoint.api");
const commitFormatters_1 = require("../../../lib/github/commitFormatters");
const getDevAccessToken_1 = require("../../private/getDevAccessToken");
const sandbox_1 = require("../../sandbox");
jest.unmock('find-up');
jest.unmock('del');
jest.unmock('make-dir');
jest.setTimeout(25000);
const accessToken = (0, getDevAccessToken_1.getDevAccessToken)();
const octokit = new rest_1.Octokit({ auth: accessToken });
const sandboxPath = (0, sandbox_1.getSandboxPath)({ filename: __filename });
// repo
const REPO_OWNER = 'backport-org';
const REPO_NAME = 'integration-test';
const AUTHOR = 'sorenlouv';
// commit 1
const COMMIT_SHA_1 = '5bf29b7d847ea3dbde9280448f0f62ad0f22d3ad';
const BRANCH_WITH_ONE_COMMIT = `backport/7.x/commit-${(0, commitFormatters_1.getShortSha)(COMMIT_SHA_1)}`;
// commit 2
const COMMIT_SHA_2 = '59d6ff1ca90a4ce210c0a4f0e159214875c19d60';
const BRANCH_WITH_TWO_COMMITS = `backport/7.x/commit-${(0, commitFormatters_1.getShortSha)(COMMIT_SHA_1)}_commit-${(0, commitFormatters_1.getShortSha)(COMMIT_SHA_2)}`;
describe('entrypoint.module', () => {
describe('when a single commit is backported', () => {
let res;
let pullRequestResponse;
beforeAll(async () => {
await resetState(accessToken);
res = await (0, entrypoint_api_1.backportRun)({
options: {
dir: sandboxPath,
accessToken,
repoOwner: 'backport-org',
repoName: 'integration-test',
sha: COMMIT_SHA_1,
targetBranches: ['7.x'],
},
});
// @ts-expect-error
const pullRequestNumber = res.results[0].pullRequestNumber;
pullRequestResponse = await octokit.pulls.get({
owner: REPO_OWNER,
repo: REPO_NAME,
pull_number: pullRequestNumber,
});
});
it('returns the backport result', () => {
expect(res).toEqual({
commits: [
{
author: { email: 'sorenlouv@gmail.com', name: 'Søren Louv-Jansen' },
targetPullRequestStates: [],
sourceBranch: 'master',
sourceCommit: {
committedDate: '2020-08-15T10:37:41Z',
message: 'Add ❤️ emoji',
sha: COMMIT_SHA_1,
branchLabelMapping: undefined,
},
suggestedTargetBranches: [],
sourcePullRequest: undefined,
},
],
results: [
{
didUpdate: false,
pullRequestNumber: expect.any(Number),
pullRequestUrl: expect.stringContaining('https://github.com/backport-org/integration-test/pull/'),
status: 'success',
targetBranch: '7.x',
},
],
status: 'success',
});
});
it('pull request: status code', async () => {
expect(pullRequestResponse.status).toEqual(200);
});
it('pull request: title', async () => {
expect(pullRequestResponse.data.title).toEqual('[7.x] Add ❤️ emoji');
});
it('pull request: body', async () => {
expect(pullRequestResponse.data.body).toMatchInlineSnapshot(`
"# Backport
This will backport the following commits from \`master\` to \`7.x\`:
- Add ❤️ emoji (5bf29b7d)
<!--- Backport version: 1.2.3-mocked -->
### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport)"
`);
});
it('pull request: head branch is in fork repo', async () => {
expect(pullRequestResponse.data.head.label).toEqual(`sorenlouv:${BRANCH_WITH_ONE_COMMIT}`);
});
it('pull request: base branch', async () => {
expect(pullRequestResponse.data.base.label).toEqual('backport-org:7.x');
});
it('does not create any new branches in origin (backport-org/integration-test)', async () => {
const branches = await getBranchesOnGithub({
accessToken,
repoOwner: REPO_OWNER,
repoName: REPO_NAME,
});
expect(branches.map((b) => b.name)).toEqual(['7.x', 'master']);
});
it('creates a branch in the fork (sorenlouv/integration-test)', async () => {
const branches = await getBranchesOnGithub({
accessToken,
repoOwner: AUTHOR,
repoName: REPO_NAME,
});
expect(branches.map((b) => b.name)).toEqual([
'7.x',
BRANCH_WITH_ONE_COMMIT,
'master',
]);
});
});
describe('when two commits are backported', () => {
let res;
let pullRequestResponse;
beforeAll(async () => {
await resetState(accessToken);
res = await (0, entrypoint_api_1.backportRun)({
options: {
dir: sandboxPath,
accessToken,
repoOwner: 'backport-org',
repoName: 'integration-test',
sha: [COMMIT_SHA_1, COMMIT_SHA_2],
targetBranches: ['7.x'],
},
});
// @ts-expect-error
const pullRequestNumber = res.results[0].pullRequestNumber;
pullRequestResponse = await octokit.pulls.get({
owner: REPO_OWNER,
repo: REPO_NAME,
pull_number: pullRequestNumber,
});
});
it('returns the backport result containing both commits', () => {
expect(res).toEqual({
commits: [
{
author: { email: 'sorenlouv@gmail.com', name: 'Søren Louv-Jansen' },
targetPullRequestStates: [],
sourceBranch: 'master',
sourceCommit: {
committedDate: '2020-08-15T10:37:41Z',
message: 'Add ❤️ emoji',
sha: COMMIT_SHA_1,
branchLabelMapping: undefined,
},
suggestedTargetBranches: [],
sourcePullRequest: undefined,
},
{
author: { email: 'sorenlouv@gmail.com', name: 'Søren Louv-Jansen' },
suggestedTargetBranches: [],
targetPullRequestStates: [],
sourceBranch: 'master',
sourceCommit: {
committedDate: '2020-08-15T10:44:04Z',
message: 'Add family emoji (#2)',
sha: COMMIT_SHA_2,
},
sourcePullRequest: undefined,
},
],
results: [
{
didUpdate: false,
pullRequestNumber: expect.any(Number),
pullRequestUrl: expect.stringContaining('https://github.com/backport-org/integration-test/pull/'),
status: 'success',
targetBranch: '7.x',
},
],
status: 'success',
});
});
it('pull request: status code', async () => {
expect(pullRequestResponse.status).toEqual(200);
});
it('pull request: title', async () => {
expect(pullRequestResponse.data.title).toEqual('[7.x] Add ❤️ emoji | Add family emoji (#2)');
});
it('pull request: body', async () => {
expect(pullRequestResponse.data.body).toMatchInlineSnapshot(`
"# Backport
This will backport the following commits from \`master\` to \`7.x\`:
- Add ❤️ emoji (5bf29b7d)
- Add family emoji (#2) (59d6ff1c)
<!--- Backport version: 1.2.3-mocked -->
### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport)"
`);
});
it('pull request: head branch contains both commits in name', async () => {
expect(pullRequestResponse.data.head.label).toEqual(`sorenlouv:${BRANCH_WITH_TWO_COMMITS}`);
});
it('pull request: base branch', async () => {
expect(pullRequestResponse.data.base.label).toEqual('backport-org:7.x');
});
});
describe('when disabling fork mode', () => {
let res;
let pullRequestResponse;
beforeAll(async () => {
await resetState(accessToken);
res = await (0, entrypoint_api_1.backportRun)({
options: {
fork: false,
dir: sandboxPath,
accessToken,
repoOwner: 'backport-org',
repoName: 'integration-test',
sha: COMMIT_SHA_1,
targetBranches: ['7.x'],
},
});
// @ts-expect-error
const pullRequestNumber = res.results[0].pullRequestNumber;
pullRequestResponse = await octokit.pulls.get({
owner: REPO_OWNER,
repo: REPO_NAME,
pull_number: pullRequestNumber,
});
});
it('pull request: title', async () => {
expect(pullRequestResponse.data.title).toEqual('[7.x] Add ❤️ emoji');
});
it('pull request: body', async () => {
expect(pullRequestResponse.data.body).toMatchInlineSnapshot(`
"# Backport
This will backport the following commits from \`master\` to \`7.x\`:
- Add ❤️ emoji (5bf29b7d)
<!--- Backport version: 1.2.3-mocked -->
### Questions ?
Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport)"
`);
});
it('pull request: head branch is in origin (non-fork) repo', async () => {
expect(pullRequestResponse.data.head.label).toEqual(`backport-org:${BRANCH_WITH_ONE_COMMIT}`);
});
it('pull request: base branch', async () => {
expect(pullRequestResponse.data.base.label).toEqual('backport-org:7.x');
});
it('returns pull request', () => {
expect(res).toEqual({
commits: [
{
author: { email: 'sorenlouv@gmail.com', name: 'Søren Louv-Jansen' },
targetPullRequestStates: [],
sourceBranch: 'master',
sourceCommit: {
committedDate: '2020-08-15T10:37:41Z',
message: 'Add ❤️ emoji',
sha: COMMIT_SHA_1,
branchLabelMapping: undefined,
},
suggestedTargetBranches: [],
sourcePullRequest: undefined,
},
],
results: [
{
didUpdate: false,
pullRequestNumber: expect.any(Number),
pullRequestUrl: expect.stringContaining('https://github.com/backport-org/integration-test/pull/'),
status: 'success',
targetBranch: '7.x',
},
],
status: 'success',
});
});
it('creates a new branch in origin (backport-org/integration-test)', async () => {
const branches = await getBranchesOnGithub({
accessToken,
repoOwner: REPO_OWNER,
repoName: REPO_NAME,
});
expect(branches.map((b) => b.name)).toEqual([
'7.x',
BRANCH_WITH_ONE_COMMIT,
'master',
]);
});
it('does not create branches in the fork (sorenlouv/integration-test)', async () => {
const branches = await getBranchesOnGithub({
accessToken,
repoOwner: AUTHOR,
repoName: REPO_NAME,
});
expect(branches.map((b) => b.name)).toEqual(['7.x', 'master']);
});
});
});
async function getBranchesOnGithub({ accessToken, repoOwner, repoName, }) {
const octokit = new rest_1.Octokit({
auth: accessToken,
});
const res = await octokit.repos.listBranches({
owner: repoOwner,
repo: repoName,
});
return res.data;
}
async function deleteBranchOnGithub({ accessToken, repoOwner, repoName, branchName, }) {
try {
const octokit = new rest_1.Octokit({
auth: accessToken,
});
const opts = {
owner: repoOwner,
repo: repoName,
ref: `heads/${branchName}`,
};
const res = await octokit.git.deleteRef(opts);
return res.data;
}
catch (e) {
//@ts-expect-error
if (e.message === 'Reference does not exist') {
return;
}
throw e;
}
}
async function resetState(accessToken) {
const ownerBranches = await getBranchesOnGithub({
accessToken,
repoOwner: REPO_OWNER,
repoName: REPO_NAME,
});
// delete all branches except master and 7.x
await Promise.all(ownerBranches
.filter((b) => b.name !== 'master' && b.name !== '7.x')
.map((b) => {
return deleteBranchOnGithub({
accessToken,
repoOwner: REPO_OWNER,
repoName: REPO_NAME,
branchName: b.name,
});
}));
const forkBranches = await getBranchesOnGithub({
accessToken,
repoOwner: AUTHOR,
repoName: REPO_NAME,
});
// delete all branches except master and 7.x
await Promise.all(forkBranches
.filter((b) => b.name !== 'master' && b.name !== '7.x')
.map((b) => {
return deleteBranchOnGithub({
accessToken,
repoOwner: AUTHOR,
repoName: REPO_NAME,
branchName: b.name,
});
}));
await (0, sandbox_1.resetSandbox)(sandboxPath);
}
//# sourceMappingURL=entrypoint.module.mutation.test.js.map