From c8d3241adb891311b35a908939f8b6c7c7290211 Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Tue, 20 Jun 2023 22:18:19 +0200 Subject: [PATCH] feat(issue-17): override backporting pr data --- README.md | 7 +- action.yml | 12 ++++ dist/cli/index.js | 27 +++++--- dist/gha/index.js | 21 ++++-- src/service/args/args.types.ts | 4 ++ src/service/args/cli/cli-args-parser.ts | 12 +++- src/service/args/gha/gha-args-parser.ts | 6 +- .../configs/pullrequest/pr-configs-parser.ts | 14 ++-- src/service/git/git.types.ts | 6 +- src/service/runner/runner.ts | 2 +- test/service/args/cli/cli-args-parser.test.ts | 26 ++++++- test/service/args/gha/gha-args-parser.test.ts | 14 +++- .../pullrequest/pr-configs-parser.test.ts | 68 +++++++++++++++++++ test/service/runner/cli-runner.test.ts | 48 +++++++++++++ test/service/runner/gha-runner.test.ts | 42 ++++++++++++ 15 files changed, 279 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 1fc2874..5346116 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,13 @@ This toold comes with some inputs that allow users to override the default behav | Pull Request | -pr, --pull-request | Y | Original pull request url, the one that must be backported, e.g., https://github.com/lampajr/backporting/pull/1 | | | Auth | -a, --auth | N | `GITHUB_TOKEN` or a `repo` scoped [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) | "" | | Folder | -f, --folder | N | Local folder where the repo will be checked out, e.g., /tmp/folder | {cwd}/bp | +| Title | --title | N | Backporting pull request title | "{original-pr-title}" | +| Body | --body | N | Backporting pull request body | "{original-pr-body}" | +| Body Prefix | --body-prefix | N | Prefix to the backporting pull request body | "Backport: {original-pr-link}" | +| Backport Branch Name | --bp-branch-name | N | Name of the backporting pull request branch | bp-{target-branch}-{sha} | | Dry Run | -d, --dry-run | N | If enabled the tool does not push nor create anything remotely, use this to skip PR creation | false | + ## GitHub Action This action can be used in any GitHub workflow, below you can find a simple example of manually triggered workflow backporting a specific pull request (provided as input). @@ -135,13 +140,11 @@ For a complete description of all inputs see [Inputs section](#inputs). **BPer** is in development mode, this means that it has many limitations right now. I'll try to summarize the most importan ones: -- No way to override backporting pull request fields like body, reviewers and so on. - You can backport pull requests only. - It only works for [GitHub](https://github.com/). - Integrated in GitHub Actions CI/CD only. Based on these limitations, the next **Future Works** could be the following: -- Give users the possibility to override/customize the backporting pull request. - Provide a way to backport single commit too (or a set of them), even if no original pull request is present. - Integrate this tool with other git management services (like GitLab and Bitbucket) to make it as generic as possible. - Provide some reusable GitHub workflows. diff --git a/action.yml b/action.yml index 6543c0c..e734ec4 100644 --- a/action.yml +++ b/action.yml @@ -15,6 +15,18 @@ inputs: target-branch: description: "Branch where the pull request must be backported to." required: true + title: + description: "Backporting PR title. Default is the original PR title prefixed by the target branch." + required: false + body: + description: "Backporting PR body. Default is the original PR body prefixed by `backport: `." + required: false + body-prefix: + description: "Backporting PR body prefix. Default is `backport: `" + required: false + bp-branch-name: + description: "Backporting PR branch name. Default is auto-generated from commit." + required: false runs: using: node16 diff --git a/dist/cli/index.js b/dist/cli/index.js index 8265fac..d92b4d9 100755 --- a/dist/cli/index.js +++ b/dist/cli/index.js @@ -39,7 +39,11 @@ class CLIArgsParser { .requiredOption("-pr, --pull-request ", "pull request url, e.g., https://github.com/lampajr/backporting/pull/1.") .option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely", false) .option("-a, --auth ", "git service authentication string, e.g., github token.", "") - .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder.", undefined); + .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder.", undefined) + .option("--title ", "backport pr title, default original pr title prefixed by target branch.", undefined) + .option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix.", undefined) + .option("--body-prefix ", "backport pr body prefix, default `backport `.", undefined) + .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit.", undefined); } parse() { const opts = this.getCommand() @@ -50,7 +54,11 @@ class CLIArgsParser { auth: opts.auth, pullRequest: opts.pullRequest, targetBranch: opts.targetBranch, - folder: opts.folder + folder: opts.folder, + title: opts.title, + body: opts.body, + bodyPrefix: opts.bodyPrefix, + bpBranchName: opts.bpBranchName, }; } } @@ -122,32 +130,35 @@ class PullRequestConfigsParser extends configs_parser_1.default { folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`, targetBranch: args.targetBranch, originalPullRequest: pr, - backportPullRequest: this.getDefaultBackportPullRequest(pr, args.targetBranch) + backportPullRequest: this.getDefaultBackportPullRequest(pr, args) }; } getDefaultFolder() { return "bp"; } /** - * Create a default backport pull request starting from the target branch and + * Create a backport pull request starting from the target branch and * the original pr to be backported * @param originalPullRequest original pull request * @param targetBranch target branch where the backport should be applied * @returns {GitPullRequest} */ - getDefaultBackportPullRequest(originalPullRequest, targetBranch) { + getDefaultBackportPullRequest(originalPullRequest, args) { const reviewers = []; reviewers.push(originalPullRequest.author); if (originalPullRequest.mergedBy) { reviewers.push(originalPullRequest.mergedBy); } + const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`; + const body = args.body ?? `${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`; return { author: originalPullRequest.author, - title: `[${targetBranch}] ${originalPullRequest.title}`, - body: `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`, + title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`, + body: `${bodyPrefix}${body}`, reviewers: [...new Set(reviewers)], targetRepo: originalPullRequest.targetRepo, sourceRepo: originalPullRequest.targetRepo, + branchName: args.bpBranchName, nCommits: 0, commits: [] // TODO needed? }; @@ -649,7 +660,7 @@ class Runner { // 4. clone the repository await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch); // 5. create new branch from target one and checkout - const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; + const backportBranch = backportPR.branchName ?? `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; await git.createLocalBranch(configs.folder, backportBranch); // 6. fetch pull request remote if source owner != target owner or pull request still open if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner || diff --git a/dist/gha/index.js b/dist/gha/index.js index 8f22edd..d829ca3 100755 --- a/dist/gha/index.js +++ b/dist/gha/index.js @@ -36,7 +36,11 @@ class GHAArgsParser { auth: (0, core_1.getInput)("auth") ? (0, core_1.getInput)("auth") : "", pullRequest: (0, core_1.getInput)("pull-request"), targetBranch: (0, core_1.getInput)("target-branch"), - folder: (0, core_1.getInput)("folder") !== "" ? (0, core_1.getInput)("folder") : undefined + folder: (0, core_1.getInput)("folder") !== "" ? (0, core_1.getInput)("folder") : undefined, + title: (0, core_1.getInput)("title"), + body: (0, core_1.getInput)("body"), + bodyPrefix: (0, core_1.getInput)("body-prefix"), + bpBranchName: (0, core_1.getInput)("bp-branch-name"), }; } } @@ -108,32 +112,35 @@ class PullRequestConfigsParser extends configs_parser_1.default { folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`, targetBranch: args.targetBranch, originalPullRequest: pr, - backportPullRequest: this.getDefaultBackportPullRequest(pr, args.targetBranch) + backportPullRequest: this.getDefaultBackportPullRequest(pr, args) }; } getDefaultFolder() { return "bp"; } /** - * Create a default backport pull request starting from the target branch and + * Create a backport pull request starting from the target branch and * the original pr to be backported * @param originalPullRequest original pull request * @param targetBranch target branch where the backport should be applied * @returns {GitPullRequest} */ - getDefaultBackportPullRequest(originalPullRequest, targetBranch) { + getDefaultBackportPullRequest(originalPullRequest, args) { const reviewers = []; reviewers.push(originalPullRequest.author); if (originalPullRequest.mergedBy) { reviewers.push(originalPullRequest.mergedBy); } + const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`; + const body = args.body ?? `${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`; return { author: originalPullRequest.author, - title: `[${targetBranch}] ${originalPullRequest.title}`, - body: `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`, + title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`, + body: `${bodyPrefix}${body}`, reviewers: [...new Set(reviewers)], targetRepo: originalPullRequest.targetRepo, sourceRepo: originalPullRequest.targetRepo, + branchName: args.bpBranchName, nCommits: 0, commits: [] // TODO needed? }; @@ -635,7 +642,7 @@ class Runner { // 4. clone the repository await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch); // 5. create new branch from target one and checkout - const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; + const backportBranch = backportPR.branchName ?? `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; await git.createLocalBranch(configs.folder, backportBranch); // 6. fetch pull request remote if source owner != target owner or pull request still open if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner || diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts index 07b74f3..0986fdf 100644 --- a/src/service/args/args.types.ts +++ b/src/service/args/args.types.ts @@ -8,4 +8,8 @@ export interface Args { pullRequest: string, // url of the pull request to backport folder?: string, // local folder where the repositories should be cloned author?: string, // backport pr author, default taken from pr + title?: string, // backport pr title, default original pr title prefixed by target branch + body?: string, // backport pr title, default original pr body prefixed by bodyPrefix + bodyPrefix?: string, // backport pr body prefix, default `backport ` + bpBranchName?: string, // backport pr branch name, default computed from commit } \ No newline at end of file diff --git a/src/service/args/cli/cli-args-parser.ts b/src/service/args/cli/cli-args-parser.ts index a3882eb..8f2b26a 100644 --- a/src/service/args/cli/cli-args-parser.ts +++ b/src/service/args/cli/cli-args-parser.ts @@ -14,7 +14,11 @@ export default class CLIArgsParser implements ArgsParser { .requiredOption("-pr, --pull-request ", "pull request url, e.g., https://github.com/lampajr/backporting/pull/1.") .option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely", false) .option("-a, --auth ", "git service authentication string, e.g., github token.", "") - .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder.", undefined); + .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder.", undefined) + .option("--title ", "backport pr title, default original pr title prefixed by target branch.", undefined) + .option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix.", undefined) + .option("--body-prefix ", "backport pr body prefix, default `backport `.", undefined) + .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit.", undefined); } parse(): Args { @@ -27,7 +31,11 @@ export default class CLIArgsParser implements ArgsParser { auth: opts.auth, pullRequest: opts.pullRequest, targetBranch: opts.targetBranch, - folder: opts.folder + folder: opts.folder, + title: opts.title, + body: opts.body, + bodyPrefix: opts.bodyPrefix, + bpBranchName: opts.bpBranchName, }; } diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts index d9439a7..5eace35 100644 --- a/src/service/args/gha/gha-args-parser.ts +++ b/src/service/args/gha/gha-args-parser.ts @@ -10,7 +10,11 @@ export default class GHAArgsParser implements ArgsParser { auth: getInput("auth") ? getInput("auth") : "", pullRequest: getInput("pull-request"), targetBranch: getInput("target-branch"), - folder: getInput("folder") !== "" ? getInput("folder") : undefined + folder: getInput("folder") !== "" ? getInput("folder") : undefined, + title: getInput("title"), + body: getInput("body"), + bodyPrefix: getInput("body-prefix"), + bpBranchName: getInput("bp-branch-name"), }; } diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts index baade07..8e5034e 100644 --- a/src/service/configs/pullrequest/pr-configs-parser.ts +++ b/src/service/configs/pullrequest/pr-configs-parser.ts @@ -25,7 +25,7 @@ export default class PullRequestConfigsParser extends ConfigsParser { folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`, targetBranch: args.targetBranch, originalPullRequest: pr, - backportPullRequest: this.getDefaultBackportPullRequest(pr, args.targetBranch) + backportPullRequest: this.getDefaultBackportPullRequest(pr, args) }; } @@ -34,26 +34,30 @@ export default class PullRequestConfigsParser extends ConfigsParser { } /** - * Create a default backport pull request starting from the target branch and + * Create a backport pull request starting from the target branch and * the original pr to be backported * @param originalPullRequest original pull request * @param targetBranch target branch where the backport should be applied * @returns {GitPullRequest} */ - private getDefaultBackportPullRequest(originalPullRequest: GitPullRequest, targetBranch: string): GitPullRequest { + private getDefaultBackportPullRequest(originalPullRequest: GitPullRequest, args: Args): GitPullRequest { const reviewers = []; reviewers.push(originalPullRequest.author); if (originalPullRequest.mergedBy) { reviewers.push(originalPullRequest.mergedBy); } + const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`; + const body = args.body ?? `${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`; + return { author: originalPullRequest.author, - title: `[${targetBranch}] ${originalPullRequest.title}`, - body: `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`, + title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`, + body: `${bodyPrefix}${body}`, reviewers: [...new Set(reviewers)], targetRepo: originalPullRequest.targetRepo, sourceRepo: originalPullRequest.targetRepo, + branchName: args.bpBranchName, nCommits: 0, // TODO: needed? commits: [] // TODO needed? }; diff --git a/src/service/git/git.types.ts b/src/service/git/git.types.ts index 5a515df..ba90f6d 100644 --- a/src/service/git/git.types.ts +++ b/src/service/git/git.types.ts @@ -12,7 +12,8 @@ export interface GitPullRequest { targetRepo: GitRepository, sourceRepo: GitRepository, nCommits: number, // number of commits in the pr - commits: string[] // merge commit or last one + commits: string[], // merge commit or last one + branchName?: string, } export interface GitRepository { @@ -28,7 +29,8 @@ export interface BackportPullRequest { base: string, // name of the target branch title: string, // pr title body: string, // pr body - reviewers: string[] // pr list of reviewers + reviewers: string[], // pr list of reviewers + branchName?: string, } export enum GitServiceType { diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts index f242af5..b4bf10d 100644 --- a/src/service/runner/runner.ts +++ b/src/service/runner/runner.ts @@ -86,7 +86,7 @@ export default class Runner { await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch); // 5. create new branch from target one and checkout - const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; + const backportBranch = backportPR.branchName ?? `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; await git.createLocalBranch(configs.folder, backportBranch); // 6. fetch pull request remote if source owner != target owner or pull request still open diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts index 26f5383..6fbb5f2 100644 --- a/test/service/args/cli/cli-args-parser.test.ts +++ b/test/service/args/cli/cli-args-parser.test.ts @@ -28,6 +28,10 @@ describe("cli args parser", () => { expect(args.folder).toEqual(undefined); expect(args.targetBranch).toEqual("target"); expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1"); + expect(args.title).toEqual(undefined); + expect(args.body).toEqual(undefined); + expect(args.bodyPrefix).toEqual(undefined); + expect(args.bpBranchName).toEqual(undefined); }); test("valid execution [default, long]", () => { @@ -45,6 +49,10 @@ describe("cli args parser", () => { expect(args.folder).toEqual(undefined); expect(args.targetBranch).toEqual("target"); expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1"); + expect(args.title).toEqual(undefined); + expect(args.body).toEqual(undefined); + expect(args.bodyPrefix).toEqual(undefined); + expect(args.bpBranchName).toEqual(undefined); }); test("valid execution [override, short]", () => { @@ -65,6 +73,10 @@ describe("cli args parser", () => { expect(args.folder).toEqual(undefined); expect(args.targetBranch).toEqual("target"); expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1"); + expect(args.title).toEqual(undefined); + expect(args.body).toEqual(undefined); + expect(args.bodyPrefix).toEqual(undefined); + expect(args.bpBranchName).toEqual(undefined); }); test("valid execution [override, long]", () => { @@ -75,7 +87,15 @@ describe("cli args parser", () => { "--target-branch", "target", "--pull-request", - "https://localhost/whatever/pulls/1" + "https://localhost/whatever/pulls/1", + "--title", + "New Title", + "--body", + "New Body", + "--body-prefix", + "New Body Prefix", + "--bp-branch-name", + "bp_branch_name", ]); const args: Args = parser.parse(); @@ -85,6 +105,10 @@ describe("cli args parser", () => { expect(args.folder).toEqual(undefined); expect(args.targetBranch).toEqual("target"); expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1"); + expect(args.title).toEqual("New Title"); + expect(args.body).toEqual("New Body"); + expect(args.bodyPrefix).toEqual("New Body Prefix"); + expect(args.bpBranchName).toEqual("bp_branch_name"); }); }); \ No newline at end of file diff --git a/test/service/args/gha/gha-args-parser.test.ts b/test/service/args/gha/gha-args-parser.test.ts index 3297691..e8cc233 100644 --- a/test/service/args/gha/gha-args-parser.test.ts +++ b/test/service/args/gha/gha-args-parser.test.ts @@ -28,6 +28,10 @@ describe("gha args parser", () => { expect(args.folder).toEqual(undefined); expect(args.targetBranch).toEqual("target"); expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1"); + expect(args.title).toEqual(undefined); + expect(args.body).toEqual(undefined); + expect(args.bodyPrefix).toEqual(undefined); + expect(args.bpBranchName).toEqual(undefined); }); test("valid execution [override]", () => { @@ -35,7 +39,11 @@ describe("gha args parser", () => { "dry-run": "true", "auth": "bearer-token", "target-branch": "target", - "pull-request": "https://localhost/whatever/pulls/1" + "pull-request": "https://localhost/whatever/pulls/1", + "title": "New Title", + "body": "New Body", + "body-prefix": "New Body Prefix", + "bp-branch-name": "bp_branch_name", }); const args: Args = parser.parse(); @@ -45,6 +53,10 @@ describe("gha args parser", () => { expect(args.folder).toEqual(undefined); expect(args.targetBranch).toEqual("target"); expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1"); + expect(args.title).toEqual("New Title"); + expect(args.body).toEqual("New Body"); + expect(args.bodyPrefix).toEqual("New Body Prefix"); + expect(args.bpBranchName).toEqual("bp_branch_name"); }); }); \ No newline at end of file diff --git a/test/service/configs/pullrequest/pr-configs-parser.test.ts b/test/service/configs/pullrequest/pr-configs-parser.test.ts index f01cd58..c57fcec 100644 --- a/test/service/configs/pullrequest/pr-configs-parser.test.ts +++ b/test/service/configs/pullrequest/pr-configs-parser.test.ts @@ -84,6 +84,7 @@ describe("pull request config parser", () => { project: "reponame", cloneUrl: "https://github.com/owner/reponame.git" }, + bpBranchName: undefined, nCommits: 0, commits: [] }); @@ -158,6 +159,7 @@ describe("pull request config parser", () => { project: "reponame", cloneUrl: "https://github.com/fork/reponame.git" }, + bpBranchName: undefined, nCommits: 2, // taken from head.sha commits: ["91748965051fae1330ad58d15cf694e103267c87"] @@ -174,4 +176,70 @@ describe("pull request config parser", () => { expect(async () => await parser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!"); }); + + test("override backport pr data", async () => { + const args: Args = { + dryRun: false, + auth: "", + pullRequest: mergedPRUrl, + targetBranch: "prod", + title: "New Title", + body: "New Body", + bodyPrefix: "New Body Prefix -", + }; + + const configs: Configs = await parser.parseAndValidate(args); + + expect(configs.dryRun).toEqual(false); + expect(configs.author).toEqual("gh-user"); + expect(configs.auth).toEqual(""); + expect(configs.targetBranch).toEqual("prod"); + expect(configs.folder).toEqual(process.cwd() + "/bp"); + expect(configs.originalPullRequest).toEqual({ + number: 2368, + author: "gh-user", + url: "https://api.github.com/repos/owner/reponame/pulls/2368", + htmlUrl: "https://github.com/owner/reponame/pull/2368", + state: "closed", + merged: true, + mergedBy: "that-s-a-user", + title: "PR Title", + body: "Please review and merge", + reviewers: ["requested-gh-user", "gh-user"], + targetRepo: { + owner: "owner", + project: "reponame", + cloneUrl: "https://github.com/owner/reponame.git" + }, + sourceRepo: { + owner: "fork", + project: "reponame", + cloneUrl: "https://github.com/fork/reponame.git" + }, + bpBranchName: undefined, + nCommits: 2, + commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"], + }); + expect(configs.backportPullRequest).toEqual({ + author: "gh-user", + url: undefined, + htmlUrl: undefined, + title: "New Title", + body: "New Body Prefix -New Body", + reviewers: ["gh-user", "that-s-a-user"], + targetRepo: { + owner: "owner", + project: "reponame", + cloneUrl: "https://github.com/owner/reponame.git" + }, + sourceRepo: { + owner: "owner", + project: "reponame", + cloneUrl: "https://github.com/owner/reponame.git" + }, + bpBranchName: undefined, + nCommits: 0, + commits: [] + }); + }); }); \ No newline at end of file diff --git a/test/service/runner/cli-runner.test.ts b/test/service/runner/cli-runner.test.ts index 5a54803..f8c232d 100644 --- a/test/service/runner/cli-runner.test.ts +++ b/test/service/runner/cli-runner.test.ts @@ -282,4 +282,52 @@ describe("cli runner", () => { } ); }); + + test("override backporting pr data", async () => { + addProcessArgs([ + "-tb", + "target", + "-pr", + "https://github.com/owner/reponame/pull/2368", + "--title", + "New Title", + "--body", + "New Body", + "--body-prefix", + "New Body Prefix - ", + "--bp-branch-name", + "bp_branch_name", + ]); + + await runner.execute(); + + const cwd = process.cwd() + "/bp"; + + expect(GitCLIService.prototype.clone).toBeCalledTimes(1); + expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target"); + + expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); + expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp_branch_name"); + + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); + + expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); + expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); + + expect(GitCLIService.prototype.push).toBeCalledTimes(1); + expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name"); + + expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1); + expect(GitHubService.prototype.createPullRequest).toBeCalledWith({ + owner: "owner", + repo: "reponame", + head: "bp_branch_name", + base: "target", + title: "New Title", + body: "New Body Prefix - New Body", + reviewers: ["gh-user", "that-s-a-user"] + } + ); + }); }); \ No newline at end of file diff --git a/test/service/runner/gha-runner.test.ts b/test/service/runner/gha-runner.test.ts index 678a1cc..e1abfd0 100644 --- a/test/service/runner/gha-runner.test.ts +++ b/test/service/runner/gha-runner.test.ts @@ -138,4 +138,46 @@ describe("gha runner", () => { } ); }); + + test("override backporting pr data", async () => { + spyGetInput({ + "target-branch": "target", + "pull-request": "https://github.com/owner/reponame/pull/2368", + "title": "New Title", + "body": "New Body", + "body-prefix": "New Body Prefix - ", + "bp-branch-name": "bp_branch_name", + }); + + await runner.execute(); + + const cwd = process.cwd() + "/bp"; + + expect(GitCLIService.prototype.clone).toBeCalledTimes(1); + expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target"); + + expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); + expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp_branch_name"); + + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); + + expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); + expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); + + expect(GitCLIService.prototype.push).toBeCalledTimes(1); + expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name"); + + expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1); + expect(GitHubService.prototype.createPullRequest).toBeCalledWith({ + owner: "owner", + repo: "reponame", + head: "bp_branch_name", + base: "target", + title: "New Title", + body: "New Body Prefix - New Body", + reviewers: ["gh-user", "that-s-a-user"] + } + ); + }); }); \ No newline at end of file