diff --git a/README.md b/README.md index 8b8c7f9..d2ce79b 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,13 @@ It works in this way: given the provided `pull/merge request` it infers the serv After that it clones the corresponding git repository, check out in the provided `target branch` and create a new branch from that (name automatically generated if not provided as option). -By default the tool will try to cherry-pick the single squashed/merged commit into the newly created branch (please consider using `--no-squash` option if you want to cherry-pick all commits belonging to the provided pull request). +By default the tool will try to cherry-pick the single squashed/merged commit into the newly created branch. The `--no-squash` and `--auto-no-squash` options control this behavior according the following table. + +| No squash | Auto no squash |Behavior| +|---|---|---| +| unset/false | unset/false | cherry-pick a single commit, squashed or merged | +| set/true | unset/false | cherry-pick all commits found in the the original pull/merge request| +| (ignored) | set/true | cherry-pick all commits if the original pull/merge request was merged, a single commit if it was squashed | Based on the original pull request, creates a new one containing the backporting to the target branch. Note that most of these information can be overridden with appropriate CLI options or GHA inputs. @@ -121,7 +127,8 @@ This tool comes with some inputs that allow users to override the default behavi | Backport Branch Names | --bp-branch-name | N | Comma separated lists of the backporting pull request branch names, if they exceeds 250 chars they will be truncated | bp-{target-branch}-{sha1}...{shaN} | | Labels | --labels | N | Provide custom labels to be added to the backporting pull request | [] | | Inherit labels | --inherit-labels | N | If enabled inherit lables from the original pull request | false | -| No squash | --no-squash | N | If provided the backporting will try to backport all pull request commits without squashing | false | +| No squash | --no-squash | N | Backport all commits found in the pull request. The default behavior is to only backport the first commit that was merged in the base branch. | | +| Auto no squash | --auto-no-squash | N | If the pull request was merged or is open, backport all commits. If the pull request commits were squashed, backport the squashed commit. | | | Strategy | --strategy | N | Cherry pick merging strategy, see [git-merge](https://git-scm.com/docs/git-merge#_merge_strategies) doc for all possible values | "recursive" | | Strategy Option | --strategy-option | N | Cherry pick merging strategy option, see [git-merge](https://git-scm.com/docs/git-merge#_merge_strategies) doc for all possible values | "theirs" | | Cherry-pick Options | --cherry-pick-options | N | Additional cherry-pick options, see [git-cherry-pick](https://git-scm.com/docs/git-cherry-pick) doc for all possible values | "theirs" | diff --git a/action.yml b/action.yml index b157e59..fc166c9 100644 --- a/action.yml +++ b/action.yml @@ -85,10 +85,14 @@ inputs: default: "false" no-squash: description: > - If set to true the tool will backport all commits as part of the pull request - instead of the suqashed one + Backport all commits found in the pull request. + The default behavior is to only backport the first commit that was merged in the base branch. + required: false + auto-no-squash: + description: > + If the pull request was merged or is open, backport all commits. + If the pull request commits were squashed, backport the squashed commit. required: false - default: "false" strategy: description: Cherry-pick merge strategy required: false diff --git a/dist/cli/index.js b/dist/cli/index.js index 531662b..bd839f1 100755 --- a/dist/cli/index.js +++ b/dist/cli/index.js @@ -66,6 +66,7 @@ class ArgsParser { labels: this.getOrDefault(args.labels, []), inheritLabels: this.getOrDefault(args.inheritLabels, false), squash: this.getOrDefault(args.squash, true), + autoNoSquash: this.getOrDefault(args.autoNoSquash, false), strategy: this.getOrDefault(args.strategy), strategyOption: this.getOrDefault(args.strategyOption), cherryPickOptions: this.getOrDefault(args.cherryPickOptions), @@ -203,7 +204,8 @@ class CLIArgsParser extends args_parser_1.default { .option("--no-inherit-reviewers", "if provided and reviewers option is empty then inherit them from original pull request") .option("--labels ", "comma separated list of labels to be assigned to the backported pull request", args_utils_1.getAsCommaSeparatedList) .option("--inherit-labels", "if true the backported pull request will inherit labels from the original one") - .option("--no-squash", "if provided the tool will backport all commits as part of the pull request") + .option("--no-squash", "Backport all commits found in the pull request. The default behavior is to only backport the first commit that was merged in the base branch") + .option("--auto-no-squash", "If the pull request was merged or is open, backport all commits. If the pull request commits were squashed, backport the squashed commit.") .option("--strategy ", "cherry-pick merge strategy, default to 'recursive'", undefined) .option("--strategy-option ", "cherry-pick merge strategy option, default to 'theirs'") .option("--cherry-pick-options ", "additional cherry-pick options") @@ -240,6 +242,7 @@ class CLIArgsParser extends args_parser_1.default { labels: opts.labels, inheritLabels: opts.inheritLabels, squash: opts.squash, + autoNoSquash: opts.autoNoSquash, strategy: opts.strategy, strategyOption: opts.strategyOption, cherryPickOptions: opts.cherryPickOptions, @@ -332,6 +335,9 @@ class PullRequestConfigsParser extends configs_parser_1.default { } async parse(args) { let pr; + if (args.autoNoSquash) { + args.squash = undefined; + } try { pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest, args.squash); } @@ -661,12 +667,16 @@ GitClientFactory.logger = logger_service_factory_1.default.getLogger(); /***/ }), /***/ 9080: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getEnv = exports.getGitTokenFromEnv = exports.inferGitApiUrl = exports.inferGitClient = void 0; +exports.getEnv = exports.getGitTokenFromEnv = exports.inferSquash = exports.inferGitApiUrl = exports.inferGitClient = void 0; +const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936)); const git_types_1 = __nccwpck_require__(750); const configs_types_1 = __nccwpck_require__(4753); const PUBLIC_GITHUB_URL = "https://github.com"; @@ -706,6 +716,30 @@ const inferGitApiUrl = (prUrl, apiVersion = "v4") => { return `${baseUrl}/api/${apiVersion}`; }; exports.inferGitApiUrl = inferGitApiUrl; +/** + * Infer the value of the squash option + * @param open true if the pull/merge request is still open + * @param squash_commit undefined if the pull/merge request was merged, the sha of the squashed commit if it was squashed + * @returns true if a single commit must be cherry-picked, false if all merged commits must be cherry-picked + */ +const inferSquash = (open, squash_commit) => { + const logger = logger_service_factory_1.default.getLogger(); + if (open) { + logger.debug("cherry-pick all commits because they have not been merged (or squashed) in the base branch yet"); + return false; + } + else { + if (squash_commit !== undefined) { + logger.debug(`cherry-pick the squashed commit ${squash_commit}`); + return true; + } + else { + logger.debug("cherry-pick the merged commit(s)"); + return false; + } + } +}; +exports.inferSquash = inferSquash; /** * Retrieve the git token from env variable, the default is taken from GIT_TOKEN env. * All specific git env variable have precedence and override the default one. @@ -781,6 +815,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); +const git_util_1 = __nccwpck_require__(9080); const git_types_1 = __nccwpck_require__(750); const github_mapper_1 = __importDefault(__nccwpck_require__(5764)); const octokit_factory_1 = __importDefault(__nccwpck_require__(4257)); @@ -803,13 +838,28 @@ class GitHubClient { getDefaultGitEmail() { return "noreply@github.com"; } - async getPullRequest(owner, repo, prNumber, squash = true) { + async getPullRequest(owner, repo, prNumber, squash) { this.logger.debug(`Fetching pull request ${owner}/${repo}/${prNumber}`); const { data } = await this.octokit.rest.pulls.get({ owner: owner, repo: repo, pull_number: prNumber, }); + if (squash === undefined) { + let commit_sha = undefined; + const open = data.state == "open"; + if (!open) { + const commit = await this.octokit.rest.git.getCommit({ + owner: owner, + repo: repo, + commit_sha: data.merge_commit_sha, + }); + if (commit.data.parents.length === 1) { + commit_sha = data.merge_commit_sha; + } + } + squash = (0, git_util_1.inferSquash)(open, commit_sha); + } const commits = []; if (!squash) { // fetch all commits @@ -827,7 +877,7 @@ class GitHubClient { } return this.mapper.mapPullRequest(data, commits); } - async getPullRequestFromUrl(prUrl, squash = true) { + async getPullRequestFromUrl(prUrl, squash) { const { owner, project, id } = this.extractPullRequestData(prUrl); return this.getPullRequest(owner, project, id, squash); } @@ -1006,6 +1056,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); +const git_util_1 = __nccwpck_require__(9080); const git_types_1 = __nccwpck_require__(750); const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936)); const gitlab_mapper_1 = __importDefault(__nccwpck_require__(2675)); @@ -1038,9 +1089,12 @@ class GitLabClient { } // READ // example: /api/v4/projects/%2Fbackporting-example/merge_requests/1 - async getPullRequest(namespace, repo, mrNumber, squash = true) { + async getPullRequest(namespace, repo, mrNumber, squash) { const projectId = this.getProjectId(namespace, repo); const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`); + if (squash === undefined) { + squash = (0, git_util_1.inferSquash)(data.state == "opened", data.squash_commit_sha); + } const commits = []; if (!squash) { // fetch all commits @@ -1055,7 +1109,7 @@ class GitLabClient { } return this.mapper.mapPullRequest(data, commits); } - getPullRequestFromUrl(mrUrl, squash = true) { + getPullRequestFromUrl(mrUrl, squash) { const { namespace, project, id } = this.extractMergeRequestData(mrUrl); return this.getPullRequest(namespace, project, id, squash); } diff --git a/dist/gha/index.js b/dist/gha/index.js index 417d0d1..eb93b89 100755 --- a/dist/gha/index.js +++ b/dist/gha/index.js @@ -66,6 +66,7 @@ class ArgsParser { labels: this.getOrDefault(args.labels, []), inheritLabels: this.getOrDefault(args.inheritLabels, false), squash: this.getOrDefault(args.squash, true), + autoNoSquash: this.getOrDefault(args.autoNoSquash, false), strategy: this.getOrDefault(args.strategy), strategyOption: this.getOrDefault(args.strategyOption), cherryPickOptions: this.getOrDefault(args.cherryPickOptions), @@ -207,6 +208,7 @@ class GHAArgsParser extends args_parser_1.default { labels: (0, args_utils_1.getAsCommaSeparatedList)((0, core_1.getInput)("labels")), inheritLabels: (0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("inherit-labels")), squash: !(0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("no-squash")), + autoNoSquash: (0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("auto-no-squash")), strategy: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("strategy")), strategyOption: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("strategy-option")), cherryPickOptions: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("cherry-pick-options")), @@ -299,6 +301,9 @@ class PullRequestConfigsParser extends configs_parser_1.default { } async parse(args) { let pr; + if (args.autoNoSquash) { + args.squash = undefined; + } try { pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest, args.squash); } @@ -628,12 +633,16 @@ GitClientFactory.logger = logger_service_factory_1.default.getLogger(); /***/ }), /***/ 9080: -/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); -exports.getEnv = exports.getGitTokenFromEnv = exports.inferGitApiUrl = exports.inferGitClient = void 0; +exports.getEnv = exports.getGitTokenFromEnv = exports.inferSquash = exports.inferGitApiUrl = exports.inferGitClient = void 0; +const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936)); const git_types_1 = __nccwpck_require__(750); const configs_types_1 = __nccwpck_require__(4753); const PUBLIC_GITHUB_URL = "https://github.com"; @@ -673,6 +682,30 @@ const inferGitApiUrl = (prUrl, apiVersion = "v4") => { return `${baseUrl}/api/${apiVersion}`; }; exports.inferGitApiUrl = inferGitApiUrl; +/** + * Infer the value of the squash option + * @param open true if the pull/merge request is still open + * @param squash_commit undefined if the pull/merge request was merged, the sha of the squashed commit if it was squashed + * @returns true if a single commit must be cherry-picked, false if all merged commits must be cherry-picked + */ +const inferSquash = (open, squash_commit) => { + const logger = logger_service_factory_1.default.getLogger(); + if (open) { + logger.debug("cherry-pick all commits because they have not been merged (or squashed) in the base branch yet"); + return false; + } + else { + if (squash_commit !== undefined) { + logger.debug(`cherry-pick the squashed commit ${squash_commit}`); + return true; + } + else { + logger.debug("cherry-pick the merged commit(s)"); + return false; + } + } +}; +exports.inferSquash = inferSquash; /** * Retrieve the git token from env variable, the default is taken from GIT_TOKEN env. * All specific git env variable have precedence and override the default one. @@ -748,6 +781,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); +const git_util_1 = __nccwpck_require__(9080); const git_types_1 = __nccwpck_require__(750); const github_mapper_1 = __importDefault(__nccwpck_require__(5764)); const octokit_factory_1 = __importDefault(__nccwpck_require__(4257)); @@ -770,13 +804,28 @@ class GitHubClient { getDefaultGitEmail() { return "noreply@github.com"; } - async getPullRequest(owner, repo, prNumber, squash = true) { + async getPullRequest(owner, repo, prNumber, squash) { this.logger.debug(`Fetching pull request ${owner}/${repo}/${prNumber}`); const { data } = await this.octokit.rest.pulls.get({ owner: owner, repo: repo, pull_number: prNumber, }); + if (squash === undefined) { + let commit_sha = undefined; + const open = data.state == "open"; + if (!open) { + const commit = await this.octokit.rest.git.getCommit({ + owner: owner, + repo: repo, + commit_sha: data.merge_commit_sha, + }); + if (commit.data.parents.length === 1) { + commit_sha = data.merge_commit_sha; + } + } + squash = (0, git_util_1.inferSquash)(open, commit_sha); + } const commits = []; if (!squash) { // fetch all commits @@ -794,7 +843,7 @@ class GitHubClient { } return this.mapper.mapPullRequest(data, commits); } - async getPullRequestFromUrl(prUrl, squash = true) { + async getPullRequestFromUrl(prUrl, squash) { const { owner, project, id } = this.extractPullRequestData(prUrl); return this.getPullRequest(owner, project, id, squash); } @@ -973,6 +1022,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", ({ value: true })); +const git_util_1 = __nccwpck_require__(9080); const git_types_1 = __nccwpck_require__(750); const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936)); const gitlab_mapper_1 = __importDefault(__nccwpck_require__(2675)); @@ -1005,9 +1055,12 @@ class GitLabClient { } // READ // example: /api/v4/projects/%2Fbackporting-example/merge_requests/1 - async getPullRequest(namespace, repo, mrNumber, squash = true) { + async getPullRequest(namespace, repo, mrNumber, squash) { const projectId = this.getProjectId(namespace, repo); const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`); + if (squash === undefined) { + squash = (0, git_util_1.inferSquash)(data.state == "opened", data.squash_commit_sha); + } const commits = []; if (!squash) { // fetch all commits @@ -1022,7 +1075,7 @@ class GitLabClient { } return this.mapper.mapPullRequest(data, commits); } - getPullRequestFromUrl(mrUrl, squash = true) { + getPullRequestFromUrl(mrUrl, squash) { const { namespace, project, id } = this.extractMergeRequestData(mrUrl); return this.getPullRequest(namespace, project, id, squash); } diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts index 8a45370..338cc56 100644 --- a/src/service/args/args-parser.ts +++ b/src/service/args/args-parser.ts @@ -44,6 +44,7 @@ export default abstract class ArgsParser { labels: this.getOrDefault(args.labels, []), inheritLabels: this.getOrDefault(args.inheritLabels, false), squash: this.getOrDefault(args.squash, true), + autoNoSquash: this.getOrDefault(args.autoNoSquash, false), strategy: this.getOrDefault(args.strategy), strategyOption: this.getOrDefault(args.strategyOption), cherryPickOptions: this.getOrDefault(args.cherryPickOptions), diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts index fa14a4a..a951c1d 100644 --- a/src/service/args/args.types.ts +++ b/src/service/args/args.types.ts @@ -22,7 +22,8 @@ export interface Args { inheritReviewers?: boolean, // if true and reviewers == [] then inherit reviewers from original pr labels?: string[], // backport pr labels inheritLabels?: boolean, // if true inherit labels from original pr - squash?: boolean, // if false use squashed/merged commit otherwise backport all commits as part of the pr + squash?: boolean, + autoNoSquash?: boolean, strategy?: string, // cherry-pick merge strategy strategyOption?: string, // cherry-pick merge strategy option cherryPickOptions?: string, // additional cherry-pick options diff --git a/src/service/args/cli/cli-args-parser.ts b/src/service/args/cli/cli-args-parser.ts index 995e63f..7c5d7ec 100644 --- a/src/service/args/cli/cli-args-parser.ts +++ b/src/service/args/cli/cli-args-parser.ts @@ -28,7 +28,8 @@ export default class CLIArgsParser extends ArgsParser { .option("--no-inherit-reviewers", "if provided and reviewers option is empty then inherit them from original pull request") .option("--labels ", "comma separated list of labels to be assigned to the backported pull request", getAsCommaSeparatedList) .option("--inherit-labels", "if true the backported pull request will inherit labels from the original one") - .option("--no-squash", "if provided the tool will backport all commits as part of the pull request") + .option("--no-squash", "Backport all commits found in the pull request. The default behavior is to only backport the first commit that was merged in the base branch") + .option("--auto-no-squash", "If the pull request was merged or is open, backport all commits. If the pull request commits were squashed, backport the squashed commit.") .option("--strategy ", "cherry-pick merge strategy, default to 'recursive'", undefined) .option("--strategy-option ", "cherry-pick merge strategy option, default to 'theirs'") .option("--cherry-pick-options ", "additional cherry-pick options") @@ -66,6 +67,7 @@ export default class CLIArgsParser extends ArgsParser { labels: opts.labels, inheritLabels: opts.inheritLabels, squash: opts.squash, + autoNoSquash: opts.autoNoSquash, strategy: opts.strategy, strategyOption: opts.strategyOption, cherryPickOptions: opts.cherryPickOptions, diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts index b79be49..e51106d 100644 --- a/src/service/args/gha/gha-args-parser.ts +++ b/src/service/args/gha/gha-args-parser.ts @@ -32,6 +32,7 @@ export default class GHAArgsParser extends ArgsParser { labels: getAsCommaSeparatedList(getInput("labels")), inheritLabels: getAsBooleanOrDefault(getInput("inherit-labels")), squash: !getAsBooleanOrDefault(getInput("no-squash")), + autoNoSquash: getAsBooleanOrDefault(getInput("auto-no-squash")), strategy: getOrUndefined(getInput("strategy")), strategyOption: getOrUndefined(getInput("strategy-option")), cherryPickOptions: getOrUndefined(getInput("cherry-pick-options")), diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts index ba3eb47..d66cccd 100644 --- a/src/service/configs/pullrequest/pr-configs-parser.ts +++ b/src/service/configs/pullrequest/pr-configs-parser.ts @@ -16,9 +16,12 @@ export default class PullRequestConfigsParser extends ConfigsParser { } public async parse(args: Args): Promise { - let pr: GitPullRequest; + let pr: GitPullRequest; + if (args.autoNoSquash) { + args.squash = undefined; + } try { - pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest, args.squash!); + pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest, args.squash); } catch(error) { this.logger.error("Something went wrong retrieving pull request"); throw error; diff --git a/src/service/git/git-client.ts b/src/service/git/git-client.ts index c9d0f10..3df6a0e 100644 --- a/src/service/git/git-client.ts +++ b/src/service/git/git-client.ts @@ -25,7 +25,7 @@ import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/ * @param squash if true keep just one single commit, otherwise get the full list * @returns {Promise} */ - getPullRequest(owner: string, repo: string, prNumber: number, squash: boolean): Promise; + getPullRequest(owner: string, repo: string, prNumber: number, squash: boolean | undefined): Promise; /** * Get a pull request object from the underneath git service @@ -33,7 +33,7 @@ import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/ * @param squash if true keep just one single commit, otherwise get the full list * @returns {Promise} */ - getPullRequestFromUrl(prUrl: string, squash: boolean): Promise; + getPullRequestFromUrl(prUrl: string, squash: boolean | undefined): Promise; // WRITE diff --git a/src/service/git/git-util.ts b/src/service/git/git-util.ts index 67d32ff..1a70a1d 100644 --- a/src/service/git/git-util.ts +++ b/src/service/git/git-util.ts @@ -1,3 +1,4 @@ +import LoggerServiceFactory from "@bp/service/logger/logger-service-factory"; import { GitClientType } from "@bp/service/git/git.types"; import { AuthTokenId } from "@bp/service/configs/configs.types"; @@ -41,6 +42,29 @@ export const inferGitApiUrl = (prUrl: string, apiVersion = "v4"): string => { return `${baseUrl}/api/${apiVersion}`; }; +/** + * Infer the value of the squash option + * @param open true if the pull/merge request is still open + * @param squash_commit undefined if the pull/merge request was merged, the sha of the squashed commit if it was squashed + * @returns true if a single commit must be cherry-picked, false if all merged commits must be cherry-picked + */ +export const inferSquash = (open: boolean, squash_commit: string | undefined): boolean => { + const logger = LoggerServiceFactory.getLogger(); + + if (open) { + logger.debug("cherry-pick all commits because they have not been merged (or squashed) in the base branch yet"); + return false; + } else { + if (squash_commit !== undefined) { + logger.debug(`cherry-pick the squashed commit ${squash_commit}`); + return true; + } else { + logger.debug("cherry-pick the merged commit(s)"); + return false; + } + } +}; + /** * Retrieve the git token from env variable, the default is taken from GIT_TOKEN env. * All specific git env variable have precedence and override the default one. diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts index 40f1831..4a35423 100644 --- a/src/service/git/github/github-client.ts +++ b/src/service/git/github/github-client.ts @@ -1,4 +1,5 @@ import GitClient from "@bp/service/git/git-client"; +import { inferSquash } from "@bp/service/git/git-util"; import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/git/git.types"; import GitHubMapper from "@bp/service/git/github/github-mapper"; import OctokitFactory from "@bp/service/git/github/octokit-factory"; @@ -37,7 +38,7 @@ export default class GitHubClient implements GitClient { return "noreply@github.com"; } - async getPullRequest(owner: string, repo: string, prNumber: number, squash = true): Promise { + async getPullRequest(owner: string, repo: string, prNumber: number, squash: boolean | undefined): Promise { this.logger.debug(`Fetching pull request ${owner}/${repo}/${prNumber}`); const { data } = await this.octokit.rest.pulls.get({ owner: owner, @@ -45,6 +46,22 @@ export default class GitHubClient implements GitClient { pull_number: prNumber, }); + if (squash === undefined) { + let commit_sha: string | undefined = undefined; + const open: boolean = data.state == "open"; + if (!open) { + const commit = await this.octokit.rest.git.getCommit({ + owner: owner, + repo: repo, + commit_sha: (data.merge_commit_sha as string), + }); + if (commit.data.parents.length === 1) { + commit_sha = (data.merge_commit_sha as string); + } + } + squash = inferSquash(open, commit_sha); + } + const commits: string[] = []; if (!squash) { // fetch all commits @@ -64,7 +81,7 @@ export default class GitHubClient implements GitClient { return this.mapper.mapPullRequest(data as PullRequest, commits); } - async getPullRequestFromUrl(prUrl: string, squash = true): Promise { + async getPullRequestFromUrl(prUrl: string, squash: boolean | undefined): Promise { const { owner, project, id } = this.extractPullRequestData(prUrl); return this.getPullRequest(owner, project, id, squash); } diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts index c874b70..8db5c58 100644 --- a/src/service/git/gitlab/gitlab-client.ts +++ b/src/service/git/gitlab/gitlab-client.ts @@ -1,5 +1,6 @@ import LoggerService from "@bp/service/logger/logger-service"; import GitClient from "@bp/service/git/git-client"; +import { inferSquash } from "@bp/service/git/git-util"; import { GitPullRequest, BackportPullRequest, GitClientType } from "@bp/service/git/git.types"; import LoggerServiceFactory from "@bp/service/logger/logger-service-factory"; import { CommitSchema, MergeRequestSchema, UserSchema } from "@gitbeaker/rest"; @@ -45,10 +46,14 @@ export default class GitLabClient implements GitClient { // READ // example: /api/v4/projects/%2Fbackporting-example/merge_requests/1 - async getPullRequest(namespace: string, repo: string, mrNumber: number, squash = true): Promise { + async getPullRequest(namespace: string, repo: string, mrNumber: number, squash: boolean | undefined): Promise { const projectId = this.getProjectId(namespace, repo); const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`); + if (squash === undefined) { + squash = inferSquash(data.state === "opened", data.squash_commit_sha); + } + const commits: string[] = []; if (!squash) { // fetch all commits @@ -65,7 +70,7 @@ export default class GitLabClient implements GitClient { return this.mapper.mapPullRequest(data as MergeRequestSchema, commits); } - getPullRequestFromUrl(mrUrl: string, squash = true): Promise { + getPullRequestFromUrl(mrUrl: string, squash: boolean | undefined): Promise { const { namespace, project, id } = this.extractMergeRequestData(mrUrl); return this.getPullRequest(namespace, project, id, squash); } diff --git a/test/service/configs/pullrequest/github-pr-configs-parser-multiple.test.ts b/test/service/configs/pullrequest/github-pr-configs-parser-multiple.test.ts index 96e0ce0..138a1b0 100644 --- a/test/service/configs/pullrequest/github-pr-configs-parser-multiple.test.ts +++ b/test/service/configs/pullrequest/github-pr-configs-parser-multiple.test.ts @@ -57,7 +57,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -129,7 +129,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -202,7 +202,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -275,7 +275,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); diff --git a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts index 758b0b4..4348504 100644 --- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts +++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts @@ -89,7 +89,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -182,9 +182,9 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 4444, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 4444, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); - expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); + expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"]); expect(configs.dryRun).toEqual(true); expect(configs.auth).toEqual("whatever"); @@ -217,8 +217,7 @@ describe("github pull request config parser", () => { }, bpBranchName: undefined, nCommits: 2, - // taken from head.sha - commits: ["91748965051fae1330ad58d15cf694e103267c87"] + commits: ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"], }); }); @@ -258,7 +257,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -331,7 +330,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -372,7 +371,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -444,7 +443,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -518,7 +517,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -791,7 +790,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); @@ -888,7 +887,7 @@ describe("github pull request config parser", () => { const configs: Configs = await configParser.parseAndValidate(args); expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1); - expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true); + expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, undefined); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1); expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []); diff --git a/test/service/configs/pullrequest/gitlab-pr-configs-parser-multiple.test.ts b/test/service/configs/pullrequest/gitlab-pr-configs-parser-multiple.test.ts index deff8de..140c343 100644 --- a/test/service/configs/pullrequest/gitlab-pr-configs-parser-multiple.test.ts +++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser-multiple.test.ts @@ -51,6 +51,7 @@ describe("gitlab merge request config parser", () => { labels: [], inheritLabels: false, comments: [], + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -123,6 +124,7 @@ describe("gitlab merge request config parser", () => { labels: [], inheritLabels: false, comments: [], + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -195,7 +197,8 @@ describe("gitlab merge request config parser", () => { labels: [], inheritLabels: false, comments: [], - bpBranchName: "custom-branch" + bpBranchName: "custom-branch", + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -268,7 +271,8 @@ describe("gitlab merge request config parser", () => { labels: [], inheritLabels: false, comments: [], - bpBranchName: "custom1, custom2, custom3" + bpBranchName: "custom1, custom2, custom3", + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); diff --git a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts index b10ae17..9030cc9 100644 --- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts +++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts @@ -88,6 +88,7 @@ describe("gitlab merge request config parser", () => { reviewers: [], assignees: [], inheritReviewers: true, + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -158,6 +159,7 @@ describe("gitlab merge request config parser", () => { reviewers: [], assignees: [], inheritReviewers: true, + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -187,6 +189,7 @@ describe("gitlab merge request config parser", () => { reviewers: [], assignees: [], inheritReviewers: true, + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -243,6 +246,7 @@ describe("gitlab merge request config parser", () => { reviewers: [], assignees: [], inheritReviewers: true, + squash: true, }; await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged"); @@ -262,6 +266,7 @@ describe("gitlab merge request config parser", () => { reviewers: [], assignees: [], inheritReviewers: true, + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -333,6 +338,7 @@ describe("gitlab merge request config parser", () => { reviewers: ["user1", "user2"], assignees: ["user3", "user4"], inheritReviewers: true, // not taken into account + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -404,6 +410,7 @@ describe("gitlab merge request config parser", () => { reviewers: [], assignees: ["user3", "user4"], inheritReviewers: false, + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -477,6 +484,7 @@ describe("gitlab merge request config parser", () => { inheritReviewers: false, labels: ["custom-label", "backport-prod"], // also include the one inherited inheritLabels: true, + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -742,6 +750,7 @@ describe("gitlab merge request config parser", () => { labels: [], inheritLabels: false, comments: ["First comment", "Second comment"], + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); @@ -816,6 +825,7 @@ describe("gitlab merge request config parser", () => { labels: [], inheritLabels: false, comments: ["First comment", "Second comment"], + squash: true, }; const configs: Configs = await configParser.parseAndValidate(args); diff --git a/test/service/git/git-util.test.ts b/test/service/git/git-util.test.ts index 5e202e6..0a73d75 100644 --- a/test/service/git/git-util.test.ts +++ b/test/service/git/git-util.test.ts @@ -1,4 +1,4 @@ -import { inferGitApiUrl, inferGitClient } from "@bp/service/git/git-util"; +import { inferGitApiUrl, inferGitClient, inferSquash } from "@bp/service/git/git-util"; import { GitClientType } from "@bp/service/git/git.types"; describe("check git utilities", () => { @@ -54,4 +54,10 @@ describe("check git utilities", () => { test("check infer codeberg client", ()=> { expect(inferGitClient("https://codeberg.org/lampajr/backporting-example/pulls/1")).toStrictEqual(GitClientType.CODEBERG); }); -}); \ No newline at end of file + + test("check inferSquash", ()=> { + expect(inferSquash(true, undefined)).toStrictEqual(false); + expect(inferSquash(false, "SHA")).toStrictEqual(true); + expect(inferSquash(false, undefined)).toStrictEqual(false); + }); +}); diff --git a/test/service/git/github/github-client.test.ts b/test/service/git/github/github-client.test.ts index 97fc996..35a4d5c 100644 --- a/test/service/git/github/github-client.test.ts +++ b/test/service/git/github/github-client.test.ts @@ -22,7 +22,7 @@ describe("github service", () => { }); test("get pull request: success", async () => { - const res: GitPullRequest = await gitClient.getPullRequest(TARGET_OWNER, REPO, MERGED_PR_FIXTURE.number); + const res: GitPullRequest = await gitClient.getPullRequest(TARGET_OWNER, REPO, MERGED_PR_FIXTURE.number, true); expect(res.sourceRepo).toEqual({ owner: "fork", project: "reponame", diff --git a/test/service/git/gitlab/gitlab-client.test.ts b/test/service/git/gitlab/gitlab-client.test.ts index b33ab9e..38deda1 100644 --- a/test/service/git/gitlab/gitlab-client.test.ts +++ b/test/service/git/gitlab/gitlab-client.test.ts @@ -31,7 +31,7 @@ describe("github service", () => { }); test("get merged pull request", async () => { - const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 1); + const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 1, true); // check content expect(res.sourceRepo).toEqual({ @@ -56,7 +56,7 @@ describe("github service", () => { }); test("get open pull request", async () => { - const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 2); + const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 2, true); expect(res.sourceRepo).toEqual({ owner: "superuser", project: "backporting-example", @@ -325,7 +325,7 @@ describe("github service", () => { }); test("get pull request for nested namespaces", async () => { - const res: GitPullRequest = await gitClient.getPullRequestFromUrl("https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example/-/merge_requests/4"); + const res: GitPullRequest = await gitClient.getPullRequestFromUrl("https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example/-/merge_requests/4", true); // check content expect(res.sourceRepo).toEqual({ diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts index 008eac8..5c4ecf3 100644 --- a/test/service/runner/cli-github-runner.test.ts +++ b/test/service/runner/cli-github-runner.test.ts @@ -300,7 +300,7 @@ describe("cli runner", () => { await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged"); }); - test("open pull request", async () => { + test("open pull request simple", async () => { addProcessArgs([ "-tb", "target", @@ -347,6 +347,55 @@ describe("cli runner", () => { expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1); }); + test("open pull request with --auto-no-squash", async () => { + addProcessArgs([ + "-tb", + "target", + "-pr", + "https://github.com/owner/reponame/pull/4444", + "--auto-no-squash", + ]); + + await runner.execute(); + + const cwd = process.cwd() + "/bp"; + + expect(GitClientFactory.getOrCreate).toBeCalledTimes(1); + expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, undefined, "https://api.github.com"); + + 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-target-0404fb9-11da4e3"); + + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444"); + + expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2); + expect(GitCLIService.prototype.cherryPick).toHaveBeenLastCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695", undefined, undefined, undefined); + expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", undefined, undefined, undefined); + + expect(GitCLIService.prototype.push).toBeCalledTimes(1); + expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3"); + + expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1); + expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({ + owner: "owner", + repo: "reponame", + head: "bp-target-0404fb9-11da4e3", + base: "target", + title: "[target] PR Title", + body: "**Backport:** https://github.com/owner/reponame/pull/4444\r\n\r\nPlease review and merge", + reviewers: ["gh-user"], + assignees: [], + labels: [], + comments: [], + } + ); + expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1); + }); + test("override backporting pr data", async () => { addProcessArgs([ "-tb", diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts index 7dceabc..72a46aa 100644 --- a/test/support/mock/git-client-mock-support.ts +++ b/test/support/mock/git-client-mock-support.ts @@ -1,6 +1,6 @@ import LoggerServiceFactory from "@bp/service/logger/logger-service-factory"; import { Moctokit } from "@kie/mock-github"; -import { TARGET_OWNER, REPO, MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, NOT_FOUND_PR_NUMBER, MULT_COMMITS_PR_FIXTURE, MULT_COMMITS_PR_COMMITS, NEW_PR_URL, NEW_PR_NUMBER } from "./github-data"; +import { TARGET_OWNER, REPO, MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, NOT_FOUND_PR_NUMBER, MULT_COMMITS_PR_FIXTURE, MULT_COMMITS_PR_COMMITS, NEW_PR_URL, NEW_PR_NUMBER, GITHUB_GET_COMMIT } from "./github-data"; import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER, MERGED_SQUASHED_MR_COMMITS } from "./gitlab-data"; // high number, for each test we are not expecting @@ -157,6 +157,17 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit => data: MULT_COMMITS_PR_COMMITS }); + mock.rest.pulls + .listCommits({ + owner: TARGET_OWNER, + repo: REPO, + pull_number: OPEN_PR_FIXTURE.number + }) + .reply({ + status: 200, + data: MULT_COMMITS_PR_COMMITS + }); + mock.rest.pulls .create() .reply({ @@ -200,6 +211,17 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit => data: {} }); + mock.rest.git + .getCommit({ + owner: TARGET_OWNER, + repo: REPO, + commit_sha: "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", + }) + .reply({ + status: 200, + data: GITHUB_GET_COMMIT, + }); + // invalid requests mock.rest.pulls .get({ diff --git a/test/support/mock/github-data.ts b/test/support/mock/github-data.ts index 5673fd7..0b46741 100644 --- a/test/support/mock/github-data.ts +++ b/test/support/mock/github-data.ts @@ -1832,6 +1832,14 @@ export const MULT_COMMITS_PR_FIXTURE = { "changed_files": 2 }; +export const GITHUB_GET_COMMIT = { + "parents": [ + { + "sha": "SHA" + } + ] +}; + export const MULT_COMMITS_PR_COMMITS = [ { "sha": "0404fb922ab75c3a8aecad5c97d9af388df04695",