Skip to content

Commit

Permalink
Merge pull request #84 from zeebe-io/author-placeholder
Browse files Browse the repository at this point in the history
Pull request author placeholder
  • Loading branch information
korthout authored Jul 4, 2021
2 parents e0508cc + 68ea0fd commit 4c106a2
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 53 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ The following placeholders are available and are replaced with:
Placeholder | Replaced with
------------|------------
`issue_refs` | GitHub issue references to all issues mentioned in the original pull request description seperated by a space, e.g. `#123 #456 zeebe-io/backport-action#789`
`pull_author` | The username of the original pull request's author, e.g. `korthout`
`pull_number` | The number of the original pull request that is backported, e.g. `123`
`target_branch`| The branchname to which the pull request is backported, e.g. `release-0.23`

Expand Down
51 changes: 31 additions & 20 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.

28 changes: 9 additions & 19 deletions src/backport.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import * as core from "@actions/core";
import dedent from "dedent";

import { CreatePullRequestResponse, RequestReviewersResponse } from "./github";
import {
CreatePullRequestResponse,
RequestReviewersResponse,
PullRequest,
} from "./github";
import { GithubApi } from "./github";
import * as exec from "./exec";
import * as utils from "./utils";
Expand Down Expand Up @@ -134,12 +138,7 @@ export class Backport {
}

console.info(`Create PR for ${branchname}`);
const { title, body } = this.composePRContent(
target,
mainpr.title,
pull_number,
mainpr.body
);
const { title, body } = this.composePRContent(target, mainpr);
const new_pr_response = await this.github.createPR({
owner,
repo,
Expand Down Expand Up @@ -208,18 +207,9 @@ export class Backport {
}
}

private composePRContent(
target: string,
issue_title: string,
issue_number: number,
original_body: string
): PRContent {
const title = `[Backport ${target}] ${issue_title}`;
const issues = utils.getMentionedIssueRefs(original_body);
const body = this.config.pull.description
.replace("${pull_number}", issue_number.toString())
.replace("${target_branch}", target)
.replace("${issue_refs}", issues.join(" "));
private composePRContent(target: string, main: PullRequest): PRContent {
const title = `[Backport ${target}] ${main.title}`;
const body = utils.composeBody(this.config.pull.description, main, target);
return { title, body };
}

Expand Down
3 changes: 3 additions & 0 deletions src/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ export type PullRequest = {
base: {
sha: string;
};
user: {
login: string;
};
labels: {
name: string;
}[];
Expand Down
91 changes: 89 additions & 2 deletions src/test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import dedent from "dedent";
import { getMentionedIssueRefs } from "../utils";
import { getMentionedIssueRefs, composeBody } from "../utils";

describe("get mentioned issues", () => {
describe("returns an empty list", () => {
Expand Down Expand Up @@ -128,8 +128,95 @@ describe("get mentioned issues", () => {
]);
});
});
});

describe("compose body", () => {
const main_default = {
number: 123,
body: "foo-body",
user: { login: "foo-author" },
};
const target = "foo-target";

describe("returns same value as provided template", () => {
it("for an empty template", () => {
expect(composeBody("", main_default, target)).toEqual("");
});

it("for a template without placeholders", () => {
const template = text({});
expect(composeBody(template, main_default, target)).toEqual(template);
});

it("for a template with unknown placeholders", () => {
const template = text({
start: "${abc}",
middle: "${def}",
end: "${ghi}",
part: "${jkl}",
});
expect(composeBody(template, main_default, target)).toEqual(template);
});
});

describe("returns evaluated templated", () => {
it("for a template with target_branch placeholder", () => {
const template = "Backport of some-title to `${target_branch}`";
expect(composeBody(template, main_default, target)).toEqual(
"Backport of some-title to `foo-target`"
);
});

it("for a template with pull_number placeholder", () => {
const template = "Backport of #${pull_number} to some-target";
expect(composeBody(template, main_default, target)).toEqual(
"Backport of #123 to some-target"
);
});

describe("for a template with issue_refs placeholder", () => {
const template = "Backport that refers to: ${issue_refs}";

it("and body has no referred issues", () => {
expect(composeBody(template, main_default, target)).toEqual(
"Backport that refers to: "
);
});

// todo deal with urls to unrelated repos
it("and body has a referred issue", () => {
expect(
composeBody(
template,
{
...main_default,
body: "Body mentions #123 and that's it.",
},
target
)
).toEqual("Backport that refers to: #123");
});

it("and body has some referred issues", () => {
expect(
composeBody(
template,
{
...main_default,
body: "This body refers to #123 and foo/bar#456",
},
target
)
).toEqual("Backport that refers to: #123 foo/bar#456");
});
});

it("for a template with pull_author placeholder", () => {
const template = "Backport of pull made by @${pull_author}";
expect(composeBody(template, main_default, target)).toEqual(
"Backport of pull made by @foo-author"
);
});
});
});

function text({
Expand Down
49 changes: 38 additions & 11 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
/**
* @param template The backport description template
* @param main The main pull request that is backported
* @param target The target branchname
* @returns Description that can be used as the backport pull request body
*/
export function composeBody(
template: string,
main: PullRequest,
target: string
): string {
const issues = getMentionedIssueRefs(main.body);
return template
.replace("${pull_author}", main.user.login)
.replace("${pull_number}", main.number.toString())
.replace("${target_branch}", target)
.replace("${issue_refs}", issues.join(" "));
}

type PullRequest = {
number: number;
body: string;
user: {
login: string;
};
};

/**
* @param body Text in which to search for mentioned issues
* @returns All found mentioned issues as GitHub issue references
*/
export function getMentionedIssueRefs(body: string): string[] {
const issueUrls =
body.match(patterns.url.global)?.map((url) => toRef(url)) ?? [];
const issueRefs = body.match(patterns.ref) ?? [];
return issueUrls.concat(issueRefs).map((ref) => ref.trim());
}

const patterns = {
// matches urls to github issues at start, middle, end of line as individual word
// may be lead and trailed by whitespace which should be trimmed
Expand All @@ -17,17 +55,6 @@ const patterns = {
ref: /(?:^| )((?<org>[^\n #\/]+)\/(?<repo>[^\n #\/]+))?#(?<number>[0-9]+)(?: |$)/gm,
};

/**
* @param body Text in which to search for mentioned issues
* @returns All found mentioned issues as GitHub issue references
*/
export function getMentionedIssueRefs(body: string): string[] {
const issueUrls =
body.match(patterns.url.global)?.map((url) => toRef(url)) ?? [];
const issueRefs = body.match(patterns.ref) ?? [];
return issueUrls.concat(issueRefs).map((ref) => ref.trim());
}

const toRef = (url: string) => {
// matchAll is not yet available to directly access the captured groups of all matches
// so this maps the urls to GitHub refs by matching again without the global flag
Expand Down

0 comments on commit 4c106a2

Please sign in to comment.