Skip to content

Commit

Permalink
feat: request reviewers automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
korthout committed Nov 27, 2020
1 parent 7044208 commit b405c7e
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 41 deletions.
56 changes: 39 additions & 17 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

91 changes: 68 additions & 23 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@ import * as core from "@actions/core";
import { exec } from "@actions/exec";
import * as github from "@actions/github";
import { EventPayloads } from "@octokit/webhooks";
import { OctokitResponse, PullsCreateResponseData } from "@octokit/types";
import {
OctokitResponse,
PullsCreateResponseData,
PullsRequestReviewersResponseData,
} from "@octokit/types";
import dedent from "dedent";
import { resolve } from "path";

const labelRegExp = /^backport ([^ ]+)?$/;

Expand All @@ -29,6 +34,13 @@ type PRContent = {
body: string;
};

type ReviewRequest = {
owner: string;
repo: string;
pull_number: number;
reviewers?: string[];
};

async function run(): Promise<void> {
try {
const token = core.getInput("github_token", { required: true });
Expand All @@ -40,11 +52,11 @@ async function run(): Promise<void> {
const owner = github.context.repo.owner;
const repo = payload.repository.name;

const issue_number = payload.pull_request.number;
const issue_title = payload.pull_request.title;
const headref = payload.pull_request.head.sha;
const baseref = payload.pull_request.base.sha;
const labels = payload.pull_request.labels;
const pr = payload.pull_request;
const headref = pr.head.sha;
const baseref = pr.base.sha;
const labels = pr.labels;
const reviewers = pr.requested_reviewers.map((r) => r.login);

console.log(`Detected labels on PR: ${labels.map((label) => label.name)}`);

Expand All @@ -64,7 +76,7 @@ async function run(): Promise<void> {
console.log(`Found target in label: ${target}`);

try {
const branchname = `backport-${issue_number}-to-${target}`;
const branchname = `backport-${pr.number}-to-${target}`;

console.log(`Start backport to ${branchname}`);
const exitcode = await callBackportScript(
Expand All @@ -80,20 +92,15 @@ async function run(): Promise<void> {
const message = composeMessageForGitFailure(target, exitcode);
console.error(message);
await createComment(
{ owner, repo, issue_number, body: message },
{ owner, repo, issue_number: pr.number, body: message },
token
);
continue;
}

const { title, body } = composePRContent(
target,
issue_title,
issue_number
);

console.info(`Create PR for ${branchname}`);
const response = await createPR(
const { title, body } = composePRContent(target, pr.title, pr.number);
const new_pr_response = await createPR(
{
owner,
repo,
Expand All @@ -106,26 +113,43 @@ async function run(): Promise<void> {
token
);

if (response.status != 201) {
console.error(JSON.stringify(response));
const message = composeMessageForCreatePRFailed(response);
if (new_pr_response.status != 201) {
console.error(JSON.stringify(new_pr_response));
const message = composeMessageForCreatePRFailed(new_pr_response);
await createComment(
{ owner, repo, issue_number, body: message },
{ owner, repo, issue_number: pr.number, body: message },
token
);
continue;
}
const new_pr = new_pr_response.data;

const pr_number = response.data.number;
const message = `Successfully created backport PR #${pr_number} for \`${target}\`.`;
const review_response = await requestReviewers(
{ owner, repo, pull_number: new_pr.number, reviewers },
token
);
if (review_response.status != 201) {
console.error(JSON.stringify(review_response));
const message = composeMessageForRequestReviewersFailed(
review_response,
target
);
await createComment(
{ owner, repo, issue_number: pr.number, body: message },
token
);
continue;
}

const message = composeMessageForSuccess(new_pr.number, target);
await createComment(
{ owner, repo, issue_number, body: message },
{ owner, repo, issue_number: pr.number, body: message },
token
);
} catch (error) {
console.error(error.message);
await createComment(
{ owner, repo, issue_number, body: error.message },
{ owner, repo, issue_number: pr.number, body: error.message },
token
);
}
Expand Down Expand Up @@ -179,6 +203,11 @@ function composePRContent(
return { title, body };
}

async function requestReviewers(request: ReviewRequest, token: string) {
console.log(`Request reviewers: ${request.reviewers}`);
return github.getOctokit(token).pulls.requestReviewers(request);
}

function composeMessageForGitFailure(target: string, exitcode: number): string {
//TODO better error messages depending on exit code
return dedent`Backport failed for ${target} with exitcode ${exitcode}`;
Expand All @@ -193,4 +222,20 @@ function composeMessageForCreatePRFailed(
(see action log for full response)`;
}

function composeMessageForRequestReviewersFailed(
response: OctokitResponse<PullsRequestReviewersResponseData>,
target: string
): string {
return dedent`${composeMessageForSuccess(response.data.number, target)}
But, request reviewers was rejected with status ${
response.status
}.
(see action log for full response)`;
}

function composeMessageForSuccess(pr_number: number, target: string) {
return dedent`Successfully created backport PR #${pr_number} for \`${target}\`.`;
}

run();

0 comments on commit b405c7e

Please sign in to comment.