Skip to content

Commit

Permalink
Merge d97e8aa into dc43b28
Browse files Browse the repository at this point in the history
  • Loading branch information
sorenlouv committed Jun 27, 2020
2 parents dc43b28 + d97e8aa commit 18f754a
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 76 deletions.
33 changes: 27 additions & 6 deletions src/runWithOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ describe('runWithOptions', () => {
let rpcExecMock: SpyHelper<typeof childProcess.exec>;
let rpcExecOriginalMock: SpyHelper<typeof childProcess.execAsCallback>;
let inquirerPromptMock: SpyHelper<typeof inquirer.prompt>;
let axiosRequestSpy: SpyHelper<typeof axios.request>;

afterEach(() => {
jest.clearAllMocks();
Expand Down Expand Up @@ -103,7 +104,7 @@ describe('runWithOptions', () => {
});

// Mock Github v3 API
jest
axiosRequestSpy = jest
.spyOn(axios, 'request')

// mock create pull request
Expand All @@ -129,19 +130,39 @@ describe('runWithOptions', () => {
});

it('createPullRequest should be called with correct args', () => {
expect(createPullRequest.createPullRequest).toHaveBeenCalledWith(
expect.objectContaining({
expect(createPullRequest.createPullRequest).toHaveBeenCalledWith({
options: expect.objectContaining({
repoName: 'kibana',
repoOwner: 'elastic',
githubApiBaseUrlV4: 'https://api.github.com/graphql',
}),
{
commits: [
{
existingTargetPullRequests: [],
formattedMessage: 'Add 👻 (2e63475c)',
pullNumber: undefined,
selectedTargetBranches: [],
sha: '2e63475c483f7844b0f2833bc57fdee32095bacb',
sourceBranch: 'mySourceBranch',
},
],
targetBranch: '6.x',
backportBranch: 'backport/6.x/commit-2e63475c',
});
});

it('should make correct request when creating pull request', () => {
expect(axiosRequestSpy).toHaveBeenCalledWith({
auth: { password: 'myAccessToken', username: 'sqren' },
data: {
base: '6.x',
body: `Backports the following commits to 6.x:\n - Add 👻 (2e63475c)\n\nmyPrDescription`,
head: 'sqren:backport/6.x/commit-2e63475c',
title: 'myPrTitle 6.x Add 👻 (2e63475c)',
}
);
},
method: 'post',
url: 'https://api.github.com/repos/elastic/kibana/pulls',
});
});

it('prompt calls should match snapshot', () => {
Expand Down
8 changes: 6 additions & 2 deletions src/services/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,21 @@ export async function createBackportBranch({
}
}

export function deleteBackportBranch({
export async function deleteBackportBranch({
options,
backportBranch,
}: {
options: BackportOptions;
backportBranch: string;
}) {
return exec(
const spinner = ora().start();

await exec(
`git checkout ${options.sourceBranch} && git branch -D ${backportBranch}`,
{ cwd: getRepoPath(options) }
);

spinner.stop();
}

export function getRemoteName(options: BackportOptions) {
Expand Down
2 changes: 1 addition & 1 deletion src/services/github/v3/addLabelsToPullRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export async function addLabelsToPullRequest(
pullNumber: number,
labels: string[]
): Promise<void> {
const text = `Adding labels to #${pullNumber}: ${labels.join(', ')}`;
const text = `Adding labels: ${labels.join(', ')}`;
logger.info(text);
const spinner = ora(text).start();

Expand Down
104 changes: 89 additions & 15 deletions src/services/github/v3/createPullRequest.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,57 @@
import chalk from 'chalk';
import ora from 'ora';
import { BackportOptions } from '../../../options/options';
import { logger } from '../../logger';
import { CommitSelected } from '../../../types/Commit';
import { getFullBackportBranch } from '../../git';
import { logger, consoleLog } from '../../logger';
import { fetchExistingPullNumber } from '../v4/fetchExistingPullRequest';
import { apiRequestV3 } from './apiRequestV3';

interface GithubIssue {
html_url: string;
number: number;
}

export async function createPullRequest(
{
export async function createPullRequest({
options,
commits,
targetBranch,
backportBranch,
}: {
options: BackportOptions;
commits: CommitSelected[];
targetBranch: string;
backportBranch: string;
}) {
const payload = getPullRequestPayload({
options,
commits,
targetBranch,
backportBranch,
});
logger.info(
`Creating PR with title: "${payload.title}". ${payload.head} -> ${payload.base}`
);

const {
githubApiBaseUrlV3,
repoName,
repoOwner,
accessToken,
username,
dryRun,
}: BackportOptions,
payload: {
title: string;
body: string;
head: string;
base: string;
}
) {
logger.info(
`Creating PR with title: "${payload.title}". ${payload.head} -> ${payload.base}`
);

} = options;
const spinner = ora(`Creating pull request`).start();

if (dryRun) {
spinner.succeed('Dry run: Creating pull request');

// output PR summary
consoleLog(chalk.bold('\nPull request summary:'));
consoleLog(`Branch: ${payload.head} -> ${payload.base}`);
consoleLog(`Title: ${payload.title}`);
consoleLog(`Body: ${payload.body}\n`);

return { html_url: 'example_url', number: 1337 };
}

Expand All @@ -53,7 +73,61 @@ export async function createPullRequest(
number: res.number,
};
} catch (e) {
try {
const existingPR = await fetchExistingPullNumber({
options,
targetBranch,
backportBranch,
});

if (existingPR) {
spinner.succeed('Updating existing pull request');
return existingPR;
}
} catch (e) {
spinner.fail();
}

spinner.fail();
throw e;
}
}

function getPullRequestPayload({
options,
commits,
targetBranch,
backportBranch,
}: {
options: BackportOptions;
commits: CommitSelected[];
targetBranch: string;
backportBranch: string;
}) {
const { prDescription, prTitle } = options;
const commitMessages = commits
.map((commit) => ` - ${commit.formattedMessage}`)
.join('\n');
const bodySuffix = prDescription ? `\n\n${prDescription}` : '';

return {
title: getPullRequestTitle(targetBranch, commits, prTitle),
body: `Backports the following commits to ${targetBranch}:\n${commitMessages}${bodySuffix}`,
head: getFullBackportBranch(options, backportBranch),
base: targetBranch,
};
}

function getPullRequestTitle(
targetBranch: string,
commits: CommitSelected[],
prTitle: string
) {
const commitMessages = commits
.map((commit) => commit.formattedMessage)
.join(' | ');
return prTitle
.replace('{targetBranch}', targetBranch)
.replace('{commitMessages}', commitMessages)
.slice(0, 240);
}
81 changes: 81 additions & 0 deletions src/services/github/v4/fetchExistingPullRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { BackportOptions } from '../../../options/options';
import { getRemoteName } from '../../git';
import { apiRequestV4 } from './apiRequestV4';

export async function fetchExistingPullNumber({
options,
targetBranch,
backportBranch,
}: {
options: BackportOptions;
targetBranch: string;
backportBranch: string;
}) {
const { githubApiBaseUrlV4, repoName, accessToken } = options;
const query = /* GraphQL */ `
query getExistingPullRequest(
$repoOwner: String!
$repoName: String!
$targetBranch: String!
$backportBranch: String!
) {
repository(owner: $repoOwner, name: $repoName) {
name
ref(qualifiedName: $backportBranch) {
name
associatedPullRequests(
first: 1
states: OPEN
baseRefName: $targetBranch
headRefName: $backportBranch
) {
edges {
node {
number
url
}
}
}
}
}
}
`;

const res = await apiRequestV4<DataResponse>({
githubApiBaseUrlV4,
accessToken,
query,
variables: {
repoOwner: getRemoteName(options),
repoName,
targetBranch,
backportBranch,
},
});

if (!res.repository.ref) {
return;
}

return {
html_url: res.repository.ref.associatedPullRequests.edges[0].node.url,
number: res.repository.ref.associatedPullRequests.edges[0].node.number,
};
}

interface DataResponse {
repository: {
name: string;
ref: {
name: string;
associatedPullRequests: {
edges: {
node: {
number: number;
url: string;
};
}[];
};
} | null;
};
}
8 changes: 4 additions & 4 deletions src/ui/cherrypickAndCreatePullRequest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ describe('cherrypickAndCreateTargetPullRequest', () => {
Array [
"Cherry-picking: myOtherCommitMessage (#2000)",
],
Array [],
Array [
"Pushing branch \\"sqren:backport/6.x/pr-1000_pr-2000\\"",
],
Array [],
Array [
"Creating pull request",
],
Array [
"Adding labels to #1337: backport",
"Adding labels: backport",
],
]
`);
Expand Down Expand Up @@ -298,15 +298,15 @@ describe('cherrypickAndCreateTargetPullRequest', () => {
Array [
"Finalizing cherrypick",
],
Array [],
Array [
"Pushing branch \\"sqren:backport/6.x/commit-mySha\\"",
],
Array [],
Array [
"Creating pull request",
],
Array [
"Adding labels to #1337: backport",
"Adding labels: backport",
],
]
`);
Expand Down
Loading

0 comments on commit 18f754a

Please sign in to comment.