mirror of
https://code.forgejo.org/actions/git-backporting.git
synced 2025-05-18 19:49:13 -04:00
feat: implement error notification as pr comment
This commit is contained in:
parent
6042bcc40b
commit
c02522a9f1
27 changed files with 432 additions and 35 deletions
|
@ -79,9 +79,11 @@ describe("cli args parser", () => {
|
|||
expect(args.labels).toEqual([]);
|
||||
expect(args.inheritLabels).toEqual(false);
|
||||
expect(args.squash).toEqual(true);
|
||||
expect(args.autoNoSquash).toEqual(false);
|
||||
expect(args.strategy).toEqual(undefined);
|
||||
expect(args.strategyOption).toEqual(undefined);
|
||||
expect(args.cherryPickOptions).toEqual(undefined);
|
||||
expect(args.enableErrorNotification).toEqual(false);
|
||||
});
|
||||
|
||||
test("with config file [default, short]", () => {
|
||||
|
@ -109,9 +111,11 @@ describe("cli args parser", () => {
|
|||
expect(args.labels).toEqual([]);
|
||||
expect(args.inheritLabels).toEqual(false);
|
||||
expect(args.squash).toEqual(true);
|
||||
expect(args.autoNoSquash).toEqual(false);
|
||||
expect(args.strategy).toEqual(undefined);
|
||||
expect(args.strategyOption).toEqual(undefined);
|
||||
expect(args.cherryPickOptions).toEqual(undefined);
|
||||
expect(args.enableErrorNotification).toEqual(false);
|
||||
});
|
||||
|
||||
test("valid execution [default, long]", () => {
|
||||
|
@ -521,4 +525,17 @@ describe("cli args parser", () => {
|
|||
|
||||
expect(() => parser.parse()).toThrowError("Missing option: pull request must be provided");
|
||||
});
|
||||
|
||||
test("enable error notification flag", () => {
|
||||
addProcessArgs([
|
||||
"-tb",
|
||||
"target, old",
|
||||
"-pr",
|
||||
"https://localhost/whatever/pulls/1",
|
||||
"--enable-err-notification",
|
||||
]);
|
||||
|
||||
const args: Args = parser.parse();
|
||||
expect(args.enableErrorNotification).toEqual(true);
|
||||
});
|
||||
});
|
|
@ -295,7 +295,6 @@ describe("gha args parser", () => {
|
|||
expect(args.cherryPickOptions).toEqual(undefined);
|
||||
});
|
||||
|
||||
|
||||
test("invalid execution with empty target branch", () => {
|
||||
spyGetInput({
|
||||
"target-branch": " ",
|
||||
|
@ -320,4 +319,15 @@ describe("gha args parser", () => {
|
|||
|
||||
expect(() => parser.parse()).toThrowError("Missing option: pull request must be provided");
|
||||
});
|
||||
|
||||
test("enable error notification flag", () => {
|
||||
spyGetInput({
|
||||
"target-branch": "target,old",
|
||||
"pull-request": "https://localhost/whatever/pulls/1",
|
||||
"enable-err-notification": "true"
|
||||
});
|
||||
|
||||
const args: Args = parser.parse();
|
||||
expect(args.enableErrorNotification).toEqual(true);
|
||||
});
|
||||
});
|
|
@ -139,6 +139,10 @@ describe("github pull request config parser", () => {
|
|||
labels: [],
|
||||
comments: [],
|
||||
});
|
||||
expect(configs.errorNotification).toEqual({
|
||||
enabled: false,
|
||||
message: "Backporting failed: {{error}}"
|
||||
});
|
||||
});
|
||||
|
||||
test("override folder", async () => {
|
||||
|
@ -939,4 +943,26 @@ describe("github pull request config parser", () => {
|
|||
comments: ["First comment", "Second comment"],
|
||||
});
|
||||
});
|
||||
|
||||
test("enable error notification message", async () => {
|
||||
const args: Args = {
|
||||
dryRun: false,
|
||||
auth: "",
|
||||
pullRequest: mergedPRUrl,
|
||||
targetBranch: "prod",
|
||||
enableErrorNotification: true,
|
||||
};
|
||||
|
||||
const configs: Configs = await configParser.parseAndValidate(args);
|
||||
|
||||
expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
|
||||
expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined);
|
||||
expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
|
||||
expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
|
||||
|
||||
expect(configs.errorNotification).toEqual({
|
||||
"enabled": true,
|
||||
"message": "Backporting failed: {{error}}"
|
||||
});
|
||||
});
|
||||
});
|
|
@ -144,6 +144,10 @@ describe("gitlab merge request config parser", () => {
|
|||
labels: [],
|
||||
comments: [],
|
||||
});
|
||||
expect(configs.errorNotification).toEqual({
|
||||
"enabled": false,
|
||||
"message": "Backporting failed: {{error}}"
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -882,4 +886,26 @@ describe("gitlab merge request config parser", () => {
|
|||
comments: ["First comment", "Second comment"],
|
||||
});
|
||||
});
|
||||
|
||||
test("enable error notification message", async () => {
|
||||
const args: Args = {
|
||||
dryRun: false,
|
||||
auth: "",
|
||||
pullRequest: mergedPRUrl,
|
||||
targetBranch: "prod",
|
||||
enableErrorNotification: true,
|
||||
};
|
||||
|
||||
const configs: Configs = await configParser.parseAndValidate(args);
|
||||
|
||||
expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
|
||||
expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, undefined);
|
||||
expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
|
||||
expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
|
||||
|
||||
expect(configs.errorNotification).toEqual({
|
||||
"enabled": true,
|
||||
"message": "Backporting failed: {{error}}",
|
||||
});
|
||||
});
|
||||
});
|
|
@ -30,6 +30,7 @@ const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
|
|||
|
||||
jest.mock("@bp/service/git/git-cli");
|
||||
jest.spyOn(GitHubClient.prototype, "createPullRequest");
|
||||
jest.spyOn(GitHubClient.prototype, "createPullRequestComment");
|
||||
jest.spyOn(GitClientFactory, "getOrCreate");
|
||||
|
||||
let parser: ArgsParser;
|
||||
|
@ -94,6 +95,7 @@ describe("cli runner", () => {
|
|||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("overriding author", async () => {
|
||||
|
@ -287,6 +289,7 @@ describe("cli runner", () => {
|
|||
}
|
||||
);
|
||||
expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("closed and not merged pull request", async () => {
|
||||
|
@ -1156,6 +1159,7 @@ describe("cli runner", () => {
|
|||
comments: [],
|
||||
});
|
||||
expect(GitHubClient.prototype.createPullRequest).toThrowError();
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("auth using GITHUB_TOKEN takes precedence over GIT_TOKEN env variable", async () => {
|
||||
|
@ -1231,4 +1235,96 @@ describe("cli runner", () => {
|
|||
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
|
||||
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "prod");
|
||||
});
|
||||
|
||||
test("with multiple target branches, one failure and error notification enabled", async () => {
|
||||
jest.spyOn(GitHubClient.prototype, "createPullRequest").mockImplementation((backport: BackportPullRequest) => {
|
||||
|
||||
throw new Error(`Mocked error: ${backport.base}`);
|
||||
});
|
||||
|
||||
addProcessArgs([
|
||||
"-tb",
|
||||
"v1, v2, v3",
|
||||
"-pr",
|
||||
"https://github.com/owner/reponame/pull/2368",
|
||||
"-f",
|
||||
"/tmp/folder",
|
||||
"--bp-branch-name",
|
||||
"custom-failure-head",
|
||||
"--enable-err-notification",
|
||||
]);
|
||||
|
||||
await expect(() => runner.execute()).rejects.toThrowError("Failure occurred during one of the backports: [Error: Mocked error: v1 ; Error: Mocked error: v2 ; Error: Mocked error: v3]");
|
||||
|
||||
const cwd = "/tmp/folder";
|
||||
|
||||
expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
|
||||
expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, undefined, "https://api.github.com");
|
||||
|
||||
expect(GitCLIService.prototype.clone).toBeCalledTimes(3);
|
||||
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "v1");
|
||||
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "v2");
|
||||
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "v3");
|
||||
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(3);
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom-failure-head-v1");
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom-failure-head-v2");
|
||||
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom-failure-head-v3");
|
||||
|
||||
expect(GitCLIService.prototype.fetch).toBeCalledTimes(3);
|
||||
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
|
||||
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(3);
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined, undefined);
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined, undefined);
|
||||
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined, undefined);
|
||||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(3);
|
||||
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom-failure-head-v1");
|
||||
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom-failure-head-v2");
|
||||
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom-failure-head-v3");
|
||||
|
||||
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(3);
|
||||
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
|
||||
owner: "owner",
|
||||
repo: "reponame",
|
||||
head: "custom-failure-head-v1",
|
||||
base: "v1",
|
||||
title: "[v1] PR Title",
|
||||
body: "**Backport:** https://github.com/owner/reponame/pull/2368\r\n\r\nPlease review and merge",
|
||||
reviewers: ["gh-user", "that-s-a-user"],
|
||||
assignees: [],
|
||||
labels: [],
|
||||
comments: [],
|
||||
});
|
||||
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
|
||||
owner: "owner",
|
||||
repo: "reponame",
|
||||
head: "custom-failure-head-v2",
|
||||
base: "v2",
|
||||
title: "[v2] PR Title",
|
||||
body: "**Backport:** https://github.com/owner/reponame/pull/2368\r\n\r\nPlease review and merge",
|
||||
reviewers: ["gh-user", "that-s-a-user"],
|
||||
assignees: [],
|
||||
labels: [],
|
||||
comments: [],
|
||||
});
|
||||
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
|
||||
owner: "owner",
|
||||
repo: "reponame",
|
||||
head: "custom-failure-head-v3",
|
||||
base: "v3",
|
||||
title: "[v3] PR Title",
|
||||
body: "**Backport:** https://github.com/owner/reponame/pull/2368\r\n\r\nPlease review and merge",
|
||||
reviewers: ["gh-user", "that-s-a-user"],
|
||||
assignees: [],
|
||||
labels: [],
|
||||
comments: [],
|
||||
});
|
||||
expect(GitHubClient.prototype.createPullRequest).toThrowError();
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledTimes(3);
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledWith("https://api.github.com/repos/owner/reponame/pulls/2368", "Backporting failed: Error: Mocked error: v1");
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledWith("https://api.github.com/repos/owner/reponame/pulls/2368", "Backporting failed: Error: Mocked error: v2");
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledWith("https://api.github.com/repos/owner/reponame/pulls/2368", "Backporting failed: Error: Mocked error: v3");
|
||||
});
|
||||
});
|
|
@ -44,6 +44,7 @@ jest.mock("axios", () => {
|
|||
|
||||
jest.mock("@bp/service/git/git-cli");
|
||||
jest.spyOn(GitLabClient.prototype, "createPullRequest");
|
||||
jest.spyOn(GitLabClient.prototype, "createPullRequestComment");
|
||||
jest.spyOn(GitClientFactory, "getOrCreate");
|
||||
|
||||
|
||||
|
@ -105,6 +106,7 @@ describe("cli runner", () => {
|
|||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
|
||||
expect(GitLabClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("dry run with relative folder", async () => {
|
||||
|
@ -199,6 +201,7 @@ describe("cli runner", () => {
|
|||
]);
|
||||
|
||||
await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged");
|
||||
expect(GitLabClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("merged pull request", async () => {
|
||||
|
@ -246,6 +249,7 @@ describe("cli runner", () => {
|
|||
comments: [],
|
||||
}
|
||||
);
|
||||
expect(GitLabClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
|
|||
|
||||
jest.mock("@bp/service/git/git-cli");
|
||||
jest.spyOn(GitHubClient.prototype, "createPullRequest");
|
||||
jest.spyOn(GitHubClient.prototype, "createPullRequestComment");
|
||||
jest.spyOn(GitClientFactory, "getOrCreate");
|
||||
|
||||
let parser: ArgsParser;
|
||||
|
@ -87,6 +88,7 @@ describe("gha runner", () => {
|
|||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
|
||||
expect(GitHubClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("without dry run", async () => {
|
||||
|
|
|
@ -43,6 +43,7 @@ jest.mock("axios", () => {
|
|||
|
||||
jest.mock("@bp/service/git/git-cli");
|
||||
jest.spyOn(GitLabClient.prototype, "createPullRequest");
|
||||
jest.spyOn(GitLabClient.prototype, "createPullRequestComment");
|
||||
jest.spyOn(GitClientFactory, "getOrCreate");
|
||||
|
||||
let parser: ArgsParser;
|
||||
|
@ -98,6 +99,7 @@ describe("gha runner", () => {
|
|||
|
||||
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
|
||||
expect(GitLabClient.prototype.createPullRequestComment).toBeCalledTimes(0);
|
||||
});
|
||||
|
||||
test("without dry run", async () => {
|
||||
|
|
11
test/service/runner/runner-util.test.ts
Normal file
11
test/service/runner/runner-util.test.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import { injectError } from "@bp/service/runner/runner-util";
|
||||
|
||||
describe("check runner utilities", () => {
|
||||
test("properly inject error message", () => {
|
||||
expect(injectError("Original message: {{error}}", "to inject")).toStrictEqual("Original message: to inject");
|
||||
});
|
||||
|
||||
test("missing placeholder in the original message", () => {
|
||||
expect(injectError("Original message: {{wrong}}", "to inject")).toStrictEqual("Original message: {{wrong}}");
|
||||
});
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue