From f923f7f4c2c07d2a5fcd126ad3629d74c3706b94 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Sun, 9 Jul 2023 21:31:30 +0200
Subject: [PATCH 01/75] test: fix gitlab data
---
test/support/mock/gitlab-data.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/support/mock/gitlab-data.ts b/test/support/mock/gitlab-data.ts
index ea68947..7df3263 100644
--- a/test/support/mock/gitlab-data.ts
+++ b/test/support/mock/gitlab-data.ts
@@ -110,7 +110,7 @@ export const PROJECT_EXAMPLE = {
"build_git_strategy":"fetch",
"keep_latest_artifact":true,
"restrict_user_defined_variables":false,
- "runners_token":"GR13489419z7QQ54AUgJaNMFD5asU",
+ "runners_token":"TOKEN",
"runner_token_expiration_interval":null,
"group_runners_enabled":true,
"auto_cancel_pending_pipelines":"enabled",
From fcc01673f4bc9aa2786faf6dfd503a29e5ca0cd9 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Mon, 10 Jul 2023 08:49:11 +0200
Subject: [PATCH 02/75] feat(issue-41): set and inherit labels (#48)
fix https://github.com/kiegroup/git-backporting/issues/41
---
README.md | 6 +-
action.yml | 7 ++
dist/cli/index.js | 103 ++++++++++++----
dist/gha/index.js | 114 ++++++++++++------
src/service/args/args-parser.ts | 2 +
src/service/args/args-utils.ts | 28 +++++
src/service/args/args.types.ts | 2 +
src/service/args/cli/cli-args-parser.ts | 38 +++---
src/service/args/gha/gha-args-parser.ts | 51 +++-----
.../configs/pullrequest/pr-configs-parser.ts | 6 +
src/service/git/git.types.ts | 2 +
src/service/git/github/github-client.ts | 15 ++-
src/service/git/github/github-mapper.ts | 1 +
src/service/git/gitlab/gitlab-client.ts | 12 ++
src/service/git/gitlab/gitlab-mapper.ts | 2 +-
src/service/runner/runner.ts | 1 +
test/service/args/args-utils.test.ts | 40 +++++-
test/service/args/cli/cli-args-parser.test.ts | 24 ++++
test/service/args/gha/gha-args-parser.test.ts | 34 +++---
.../github-pr-configs-parser.test.ts | 95 ++++++++++++++-
.../gitlab-pr-configs-parser.test.ts | 93 +++++++++++++-
test/service/git/gitlab/gitlab-client.test.ts | 38 ++++++
test/service/runner/cli-github-runner.test.ts | 99 ++++++++++++++-
test/service/runner/cli-gitlab-runner.test.ts | 98 +++++++++++++++
test/service/runner/gha-github-runner.test.ts | 91 ++++++++++++++
test/service/runner/gha-gitlab-runner.test.ts | 88 ++++++++++++++
test/support/mock/github-data.ts | 10 +-
test/support/mock/gitlab-data.ts | 2 +-
28 files changed, 962 insertions(+), 140 deletions(-)
diff --git a/README.md b/README.md
index 2393f6f..b3480bd 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
-
+
@@ -94,6 +94,8 @@ This tool comes with some inputs that allow users to override the default behavi
| Assignees | --assignes | N | Backporting pull request comma-separated assignees list | [] |
| No Reviewers Inheritance | --no-inherit-reviewers | N | Considered only if reviewers is empty, if true keep reviewers as empty list, otherwise inherit from original pull request | false |
| Backport Branch Name | --bp-branch-name | N | Name of the backporting pull request branch | bp-{target-branch}-{sha} |
+| 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 |
| Dry Run | -d, --dry-run | N | If enabled the tool does not push nor create anything remotely, use this to skip PR creation | false |
> **NOTE**: `pull request` and `target branch` are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
@@ -280,6 +282,8 @@ Every change must be submitted through a *GitHub* pull request (PR). Backporting
> **Note**: you don't need to take care about typescript compilation and minifycation, there are automated [git hooks](./.husky) taking care of that!
+**Hint**: if you are still in a `work in progress` branch and you want to push your changes remotely, consider adding `--no-verify` for both `commit` and `push`, e.g., `git push origin --no-verify`
+
## License
Backporting (BPer) open source project is licensed under the [MIT](./LICENSE) license.
\ No newline at end of file
diff --git a/action.yml b/action.yml
index dcfe863..43c2fcc 100644
--- a/action.yml
+++ b/action.yml
@@ -48,6 +48,13 @@ inputs:
description: "Considered only if reviewers is empty, if true keep reviewers as empty list, otherwise inherit from original pull request"
required: false
default: "false"
+ labels:
+ description: "Comma separated list of labels to be assigned to the backported pull request"
+ required: false
+ inherit-labels:
+ description: "If true the backported pull request will inherit labels from the original one"
+ required: false
+ default: "false"
runs:
using: node16
diff --git a/dist/cli/index.js b/dist/cli/index.js
index aec50b6..866fdad 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -58,6 +58,8 @@ class ArgsParser {
reviewers: this.getOrDefault(args.reviewers, []),
assignees: this.getOrDefault(args.assignees, []),
inheritReviewers: this.getOrDefault(args.inheritReviewers, true),
+ labels: this.getOrDefault(args.labels, []),
+ inheritLabels: this.getOrDefault(args.inheritLabels, false),
};
}
}
@@ -95,7 +97,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.readConfigFile = exports.parseArgs = void 0;
+exports.getAsBooleanOrDefault = exports.getAsCommaSeparatedList = exports.getAsCleanedCommaSeparatedList = exports.getOrUndefined = exports.readConfigFile = exports.parseArgs = void 0;
const fs = __importStar(__nccwpck_require__(7147));
/**
* Parse the input configuation string as json object and
@@ -117,6 +119,34 @@ function readConfigFile(pathToFile) {
return parseArgs(asString);
}
exports.readConfigFile = readConfigFile;
+/**
+ * Return the input only if it is not a blank or null string, otherwise returns undefined
+ * @param key input key
+ * @returns the value or undefined
+ */
+function getOrUndefined(value) {
+ return value !== "" ? value : undefined;
+}
+exports.getOrUndefined = getOrUndefined;
+// get rid of inner spaces too
+function getAsCleanedCommaSeparatedList(value) {
+ // trim the value
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.replace(/\s/g, "").split(",") : undefined;
+}
+exports.getAsCleanedCommaSeparatedList = getAsCleanedCommaSeparatedList;
+// preserve inner spaces
+function getAsCommaSeparatedList(value) {
+ // trim the value
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.split(",").map(v => v.trim()) : undefined;
+}
+exports.getAsCommaSeparatedList = getAsCommaSeparatedList;
+function getAsBooleanOrDefault(value) {
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.toLowerCase() === "true" : undefined;
+}
+exports.getAsBooleanOrDefault = getAsBooleanOrDefault;
/***/ }),
@@ -134,31 +164,28 @@ const args_parser_1 = __importDefault(__nccwpck_require__(3025));
const commander_1 = __nccwpck_require__(4379);
const package_json_1 = __nccwpck_require__(6625);
const args_utils_1 = __nccwpck_require__(8048);
-function commaSeparatedList(value, _prev) {
- // remove all whitespaces
- const cleanedValue = value.trim();
- return cleanedValue !== "" ? cleanedValue.replace(/\s/g, "").split(",") : [];
-}
class CLIArgsParser extends args_parser_1.default {
getCommand() {
return new commander_1.Command(package_json_1.name)
.version(package_json_1.version)
.description(package_json_1.description)
- .option("-tb, --target-branch ", "branch where changes must be backported to.")
- .option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1.")
+ .option("-tb, --target-branch ", "branch where changes must be backported to")
+ .option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
- .option("-a, --auth ", "git service authentication string, e.g., github token.")
- .option("-gu, --git-user ", "local git user name, default is 'GitHub'.")
- .option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'.")
- .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder.")
- .option("--title ", "backport pr title, default original pr title prefixed by target branch.")
- .option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix.")
- .option("--body-prefix ", "backport pr body prefix, default `backport `.")
- .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit.")
- .option("--reviewers ", "comma separated list of reviewers for the backporting pull request.", commaSeparatedList)
- .option("--assignees ", "comma separated list of assignees for the backporting pull request.", commaSeparatedList)
+ .option("-a, --auth ", "git service authentication string, e.g., github token")
+ .option("-gu, --git-user ", "local git user name, default is 'GitHub'")
+ .option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'")
+ .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder")
+ .option("--title ", "backport pr title, default original pr title prefixed by target branch")
+ .option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix")
+ .option("--body-prefix ", "backport pr body prefix, default `backport `")
+ .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit")
+ .option("--reviewers ", "comma separated list of reviewers for the backporting pull request", args_utils_1.getAsCleanedCommaSeparatedList)
+ .option("--assignees ", "comma separated list of assignees for the backporting pull request", args_utils_1.getAsCleanedCommaSeparatedList)
.option("--no-inherit-reviewers", "if provided and reviewers option is empty then inherit them from original pull request")
- .option("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface.");
+ .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("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
readArgs() {
const opts = this.getCommand()
@@ -185,6 +212,8 @@ class CLIArgsParser extends args_parser_1.default {
reviewers: opts.reviewers,
assignees: opts.assignees,
inheritReviewers: opts.inheritReviewers,
+ labels: opts.labels,
+ inheritLabels: opts.inheritLabels,
};
}
return args;
@@ -292,12 +321,17 @@ class PullRequestConfigsParser extends configs_parser_1.default {
}
const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`;
const body = args.body ?? `${originalPullRequest.body}`;
+ const labels = args.labels ?? [];
+ if (args.inheritLabels) {
+ labels.push(...originalPullRequest.labels);
+ }
return {
author: args.gitUser ?? this.gitClient.getDefaultGitUser(),
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
body: `${bodyPrefix}${body}`,
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
+ labels: [...new Set(labels)],
targetRepo: originalPullRequest.targetRepo,
sourceRepo: originalPullRequest.targetRepo,
branchName: args.bpBranchName,
@@ -608,11 +642,24 @@ class GitHubClient {
head: backport.head,
base: backport.base,
title: backport.title,
- body: backport.body
+ body: backport.body,
});
if (!data) {
throw new Error("Pull request creation failed");
}
+ if (backport.labels.length > 0) {
+ try {
+ await this.octokit.issues.addLabels({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ labels: backport.labels,
+ });
+ }
+ catch (error) {
+ this.logger.error(`Error setting labels: ${error}`);
+ }
+ }
if (backport.reviewers.length > 0) {
try {
await this.octokit.pulls.requestReviewers({
@@ -690,6 +737,7 @@ class GitHubMapper {
mergedBy: pr.merged_by?.login,
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
assignees: pr.assignees.filter(r => "login" in r).map(r => r.login),
+ labels: pr.labels.map(l => l.name),
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
@@ -810,6 +858,18 @@ class GitLabClient {
assignee_ids: [],
});
const mr = data;
+ // labels
+ if (backport.labels.length > 0) {
+ try {
+ this.logger.info("Setting labels: " + backport.labels);
+ await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ labels: backport.labels.join(","),
+ });
+ }
+ catch (error) {
+ this.logger.warn("Failure trying to update labels. " + error);
+ }
+ }
// reviewers
const reviewerIds = [];
for (const r of backport.reviewers) {
@@ -924,7 +984,6 @@ class GitLabMapper {
}
}
async mapPullRequest(mr) {
- // throw new Error("Method not implemented.");
return {
number: mr.iid,
author: mr.author.username,
@@ -937,6 +996,7 @@ class GitLabMapper {
mergedBy: mr.merged_by?.username,
reviewers: mr.reviewers?.map((r => r.username)) ?? [],
assignees: mr.assignees?.map((r => r.username)) ?? [],
+ labels: mr.labels ?? [],
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
nCommits: 1,
@@ -1151,6 +1211,7 @@ class Runner {
body: backportPR.body,
reviewers: backportPR.reviewers,
assignees: backportPR.assignees,
+ labels: backportPR.labels,
};
if (!configs.dryRun) {
// 8. push the new branch to origin
diff --git a/dist/gha/index.js b/dist/gha/index.js
index dd6ce0d..497b6f4 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -58,6 +58,8 @@ class ArgsParser {
reviewers: this.getOrDefault(args.reviewers, []),
assignees: this.getOrDefault(args.assignees, []),
inheritReviewers: this.getOrDefault(args.inheritReviewers, true),
+ labels: this.getOrDefault(args.labels, []),
+ inheritLabels: this.getOrDefault(args.inheritLabels, false),
};
}
}
@@ -95,7 +97,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.readConfigFile = exports.parseArgs = void 0;
+exports.getAsBooleanOrDefault = exports.getAsCommaSeparatedList = exports.getAsCleanedCommaSeparatedList = exports.getOrUndefined = exports.readConfigFile = exports.parseArgs = void 0;
const fs = __importStar(__nccwpck_require__(7147));
/**
* Parse the input configuation string as json object and
@@ -117,6 +119,34 @@ function readConfigFile(pathToFile) {
return parseArgs(asString);
}
exports.readConfigFile = readConfigFile;
+/**
+ * Return the input only if it is not a blank or null string, otherwise returns undefined
+ * @param key input key
+ * @returns the value or undefined
+ */
+function getOrUndefined(value) {
+ return value !== "" ? value : undefined;
+}
+exports.getOrUndefined = getOrUndefined;
+// get rid of inner spaces too
+function getAsCleanedCommaSeparatedList(value) {
+ // trim the value
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.replace(/\s/g, "").split(",") : undefined;
+}
+exports.getAsCleanedCommaSeparatedList = getAsCleanedCommaSeparatedList;
+// preserve inner spaces
+function getAsCommaSeparatedList(value) {
+ // trim the value
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.split(",").map(v => v.trim()) : undefined;
+}
+exports.getAsCommaSeparatedList = getAsCommaSeparatedList;
+function getAsBooleanOrDefault(value) {
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.toLowerCase() === "true" : undefined;
+}
+exports.getAsBooleanOrDefault = getAsBooleanOrDefault;
/***/ }),
@@ -134,46 +164,30 @@ const args_parser_1 = __importDefault(__nccwpck_require__(3025));
const core_1 = __nccwpck_require__(2186);
const args_utils_1 = __nccwpck_require__(8048);
class GHAArgsParser extends args_parser_1.default {
- /**
- * Return the input only if it is not a blank or null string, otherwise returns undefined
- * @param key input key
- * @returns the value or undefined
- */
- getOrUndefined(key) {
- const value = (0, core_1.getInput)(key);
- return value !== "" ? value : undefined;
- }
- getAsCommaSeparatedList(key) {
- // trim the value
- const value = ((0, core_1.getInput)(key) ?? "").trim();
- return value !== "" ? value.replace(/\s/g, "").split(",") : undefined;
- }
- getAsBooleanOrDefault(key) {
- const value = (0, core_1.getInput)(key).trim();
- return value !== "" ? value.toLowerCase() === "true" : undefined;
- }
readArgs() {
- const configFile = this.getOrUndefined("config-file");
+ const configFile = (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("config-file"));
let args;
if (configFile) {
args = (0, args_utils_1.readConfigFile)(configFile);
}
else {
args = {
- dryRun: this.getAsBooleanOrDefault("dry-run"),
- auth: this.getOrUndefined("auth"),
+ dryRun: (0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("dry-run")),
+ auth: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("auth")),
pullRequest: (0, core_1.getInput)("pull-request"),
targetBranch: (0, core_1.getInput)("target-branch"),
- folder: this.getOrUndefined("folder"),
- gitUser: this.getOrUndefined("git-user"),
- gitEmail: this.getOrUndefined("git-email"),
- title: this.getOrUndefined("title"),
- body: this.getOrUndefined("body"),
- bodyPrefix: this.getOrUndefined("body-prefix"),
- bpBranchName: this.getOrUndefined("bp-branch-name"),
- reviewers: this.getAsCommaSeparatedList("reviewers"),
- assignees: this.getAsCommaSeparatedList("assignees"),
- inheritReviewers: !this.getAsBooleanOrDefault("no-inherit-reviewers"),
+ folder: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("folder")),
+ gitUser: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-user")),
+ gitEmail: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-email")),
+ title: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("title")),
+ body: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("body")),
+ bodyPrefix: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("body-prefix")),
+ bpBranchName: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("bp-branch-name")),
+ reviewers: (0, args_utils_1.getAsCleanedCommaSeparatedList)((0, core_1.getInput)("reviewers")),
+ assignees: (0, args_utils_1.getAsCleanedCommaSeparatedList)((0, core_1.getInput)("assignees")),
+ inheritReviewers: !(0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("no-inherit-reviewers")),
+ labels: (0, args_utils_1.getAsCommaSeparatedList)((0, core_1.getInput)("labels")),
+ inheritLabels: (0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("inherit-labels")),
};
}
return args;
@@ -281,12 +295,17 @@ class PullRequestConfigsParser extends configs_parser_1.default {
}
const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`;
const body = args.body ?? `${originalPullRequest.body}`;
+ const labels = args.labels ?? [];
+ if (args.inheritLabels) {
+ labels.push(...originalPullRequest.labels);
+ }
return {
author: args.gitUser ?? this.gitClient.getDefaultGitUser(),
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
body: `${bodyPrefix}${body}`,
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
+ labels: [...new Set(labels)],
targetRepo: originalPullRequest.targetRepo,
sourceRepo: originalPullRequest.targetRepo,
branchName: args.bpBranchName,
@@ -597,11 +616,24 @@ class GitHubClient {
head: backport.head,
base: backport.base,
title: backport.title,
- body: backport.body
+ body: backport.body,
});
if (!data) {
throw new Error("Pull request creation failed");
}
+ if (backport.labels.length > 0) {
+ try {
+ await this.octokit.issues.addLabels({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ labels: backport.labels,
+ });
+ }
+ catch (error) {
+ this.logger.error(`Error setting labels: ${error}`);
+ }
+ }
if (backport.reviewers.length > 0) {
try {
await this.octokit.pulls.requestReviewers({
@@ -679,6 +711,7 @@ class GitHubMapper {
mergedBy: pr.merged_by?.login,
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
assignees: pr.assignees.filter(r => "login" in r).map(r => r.login),
+ labels: pr.labels.map(l => l.name),
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
@@ -799,6 +832,18 @@ class GitLabClient {
assignee_ids: [],
});
const mr = data;
+ // labels
+ if (backport.labels.length > 0) {
+ try {
+ this.logger.info("Setting labels: " + backport.labels);
+ await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ labels: backport.labels.join(","),
+ });
+ }
+ catch (error) {
+ this.logger.warn("Failure trying to update labels. " + error);
+ }
+ }
// reviewers
const reviewerIds = [];
for (const r of backport.reviewers) {
@@ -913,7 +958,6 @@ class GitLabMapper {
}
}
async mapPullRequest(mr) {
- // throw new Error("Method not implemented.");
return {
number: mr.iid,
author: mr.author.username,
@@ -926,6 +970,7 @@ class GitLabMapper {
mergedBy: mr.merged_by?.username,
reviewers: mr.reviewers?.map((r => r.username)) ?? [],
assignees: mr.assignees?.map((r => r.username)) ?? [],
+ labels: mr.labels ?? [],
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
nCommits: 1,
@@ -1140,6 +1185,7 @@ class Runner {
body: backportPR.body,
reviewers: backportPR.reviewers,
assignees: backportPR.assignees,
+ labels: backportPR.labels,
};
if (!configs.dryRun) {
// 8. push the new branch to origin
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index e2bddb9..c36c35c 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -36,6 +36,8 @@ export default abstract class ArgsParser {
reviewers: this.getOrDefault(args.reviewers, []),
assignees: this.getOrDefault(args.assignees, []),
inheritReviewers: this.getOrDefault(args.inheritReviewers, true),
+ labels: this.getOrDefault(args.labels, []),
+ inheritLabels: this.getOrDefault(args.inheritLabels, false),
};
}
}
\ No newline at end of file
diff --git a/src/service/args/args-utils.ts b/src/service/args/args-utils.ts
index b449fd4..13a3606 100644
--- a/src/service/args/args-utils.ts
+++ b/src/service/args/args-utils.ts
@@ -19,4 +19,32 @@ export function parseArgs(configFileContent: string): Args {
export function readConfigFile(pathToFile: string): Args {
const asString: string = fs.readFileSync(pathToFile, "utf-8");
return parseArgs(asString);
+}
+
+/**
+ * Return the input only if it is not a blank or null string, otherwise returns undefined
+ * @param key input key
+ * @returns the value or undefined
+ */
+export function getOrUndefined(value: string): string | undefined {
+ return value !== "" ? value : undefined;
+}
+
+// get rid of inner spaces too
+export function getAsCleanedCommaSeparatedList(value: string): string[] | undefined {
+ // trim the value
+ const trimmed: string = value.trim();
+ return trimmed !== "" ? trimmed.replace(/\s/g, "").split(",") : undefined;
+}
+
+// preserve inner spaces
+export function getAsCommaSeparatedList(value: string): string[] | undefined {
+ // trim the value
+ const trimmed: string = value.trim();
+ return trimmed !== "" ? trimmed.split(",").map(v => v.trim()) : undefined;
+}
+
+export function getAsBooleanOrDefault(value: string): boolean | undefined {
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.toLowerCase() === "true" : undefined;
}
\ No newline at end of file
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index 6279136..e1ada50 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -16,4 +16,6 @@ export interface Args {
reviewers?: string[], // backport pr reviewers
assignees?: string[], // backport pr assignees
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
}
\ 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 fe42b9b..e3297d1 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -2,13 +2,7 @@ import ArgsParser from "@bp/service/args/args-parser";
import { Args } from "@bp/service/args/args.types";
import { Command } from "commander";
import { name, version, description } from "@bp/../package.json";
-import { readConfigFile } from "@bp/service/args/args-utils";
-
-function commaSeparatedList(value: string, _prev: unknown): string[] {
- // remove all whitespaces
- const cleanedValue: string = value.trim();
- return cleanedValue !== "" ? cleanedValue.replace(/\s/g, "").split(",") : [];
-}
+import { getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, readConfigFile } from "@bp/service/args/args-utils";
export default class CLIArgsParser extends ArgsParser {
@@ -16,21 +10,23 @@ export default class CLIArgsParser extends ArgsParser {
return new Command(name)
.version(version)
.description(description)
- .option("-tb, --target-branch ", "branch where changes must be backported to.")
- .option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1.")
+ .option("-tb, --target-branch ", "branch where changes must be backported to")
+ .option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
- .option("-a, --auth ", "git service authentication string, e.g., github token.")
- .option("-gu, --git-user ", "local git user name, default is 'GitHub'.")
- .option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'.")
- .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder.")
- .option("--title ", "backport pr title, default original pr title prefixed by target branch.")
- .option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix.")
- .option("--body-prefix ", "backport pr body prefix, default `backport `.")
- .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit.")
- .option("--reviewers ", "comma separated list of reviewers for the backporting pull request.", commaSeparatedList)
- .option("--assignees ", "comma separated list of assignees for the backporting pull request.", commaSeparatedList)
+ .option("-a, --auth ", "git service authentication string, e.g., github token")
+ .option("-gu, --git-user ", "local git user name, default is 'GitHub'")
+ .option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'")
+ .option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder")
+ .option("--title ", "backport pr title, default original pr title prefixed by target branch")
+ .option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix")
+ .option("--body-prefix ", "backport pr body prefix, default `backport `")
+ .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit")
+ .option("--reviewers ", "comma separated list of reviewers for the backporting pull request", getAsCleanedCommaSeparatedList)
+ .option("--assignees ", "comma separated list of assignees for the backporting pull request", getAsCleanedCommaSeparatedList)
.option("--no-inherit-reviewers", "if provided and reviewers option is empty then inherit them from original pull request")
- .option("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface.");
+ .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("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
readArgs(): Args {
@@ -58,6 +54,8 @@ export default class CLIArgsParser extends ArgsParser {
reviewers: opts.reviewers,
assignees: opts.assignees,
inheritReviewers: opts.inheritReviewers,
+ labels: opts.labels,
+ inheritLabels: opts.inheritLabels,
};
}
diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts
index 74debbd..d06e40e 100644
--- a/src/service/args/gha/gha-args-parser.ts
+++ b/src/service/args/gha/gha-args-parser.ts
@@ -1,53 +1,34 @@
import ArgsParser from "@bp/service/args/args-parser";
import { Args } from "@bp/service/args/args.types";
import { getInput } from "@actions/core";
-import { readConfigFile } from "@bp/service/args/args-utils";
+import { getAsBooleanOrDefault, getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, getOrUndefined, readConfigFile } from "@bp/service/args/args-utils";
export default class GHAArgsParser extends ArgsParser {
- /**
- * Return the input only if it is not a blank or null string, otherwise returns undefined
- * @param key input key
- * @returns the value or undefined
- */
- public getOrUndefined(key: string): string | undefined {
- const value = getInput(key);
- return value !== "" ? value : undefined;
- }
-
- public getAsCommaSeparatedList(key: string): string[] | undefined {
- // trim the value
- const value: string = (getInput(key) ?? "").trim();
- return value !== "" ? value.replace(/\s/g, "").split(",") : undefined;
- }
-
- private getAsBooleanOrDefault(key: string): boolean | undefined {
- const value = getInput(key).trim();
- return value !== "" ? value.toLowerCase() === "true" : undefined;
- }
-
readArgs(): Args {
- const configFile = this.getOrUndefined("config-file");
+ const configFile = getOrUndefined(getInput("config-file"));
let args: Args;
if (configFile) {
args = readConfigFile(configFile);
} else {
args = {
- dryRun: this.getAsBooleanOrDefault("dry-run"),
- auth: this.getOrUndefined("auth"),
+ dryRun: getAsBooleanOrDefault(getInput("dry-run")),
+ auth: getOrUndefined(getInput("auth")),
pullRequest: getInput("pull-request"),
targetBranch: getInput("target-branch"),
- folder: this.getOrUndefined("folder"),
- gitUser: this.getOrUndefined("git-user"),
- gitEmail: this.getOrUndefined("git-email"),
- title: this.getOrUndefined("title"),
- body: this.getOrUndefined("body"),
- bodyPrefix: this.getOrUndefined("body-prefix"),
- bpBranchName: this.getOrUndefined("bp-branch-name"),
- reviewers: this.getAsCommaSeparatedList("reviewers"),
- assignees: this.getAsCommaSeparatedList("assignees"),
- inheritReviewers: !this.getAsBooleanOrDefault("no-inherit-reviewers"),
+ folder: getOrUndefined(getInput("folder")),
+ gitUser: getOrUndefined(getInput("git-user")),
+ gitEmail: getOrUndefined(getInput("git-email")),
+ title: getOrUndefined(getInput("title")),
+ body: getOrUndefined(getInput("body")),
+ bodyPrefix: getOrUndefined(getInput("body-prefix")),
+ bpBranchName: getOrUndefined(getInput("bp-branch-name")),
+ reviewers: getAsCleanedCommaSeparatedList(getInput("reviewers")),
+ assignees: getAsCleanedCommaSeparatedList(getInput("assignees")),
+ inheritReviewers: !getAsBooleanOrDefault(getInput("no-inherit-reviewers")),
+ labels: getAsCommaSeparatedList(getInput("labels")),
+ inheritLabels: getAsBooleanOrDefault(getInput("inherit-labels")),
};
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index f54ba5e..6ca50da 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -63,12 +63,18 @@ export default class PullRequestConfigsParser extends ConfigsParser {
const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`;
const body = args.body ?? `${originalPullRequest.body}`;
+ const labels = args.labels ?? [];
+ if (args.inheritLabels) {
+ labels.push(...originalPullRequest.labels);
+ }
+
return {
author: args.gitUser ?? this.gitClient.getDefaultGitUser(),
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
body: `${bodyPrefix}${body}`,
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
+ labels: [...new Set(labels)],
targetRepo: originalPullRequest.targetRepo,
sourceRepo: originalPullRequest.targetRepo,
branchName: args.bpBranchName,
diff --git a/src/service/git/git.types.ts b/src/service/git/git.types.ts
index 9a4da4d..4ca5405 100644
--- a/src/service/git/git.types.ts
+++ b/src/service/git/git.types.ts
@@ -10,6 +10,7 @@ export interface GitPullRequest {
body: string,
reviewers: string[],
assignees: string[],
+ labels: string[],
targetRepo: GitRepository,
sourceRepo: GitRepository,
nCommits?: number, // number of commits in the pr
@@ -32,6 +33,7 @@ export interface BackportPullRequest {
body: string, // pr body
reviewers: string[], // pr list of reviewers
assignees: string[], // pr list of assignees
+ labels: string[], // pr list of assigned labels
branchName?: string,
}
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index 6f79c0c..c7d8f81 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -59,13 +59,26 @@ export default class GitHubClient implements GitClient {
head: backport.head,
base: backport.base,
title: backport.title,
- body: backport.body
+ body: backport.body,
});
if (!data) {
throw new Error("Pull request creation failed");
}
+ if (backport.labels.length > 0) {
+ try {
+ await this.octokit.issues.addLabels({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: (data as PullRequest).number,
+ labels: backport.labels,
+ });
+ } catch (error) {
+ this.logger.error(`Error setting labels: ${error}`);
+ }
+ }
+
if (backport.reviewers.length > 0) {
try {
await this.octokit.pulls.requestReviewers({
diff --git a/src/service/git/github/github-mapper.ts b/src/service/git/github/github-mapper.ts
index 6e33b9f..caa1bb1 100644
--- a/src/service/git/github/github-mapper.ts
+++ b/src/service/git/github/github-mapper.ts
@@ -26,6 +26,7 @@ export default class GitHubMapper implements GitResponseMapper "login" in r).map((r => (r as User)?.login)),
assignees: pr.assignees.filter(r => "login" in r).map(r => r.login),
+ labels: pr.labels.map(l => l.name),
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index 8b7069d..427a0ac 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -72,6 +72,18 @@ export default class GitLabClient implements GitClient {
const mr = data as MergeRequestSchema;
+ // labels
+ if (backport.labels.length > 0) {
+ try {
+ this.logger.info("Setting labels: " + backport.labels);
+ await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ labels: backport.labels.join(","),
+ });
+ } catch(error) {
+ this.logger.warn("Failure trying to update labels. " + error);
+ }
+ }
+
// reviewers
const reviewerIds: number[] = [];
for(const r of backport.reviewers) {
diff --git a/src/service/git/gitlab/gitlab-mapper.ts b/src/service/git/gitlab/gitlab-mapper.ts
index 4aa4291..cc917a2 100644
--- a/src/service/git/gitlab/gitlab-mapper.ts
+++ b/src/service/git/gitlab/gitlab-mapper.ts
@@ -25,7 +25,6 @@ export default class GitLabMapper implements GitResponseMapper {
- // throw new Error("Method not implemented.");
return {
number: mr.iid,
author: mr.author.username,
@@ -38,6 +37,7 @@ export default class GitLabMapper implements GitResponseMapper r.username)) ?? [],
assignees: mr.assignees?.map((r => r.username)) ?? [],
+ labels: mr.labels ?? [],
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
nCommits: 1, // info not present on mr
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index 2bb4e1f..642cc78 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -100,6 +100,7 @@ export default class Runner {
body: backportPR.body,
reviewers: backportPR.reviewers,
assignees: backportPR.assignees,
+ labels: backportPR.labels,
};
if (!configs.dryRun) {
diff --git a/test/service/args/args-utils.test.ts b/test/service/args/args-utils.test.ts
index 57f5f30..508e5d7 100644
--- a/test/service/args/args-utils.test.ts
+++ b/test/service/args/args-utils.test.ts
@@ -1,5 +1,6 @@
-import { parseArgs, readConfigFile } from "@bp/service/args/args-utils";
-import { createTestFile, removeTestFile } from "../../support/utils";
+import { getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, getOrUndefined, parseArgs, readConfigFile } from "@bp/service/args/args-utils";
+import { createTestFile, expectArrayEqual, removeTestFile, spyGetInput } from "../../support/utils";
+import { getInput } from "@actions/core";
const RANDOM_CONFIG_FILE_CONTENT_PATHNAME = "./args-utils-test-random-config-file.json";
const RANDOM_CONFIG_FILE_CONTENT = {
@@ -39,4 +40,39 @@ describe("args utils test suite", () => {
test("check readConfigFile function", () => {
expect(readConfigFile(RANDOM_CONFIG_FILE_CONTENT_PATHNAME)).toStrictEqual(RANDOM_CONFIG_FILE_CONTENT);
});
+
+ test("gha getOrUndefined", () => {
+ spyGetInput({
+ "present": "value",
+ "empty": "",
+ });
+ expect(getOrUndefined(getInput("empty"))).toStrictEqual(undefined);
+ expect(getOrUndefined(getInput("present"))).toStrictEqual("value");
+ });
+
+ test("gha getAsCleanedCommaSeparatedList", () => {
+ spyGetInput({
+ "present": "value1, value2 , value3",
+ "empty": "",
+ "blank": " ",
+ "inner": " inner spaces ",
+ });
+ expectArrayEqual(getAsCleanedCommaSeparatedList(getInput("present"))!, ["value1", "value2", "value3"]);
+ expect(getAsCleanedCommaSeparatedList(getInput("empty"))).toStrictEqual(undefined);
+ expect(getAsCleanedCommaSeparatedList(getInput("blank"))).toStrictEqual(undefined);
+ expect(getAsCleanedCommaSeparatedList(getInput("inner"))).toStrictEqual(["innerspaces"]);
+ });
+
+ test("gha getAsCommaSeparatedList", () => {
+ spyGetInput({
+ "present": "value1, value2 , value3",
+ "empty": "",
+ "blank": " ",
+ "inner": " inner spaces ",
+ });
+ expectArrayEqual(getAsCommaSeparatedList(getInput("present"))!, ["value1", "value2", "value3"]);
+ expect(getAsCommaSeparatedList(getInput("empty"))).toStrictEqual(undefined);
+ expect(getAsCommaSeparatedList(getInput("blank"))).toStrictEqual(undefined);
+ expectArrayEqual(getAsCommaSeparatedList(getInput("inner"))!, ["inner spaces"]);
+ });
});
\ No newline at end of file
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index ff09dd0..d7b6338 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -24,6 +24,8 @@ const RANDOM_CONFIG_FILE_CONTENT = {
"reviewers": ["reviewer1", "reviewer2"],
"assignees": ["assignee1", "assignee2"],
"inheritReviewers": true,
+ "labels": ["cherry-pick :cherries:"],
+ "inheritLabels": true,
};
describe("cli args parser", () => {
@@ -72,6 +74,8 @@ describe("cli args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
});
test("with config file [default, short]", () => {
@@ -95,6 +99,8 @@ describe("cli args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
});
test("valid execution [default, long]", () => {
@@ -120,6 +126,8 @@ describe("cli args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
});
test("with config file [default, long]", () => {
@@ -143,6 +151,8 @@ describe("cli args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
});
test("valid execution [override, short]", () => {
@@ -175,6 +185,8 @@ describe("cli args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
});
test("valid execution [override, long]", () => {
@@ -203,6 +215,9 @@ describe("cli args parser", () => {
"--assignees",
" pippo,pluto, paperino",
"--no-inherit-reviewers",
+ "--labels",
+ "cherry-pick :cherries:, another spaced label",
+ "--inherit-labels",
]);
const args: Args = parser.parse();
@@ -220,6 +235,8 @@ describe("cli args parser", () => {
expectArrayEqual(args.reviewers!, ["al", "john", "jack"]);
expectArrayEqual(args.assignees!, ["pippo", "pluto", "paperino"]);
expect(args.inheritReviewers).toEqual(false);
+ expectArrayEqual(args.labels!, ["cherry-pick :cherries:", "another spaced label"]);
+ expect(args.inheritLabels).toEqual(true);
});
test("override using config file", () => {
@@ -243,6 +260,8 @@ describe("cli args parser", () => {
expectArrayEqual(args.reviewers!, ["reviewer1", "reviewer2"]);
expectArrayEqual(args.assignees!,["assignee1", "assignee2"]);
expect(args.inheritReviewers).toEqual(true);
+ expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
+ expect(args.inheritLabels).toEqual(true);
});
test("ignore custom option when config file is set", () => {
@@ -273,6 +292,9 @@ describe("cli args parser", () => {
"--assignees",
" pippo,pluto, paperino",
"--no-inherit-reviewers",
+ "--labels",
+ "cherry-pick :cherries:, another spaced label",
+ "--inherit-labels",
]);
const args: Args = parser.parse();
@@ -290,5 +312,7 @@ describe("cli args parser", () => {
expectArrayEqual(args.reviewers!, ["reviewer1", "reviewer2"]);
expectArrayEqual(args.assignees!,["assignee1", "assignee2"]);
expect(args.inheritReviewers).toEqual(true);
+ expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
+ expect(args.inheritLabels).toEqual(true);
});
});
\ 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 130f7d5..0d42806 100644
--- a/test/service/args/gha/gha-args-parser.test.ts
+++ b/test/service/args/gha/gha-args-parser.test.ts
@@ -24,6 +24,8 @@ const RANDOM_CONFIG_FILE_CONTENT = {
"reviewers": ["reviewer1", "reviewer2"],
"assignees": ["assignee1", "assignee2"],
"inheritReviewers": true,
+ "labels": ["cherry-pick :cherries:"],
+ "inheritLabels": true,
};
describe("gha args parser", () => {
@@ -50,26 +52,6 @@ describe("gha args parser", () => {
jest.clearAllMocks();
});
- test("getOrUndefined", () => {
- spyGetInput({
- "present": "value",
- "empty": "",
- });
- expect(parser.getOrUndefined("empty")).toStrictEqual(undefined);
- expect(parser.getOrUndefined("present")).toStrictEqual("value");
- });
-
- test("getAsCommaSeparatedList", () => {
- spyGetInput({
- "present": "value1, value2 , value3",
- "empty": "",
- "blank": " ",
- });
- expectArrayEqual(parser.getAsCommaSeparatedList("present")!, ["value1", "value2", "value3"]);
- expect(parser.getAsCommaSeparatedList("empty")).toStrictEqual(undefined);
- expect(parser.getAsCommaSeparatedList("blank")).toStrictEqual(undefined);
- });
-
test("valid execution [default]", () => {
spyGetInput({
"target-branch": "target",
@@ -89,6 +71,8 @@ describe("gha args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
});
test("valid execution [override]", () => {
@@ -106,6 +90,8 @@ describe("gha args parser", () => {
"reviewers": "al , john, jack",
"assignees": " pippo,pluto, paperino",
"no-inherit-reviewers": "true",
+ "labels": "cherry-pick :cherries:, another spaced label",
+ "inherit-labels": "true"
});
const args: Args = parser.parse();
@@ -123,6 +109,8 @@ describe("gha args parser", () => {
expectArrayEqual(args.reviewers!, ["al", "john", "jack"]);
expectArrayEqual(args.assignees!, ["pippo", "pluto", "paperino"]);
expect(args.inheritReviewers).toEqual(false);
+ expectArrayEqual(args.labels!, ["cherry-pick :cherries:", "another spaced label"]);
+ expect(args.inheritLabels).toEqual(true);
});
test("using config file", () => {
@@ -145,6 +133,8 @@ describe("gha args parser", () => {
expect(args.reviewers).toEqual([]);
expect(args.assignees).toEqual([]);
expect(args.inheritReviewers).toEqual(true);
+ expectArrayEqual(args.labels!, []);
+ expect(args.inheritLabels).toEqual(false);
});
test("ignore custom options when using config file", () => {
@@ -163,6 +153,8 @@ describe("gha args parser", () => {
"reviewers": "al , john, jack",
"assignees": " pippo,pluto, paperino",
"no-inherit-reviewers": "true",
+ "labels": "cherry-pick :cherries:, another spaced label",
+ "inherit-labels": "false"
});
const args: Args = parser.parse();
@@ -180,5 +172,7 @@ describe("gha args parser", () => {
expectArrayEqual(args.reviewers!, ["reviewer1", "reviewer2"]);
expectArrayEqual(args.assignees!,["assignee1", "assignee2"]);
expect(args.inheritReviewers).toEqual(true);
+ expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
+ expect(args.inheritLabels).toEqual(true);
});
});
\ No newline at end of file
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 5f5d8ae..4d5b1ba 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -28,6 +28,8 @@ const GITHUB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"reviewers": ["user1", "user2"],
"assignees": ["user3", "user4"],
"inheritReviewers": true, // not taken into account
+ "labels": ["cherry-pick :cherries:"],
+ "inheritLabels": true,
};
describe("github pull request config parser", () => {
@@ -104,6 +106,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["requested-gh-user", "gh-user"],
assignees: [],
+ labels: ["original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -125,6 +128,7 @@ describe("github pull request config parser", () => {
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: [],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -199,6 +203,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["gh-user"],
assignees: [],
+ labels: [],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -233,7 +238,7 @@ describe("github pull request config parser", () => {
});
- test("override backport pr data inherting reviewers", async () => {
+ test("override backport pr data inheriting reviewers", async () => {
const args: Args = {
dryRun: false,
auth: "",
@@ -271,6 +276,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["requested-gh-user", "gh-user"],
assignees: [],
+ labels: ["original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -293,6 +299,7 @@ describe("github pull request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
+ labels: [],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -345,6 +352,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["requested-gh-user", "gh-user"],
assignees: [],
+ labels: ["original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -367,6 +375,7 @@ describe("github pull request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: [],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -419,6 +428,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["requested-gh-user", "gh-user"],
assignees: [],
+ labels: ["original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -441,6 +451,85 @@ describe("github pull request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: [],
+ 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,
+ });
+ });
+
+ test("override backport pr custom labels with duplicates", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: ["custom-label", "original-label"], // also include the one inherited
+ inheritLabels: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.git).toEqual({
+ user: "Me",
+ email: "me@email.com"
+ });
+ 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"],
+ assignees: [],
+ labels: ["original-label"],
+ 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: "Me",
+ url: undefined,
+ htmlUrl: undefined,
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: ["custom-label", "original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -484,6 +573,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["requested-gh-user", "gh-user"],
assignees: [],
+ labels: ["original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -505,6 +595,7 @@ describe("github pull request config parser", () => {
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: [],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -548,6 +639,7 @@ describe("github pull request config parser", () => {
body: "Please review and merge",
reviewers: ["requested-gh-user", "gh-user"],
assignees: [],
+ labels: ["original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
@@ -570,6 +662,7 @@ describe("github pull request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: ["cherry-pick :cherries:", "original-label"],
targetRepo: {
owner: "owner",
project: "reponame",
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 6049da5..9e47f1b 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -28,6 +28,8 @@ const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"reviewers": [],
"assignees": ["user3", "user4"],
"inheritReviewers": false,
+ "labels": ["cherry-pick :cherries:"],
+ "inheritLabels": true,
};
@@ -107,6 +109,7 @@ describe("gitlab merge request config parser", () => {
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -128,6 +131,7 @@ describe("gitlab merge request config parser", () => {
body: "**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1\r\n\r\nThis is the body",
reviewers: ["superuser"],
assignees: [],
+ labels: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -203,6 +207,7 @@ describe("gitlab merge request config parser", () => {
body: "Still opened mr body",
reviewers: ["superuser"],
assignees: ["superuser"],
+ labels: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -236,7 +241,7 @@ describe("gitlab merge request config parser", () => {
expect(async () => await configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
});
- test("override backport pr data inherting reviewers", async () => {
+ test("override backport pr data inheriting reviewers", async () => {
const args: Args = {
dryRun: false,
auth: "",
@@ -274,6 +279,7 @@ describe("gitlab merge request config parser", () => {
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -295,6 +301,7 @@ describe("gitlab merge request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: ["superuser"],
assignees: [],
+ labels: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -347,6 +354,7 @@ describe("gitlab merge request config parser", () => {
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -368,6 +376,7 @@ describe("gitlab merge request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -420,6 +429,7 @@ describe("gitlab merge request config parser", () => {
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -441,6 +451,7 @@ describe("gitlab merge request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -455,6 +466,82 @@ describe("gitlab merge request config parser", () => {
});
});
+ test("override backport pr custom labels with duplicates", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: ["custom-label", "gitlab-original-label"], // also include the one inherited
+ inheritLabels: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.git).toEqual({
+ user: "Me",
+ email: "me@email.com"
+ });
+ expect(configs.auth).toEqual("");
+ expect(configs.targetBranch).toEqual("prod");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.originalPullRequest).toEqual({
+ number: 1,
+ author: "superuser",
+ url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ state: "merged",
+ merged: true,
+ mergedBy: "superuser",
+ title: "Update test.txt",
+ body: "This is the body",
+ reviewers: ["superuser1", "superuser2"],
+ assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
+ targetRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ sourceRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ nCommits: 1,
+ commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
+ });
+ expect(configs.backportPullRequest).toEqual({
+ author: "Me",
+ url: undefined,
+ htmlUrl: undefined,
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: ["custom-label", "gitlab-original-label"],
+ targetRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ sourceRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ bpBranchName: undefined,
+ });
+ });
test("using simple config file", async () => {
spyGetInput({
@@ -484,6 +571,7 @@ describe("gitlab merge request config parser", () => {
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -505,6 +593,7 @@ describe("gitlab merge request config parser", () => {
body: "**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1\r\n\r\nThis is the body",
reviewers: ["superuser"],
assignees: [],
+ labels: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -547,6 +636,7 @@ describe("gitlab merge request config parser", () => {
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
@@ -568,6 +658,7 @@ describe("gitlab merge request config parser", () => {
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: ["cherry-pick :cherries:", "gitlab-original-label"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
diff --git a/test/service/git/gitlab/gitlab-client.test.ts b/test/service/git/gitlab/gitlab-client.test.ts
index 686ba2e..2e3e58d 100644
--- a/test/service/git/gitlab/gitlab-client.test.ts
+++ b/test/service/git/gitlab/gitlab-client.test.ts
@@ -92,6 +92,7 @@ describe("github service", () => {
head: "bp-branch",
reviewers: [],
assignees: [],
+ labels: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -121,6 +122,7 @@ describe("github service", () => {
head: "bp-branch",
reviewers: ["superuser", "invalid"],
assignees: [],
+ labels: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -155,6 +157,7 @@ describe("github service", () => {
head: "bp-branch",
reviewers: [],
assignees: ["superuser", "invalid"],
+ labels: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -189,6 +192,7 @@ describe("github service", () => {
head: "bp-branch-2",
reviewers: ["superuser", "invalid"],
assignees: [],
+ labels: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -223,6 +227,7 @@ describe("github service", () => {
head: "bp-branch-2",
reviewers: [],
assignees: ["superuser", "invalid"],
+ labels: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -246,4 +251,37 @@ describe("github service", () => {
assignee_ids: [14041],
});
});
+
+ test("create backport pull request with custom labels", async () => {
+ const backport: BackportPullRequest = {
+ title: "Backport Title",
+ body: "Backport Body",
+ owner: "superuser",
+ repo: "backporting-example",
+ base: "old/branch",
+ head: "bp-branch-2",
+ reviewers: [],
+ assignees: [],
+ labels: ["label1", "label2"],
+ };
+
+ const url: string = await gitClient.createPullRequest(backport);
+ expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
+
+ // check axios invocation
+ expect(axiosInstanceSpy.post).toBeCalledTimes(1);
+ expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
+ source_branch: "bp-branch-2",
+ target_branch: "old/branch",
+ title: "Backport Title",
+ description: "Backport Body",
+ reviewer_ids: [],
+ assignee_ids: [],
+ }));
+ expect(axiosInstanceSpy.get).toBeCalledTimes(0);
+ expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just labels
+ expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
+ labels: "label1,label2",
+ });
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 0b7a752..12a648b 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -21,6 +21,8 @@ const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
"reviewers": [],
"assignees": ["user3", "user4"],
"inheritReviewers": false,
+ "labels": ["cli github cherry pick :cherries:"],
+ "inheritLabels": true,
};
jest.mock("@bp/service/git/git-cli");
@@ -218,6 +220,7 @@ describe("cli runner", () => {
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
+ labels: [],
}
);
});
@@ -258,6 +261,7 @@ describe("cli runner", () => {
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
+ labels: [],
}
);
});
@@ -310,6 +314,7 @@ describe("cli runner", () => {
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
reviewers: ["gh-user"],
assignees: [],
+ labels: [],
}
);
});
@@ -331,7 +336,7 @@ describe("cli runner", () => {
"--reviewers",
"user1,user2",
"--assignees",
- "user3,user4"
+ "user3,user4",
]);
await runner.execute();
@@ -363,6 +368,7 @@ describe("cli runner", () => {
body: "New Body Prefix - New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: [],
}
);
});
@@ -415,6 +421,96 @@ describe("cli runner", () => {
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: [],
+ }
+ );
+ });
+
+ test("set custom labels with inheritance", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/2368",
+ "--labels",
+ "cherry-pick :cherries:, original-label",
+ "--inherit-labels",
+ ]);
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "original-label"],
+ }
+ );
+ });
+
+ test("set custom lables without inheritance", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/2368",
+ "--labels",
+ "first-label, second-label ",
+ ]);
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: ["first-label", "second-label"],
}
);
});
@@ -454,6 +550,7 @@ describe("cli runner", () => {
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: ["cli github cherry pick :cherries:", "original-label"],
}
);
});
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index c8b9292..657a5fd 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -21,6 +21,8 @@ const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"reviewers": [],
"assignees": ["user3", "user4"],
"inheritReviewers": false,
+ "labels": ["cli gitlab cherry pick :cherries:"],
+ "inheritLabels": true,
};
jest.mock("axios", () => {
@@ -171,6 +173,7 @@ describe("cli runner", () => {
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
reviewers: ["superuser"],
assignees: [],
+ labels: [],
}
);
});
@@ -224,6 +227,7 @@ describe("cli runner", () => {
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
reviewers: ["superuser"],
assignees: [],
+ labels: [],
}
);
});
@@ -278,6 +282,7 @@ describe("cli runner", () => {
body: "New Body Prefix - New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: [],
}
);
});
@@ -330,6 +335,98 @@ describe("cli runner", () => {
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: [],
+ }
+ );
+ });
+
+ test("set custom labels with inheritance", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ "--labels",
+ "cherry-pick :cherries:, another-label",
+ "--inherit-labels",
+ ]);
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ // 0 occurrences as the mr is already merged and the owner is the same for
+ // both source and target repositories
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ base: "target",
+ title: "[target] Update test.txt",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "another-label", "gitlab-original-label"],
+ }
+ );
+ });
+
+ test("set custom labels without inheritance", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ "--labels",
+ "cherry-pick :cherries:, another-label",
+ ]);
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ // 0 occurrences as the mr is already merged and the owner is the same for
+ // both source and target repositories
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ base: "target",
+ title: "[target] Update test.txt",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "another-label"],
}
);
});
@@ -370,6 +467,7 @@ describe("cli runner", () => {
body: expect.stringContaining("**This is a backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
reviewers: [],
assignees: ["user3", "user4"],
+ labels: ["cli gitlab cherry pick :cherries:", "gitlab-original-label"],
}
);
});
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index ab2236e..9b17fee 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -21,6 +21,8 @@ const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
"reviewers": [],
"assignees": ["user3", "user4"],
"inheritReviewers": false,
+ "labels": ["gha github cherry pick :cherries:"],
+ "inheritLabels": true,
};
@@ -117,6 +119,7 @@ describe("gha runner", () => {
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
+ labels: [],
}
);
});
@@ -165,6 +168,7 @@ describe("gha runner", () => {
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
reviewers: ["gh-user"],
assignees: [],
+ labels: [],
}
);
});
@@ -210,6 +214,7 @@ describe("gha runner", () => {
body: "New Body Prefix - New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: [],
}
);
});
@@ -256,6 +261,91 @@ describe("gha runner", () => {
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: [],
+ }
+ );
+ });
+
+ test("set custom labels with inheritance", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://github.com/owner/reponame/pull/2368",
+ "labels": "cherry-pick :cherries:, another-label",
+ "inherit-labels": "true",
+ });
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "another-label", "original-label"],
+ }
+ );
+ });
+
+ test("set custom labels without inheritance", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://github.com/owner/reponame/pull/2368",
+ "labels": "cherry-pick :cherries:, another-label",
+ "inherit-labels": "false",
+ });
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "another-label"],
}
);
});
@@ -294,6 +384,7 @@ describe("gha runner", () => {
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: ["gha github cherry pick :cherries:", "original-label"],
}
);
});
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 0443342..e1d755c 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -21,6 +21,8 @@ const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"reviewers": [],
"assignees": ["user3", "user4"],
"inheritReviewers": false,
+ "labels": ["gha gitlab cherry pick :cherries:"],
+ "inheritLabels": true,
};
jest.mock("axios", () => {
@@ -128,6 +130,7 @@ describe("gha runner", () => {
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
reviewers: ["superuser"],
assignees: [],
+ labels: [],
}
);
});
@@ -175,6 +178,7 @@ describe("gha runner", () => {
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
reviewers: ["superuser"],
assignees: [],
+ labels: [],
}
);
});
@@ -220,6 +224,7 @@ describe("gha runner", () => {
body: "New Body Prefix - New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
+ labels: [],
}
);
});
@@ -266,6 +271,88 @@ describe("gha runner", () => {
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
+ labels: [],
+ }
+ );
+ });
+
+ test("set custom labels with inheritance", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ "labels": "cherry-pick :cherries:, another-label",
+ "inherit-labels": "true",
+ });
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ base: "target",
+ title: "[target] Update test.txt",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "another-label", "gitlab-original-label"],
+ }
+ );
+ });
+
+ test("set custom labels without inheritance", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ "labels": "cherry-pick :cherries:, another-label",
+ });
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ base: "target",
+ title: "[target] Update test.txt",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: ["cherry-pick :cherries:", "another-label"],
}
);
});
@@ -305,6 +392,7 @@ describe("gha runner", () => {
body: expect.stringContaining("**This is a backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
reviewers: [],
assignees: ["user3", "user4"],
+ labels: ["gha gitlab cherry pick :cherries:", "gitlab-original-label"],
}
);
});
diff --git a/test/support/mock/github-data.ts b/test/support/mock/github-data.ts
index fc13e32..a5f0f60 100644
--- a/test/support/mock/github-data.ts
+++ b/test/support/mock/github-data.ts
@@ -91,7 +91,15 @@ export const mergedPullRequestFixture = {
],
"labels": [
-
+ {
+ "id": 4901021057,
+ "node_id": "LA_kwDOImgs2354988AAAABJB-lgQ",
+ "url": "https://api.github.com/repos/owner/reponame/labels/original-label",
+ "name": "original-label",
+ "color": "AB975B",
+ "default": false,
+ "description": ""
+ }
],
"milestone": null,
"draft": false,
diff --git a/test/support/mock/gitlab-data.ts b/test/support/mock/gitlab-data.ts
index 7df3263..d1af227 100644
--- a/test/support/mock/gitlab-data.ts
+++ b/test/support/mock/gitlab-data.ts
@@ -241,7 +241,7 @@ export const MERGED_SQUASHED_MR = {
"source_project_id":76316,
"target_project_id":76316,
"labels":[
-
+ "gitlab-original-label"
],
"draft":false,
"work_in_progress":false,
From a737aa7c4c66983de358b8472121ab918de922e3 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Mon, 10 Jul 2023 15:18:51 +0200
Subject: [PATCH 03/75] fix(issue-52): use pull request github api url as
source (#53)
fix https://github.com/kiegroup/git-backporting/issues/52
---
dist/cli/index.js | 2 +-
dist/gha/index.js | 2 +-
src/service/git/git-util.ts | 2 +-
test/service/git/git-util.test.ts | 12 ++-
test/service/runner/cli-github-runner.test.ts | 82 +++++++++++++++++++
test/service/runner/cli-gitlab-runner.test.ts | 30 +++++++
test/service/runner/gha-github-runner.test.ts | 72 ++++++++++++++++
test/service/runner/gha-gitlab-runner.test.ts | 27 ++++++
test/support/mock/git-client-mock-support.ts | 7 ++
9 files changed, 231 insertions(+), 5 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 866fdad..5818d2a 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -560,7 +560,7 @@ exports.inferGitClient = inferGitClient;
const inferGitApiUrl = (prUrl, apiVersion = "v4") => {
const url = new URL(prUrl);
const baseUrl = `${url.protocol}//${url.host}`;
- if (baseUrl.includes(PUBLIC_GITHUB_URL)) {
+ if (baseUrl.includes(PUBLIC_GITHUB_URL) || baseUrl.includes(PUBLIC_GITHUB_API)) {
return PUBLIC_GITHUB_API;
}
return `${baseUrl}/api/${apiVersion}`;
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 497b6f4..20a9a92 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -534,7 +534,7 @@ exports.inferGitClient = inferGitClient;
const inferGitApiUrl = (prUrl, apiVersion = "v4") => {
const url = new URL(prUrl);
const baseUrl = `${url.protocol}//${url.host}`;
- if (baseUrl.includes(PUBLIC_GITHUB_URL)) {
+ if (baseUrl.includes(PUBLIC_GITHUB_URL) || baseUrl.includes(PUBLIC_GITHUB_API)) {
return PUBLIC_GITHUB_API;
}
return `${baseUrl}/api/${apiVersion}`;
diff --git a/src/service/git/git-util.ts b/src/service/git/git-util.ts
index e7be7ad..6d459b2 100644
--- a/src/service/git/git-util.ts
+++ b/src/service/git/git-util.ts
@@ -31,7 +31,7 @@ export const inferGitApiUrl = (prUrl: string, apiVersion = "v4"): string => {
const url = new URL(prUrl);
const baseUrl = `${url.protocol}//${url.host}`;
- if (baseUrl.includes(PUBLIC_GITHUB_URL)) {
+ if (baseUrl.includes(PUBLIC_GITHUB_URL) || baseUrl.includes(PUBLIC_GITHUB_API)) {
return PUBLIC_GITHUB_API;
}
diff --git a/test/service/git/git-util.test.ts b/test/service/git/git-util.test.ts
index af5a561..cf083c6 100644
--- a/test/service/git/git-util.test.ts
+++ b/test/service/git/git-util.test.ts
@@ -24,14 +24,22 @@ describe("check git utilities", () => {
});
test("check infer github client", ()=> {
- expect(inferGitClient("https://github.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual(GitClientType.GITHUB);
+ expect(inferGitClient("https://github.com/superuser/backporting-example/pull/4")).toStrictEqual(GitClientType.GITHUB);
});
test("check infer gitlab client", ()=> {
expect(inferGitClient("https://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual(GitClientType.GITLAB);
});
- test("Not recognized git client type", ()=> {
+ test("not recognized git client type", ()=> {
expect(() => inferGitClient("https://not.recognized/superuser/backporting-example/-/merge_requests/4")).toThrowError("Remote git service not recognized from pr url: https://not.recognized/superuser/backporting-example/-/merge_requests/4");
});
+
+ test("check infer github client using github api", ()=> {
+ expect(inferGitClient("https://api.github.com/repos/owner/repo/pulls/1")).toStrictEqual(GitClientType.GITHUB);
+ });
+
+ test("check infer github api from github api url", ()=> {
+ expect(inferGitApiUrl("https://api.github.com/repos/owner/repo/pulls/1")).toStrictEqual("https://api.github.com");
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 12a648b..0c06a6c 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -5,6 +5,8 @@ import GitHubClient from "@bp/service/git/github/github-client";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../support/utils";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
+import GitClientFactory from "@bp/service/git/git-client-factory";
+import { GitClientType } from "@bp/service/git/git.types";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT_PATHNAME = "./cli-github-runner-pr-merged-with-overrides.json";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
@@ -27,6 +29,7 @@ const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitHubClient.prototype, "createPullRequest");
+jest.spyOn(GitClientFactory, "getOrCreate");
let parser: ArgsParser;
let runner: Runner;
@@ -73,6 +76,9 @@ describe("cli runner", () => {
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");
@@ -133,6 +139,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/folder";
+ 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");
@@ -167,6 +176,9 @@ describe("cli runner", () => {
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(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target");
@@ -195,6 +207,9 @@ describe("cli runner", () => {
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");
@@ -237,6 +252,9 @@ describe("cli runner", () => {
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");
@@ -289,6 +307,9 @@ describe("cli runner", () => {
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");
@@ -343,6 +364,9 @@ describe("cli runner", () => {
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");
@@ -396,6 +420,9 @@ describe("cli runner", () => {
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");
@@ -441,6 +468,9 @@ describe("cli runner", () => {
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");
@@ -485,6 +515,9 @@ describe("cli runner", () => {
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");
@@ -525,6 +558,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, "my-auth-token", "https://api.github.com");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target");
@@ -554,4 +590,50 @@ describe("cli runner", () => {
}
);
});
+
+ // to check: https://github.com/kiegroup/git-backporting/issues/52
+ test("using github api url instead of html one", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://api.github.com/repos/owner/reponame/pulls/2368"
+ ]);
+
+ 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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index 657a5fd..31fdb61 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -6,6 +6,8 @@ import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../support/utils";
import { getAxiosMocked } from "../../support/mock/git-client-mock-support";
import { MERGED_SQUASHED_MR } from "../../support/mock/gitlab-data";
+import GitClientFactory from "@bp/service/git/git-client-factory";
+import { GitClientType } from "@bp/service/git/git.types";
const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT_PATHNAME = "./cli-gitlab-runner-pr-merged-with-overrides.json";
const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
@@ -41,6 +43,7 @@ jest.mock("axios", () => {
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitLabClient.prototype, "createPullRequest");
+jest.spyOn(GitClientFactory, "getOrCreate");
let parser: ArgsParser;
@@ -86,6 +89,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -117,6 +123,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/folder";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -148,6 +157,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -201,6 +213,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -257,6 +272,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -310,6 +328,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -355,6 +376,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -400,6 +424,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -441,6 +468,9 @@ describe("cli runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, "my-token", "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "prod");
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 9b17fee..8fb8dd4 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -5,6 +5,8 @@ import GitHubClient from "@bp/service/git/github/github-client";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
import { createTestFile, removeTestFile, spyGetInput } from "../../support/utils";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
+import GitClientFactory from "@bp/service/git/git-client-factory";
+import { GitClientType } from "@bp/service/git/git.types";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT_PATHNAME = "./gha-github-runner-pr-merged-with-overrides.json";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
@@ -28,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(GitClientFactory, "getOrCreate");
let parser: ArgsParser;
let runner: Runner;
@@ -68,6 +71,9 @@ describe("gha runner", () => {
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");
@@ -94,6 +100,9 @@ describe("gha runner", () => {
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");
@@ -143,6 +152,9 @@ describe("gha runner", () => {
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");
@@ -189,6 +201,9 @@ describe("gha runner", () => {
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");
@@ -236,6 +251,9 @@ describe("gha runner", () => {
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");
@@ -278,6 +296,9 @@ describe("gha runner", () => {
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");
@@ -320,6 +341,9 @@ describe("gha runner", () => {
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");
@@ -359,6 +383,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, "my-auth-token", "https://api.github.com");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target");
@@ -388,4 +415,49 @@ describe("gha runner", () => {
}
);
});
+
+ // to check: https://github.com/kiegroup/git-backporting/issues/52
+ test("using github api url instead of html one", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://api.github.com/repos/owner/reponame/pulls/2368"
+ });
+
+ 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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ 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-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
+
});
\ No newline at end of file
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index e1d755c..a28b410 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -6,6 +6,8 @@ import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
import { createTestFile, removeTestFile, spyGetInput } from "../../support/utils";
import { getAxiosMocked } from "../../support/mock/git-client-mock-support";
import { MERGED_SQUASHED_MR } from "../../support/mock/gitlab-data";
+import GitClientFactory from "@bp/service/git/git-client-factory";
+import { GitClientType } from "@bp/service/git/git.types";
const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT_PATHNAME = "./gha-gitlab-runner-pr-merged-with-overrides.json";
const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
@@ -41,6 +43,7 @@ jest.mock("axios", () => {
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitLabClient.prototype, "createPullRequest");
+jest.spyOn(GitClientFactory, "getOrCreate");
let parser: ArgsParser;
let runner: Runner;
@@ -79,6 +82,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -105,6 +111,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -154,6 +163,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -199,6 +211,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -246,6 +261,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -288,6 +306,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -328,6 +349,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
@@ -366,6 +390,9 @@ describe("gha runner", () => {
const cwd = process.cwd() + "/bp";
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, "my-token", "https://my.gitlab.host.com/api/v4");
+
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "prod");
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index 7b4c987..c73d410 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -149,6 +149,13 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
data: {}
});
+ mock.rest.issues
+ .addLabels()
+ .reply({
+ status: 200,
+ data: {}
+ });
+
// invalid requests
mock.rest.pulls
From c4dbb26c1d9d266ed86f3f0d6016b8cff7743f8b Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Tue, 11 Jul 2023 11:22:01 +0200
Subject: [PATCH 04/75] feat(issue-54): backport pr commits without squash
(#55)
* feat(issue-54): backport pr commits without squash
fix https://github.com/kiegroup/git-backporting/issues/54
* feat(issue-54): fixed readme
---
.github/pull_request_template.md | 33 ++++
.gitignore | 3 +
README.md | 75 +++++---
action.yml | 4 +
dist/cli/index.js | 74 ++++++--
dist/gha/index.js | 73 ++++++--
src/service/args/args-parser.ts | 1 +
src/service/args/args.types.ts | 1 +
src/service/args/cli/cli-args-parser.ts | 2 +
src/service/args/gha/gha-args-parser.ts | 1 +
.../configs/pullrequest/pr-configs-parser.ts | 2 +-
src/service/git/git-client.ts | 6 +-
src/service/git/git-mapper.ts | 1 +
src/service/git/github/github-client.ts | 26 ++-
src/service/git/github/github-mapper.ts | 11 +-
src/service/git/gitlab/gitlab-client.ts | 23 ++-
src/service/git/gitlab/gitlab-mapper.ts | 15 +-
test/service/args/cli/cli-args-parser.test.ts | 37 ++++
test/service/args/gha/gha-args-parser.test.ts | 33 +++-
.../github-pr-configs-parser.test.ts | 133 +++++++++++++-
.../gitlab-pr-configs-parser.test.ts | 112 +++++++++++-
test/service/git/gitlab/gitlab-client.test.ts | 6 +-
test/service/runner/cli-github-runner.test.ts | 50 +++++-
test/service/runner/cli-gitlab-runner.test.ts | 51 +++++-
test/service/runner/gha-github-runner.test.ts | 49 +++++-
test/service/runner/gha-gitlab-runner.test.ts | 51 +++++-
test/support/mock/git-client-mock-support.ts | 54 +++---
test/support/mock/github-data.ts | 165 +++++++++++++++++-
test/support/mock/gitlab-data.ts | 43 +++++
29 files changed, 990 insertions(+), 145 deletions(-)
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index b1b4695..20ad8a1 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -18,3 +18,36 @@ changes that span multiple kiegroup repositories and depend on each other. -->
- [ ] Documentation updated if applicable.
> **Note:** `dist/cli/index.js` and `dist/gha/index.js` are automatically generated by git hooks and gh workflows.
+
+
+
+First time here?
+
+
+This project follows [git conventional commits](https://gist.github.com/qoomon/5dfcdf8eec66a051ecd85625518cfd13) pattern, therefore the commits should have the following format:
+
+```
+():
+empty separator line
+
+empty separator line
+
+```
+
+Where the type must be one of `[build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test]`
+
+> **NOTE**: if you are still in a `work in progress` branch and you want to push your changes remotely, consider adding `--no-verify` for both `commit` and `push`, e.g., `git push origin --no-verify` - this could become useful to push changes where there are still tests failures. Once the pull request is ready, please `amend` the commit and force-push it to keep following the adopted git commit standard.
+
+
+
+
+
+How to prepare for a new release?
+
+
+There is no need to manually update `package.json` version and `CHANGELOG.md` information. This process has been automated in [Prepare Release](./workflows/prepare-release.yml) *Github* workflow.
+
+Therefore whenever enough changes are merged into the `main` branch, one of the maintainers will trigger this workflow that will automatically update `version` and `changelog` based on the commits on the git tree.
+
+More details can be found in [package release](https://github.com/kiegroup/git-backporting/blob/main/README.md#package-release) section of the README.
+
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 64a72d6..f3c41a9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,6 @@ report.json
.vscode/
build/
.npmrc
+
+# temporary files created during tests
+*test*.json
\ No newline at end of file
diff --git a/README.md b/README.md
index b3480bd..b902d8b 100644
--- a/README.md
+++ b/README.md
@@ -26,11 +26,10 @@ Table of content
* **[Who is this tool for](#who-is-this-tool-for)**
* **[CLI tool](#cli-tool)**
-* **[Supported git services](#supported-git-services)**
* **[GitHub action](#github-action)**
* **[Future works](#future-works)**
-* **[Release](#release)**
-* **[Repository migration](#repository-migration)**
+* **[Migrating to v4](#migrating-to-v4)**
+* **[Development](#development)**
* **[Contributing](#contributing)**
* **[License](#license)**
@@ -72,6 +71,23 @@ This is the easiest invocation where you let the tool set / compute most of the
* Node 16 or higher, more details on Node can be found [here](https://nodejs.org/en).
* Git, see [how to install](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if you need help.
+### How it works?
+
+The simply works in this way: given the provided `pull/merge request` it infers the git client to use (either *Github* or *Gitlab* for now) and it retrieve the corresponding pull request object (original pull/merge request to be backported into another branch).
+
+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).
+
+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.
+
+Right now all commits are cherry-picked using the following git-equivalent command:
+```bash
+$ git cherry-pick -m 1 --strategy=recursive --strategy-option=theirs
+```
+
+> **NOTE**: If there are any conflicts, the tool will block the process and exit signalling the failure as there are still no ways to interactively resolve them. In these cases a manual cherry-pick is needed, or alternatively users could manually resume the process in the cloned repository (here the user will have to resolve the conflicts, push the branch and create the pull request - all manually).
+
### Inputs
This tool comes with some inputs that allow users to override the default behavior, here the full list of available inputs:
@@ -96,6 +112,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Backport Branch Name | --bp-branch-name | N | Name of the backporting pull request branch | bp-{target-branch}-{sha} |
| 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 |
| Dry Run | -d, --dry-run | N | If enabled the tool does not push nor create anything remotely, use this to skip PR creation | false |
> **NOTE**: `pull request` and `target branch` are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
@@ -114,7 +131,7 @@ This is an example of a configuration file that can be used.
```
Keep in mind that its structue MUST match the [Args](src/service/args/args.types.ts) interface, which is actually a camel-case version of the CLI options.
-## Supported git services
+### Supported git services
Right now **Git Backporting** supports the following git management services:
* ***GITHUB***: Introduced since the first release of this tool (version `1.0.0`). The interaction with this system is performed using [*octokit*](https://octokit.github.io/rest.js) client library.
@@ -128,7 +145,7 @@ Right now **Git Backporting** supports the following git management services:
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).
```yml
-name: Pull Request Backporting using BPer
+name: Pull Request Backporting using Git Backporting
on:
workflow_dispatch:
@@ -166,7 +183,7 @@ You can also use this action with other events - you'll just need to specify `ta
For example, this configuration creates a pull request against branch `v1` once the current one is merged, provided that the label `backport-v1` is applied:
```yaml
-name: Pull Request Backporting using BPer
+name: Pull Request Backporting using Git Backporting
on:
pull_request_target:
@@ -203,19 +220,38 @@ For a complete description of all inputs see [Inputs section](#inputs).
## Future works
-**BPer** is still in development mode, this means that there are still many future works and extension. I'll try to summarize the most important ones:
+**Git Backporting** is still in development mode, this means that there are still many future works and extension that can be implemented. I'll try to summarize the most important ones:
-- Provide a way to backport single commit too (or a set of them), even if no original pull request is present.
+- Provide a way to backport single commit (or a set of them) if no original pull request is present.
- Integrate this tool with other git management services (like Bitbucket) to make it as generic as possible.
- Integrate it into other CI/CD services like gitlab CI.
- Provide some reusable *GitHub* workflows.
-## Release
+## Migrating to v4
+
+From version `v4.0.0` the project has been moved under [@kiegroup](https://github.com/kiegroup) organization. During this migration we changed some things that you should be aware of. I'll try to summarize them in the following table:
+
+> **NOTE**: these changes did not affect the tool features.
+
+| | **v4 (after migration)** | v3 or older (before migration) |
+|-------------|--------------------------|--------------------------------|
+| Owner | kiegroup | lampajr |
+| Repository | git-backporting | backporting |
+| NPM package | @kie/git-backporting | @lampajr/bper |
+| CLI tool | git-backporting | bper |
+
+So everytime you would use older version keep in mind of these changes.
+
+> **REMARK**: since from capabilities point of view `v3.1.1` and `v4.0.0` are equivalent we would recommend to directly start using `v4`.
+
+## Development
+
+### Package release
The release of this package is entirely based on [release-it](https://github.com/release-it/release-it) tool. I created some useful scripts that can make the release itself quite easy.
-### Automated release
+#### Automatic release
The first step is to prepare the changes for the next release, this is done by running:
@@ -236,7 +272,7 @@ After that you should just push the new branch and open the pull request.
Once the release preparion pull request got merged, you can run [Release package](.github/workflows/release.yml) workflow that automatically performs the release itself, including npm publishing, git tag and github release.
-### Manual release
+#### Manual release
In case we would like to perform a manual release, it would be enough to open a pull request changing the following items:
- Package version inside the `package.json`
@@ -245,23 +281,6 @@ In case we would like to perform a manual release, it would be enough to open a
Once the release preparion pull request got merged, run [Release package](.github/workflows/release.yml) workflow.
-## Repository Migration
-
-From version `v4.0.0` the project has been moved under [@kiegroup](https://github.com/kiegroup) organization. During this migration we changed some things that you should be aware of. I'll try to summarize them in the following table:
-
-> **NOTE**: these changes did not affect the tool features.
-
-| | **v4 (after migration)** | v3 or older (before migration) |
-|-------------|--------------------------|--------------------------------|
-| Owner | kiegroup | lampajr |
-| Repository | git-backporting | backporting |
-| NPM package | @kie/git-backporting | @lampajr/bper |
-| CLI tool | git-backporting | bper |
-
-So everytime you would use older version keep in mind of these changes.
-
-> **REMARK**: since from capabilities point of view `v3.1.1` and `v4.0.0` are equivalent we would recommend to directly start using `v4`.
-
## Contributing
This is an open source project, and you are more than welcome to contribute :heart:!
diff --git a/action.yml b/action.yml
index 43c2fcc..d774a98 100644
--- a/action.yml
+++ b/action.yml
@@ -55,6 +55,10 @@ inputs:
description: "If true the backported pull request will inherit labels from the original one"
required: false
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"
+ required: false
+ default: "false"
runs:
using: node16
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 5818d2a..8f41e23 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -60,6 +60,7 @@ class ArgsParser {
inheritReviewers: this.getOrDefault(args.inheritReviewers, true),
labels: this.getOrDefault(args.labels, []),
inheritLabels: this.getOrDefault(args.inheritLabels, false),
+ squash: this.getOrDefault(args.squash, true),
};
}
}
@@ -185,6 +186,7 @@ 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("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
readArgs() {
@@ -214,6 +216,7 @@ class CLIArgsParser extends args_parser_1.default {
inheritReviewers: opts.inheritReviewers,
labels: opts.labels,
inheritLabels: opts.inheritLabels,
+ squash: opts.squash,
};
}
return args;
@@ -280,7 +283,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
async parse(args) {
let pr;
try {
- pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest);
+ pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest, args.squash);
}
catch (error) {
this.logger.error("Something went wrong retrieving pull request");
@@ -619,18 +622,33 @@ class GitHubClient {
getDefaultGitEmail() {
return "noreply@github.com";
}
- async getPullRequest(owner, repo, prNumber) {
+ async getPullRequest(owner, repo, prNumber, squash = true) {
this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
- pull_number: prNumber
+ pull_number: prNumber,
});
- return this.mapper.mapPullRequest(data);
+ const commits = [];
+ if (!squash) {
+ // fetch all commits
+ try {
+ const { data } = await this.octokit.rest.pulls.listCommits({
+ owner: owner,
+ repo: repo,
+ pull_number: prNumber,
+ });
+ commits.push(...data.map(c => c.sha));
+ }
+ catch (error) {
+ throw new Error(`Failed to retrieve commits for pull request n. ${prNumber}`);
+ }
+ }
+ return this.mapper.mapPullRequest(data, commits);
}
- async getPullRequestFromUrl(prUrl) {
+ async getPullRequestFromUrl(prUrl, squash = true) {
const { owner, project, id } = this.extractPullRequestData(prUrl);
- return this.getPullRequest(owner, project, id);
+ return this.getPullRequest(owner, project, id, squash);
}
// WRITE
async createPullRequest(backport) {
@@ -724,7 +742,7 @@ class GitHubMapper {
return git_types_1.GitRepoState.CLOSED;
}
}
- async mapPullRequest(pr) {
+ async mapPullRequest(pr, commits) {
return {
number: pr.number,
author: pr.user.login,
@@ -741,10 +759,14 @@ class GitHubMapper {
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
- // if pr is open use latest commit sha otherwise use merge_commit_sha
- commits: pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha]
+ // if commits is provided use them, otherwise fetch the single sha representing the whole pr
+ commits: (commits && commits.length > 0) ? commits : this.getSha(pr),
};
}
+ getSha(pr) {
+ // if pr is open use latest commit sha otherwise use merge_commit_sha
+ return pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha];
+ }
async mapSourceRepo(pr) {
return Promise.resolve({
owner: pr.head.repo.full_name.split("/")[0],
@@ -835,14 +857,26 @@ class GitLabClient {
}
// READ
// example: /api/v4/projects/%2Fbackporting-example/merge_requests/1
- async getPullRequest(namespace, repo, mrNumber) {
+ async getPullRequest(namespace, repo, mrNumber, squash = true) {
const projectId = this.getProjectId(namespace, repo);
const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`);
- return this.mapper.mapPullRequest(data);
+ const commits = [];
+ if (!squash) {
+ // fetch all commits
+ try {
+ const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}/commits`);
+ // gitlab returns them in reverse order
+ commits.push(...data.map(c => c.id).reverse());
+ }
+ catch (error) {
+ throw new Error(`Failed to retrieve commits for merge request n. ${mrNumber}`);
+ }
+ }
+ return this.mapper.mapPullRequest(data, commits);
}
- getPullRequestFromUrl(mrUrl) {
+ getPullRequestFromUrl(mrUrl, squash = true) {
const { namespace, project, id } = this.extractMergeRequestData(mrUrl);
- return this.getPullRequest(namespace, project, id);
+ return this.getPullRequest(namespace, project, id, squash);
}
// WRITE
async createPullRequest(backport) {
@@ -983,7 +1017,7 @@ class GitLabMapper {
return git_types_1.GitRepoState.LOCKED;
}
}
- async mapPullRequest(mr) {
+ async mapPullRequest(mr, commits) {
return {
number: mr.iid,
author: mr.author.username,
@@ -999,12 +1033,16 @@ class GitLabMapper {
labels: mr.labels ?? [],
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
- nCommits: 1,
- // if mr is merged, use merge_commit_sha otherwise use sha
- // what is the difference between sha and diff_refs.head_sha?
- commits: this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha] : [mr.sha]
+ // if commits list is provided use that as source
+ nCommits: (commits && commits.length > 1) ? commits.length : 1,
+ commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
};
}
+ getSha(mr) {
+ // if mr is merged, use merge_commit_sha otherwise use sha
+ // what is the difference between sha and diff_refs.head_sha?
+ return this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha] : [mr.sha];
+ }
async mapSourceRepo(mr) {
const project = await this.getProject(mr.source_project_id);
return {
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 20a9a92..aa36c9c 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -60,6 +60,7 @@ class ArgsParser {
inheritReviewers: this.getOrDefault(args.inheritReviewers, true),
labels: this.getOrDefault(args.labels, []),
inheritLabels: this.getOrDefault(args.inheritLabels, false),
+ squash: this.getOrDefault(args.squash, true),
};
}
}
@@ -188,6 +189,7 @@ class GHAArgsParser extends args_parser_1.default {
inheritReviewers: !(0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("no-inherit-reviewers")),
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")),
};
}
return args;
@@ -254,7 +256,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
async parse(args) {
let pr;
try {
- pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest);
+ pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest, args.squash);
}
catch (error) {
this.logger.error("Something went wrong retrieving pull request");
@@ -593,18 +595,33 @@ class GitHubClient {
getDefaultGitEmail() {
return "noreply@github.com";
}
- async getPullRequest(owner, repo, prNumber) {
+ async getPullRequest(owner, repo, prNumber, squash = true) {
this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
- pull_number: prNumber
+ pull_number: prNumber,
});
- return this.mapper.mapPullRequest(data);
+ const commits = [];
+ if (!squash) {
+ // fetch all commits
+ try {
+ const { data } = await this.octokit.rest.pulls.listCommits({
+ owner: owner,
+ repo: repo,
+ pull_number: prNumber,
+ });
+ commits.push(...data.map(c => c.sha));
+ }
+ catch (error) {
+ throw new Error(`Failed to retrieve commits for pull request n. ${prNumber}`);
+ }
+ }
+ return this.mapper.mapPullRequest(data, commits);
}
- async getPullRequestFromUrl(prUrl) {
+ async getPullRequestFromUrl(prUrl, squash = true) {
const { owner, project, id } = this.extractPullRequestData(prUrl);
- return this.getPullRequest(owner, project, id);
+ return this.getPullRequest(owner, project, id, squash);
}
// WRITE
async createPullRequest(backport) {
@@ -698,7 +715,7 @@ class GitHubMapper {
return git_types_1.GitRepoState.CLOSED;
}
}
- async mapPullRequest(pr) {
+ async mapPullRequest(pr, commits) {
return {
number: pr.number,
author: pr.user.login,
@@ -715,10 +732,14 @@ class GitHubMapper {
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
- // if pr is open use latest commit sha otherwise use merge_commit_sha
- commits: pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha]
+ // if commits is provided use them, otherwise fetch the single sha representing the whole pr
+ commits: (commits && commits.length > 0) ? commits : this.getSha(pr),
};
}
+ getSha(pr) {
+ // if pr is open use latest commit sha otherwise use merge_commit_sha
+ return pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha];
+ }
async mapSourceRepo(pr) {
return Promise.resolve({
owner: pr.head.repo.full_name.split("/")[0],
@@ -809,14 +830,26 @@ class GitLabClient {
}
// READ
// example: /api/v4/projects/%2Fbackporting-example/merge_requests/1
- async getPullRequest(namespace, repo, mrNumber) {
+ async getPullRequest(namespace, repo, mrNumber, squash = true) {
const projectId = this.getProjectId(namespace, repo);
const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`);
- return this.mapper.mapPullRequest(data);
+ const commits = [];
+ if (!squash) {
+ // fetch all commits
+ try {
+ const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}/commits`);
+ // gitlab returns them in reverse order
+ commits.push(...data.map(c => c.id).reverse());
+ }
+ catch (error) {
+ throw new Error(`Failed to retrieve commits for merge request n. ${mrNumber}`);
+ }
+ }
+ return this.mapper.mapPullRequest(data, commits);
}
- getPullRequestFromUrl(mrUrl) {
+ getPullRequestFromUrl(mrUrl, squash = true) {
const { namespace, project, id } = this.extractMergeRequestData(mrUrl);
- return this.getPullRequest(namespace, project, id);
+ return this.getPullRequest(namespace, project, id, squash);
}
// WRITE
async createPullRequest(backport) {
@@ -957,7 +990,7 @@ class GitLabMapper {
return git_types_1.GitRepoState.LOCKED;
}
}
- async mapPullRequest(mr) {
+ async mapPullRequest(mr, commits) {
return {
number: mr.iid,
author: mr.author.username,
@@ -973,12 +1006,16 @@ class GitLabMapper {
labels: mr.labels ?? [],
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
- nCommits: 1,
- // if mr is merged, use merge_commit_sha otherwise use sha
- // what is the difference between sha and diff_refs.head_sha?
- commits: this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha] : [mr.sha]
+ // if commits list is provided use that as source
+ nCommits: (commits && commits.length > 1) ? commits.length : 1,
+ commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
};
}
+ getSha(mr) {
+ // if mr is merged, use merge_commit_sha otherwise use sha
+ // what is the difference between sha and diff_refs.head_sha?
+ return this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha] : [mr.sha];
+ }
async mapSourceRepo(mr) {
const project = await this.getProject(mr.source_project_id);
return {
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index c36c35c..265db2b 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -38,6 +38,7 @@ export default abstract class ArgsParser {
inheritReviewers: this.getOrDefault(args.inheritReviewers, true),
labels: this.getOrDefault(args.labels, []),
inheritLabels: this.getOrDefault(args.inheritLabels, false),
+ squash: this.getOrDefault(args.squash, true),
};
}
}
\ No newline at end of file
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index e1ada50..6596bc3 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -18,4 +18,5 @@ 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
}
\ 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 e3297d1..f37eee4 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -26,6 +26,7 @@ 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("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
@@ -56,6 +57,7 @@ export default class CLIArgsParser extends ArgsParser {
inheritReviewers: opts.inheritReviewers,
labels: opts.labels,
inheritLabels: opts.inheritLabels,
+ squash: opts.squash,
};
}
diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts
index d06e40e..18a6b3c 100644
--- a/src/service/args/gha/gha-args-parser.ts
+++ b/src/service/args/gha/gha-args-parser.ts
@@ -29,6 +29,7 @@ export default class GHAArgsParser extends ArgsParser {
inheritReviewers: !getAsBooleanOrDefault(getInput("no-inherit-reviewers")),
labels: getAsCommaSeparatedList(getInput("labels")),
inheritLabels: getAsBooleanOrDefault(getInput("inherit-labels")),
+ squash: !getAsBooleanOrDefault(getInput("no-squash")),
};
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 6ca50da..057912b 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -17,7 +17,7 @@ export default class PullRequestConfigsParser extends ConfigsParser {
public async parse(args: Args): Promise {
let pr: GitPullRequest;
try {
- pr = await this.gitClient.getPullRequestFromUrl(args.pullRequest);
+ 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 c1ff0ea..b14f603 100644
--- a/src/service/git/git-client.ts
+++ b/src/service/git/git-client.ts
@@ -17,16 +17,18 @@ import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
* @param owner repository's owner
* @param repo repository's name
* @param prNumber pull request number
+ * @param squash if true keep just one single commit, otherwise get the full list
* @returns {Promise}
*/
- getPullRequest(owner: string, repo: string, prNumber: number): Promise;
+ getPullRequest(owner: string, repo: string, prNumber: number, squash: boolean): Promise;
/**
* Get a pull request object from the underneath git service
* @param prUrl pull request html url
+ * @param squash if true keep just one single commit, otherwise get the full list
* @returns {Promise}
*/
- getPullRequestFromUrl(prUrl: string): Promise;
+ getPullRequestFromUrl(prUrl: string, squash: boolean): Promise;
// WRITE
diff --git a/src/service/git/git-mapper.ts b/src/service/git/git-mapper.ts
index 7ae88c2..5658f14 100644
--- a/src/service/git/git-mapper.ts
+++ b/src/service/git/git-mapper.ts
@@ -10,6 +10,7 @@ export default interface GitResponseMapper {
mapPullRequest(
pr: PR,
+ commits?: string[],
): Promise;
mapGitState(state: S): GitRepoState;
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index c7d8f81..af60837 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -31,20 +31,36 @@ export default class GitHubClient implements GitClient {
return "noreply@github.com";
}
- async getPullRequest(owner: string, repo: string, prNumber: number): Promise {
+ async getPullRequest(owner: string, repo: string, prNumber: number, squash = true): Promise {
this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
- pull_number: prNumber
+ pull_number: prNumber,
});
- return this.mapper.mapPullRequest(data as PullRequest);
+ const commits: string[] = [];
+ if (!squash) {
+ // fetch all commits
+ try {
+ const { data } = await this.octokit.rest.pulls.listCommits({
+ owner: owner,
+ repo: repo,
+ pull_number: prNumber,
+ });
+
+ commits.push(...data.map(c => c.sha));
+ } catch(error) {
+ throw new Error(`Failed to retrieve commits for pull request n. ${prNumber}`);
+ }
+ }
+
+ return this.mapper.mapPullRequest(data as PullRequest, commits);
}
- async getPullRequestFromUrl(prUrl: string): Promise {
+ async getPullRequestFromUrl(prUrl: string, squash = true): Promise {
const { owner, project, id } = this.extractPullRequestData(prUrl);
- return this.getPullRequest(owner, project, id);
+ return this.getPullRequest(owner, project, id, squash);
}
// WRITE
diff --git a/src/service/git/github/github-mapper.ts b/src/service/git/github/github-mapper.ts
index caa1bb1..a79cb3d 100644
--- a/src/service/git/github/github-mapper.ts
+++ b/src/service/git/github/github-mapper.ts
@@ -13,7 +13,7 @@ export default class GitHubMapper implements GitResponseMapper {
+ async mapPullRequest(pr: PullRequest, commits?: string[]): Promise {
return {
number: pr.number,
author: pr.user.login,
@@ -30,11 +30,16 @@ export default class GitHubMapper implements GitResponseMapper 0) ? commits : this.getSha(pr),
};
}
+ private getSha(pr: PullRequest) {
+ // if pr is open use latest commit sha otherwise use merge_commit_sha
+ return pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha as string];
+ }
+
async mapSourceRepo(pr: PullRequest): Promise {
return Promise.resolve({
owner: pr.head.repo.full_name.split("/")[0],
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index 427a0ac..af091ba 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -2,7 +2,7 @@ import LoggerService from "@bp/service/logger/logger-service";
import GitClient from "@bp/service/git/git-client";
import { GitPullRequest, BackportPullRequest } from "@bp/service/git/git.types";
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
-import { MergeRequestSchema, UserSchema } from "@gitbeaker/rest";
+import { CommitSchema, MergeRequestSchema, UserSchema } from "@gitbeaker/rest";
import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
import axios, { Axios } from "axios";
import https from "https";
@@ -41,16 +41,29 @@ export default class GitLabClient implements GitClient {
// READ
// example: /api/v4/projects/%2Fbackporting-example/merge_requests/1
- async getPullRequest(namespace: string, repo: string, mrNumber: number): Promise {
+ async getPullRequest(namespace: string, repo: string, mrNumber: number, squash = true): Promise {
const projectId = this.getProjectId(namespace, repo);
const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`);
- return this.mapper.mapPullRequest(data as MergeRequestSchema);
+ const commits: string[] = [];
+ if (!squash) {
+ // fetch all commits
+ try {
+ const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}/commits`);
+
+ // gitlab returns them in reverse order
+ commits.push(...(data as CommitSchema[]).map(c => c.id).reverse());
+ } catch(error) {
+ throw new Error(`Failed to retrieve commits for merge request n. ${mrNumber}`);
+ }
+ }
+
+ return this.mapper.mapPullRequest(data as MergeRequestSchema, commits);
}
- getPullRequestFromUrl(mrUrl: string): Promise {
+ getPullRequestFromUrl(mrUrl: string, squash = true): Promise {
const { namespace, project, id } = this.extractMergeRequestData(mrUrl);
- return this.getPullRequest(namespace, project, id);
+ return this.getPullRequest(namespace, project, id, squash);
}
// WRITE
diff --git a/src/service/git/gitlab/gitlab-mapper.ts b/src/service/git/gitlab/gitlab-mapper.ts
index cc917a2..5765ba6 100644
--- a/src/service/git/gitlab/gitlab-mapper.ts
+++ b/src/service/git/gitlab/gitlab-mapper.ts
@@ -24,7 +24,7 @@ export default class GitLabMapper implements GitResponseMapper {
+ async mapPullRequest(mr: MergeRequestSchema, commits?: string[]): Promise {
return {
number: mr.iid,
author: mr.author.username,
@@ -40,12 +40,17 @@ export default class GitLabMapper implements GitResponseMapper 1) ? commits.length : 1,
+ commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
};
}
+
+ private getSha(mr: MergeRequestSchema) {
+ // if mr is merged, use merge_commit_sha otherwise use sha
+ // what is the difference between sha and diff_refs.head_sha?
+ return this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha as string] : [mr.sha];
+ }
async mapSourceRepo(mr: MergeRequestSchema): Promise {
const project: ProjectSchema = await this.getProject(mr.source_project_id);
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index d7b6338..c020fab 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -76,6 +76,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("with config file [default, short]", () => {
@@ -101,6 +102,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("valid execution [default, long]", () => {
@@ -128,6 +130,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("with config file [default, long]", () => {
@@ -153,6 +156,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("valid execution [override, short]", () => {
@@ -187,6 +191,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("valid execution [override, long]", () => {
@@ -237,6 +242,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(false);
expectArrayEqual(args.labels!, ["cherry-pick :cherries:", "another spaced label"]);
expect(args.inheritLabels).toEqual(true);
+ expect(args.squash).toEqual(true);
});
test("override using config file", () => {
@@ -262,6 +268,7 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
expect(args.inheritLabels).toEqual(true);
+ expect(args.squash).toEqual(true);
});
test("ignore custom option when config file is set", () => {
@@ -314,5 +321,35 @@ describe("cli args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
expect(args.inheritLabels).toEqual(true);
+ expect(args.squash).toEqual(true);
+ });
+
+ test("override squash to false", () => {
+ addProcessArgs([
+ "--target-branch",
+ "target",
+ "--pull-request",
+ "https://localhost/whatever/pulls/1",
+ "--no-squash"
+ ]);
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ 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);
+ expect(args.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(false);
});
});
\ 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 0d42806..61a04bc 100644
--- a/test/service/args/gha/gha-args-parser.test.ts
+++ b/test/service/args/gha/gha-args-parser.test.ts
@@ -48,10 +48,6 @@ describe("gha args parser", () => {
parser = new GHAArgsParser();
});
- afterEach(() => {
- jest.clearAllMocks();
- });
-
test("valid execution [default]", () => {
spyGetInput({
"target-branch": "target",
@@ -73,6 +69,7 @@ describe("gha args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("valid execution [override]", () => {
@@ -111,6 +108,7 @@ describe("gha args parser", () => {
expect(args.inheritReviewers).toEqual(false);
expectArrayEqual(args.labels!, ["cherry-pick :cherries:", "another spaced label"]);
expect(args.inheritLabels).toEqual(true);
+ expect(args.squash).toEqual(true);
});
test("using config file", () => {
@@ -135,6 +133,7 @@ describe("gha args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expectArrayEqual(args.labels!, []);
expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
});
test("ignore custom options when using config file", () => {
@@ -174,5 +173,31 @@ describe("gha args parser", () => {
expect(args.inheritReviewers).toEqual(true);
expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
expect(args.inheritLabels).toEqual(true);
+ expect(args.squash).toEqual(true);
+ });
+
+ test("override squash to false", () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://localhost/whatever/pulls/1",
+ "no-squash": "true",
+ });
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ 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.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(false);
});
});
\ No newline at end of file
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 4d5b1ba..e11097f 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -5,8 +5,10 @@ import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../../support/utils";
-import { mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner } from "../../../support/mock/github-data";
+import { mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner, multipleCommitsPullRequestFixture } from "../../../support/mock/github-data";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
+import GitHubMapper from "@bp/service/git/github/github-mapper";
+import GitHubClient from "@bp/service/git/github/github-client";
const GITHUB_MERGED_PR_SIMPLE_CONFIG_FILE_CONTENT_PATHNAME = "./github-pr-configs-parser-simple-pr-merged.json";
const GITHUB_MERGED_PR_SIMPLE_CONFIG_FILE_CONTENT = {
@@ -32,11 +34,15 @@ const GITHUB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"inheritLabels": true,
};
+jest.spyOn(GitHubMapper.prototype, "mapPullRequest");
+jest.spyOn(GitHubClient.prototype, "getPullRequest");
+
describe("github pull request config parser", () => {
const mergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`;
const openPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${openPullRequestFixture.number}`;
const notMergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${notMergedPullRequestFixture.number}`;
+ const multipleCommitsPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${multipleCommitsPullRequestFixture.number}`;
let argsParser: CLIArgsParser;
let configParser: PullRequestConfigsParser;
@@ -67,10 +73,6 @@ describe("github pull request config parser", () => {
configParser = new PullRequestConfigsParser();
});
- afterEach(() => {
- jest.clearAllMocks();
- });
-
test("parse configs from pull request", async () => {
const args: Args = {
dryRun: false,
@@ -86,6 +88,11 @@ 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(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "GitHub",
@@ -184,6 +191,11 @@ 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(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
expect(configs.targetBranch).toEqual("prod");
@@ -234,10 +246,9 @@ describe("github pull request config parser", () => {
inheritReviewers: true,
};
- expect(async () => await configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
});
-
test("override backport pr data inheriting reviewers", async () => {
const args: Args = {
dryRun: false,
@@ -256,6 +267,11 @@ 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(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -332,6 +348,11 @@ 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(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -408,6 +429,11 @@ 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(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -486,6 +512,11 @@ 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(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -553,6 +584,11 @@ describe("github pull request config parser", () => {
const args: Args = argsParser.parse();
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "GitHub",
@@ -619,6 +655,11 @@ describe("github pull request config parser", () => {
const args: Args = argsParser.parse();
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -676,4 +717,82 @@ describe("github pull request config parser", () => {
bpBranchName: undefined,
});
});
+
+ test("parse configs from pull request without squashing with multiple commits", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: multipleCommitsPRUrl,
+ targetBranch: "prod",
+ gitUser: "GitHub",
+ gitEmail: "noreply@github.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ squash: false,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 8632, false);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"]);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.git).toEqual({
+ user: "GitHub",
+ email: "noreply@github.com"
+ });
+ expect(configs.auth).toEqual("");
+ expect(configs.targetBranch).toEqual("prod");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.originalPullRequest).toEqual({
+ number: 8632,
+ author: "gh-user",
+ url: "https://api.github.com/repos/owner/reponame/pulls/8632",
+ htmlUrl: "https://github.com/owner/reponame/pull/8632",
+ state: "closed",
+ merged: true,
+ mergedBy: "that-s-a-user",
+ title: "PR Title",
+ body: "Please review and merge",
+ reviewers: ["requested-gh-user", "gh-user"],
+ assignees: [],
+ labels: [],
+ targetRepo: {
+ owner: "owner",
+ project: "reponame",
+ cloneUrl: "https://github.com/owner/reponame.git"
+ },
+ sourceRepo: {
+ owner: "owner",
+ project: "reponame",
+ cloneUrl: "https://github.com/owner/reponame.git"
+ },
+ nCommits: 2,
+ commits: ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"]
+ });
+ expect(configs.backportPullRequest).toEqual({
+ author: "GitHub",
+ url: undefined,
+ htmlUrl: undefined,
+ title: "[prod] PR Title",
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ 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,
+ });
+ });
});
\ No newline at end of file
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 9e47f1b..f180a78 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -7,6 +7,8 @@ import { getAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR } from "../../../support/mock/gitlab-data";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
import { createTestFile, removeTestFile, spyGetInput } from "../../../support/utils";
+import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
+import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
const GITLAB_MERGED_PR_SIMPLE_CONFIG_FILE_CONTENT_PATHNAME = "./gitlab-pr-configs-parser-simple-pr-merged.json";
const GITLAB_MERGED_PR_SIMPLE_CONFIG_FILE_CONTENT = {
@@ -32,6 +34,8 @@ const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"inheritLabels": true,
};
+jest.spyOn(GitLabMapper.prototype, "mapPullRequest");
+jest.spyOn(GitLabClient.prototype, "getPullRequest");
jest.mock("axios", () => {
return {
@@ -70,10 +74,6 @@ describe("gitlab merge request config parser", () => {
configParser = new PullRequestConfigsParser();
});
- afterEach(() => {
- jest.clearAllMocks();
- });
-
test("parse configs from merge request", async () => {
const args: Args = {
dryRun: false,
@@ -89,6 +89,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Gitlab",
@@ -163,6 +168,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
expect(configs.targetBranch).toEqual("prod");
@@ -188,6 +198,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 2, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
expect(configs.targetBranch).toEqual("prod");
@@ -238,7 +253,7 @@ describe("gitlab merge request config parser", () => {
inheritReviewers: true,
};
- expect(async () => await configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("override backport pr data inheriting reviewers", async () => {
@@ -259,6 +274,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -334,6 +354,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -409,6 +434,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -486,6 +516,11 @@ describe("gitlab merge request config parser", () => {
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -551,6 +586,11 @@ describe("gitlab merge request config parser", () => {
const args: Args = argsParser.parse();
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Gitlab",
@@ -616,6 +656,11 @@ describe("gitlab merge request config parser", () => {
const args: Args = argsParser.parse();
const configs: Configs = await configParser.parseAndValidate(args);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
@@ -672,4 +717,61 @@ describe("gitlab merge request config parser", () => {
bpBranchName: undefined,
});
});
+
+ test("still open pull request without squash", async () => {
+ const args: Args = {
+ dryRun: true,
+ auth: "whatever",
+ pullRequest: openPRUrl,
+ targetBranch: "prod",
+ gitUser: "Gitlab",
+ gitEmail: "noreply@gitlab.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ squash: false,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 2, false);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), ["e4dd336a4a20f394df6665994df382fb1d193a11", "974519f65c9e0ed65277cd71026657a09fca05e7"]);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual("whatever");
+ expect(configs.targetBranch).toEqual("prod");
+ expect(configs.git).toEqual({
+ user: "Gitlab",
+ email: "noreply@gitlab.com"
+ });
+ expect(configs.originalPullRequest).toEqual({
+ number: 2,
+ author: "superuser",
+ url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
+ htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
+ state: "open",
+ merged: false,
+ mergedBy: undefined,
+ title: "Update test.txt opened",
+ body: "Still opened mr body",
+ reviewers: ["superuser"],
+ assignees: ["superuser"],
+ labels: [],
+ targetRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ sourceRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ bpBranchName: undefined,
+ nCommits: 2,
+ commits: ["e4dd336a4a20f394df6665994df382fb1d193a11", "974519f65c9e0ed65277cd71026657a09fca05e7"]
+ });
+ });
});
\ No newline at end of file
diff --git a/test/service/git/gitlab/gitlab-client.test.ts b/test/service/git/gitlab/gitlab-client.test.ts
index 2e3e58d..affe096 100644
--- a/test/service/git/gitlab/gitlab-client.test.ts
+++ b/test/service/git/gitlab/gitlab-client.test.ts
@@ -29,11 +29,7 @@ describe("github service", () => {
GitClientFactory.reset();
gitClient = GitClientFactory.getOrCreate(GitClientType.GITLAB, "whatever", "apiUrl") as GitLabClient;
});
-
- afterEach(() => {
- jest.clearAllMocks();
- });
-
+
test("get merged pull request", async () => {
const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 1);
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 0c06a6c..108420a 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -55,8 +55,6 @@ beforeEach(() => {
});
afterEach(() => {
- jest.clearAllMocks();
-
// reset process.env variables
resetProcessArgs();
});
@@ -292,7 +290,7 @@ describe("cli runner", () => {
"https://github.com/owner/reponame/pull/6666"
]);
- expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("open pull request", async () => {
@@ -636,4 +634,50 @@ describe("cli runner", () => {
}
);
});
+
+ test("multiple commits pr", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/8632",
+ "--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-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index 31fdb61..7f9ea43 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -68,8 +68,6 @@ beforeEach(() => {
});
afterEach(() => {
- jest.clearAllMocks();
-
// reset process.env variables
resetProcessArgs();
});
@@ -198,7 +196,7 @@ describe("cli runner", () => {
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3"
]);
- expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("merged pull request", async () => {
@@ -501,4 +499,51 @@ describe("cli runner", () => {
}
);
});
+
+ test("multiple commits without squash", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
+ "--no-squash",
+ ]);
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7",
+ base: "target",
+ title: "[target] Update test.txt opened",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 8fb8dd4..9d3bf0c 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -55,10 +55,6 @@ beforeEach(() => {
runner = new Runner(parser);
});
-afterEach(() => {
- jest.clearAllMocks();
-});
-
describe("gha runner", () => {
test("with dry run", async () => {
spyGetInput({
@@ -139,7 +135,7 @@ describe("gha runner", () => {
"pull-request": "https://github.com/owner/reponame/pull/6666"
});
- expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("open pull request", async () => {
@@ -460,4 +456,47 @@ describe("gha runner", () => {
);
});
+ test("multiple commits pr", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://api.github.com/repos/owner/reponame/pulls/8632",
+ "no-squash": "true",
+ });
+
+ 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-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index a28b410..6f766c3 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -66,10 +66,6 @@ beforeEach(() => {
runner = new Runner(parser);
});
-afterEach(() => {
- jest.clearAllMocks();
-});
-
describe("gha runner", () => {
test("with dry run", async () => {
spyGetInput({
@@ -150,7 +146,7 @@ describe("gha runner", () => {
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3"
});
- expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("merged pull request", async () => {
@@ -423,4 +419,49 @@ describe("gha runner", () => {
}
);
});
+
+ test("multiple commits without squash", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
+ "no-squash": "true",
+ });
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7",
+ base: "target",
+ title: "[target] Update test.txt opened",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index c73d410..040429d 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -1,7 +1,7 @@
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
import { Moctokit } from "@kie/mock-github";
-import { targetOwner, repo, mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber, sameOwnerPullRequestFixture } from "./github-data";
-import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR, PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
+import { targetOwner, repo, mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber, multipleCommitsPullRequestFixture, multipleCommitsPullRequestCommits } from "./github-data";
+import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
const logger = LoggerServiceFactory.getLogger();
@@ -22,6 +22,8 @@ export const getAxiosMocked = (url: string) => {
data = PROJECT_EXAMPLE;
} else if (url.endsWith("users?username=superuser")) {
data = [SUPERUSER];
+ } else if (url.endsWith("merge_requests/2/commits")) {
+ data = OPEN_PR_COMMITS;
}
return {
@@ -96,15 +98,15 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
});
mock.rest.pulls
- .get({
- owner: targetOwner,
- repo: repo,
- pull_number: sameOwnerPullRequestFixture.number
- })
- .reply({
- status: 200,
- data: sameOwnerPullRequestFixture
- });
+ .get({
+ owner: targetOwner,
+ repo: repo,
+ pull_number: multipleCommitsPullRequestFixture.number
+ })
+ .reply({
+ status: 200,
+ data: multipleCommitsPullRequestFixture
+ });
mock.rest.pulls
.get({
@@ -118,15 +120,26 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
});
mock.rest.pulls
- .get({
- owner: targetOwner,
- repo: repo,
- pull_number: notMergedPullRequestFixture.number
- })
- .reply({
- status: 200,
- data: notMergedPullRequestFixture
- });
+ .get({
+ owner: targetOwner,
+ repo: repo,
+ pull_number: notMergedPullRequestFixture.number
+ })
+ .reply({
+ status: 200,
+ data: notMergedPullRequestFixture
+ });
+
+ mock.rest.pulls
+ .listCommits({
+ owner: targetOwner,
+ repo: repo,
+ pull_number: multipleCommitsPullRequestFixture.number
+ })
+ .reply({
+ status: 200,
+ data: multipleCommitsPullRequestCommits
+ });
mock.rest.pulls
.create()
@@ -156,7 +169,6 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
data: {}
});
-
// invalid requests
mock.rest.pulls
.get({
diff --git a/test/support/mock/github-data.ts b/test/support/mock/github-data.ts
index a5f0f60..e91b723 100644
--- a/test/support/mock/github-data.ts
+++ b/test/support/mock/github-data.ts
@@ -1341,7 +1341,7 @@ export const notMergedPullRequestFixture = {
"changed_files": 2
};
-export const sameOwnerPullRequestFixture = {
+export const multipleCommitsPullRequestFixture = {
"url": "https://api.github.com/repos/owner/reponame/pulls/8632",
"id": 1137188271,
"node_id": "PR_kwDOABTq6s5DyB2v",
@@ -1802,4 +1802,165 @@ export const sameOwnerPullRequestFixture = {
"additions": 2,
"deletions": 2,
"changed_files": 2
-};
\ No newline at end of file
+};
+
+export const multipleCommitsPullRequestCommits = [
+ {
+ "sha": "0404fb922ab75c3a8aecad5c97d9af388df04695",
+ "node_id": "C_kwDOImgs99oAKDA0MDRmYjkyMmFiNzVjM2E4YWVjYWQ1Yzk3ZDlhZjM4OGRmMDQ2OTU",
+ "commit": {
+ "author": {
+ "name": "owner",
+ "email": "owner@email.com",
+ "date": "2023-07-06T13:46:30Z"
+ },
+ "committer": {
+ "name": "GitHub",
+ "email": "noreply@github.com",
+ "date": "2023-07-06T13:46:30Z"
+ },
+ "message": "Update file1.txt",
+ "tree": {
+ "sha": "50be1d7031b02a2ae609f432f2a1e0f818d827b2",
+ "url": "https://api.github.com/repos/owner/reponame/git/trees/50be1d7031b02a2ae609f432f2a1e0f818d827b2"
+ },
+ "url": "https://api.github.com/repos/owner/reponame/git/commits/0404fb922ab75c3a8aecad5c97d9af388df04695",
+ "comment_count": 0,
+ "verification": {
+ "verified": true,
+ "reason": "valid",
+ "signature": "-----BEGIN PGP SIGNATURE-----\n\nno-signature=\n=fivd\n-----END PGP SIGNATURE-----\n",
+ "payload": "tree 50be1d7031b02a2ae609f432f2a1e0f818d827b2\nparent c85b8fcdb741814b3e90e6e5729455cf46ff26ea\nauthor Owner 1688651190 +0200\ncommitter GitHub 1688651190 +0200\n\nUpdate file1.txt"
+ }
+ },
+ "url": "https://api.github.com/repos/owner/reponame/commits/0404fb922ab75c3a8aecad5c97d9af388df04695",
+ "html_url": "https://github.com/owner/reponame/commit/0404fb922ab75c3a8aecad5c97d9af388df04695",
+ "comments_url": "https://api.github.com/repos/owner/reponame/commits/0404fb922ab75c3a8aecad5c97d9af388df04695/comments",
+ "author": {
+ "login": "owner",
+ "id": 26715795,
+ "node_id": "MDQ6VXNlcjI2NzE1Nzk1",
+ "avatar_url": "https://avatars.githubusercontent.com/u/26715795?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/owner",
+ "html_url": "https://github.com/owner",
+ "followers_url": "https://api.github.com/users/owner/followers",
+ "following_url": "https://api.github.com/users/owner/following{/other_user}",
+ "gists_url": "https://api.github.com/users/owner/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/owner/subscriptions",
+ "organizations_url": "https://api.github.com/users/owner/orgs",
+ "repos_url": "https://api.github.com/users/owner/repos",
+ "events_url": "https://api.github.com/users/owner/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/owner/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "committer": {
+ "login": "web-flow",
+ "id": 19864447,
+ "node_id": "MDQ6VXNlcjE5ODY0NDQ3",
+ "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/web-flow",
+ "html_url": "https://github.com/web-flow",
+ "followers_url": "https://api.github.com/users/web-flow/followers",
+ "following_url": "https://api.github.com/users/web-flow/following{/other_user}",
+ "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
+ "organizations_url": "https://api.github.com/users/web-flow/orgs",
+ "repos_url": "https://api.github.com/users/web-flow/repos",
+ "events_url": "https://api.github.com/users/web-flow/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/web-flow/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "parents": [
+ {
+ "sha": "c85b8fcdb741814b3e90e6e5729455cf46ff26ea",
+ "url": "https://api.github.com/repos/owner/reponame/commits/c85b8fcdb741814b3e90e6e5729455cf46ff26ea",
+ "html_url": "https://github.com/owner/reponame/commit/c85b8fcdb741814b3e90e6e5729455cf46ff26ea"
+ }
+ ]
+ },
+ {
+ "sha": "11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ "node_id": "C_kwDOImgs99oAKDExZGE0ZTM4YWEzZTU3N2ZmZGU2ZDU0NmYxYzUyZTUzYjA0ZDMxNTE",
+ "commit": {
+ "author": {
+ "name": "Owner",
+ "email": "owner@email.com",
+ "date": "2023-07-10T13:23:44Z"
+ },
+ "committer": {
+ "name": "GitHub",
+ "email": "noreply@github.com",
+ "date": "2023-07-10T13:23:44Z"
+ },
+ "message": "Update file2.txt",
+ "tree": {
+ "sha": "fdd16fb791eef26fd84c3bfa34fd89eb1f7a85be",
+ "url": "https://api.github.com/repos/owner/reponame/git/trees/fdd16fb791eef26fd84c3bfa34fd89eb1f7a85be"
+ },
+ "url": "https://api.github.com/repos/owner/reponame/git/commits/11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ "comment_count": 0,
+ "verification": {
+ "verified": true,
+ "reason": "valid",
+ "signature": "-----BEGIN PGP SIGNATURE-----\n\nno-signature\n=//hm\n-----END PGP SIGNATURE-----\n",
+ "payload": "tree fdd16fb791eef26fd84c3bfa34fd89eb1f7a85be\nparent 0404fb922ab75c3a8aecad5c97d9af388df04695\nauthor Owner 1688995424 +0200\ncommitter GitHub 1688995424 +0200\n\nUpdate file2.txt"
+ }
+ },
+ "url": "https://api.github.com/repos/owner/reponame/commits/11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ "html_url": "https://github.com/owner/reponame/commit/11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ "comments_url": "https://api.github.com/repos/owner/reponame/commits/11da4e38aa3e577ffde6d546f1c52e53b04d3151/comments",
+ "author": {
+ "login": "owner",
+ "id": 26715795,
+ "node_id": "MDQ6VXNlcjI2NzE1Nzk1",
+ "avatar_url": "https://avatars.githubusercontent.com/u/26715795?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/owner",
+ "html_url": "https://github.com/owner",
+ "followers_url": "https://api.github.com/users/owner/followers",
+ "following_url": "https://api.github.com/users/owner/following{/other_user}",
+ "gists_url": "https://api.github.com/users/owner/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/owner/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/owner/subscriptions",
+ "organizations_url": "https://api.github.com/users/owner/orgs",
+ "repos_url": "https://api.github.com/users/owner/repos",
+ "events_url": "https://api.github.com/users/owner/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/owner/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "committer": {
+ "login": "web-flow",
+ "id": 19864447,
+ "node_id": "MDQ6VXNlcjE5ODY0NDQ3",
+ "avatar_url": "https://avatars.githubusercontent.com/u/19864447?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/web-flow",
+ "html_url": "https://github.com/web-flow",
+ "followers_url": "https://api.github.com/users/web-flow/followers",
+ "following_url": "https://api.github.com/users/web-flow/following{/other_user}",
+ "gists_url": "https://api.github.com/users/web-flow/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/web-flow/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/web-flow/subscriptions",
+ "organizations_url": "https://api.github.com/users/web-flow/orgs",
+ "repos_url": "https://api.github.com/users/web-flow/repos",
+ "events_url": "https://api.github.com/users/web-flow/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/web-flow/received_events",
+ "type": "User",
+ "site_admin": false
+ },
+ "parents": [
+ {
+ "sha": "0404fb922ab75c3a8aecad5c97d9af388df04695",
+ "url": "https://api.github.com/repos/owner/reponame/commits/0404fb922ab75c3a8aecad5c97d9af388df04695",
+ "html_url": "https://github.com/owner/reponame/commit/0404fb922ab75c3a8aecad5c97d9af388df04695"
+ }
+ ]
+ }
+];
\ No newline at end of file
diff --git a/test/support/mock/gitlab-data.ts b/test/support/mock/gitlab-data.ts
index d1af227..119913a 100644
--- a/test/support/mock/gitlab-data.ts
+++ b/test/support/mock/gitlab-data.ts
@@ -529,6 +529,49 @@ export const CLOSED_NOT_MERGED_MR = {
}
};
+export const OPEN_PR_COMMITS = [
+ {
+ "id":"974519f65c9e0ed65277cd71026657a09fca05e7",
+ "short_id":"974519f6",
+ "created_at":"2023-07-10T19:23:04.000Z",
+ "parent_ids":[
+
+ ],
+ "title":"Add another file",
+ "message":"Add another file",
+ "author_name":"Super User",
+ "author_email":"superuser@email.com",
+ "authored_date":"2023-07-10T19:23:04.000Z",
+ "committer_name":"Super User",
+ "committer_email":"superuser@email.com",
+ "committed_date":"2023-07-10T19:23:04.000Z",
+ "trailers":{
+
+ },
+ "web_url":"https://gitlab.com/superuser/backporting-example/-/commit/974519f65c9e0ed65277cd71026657a09fca05e7"
+ },
+ {
+ "id":"e4dd336a4a20f394df6665994df382fb1d193a11",
+ "short_id":"e4dd336a",
+ "created_at":"2023-06-29T09:59:10.000Z",
+ "parent_ids":[
+
+ ],
+ "title":"Add new file",
+ "message":"Add new file",
+ "author_name":"Super User",
+ "author_email":"superuser@email.com",
+ "authored_date":"2023-06-29T09:59:10.000Z",
+ "committer_name":"Super User",
+ "committer_email":"superuser@email.com",
+ "committed_date":"2023-06-29T09:59:10.000Z",
+ "trailers":{
+
+ },
+ "web_url":"https://gitlab.com/superuser/backporting-example/-/commit/e4dd336a4a20f394df6665994df382fb1d193a11"
+ }
+];
+
export const SUPERUSER = {
"id":14041,
"username":"superuser",
From 8c010b43e4b0715886de96cd8ea819a8fa42ffd8 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 11 Jul 2023 14:59:14 +0200
Subject: [PATCH 05/75] chore: release v4.1.0 (#56)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 13 +++++++++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d5e3679..fe3ae0c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## [4.1.0](https://github.com/kiegroup/git-backporting/compare/v4.0.0...v4.1.0) (2023-07-11)
+
+
+### Features
+
+* **issue-41:** set and inherit labels ([#48](https://github.com/kiegroup/git-backporting/issues/48)) ([fcc0167](https://github.com/kiegroup/git-backporting/commit/fcc01673f4bc9aa2786faf6dfd503a29e5ca0cd9))
+* **issue-54:** backport pr commits without squash ([#55](https://github.com/kiegroup/git-backporting/issues/55)) ([c4dbb26](https://github.com/kiegroup/git-backporting/commit/c4dbb26c1d9d266ed86f3f0d6016b8cff7743f8b))
+
+
+### Bug Fixes
+
+* **issue-52:** use pull request github api url as source ([#53](https://github.com/kiegroup/git-backporting/issues/53)) ([a737aa7](https://github.com/kiegroup/git-backporting/commit/a737aa7c4c66983de358b8472121ab918de922e3))
+
## [4.0.0](https://github.com/kiegroup/git-backporting/compare/v3.0.0...v4.0.0) (2023-07-06)
Project moved under @kiegroup organization.
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 8f41e23..6940f30 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23430,7 +23430,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.0.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.1.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index aef4198..470d0d8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.0.0",
+ "version": "4.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.0.0",
+ "version": "4.1.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index ff18d38..2f67c5c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.0.0",
+ "version": "4.1.0",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From 49a73504066396ca2a074f55bb23815e13ae462e Mon Sep 17 00:00:00 2001
From: Shubh Bapna <38372682+shubhbapna@users.noreply.github.com>
Date: Tue, 11 Jul 2023 16:15:52 -0400
Subject: [PATCH 06/75] perf: use concurrent promises instead of awaiting them
one by one (#59)
---
dist/cli/index.js | 126 +++++++-----------
dist/gha/index.js | 126 +++++++-----------
src/service/git/github/github-client.ts | 34 +++--
src/service/git/gitlab/gitlab-client.ts | 77 +++++------
test/service/runner/cli-gitlab-runner.test.ts | 2 +-
test/service/runner/gha-gitlab-runner.test.ts | 2 +-
test/support/mock/git-client-mock-support.ts | 2 +-
7 files changed, 147 insertions(+), 222 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 6940f30..aac84c4 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -665,45 +665,32 @@ class GitHubClient {
if (!data) {
throw new Error("Pull request creation failed");
}
+ const promises = [];
if (backport.labels.length > 0) {
- try {
- await this.octokit.issues.addLabels({
- owner: backport.owner,
- repo: backport.repo,
- issue_number: data.number,
- labels: backport.labels,
- });
- }
- catch (error) {
- this.logger.error(`Error setting labels: ${error}`);
- }
+ promises.push(this.octokit.issues.addLabels({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ labels: backport.labels,
+ }).catch(error => this.logger.error(`Error setting labels: ${error}`)));
}
if (backport.reviewers.length > 0) {
- try {
- await this.octokit.pulls.requestReviewers({
- owner: backport.owner,
- repo: backport.repo,
- pull_number: data.number,
- reviewers: backport.reviewers,
- });
- }
- catch (error) {
- this.logger.error(`Error requesting reviewers: ${error}`);
- }
+ promises.push(this.octokit.pulls.requestReviewers({
+ owner: backport.owner,
+ repo: backport.repo,
+ pull_number: data.number,
+ reviewers: backport.reviewers,
+ }).catch(error => this.logger.error(`Error requesting reviewers: ${error}`)));
}
if (backport.assignees.length > 0) {
- try {
- await this.octokit.issues.addAssignees({
- owner: backport.owner,
- repo: backport.repo,
- issue_number: data.number,
- assignees: backport.assignees,
- });
- }
- catch (error) {
- this.logger.error(`Error setting assignees: ${error}`);
- }
+ promises.push(this.octokit.issues.addAssignees({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ assignees: backport.assignees,
+ }).catch(error => this.logger.error(`Error setting assignees: ${error}`)));
}
+ await Promise.all(promises);
return data.html_url;
}
// UTILS
@@ -892,64 +879,43 @@ class GitLabClient {
assignee_ids: [],
});
const mr = data;
+ const promises = [];
// labels
if (backport.labels.length > 0) {
- try {
- this.logger.info("Setting labels: " + backport.labels);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
- labels: backport.labels.join(","),
- });
- }
- catch (error) {
- this.logger.warn("Failure trying to update labels. " + error);
- }
+ this.logger.info("Setting labels: " + backport.labels);
+ promises.push(this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ labels: backport.labels.join(","),
+ }).catch(error => this.logger.warn("Failure trying to update labels. " + error)));
}
// reviewers
- const reviewerIds = [];
- for (const r of backport.reviewers) {
- try {
- this.logger.debug("Retrieving user: " + r);
- const user = await this.getUser(r);
- reviewerIds.push(user.id);
- }
- catch (error) {
+ const reviewerIds = await Promise.all(backport.reviewers.map(async (r) => {
+ this.logger.debug("Retrieving user: " + r);
+ return this.getUser(r).then(user => user.id).catch(() => {
this.logger.warn(`Failed to retrieve reviewer ${r}`);
- }
- }
+ return undefined;
+ });
+ }));
if (reviewerIds.length > 0) {
- try {
- this.logger.info("Setting reviewers: " + reviewerIds);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
- reviewer_ids: reviewerIds.filter(r => r !== undefined),
- });
- }
- catch (error) {
- this.logger.warn("Failure trying to update reviewers. " + error);
- }
+ this.logger.info("Setting reviewers: " + reviewerIds);
+ promises.push(this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ reviewer_ids: reviewerIds.filter(r => r !== undefined),
+ }).catch(error => this.logger.warn("Failure trying to update reviewers. " + error)));
}
// assignees
- const assigneeIds = [];
- for (const a of backport.assignees) {
- try {
- this.logger.debug("Retrieving user: " + a);
- const user = await this.getUser(a);
- assigneeIds.push(user.id);
- }
- catch (error) {
+ const assigneeIds = await Promise.all(backport.assignees.map(async (a) => {
+ this.logger.debug("Retrieving user: " + a);
+ return this.getUser(a).then(user => user.id).catch(() => {
this.logger.warn(`Failed to retrieve assignee ${a}`);
- }
- }
+ return undefined;
+ });
+ }));
if (assigneeIds.length > 0) {
- try {
- this.logger.info("Setting assignees: " + assigneeIds);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
- assignee_ids: assigneeIds.filter(a => a !== undefined),
- });
- }
- catch (error) {
- this.logger.warn("Failure trying to update assignees. " + error);
- }
+ this.logger.info("Setting assignees: " + assigneeIds);
+ promises.push(this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ assignee_ids: assigneeIds.filter(a => a !== undefined),
+ }).catch(error => this.logger.warn("Failure trying to update assignees. " + error)));
}
+ await Promise.all(promises);
return mr.web_url;
}
/**
diff --git a/dist/gha/index.js b/dist/gha/index.js
index aa36c9c..b57156b 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -638,45 +638,32 @@ class GitHubClient {
if (!data) {
throw new Error("Pull request creation failed");
}
+ const promises = [];
if (backport.labels.length > 0) {
- try {
- await this.octokit.issues.addLabels({
- owner: backport.owner,
- repo: backport.repo,
- issue_number: data.number,
- labels: backport.labels,
- });
- }
- catch (error) {
- this.logger.error(`Error setting labels: ${error}`);
- }
+ promises.push(this.octokit.issues.addLabels({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ labels: backport.labels,
+ }).catch(error => this.logger.error(`Error setting labels: ${error}`)));
}
if (backport.reviewers.length > 0) {
- try {
- await this.octokit.pulls.requestReviewers({
- owner: backport.owner,
- repo: backport.repo,
- pull_number: data.number,
- reviewers: backport.reviewers,
- });
- }
- catch (error) {
- this.logger.error(`Error requesting reviewers: ${error}`);
- }
+ promises.push(this.octokit.pulls.requestReviewers({
+ owner: backport.owner,
+ repo: backport.repo,
+ pull_number: data.number,
+ reviewers: backport.reviewers,
+ }).catch(error => this.logger.error(`Error requesting reviewers: ${error}`)));
}
if (backport.assignees.length > 0) {
- try {
- await this.octokit.issues.addAssignees({
- owner: backport.owner,
- repo: backport.repo,
- issue_number: data.number,
- assignees: backport.assignees,
- });
- }
- catch (error) {
- this.logger.error(`Error setting assignees: ${error}`);
- }
+ promises.push(this.octokit.issues.addAssignees({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ assignees: backport.assignees,
+ }).catch(error => this.logger.error(`Error setting assignees: ${error}`)));
}
+ await Promise.all(promises);
return data.html_url;
}
// UTILS
@@ -865,64 +852,43 @@ class GitLabClient {
assignee_ids: [],
});
const mr = data;
+ const promises = [];
// labels
if (backport.labels.length > 0) {
- try {
- this.logger.info("Setting labels: " + backport.labels);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
- labels: backport.labels.join(","),
- });
- }
- catch (error) {
- this.logger.warn("Failure trying to update labels. " + error);
- }
+ this.logger.info("Setting labels: " + backport.labels);
+ promises.push(this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ labels: backport.labels.join(","),
+ }).catch(error => this.logger.warn("Failure trying to update labels. " + error)));
}
// reviewers
- const reviewerIds = [];
- for (const r of backport.reviewers) {
- try {
- this.logger.debug("Retrieving user: " + r);
- const user = await this.getUser(r);
- reviewerIds.push(user.id);
- }
- catch (error) {
+ const reviewerIds = await Promise.all(backport.reviewers.map(async (r) => {
+ this.logger.debug("Retrieving user: " + r);
+ return this.getUser(r).then(user => user.id).catch(() => {
this.logger.warn(`Failed to retrieve reviewer ${r}`);
- }
- }
+ return undefined;
+ });
+ }));
if (reviewerIds.length > 0) {
- try {
- this.logger.info("Setting reviewers: " + reviewerIds);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
- reviewer_ids: reviewerIds.filter(r => r !== undefined),
- });
- }
- catch (error) {
- this.logger.warn("Failure trying to update reviewers. " + error);
- }
+ this.logger.info("Setting reviewers: " + reviewerIds);
+ promises.push(this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ reviewer_ids: reviewerIds.filter(r => r !== undefined),
+ }).catch(error => this.logger.warn("Failure trying to update reviewers. " + error)));
}
// assignees
- const assigneeIds = [];
- for (const a of backport.assignees) {
- try {
- this.logger.debug("Retrieving user: " + a);
- const user = await this.getUser(a);
- assigneeIds.push(user.id);
- }
- catch (error) {
+ const assigneeIds = await Promise.all(backport.assignees.map(async (a) => {
+ this.logger.debug("Retrieving user: " + a);
+ return this.getUser(a).then(user => user.id).catch(() => {
this.logger.warn(`Failed to retrieve assignee ${a}`);
- }
- }
+ return undefined;
+ });
+ }));
if (assigneeIds.length > 0) {
- try {
- this.logger.info("Setting assignees: " + assigneeIds);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
- assignee_ids: assigneeIds.filter(a => a !== undefined),
- });
- }
- catch (error) {
- this.logger.warn("Failure trying to update assignees. " + error);
- }
+ this.logger.info("Setting assignees: " + assigneeIds);
+ promises.push(this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ assignee_ids: assigneeIds.filter(a => a !== undefined),
+ }).catch(error => this.logger.warn("Failure trying to update assignees. " + error)));
}
+ await Promise.all(promises);
return mr.web_url;
}
/**
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index af60837..012736b 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -82,45 +82,43 @@ export default class GitHubClient implements GitClient {
throw new Error("Pull request creation failed");
}
+ const promises = [];
+
if (backport.labels.length > 0) {
- try {
- await this.octokit.issues.addLabels({
+ promises.push(
+ this.octokit.issues.addLabels({
owner: backport.owner,
repo: backport.repo,
issue_number: (data as PullRequest).number,
labels: backport.labels,
- });
- } catch (error) {
- this.logger.error(`Error setting labels: ${error}`);
- }
+ }).catch(error => this.logger.error(`Error setting labels: ${error}`))
+ );
}
if (backport.reviewers.length > 0) {
- try {
- await this.octokit.pulls.requestReviewers({
+ promises.push(
+ this.octokit.pulls.requestReviewers({
owner: backport.owner,
repo: backport.repo,
pull_number: (data as PullRequest).number,
reviewers: backport.reviewers,
- });
- } catch (error) {
- this.logger.error(`Error requesting reviewers: ${error}`);
- }
+ }).catch(error => this.logger.error(`Error requesting reviewers: ${error}`))
+ );
}
if (backport.assignees.length > 0) {
- try {
- await this.octokit.issues.addAssignees({
+ promises.push(
+ this.octokit.issues.addAssignees({
owner: backport.owner,
repo: backport.repo,
issue_number: (data as PullRequest).number,
assignees: backport.assignees,
- });
- } catch (error) {
- this.logger.error(`Error setting assignees: ${error}`);
- }
+ }).catch(error => this.logger.error(`Error setting assignees: ${error}`))
+ );
}
+ await Promise.all(promises);
+
return data.html_url;
}
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index af091ba..3607c45 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -84,65 +84,60 @@ export default class GitLabClient implements GitClient {
});
const mr = data as MergeRequestSchema;
+ const promises = [];
// labels
if (backport.labels.length > 0) {
- try {
- this.logger.info("Setting labels: " + backport.labels);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ this.logger.info("Setting labels: " + backport.labels);
+ promises.push(
+ this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
labels: backport.labels.join(","),
- });
- } catch(error) {
- this.logger.warn("Failure trying to update labels. " + error);
- }
+ }).catch(error => this.logger.warn("Failure trying to update labels. " + error))
+ );
}
// reviewers
- const reviewerIds: number[] = [];
- for(const r of backport.reviewers) {
- try {
- this.logger.debug("Retrieving user: " + r);
- const user = await this.getUser(r);
- reviewerIds.push(user.id);
- } catch(error) {
- this.logger.warn(`Failed to retrieve reviewer ${r}`);
- }
- }
+ const reviewerIds = await Promise.all(backport.reviewers.map(async r => {
+ this.logger.debug("Retrieving user: " + r);
+ return this.getUser(r).then(user => user.id).catch(
+ () => {
+ this.logger.warn(`Failed to retrieve reviewer ${r}`);
+ return undefined;
+ }
+ );
+ }));
if (reviewerIds.length > 0) {
- try {
- this.logger.info("Setting reviewers: " + reviewerIds);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ this.logger.info("Setting reviewers: " + reviewerIds);
+ promises.push(
+ this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
reviewer_ids: reviewerIds.filter(r => r !== undefined),
- });
- } catch(error) {
- this.logger.warn("Failure trying to update reviewers. " + error);
- }
+ }).catch(error => this.logger.warn("Failure trying to update reviewers. " + error))
+ );
}
// assignees
- const assigneeIds: number[] = [];
- for(const a of backport.assignees) {
- try {
- this.logger.debug("Retrieving user: " + a);
- const user = await this.getUser(a);
- assigneeIds.push(user.id);
- } catch(error) {
- this.logger.warn(`Failed to retrieve assignee ${a}`);
- }
- }
+ const assigneeIds = await Promise.all(backport.assignees.map(async a => {
+ this.logger.debug("Retrieving user: " + a);
+ return this.getUser(a).then(user => user.id).catch(
+ () => {
+ this.logger.warn(`Failed to retrieve assignee ${a}`);
+ return undefined;
+ }
+ );
+ }));
if (assigneeIds.length > 0) {
- try {
- this.logger.info("Setting assignees: " + assigneeIds);
- await this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
+ this.logger.info("Setting assignees: " + assigneeIds);
+ promises.push(
+ this.client.put(`/projects/${projectId}/merge_requests/${mr.iid}`, {
assignee_ids: assigneeIds.filter(a => a !== undefined),
- });
- } catch(error) {
- this.logger.warn("Failure trying to update assignees. " + error);
- }
+ }).catch(error => this.logger.warn("Failure trying to update assignees. " + error))
+ );
}
+ await Promise.all(promises);
+
return mr.web_url;
}
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index 7f9ea43..08a36b9 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -36,7 +36,7 @@ jest.mock("axios", () => {
iid: 1, // FIXME: I am not testing this atm
}
}),
- put: jest.fn(),
+ put: async () => undefined,
}),
};
});
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 6f766c3..113b5a4 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -36,7 +36,7 @@ jest.mock("axios", () => {
iid: 1, // FIXME: I am not testing this atm
}
}),
- put: jest.fn(),
+ put: async () => undefined, // make it async so that .catch doesn't throw an error
}),
};
});
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index 040429d..6a3b4a8 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -59,7 +59,7 @@ export const postAxiosMocked = (_url: string, data?: {source_branch: string,}) =
};
};
-export const putAxiosMocked = (url: string, _data?: unknown) => {
+export const putAxiosMocked = async (url: string, _data?: unknown) => {
const responseData = undefined;
// gitlab
From 91782505ce8c32f69e53013b8a4fbb243d5d1e39 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Tue, 11 Jul 2023 22:43:22 +0200
Subject: [PATCH 07/75] test: fix process.argv reset during cli tests (#60)
---
dist/cli/index.js | 2 +-
package.json | 2 +-
test/service/args/cli/cli-args-parser.test.ts | 6 +++---
.../configs/pullrequest/github-pr-configs-parser.test.ts | 5 +++--
test/service/runner/cli-github-runner.test.ts | 9 ++++-----
test/service/runner/cli-gitlab-runner.test.ts | 9 +++------
6 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index aac84c4..2956837 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23396,7 +23396,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.1.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.1.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package.json b/package.json
index 2f67c5c..f34f623 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"package:cli": "ncc build ./build/src/bin/cli.js -o dist/cli",
"package:gha": "ncc build ./build/src/bin/gha.js -o dist/gha",
"build": "npm run clean && npm run compile && npm run package",
- "test": "jest",
+ "test": "jest --silent",
"test:report": "npm test -- --coverage --testResultsProcessor=jest-sonar-reporter",
"lint": "eslint . --ext .ts",
"lint:fix": "npm run lint -- --fix",
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index c020fab..b38d669 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -44,11 +44,11 @@ describe("cli args parser", () => {
});
beforeEach(() => {
- // create a fresh new instance every time
- parser = new CLIArgsParser();
-
// reset process.env variables
resetProcessArgs();
+
+ // create a fresh new instance every time
+ parser = new CLIArgsParser();
});
test("valid execution [default, short]", () => {
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 e11097f..4b8b40b 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -63,11 +63,12 @@ describe("github pull request config parser", () => {
});
beforeEach(() => {
- mockGitHubClient("http://localhost/api/v3");
-
// reset process.env variables
resetProcessArgs();
+ // mock octokit
+ mockGitHubClient("http://localhost/api/v3");
+
// create a fresh new instance every time
argsParser = new CLIArgsParser();
configParser = new PullRequestConfigsParser();
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 108420a..64bcce0 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -45,6 +45,10 @@ afterAll(() => {
});
beforeEach(() => {
+ // reset process.env variables
+ resetProcessArgs();
+
+ // mock octokit
mockGitHubClient();
// create CLI arguments parser
@@ -54,11 +58,6 @@ beforeEach(() => {
runner = new Runner(parser);
});
-afterEach(() => {
- // reset process.env variables
- resetProcessArgs();
-});
-
describe("cli runner", () => {
test("with dry run", async () => {
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index 08a36b9..c992022 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -60,6 +60,9 @@ afterAll(() => {
});
beforeEach(() => {
+ // reset process.env variables
+ resetProcessArgs();
+
// create CLI arguments parser
parser = new CLIArgsParser();
@@ -67,13 +70,7 @@ beforeEach(() => {
runner = new Runner(parser);
});
-afterEach(() => {
- // reset process.env variables
- resetProcessArgs();
-});
-
describe("cli runner", () => {
-
test("with dry run", async () => {
addProcessArgs([
"-d",
From ead1322c0f6bb5de96c487e8f6b6565734144853 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Tue, 11 Jul 2023 22:46:21 +0200
Subject: [PATCH 08/75] fix(issue-57): truncate the bp branch name (#58)
fix: https://github.com/kiegroup/git-backporting/issues/57
This pr will ensure that if the provided/generated backport branch name
exceede the maximum branch name length set for git, which is 250 chars,
it truncates that name to 250 chars exactly.
In order to include as much commits as possible the branch name will
contain by default the shortened version of all commits
---
README.md | 4 +-
dist/cli/index.js | 11 +-
dist/gha/index.js | 11 +-
src/service/runner/runner.ts | 13 ++-
test/service/runner/cli-github-runner.test.ts | 102 +++++++++++++-----
test/service/runner/cli-gitlab-runner.test.ts | 40 +++----
test/service/runner/gha-github-runner.test.ts | 38 +++----
test/service/runner/gha-gitlab-runner.test.ts | 38 +++----
8 files changed, 169 insertions(+), 88 deletions(-)
diff --git a/README.md b/README.md
index b902d8b..a1815e7 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@
---
-## :bangbang: Starting from v4 git-backporting has been moved under @kiegroup organization and renamed :bangbang:
+## :bangbang: Starting from v4 git-backporting has been moved under @kiegroup organization :bangbang:
---
@@ -109,7 +109,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Reviewers | --reviewers | N | Backporting pull request comma-separated reviewers list | [] |
| Assignees | --assignes | N | Backporting pull request comma-separated assignees list | [] |
| No Reviewers Inheritance | --no-inherit-reviewers | N | Considered only if reviewers is empty, if true keep reviewers as empty list, otherwise inherit from original pull request | false |
-| Backport Branch Name | --bp-branch-name | N | Name of the backporting pull request branch | bp-{target-branch}-{sha} |
+| Backport Branch Name | --bp-branch-name | N | Name of the backporting pull request branch, if it exceeds 250 chars it 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 |
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 2956837..3929d5d 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -1192,7 +1192,16 @@ class Runner {
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- const backportBranch = backportPR.branchName ?? `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`;
+ let backportBranch = backportPR.branchName;
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits = originalPR.commits.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${configs.targetBranch}-${concatenatedCommits}`;
+ }
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
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 b57156b..df80f9f 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -1165,7 +1165,16 @@ class Runner {
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- const backportBranch = backportPR.branchName ?? `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`;
+ let backportBranch = backportPR.branchName;
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits = originalPR.commits.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${configs.targetBranch}-${concatenatedCommits}`;
+ }
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
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/runner/runner.ts b/src/service/runner/runner.ts
index 642cc78..7b0db39 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -74,7 +74,18 @@ export default class Runner {
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- const backportBranch = backportPR.branchName ?? `bp-${configs.targetBranch}-${originalPR.commits!.join("-")}`;
+ let backportBranch = backportPR.branchName;
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits: string = originalPR.commits!.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${configs.targetBranch}-${concatenatedCommits}`;
+ }
+
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
+
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/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 64bcce0..0c203e7 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -80,7 +80,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -109,7 +109,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -143,7 +143,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -180,7 +180,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -211,7 +211,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -220,13 +220,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -256,7 +256,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@@ -264,13 +264,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
@@ -311,7 +311,7 @@ describe("cli runner", () => {
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-91748965051fae1330ad58d15cf694e103267c87");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9174896");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444");
@@ -320,13 +320,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9174896");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-91748965051fae1330ad58d15cf694e103267c87",
+ head: "bp-target-9174896",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
@@ -472,7 +472,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -481,13 +481,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -519,7 +519,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -528,13 +528,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -608,7 +608,7 @@ describe("cli runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -617,13 +617,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -654,7 +654,7 @@ describe("cli runner", () => {
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-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@@ -663,13 +663,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+ 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-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ head: "bp-target-0404fb9-11da4e3",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
@@ -679,4 +679,56 @@ describe("cli runner", () => {
}
);
});
+
+ test("too long bp branch name", async () => {
+ // 260 chars
+ const tooLongBranchName = "too-long-branch-name".repeat(13);
+
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/2368",
+ "--bp-branch-name",
+ tooLongBranchName,
+ ]);
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ const truncatedBranch = tooLongBranchName.slice(0, 250);
+
+ 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, truncatedBranch);
+
+ 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, truncatedBranch);
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: truncatedBranch,
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index c992022..6db8612 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -91,7 +91,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -125,7 +125,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -159,7 +159,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -168,13 +168,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644",
+ head: "bp-target-9e15674",
base: "target",
title: "[target] Update test.txt opened",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
@@ -215,7 +215,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca");
// 0 occurrences as the mr is already merged and the owner is the same for
// both source and target repositories
@@ -225,13 +225,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-target-ebb1eca",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -378,7 +378,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca");
// 0 occurrences as the mr is already merged and the owner is the same for
// both source and target repositories
@@ -388,13 +388,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-target-ebb1eca",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -426,7 +426,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca");
// 0 occurrences as the mr is already merged and the owner is the same for
// both source and target repositories
@@ -436,13 +436,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-target-ebb1eca",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -470,7 +470,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "prod");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-prod-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-prod-ebb1eca");
// 0 occurrences as the mr is already merged and the owner is the same for
// both source and target repositories
@@ -480,13 +480,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-prod-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-prod-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-prod-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-prod-ebb1eca",
base: "prod",
title: "New Title",
body: expect.stringContaining("**This is a backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -517,7 +517,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -527,13 +527,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7",
+ head: "bp-target-e4dd336-974519f",
base: "target",
title: "[target] Update test.txt opened",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 9d3bf0c..bafcf0e 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -74,7 +74,7 @@ describe("gha runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -103,7 +103,7 @@ describe("gha runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -112,13 +112,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -155,7 +155,7 @@ describe("gha runner", () => {
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-91748965051fae1330ad58d15cf694e103267c87");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9174896");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444");
@@ -164,13 +164,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9174896");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-91748965051fae1330ad58d15cf694e103267c87",
+ head: "bp-target-9174896",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
@@ -299,7 +299,7 @@ describe("gha runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -308,13 +308,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -344,7 +344,7 @@ describe("gha runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -353,13 +353,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -430,7 +430,7 @@ describe("gha runner", () => {
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-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368");
@@ -439,13 +439,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
- head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
+ head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
@@ -474,7 +474,7 @@ describe("gha runner", () => {
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-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@@ -483,13 +483,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+ 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-0404fb922ab75c3a8aecad5c97d9af388df04695-11da4e38aa3e577ffde6d546f1c52e53b04d3151",
+ head: "bp-target-0404fb9-11da4e3",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 113b5a4..65bc3a2 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -85,7 +85,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -114,7 +114,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -123,13 +123,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644",
+ head: "bp-target-9e15674",
base: "target",
title: "[target] Update test.txt opened",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
@@ -166,7 +166,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@@ -174,13 +174,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-target-ebb1eca",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -309,7 +309,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@@ -317,13 +317,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-target-ebb1eca",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -352,7 +352,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@@ -360,13 +360,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-target-ebb1eca",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -393,7 +393,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "prod");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-prod-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-prod-ebb1eca");
// 0 occurrences as the mr is already merged and the owner is the same for
// both source and target repositories
@@ -403,13 +403,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-prod-ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-prod-ebb1eca");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-prod-ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ head: "bp-prod-ebb1eca",
base: "prod",
title: "New Title",
body: expect.stringContaining("**This is a backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
@@ -438,7 +438,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
- expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
@@ -448,13 +448,13 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
- expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
- head: "bp-target-e4dd336a4a20f394df6665994df382fb1d193a11-974519f65c9e0ed65277cd71026657a09fca05e7",
+ head: "bp-target-e4dd336-974519f",
base: "target",
title: "[target] Update test.txt opened",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
From 265955dda77a8191fd1f64517fec20e8d5f8c5b4 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Wed, 12 Jul 2023 13:50:59 +0200
Subject: [PATCH 09/75] feat(issue-62): make cherry-pick strategy configurable
(#63)
fix https://github.com/kiegroup/git-backporting/issues/62
---
README.md | 8 +-
action.yml | 8 ++
dist/cli/index.js | 24 +++++-
dist/gha/index.js | 22 ++++-
src/service/args/args-parser.ts | 2 +
src/service/args/args.types.ts | 2 +
src/service/args/cli/cli-args-parser.ts | 4 +
src/service/args/gha/gha-args-parser.ts | 2 +
src/service/configs/configs.types.ts | 2 +
.../configs/pullrequest/pr-configs-parser.ts | 2 +
src/service/git/git-cli.ts | 15 +++-
src/service/runner/runner.ts | 2 +-
test/service/args/cli/cli-args-parser.test.ts | 50 +++++++++++
test/service/args/gha/gha-args-parser.test.ts | 36 ++++++++
test/service/runner/cli-github-runner.test.ts | 82 +++++++++++++++----
test/service/runner/cli-gitlab-runner.test.ts | 22 ++---
test/service/runner/gha-github-runner.test.ts | 67 ++++++++++++---
test/service/runner/gha-gitlab-runner.test.ts | 20 ++---
18 files changed, 312 insertions(+), 58 deletions(-)
diff --git a/README.md b/README.md
index a1815e7..32955ae 100644
--- a/README.md
+++ b/README.md
@@ -81,11 +81,15 @@ By default the tool will try to cherry-pick the single squashed/merged commit in
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.
-Right now all commits are cherry-picked using the following git-equivalent command:
+#### Default cherry-pick strategy
+
+The default cherry-pick strategy is `recursive` with `theirs` option for automatic conflicts resolution. Therefore, by default, all commits are cherry-picked using the following git-equivalent command:
```bash
$ git cherry-pick -m 1 --strategy=recursive --strategy-option=theirs
```
+From version `v4.2.0` we made both `strategy` and `strategy-option` fully configurable from CLI or GitHub action, so if users need a specific strategy which differs from the default one please consider using either `--strategy` or `--strategy-option`, or their equivalent GitHub action inputs, more details in [inputs](#inputs) section.
+
> **NOTE**: If there are any conflicts, the tool will block the process and exit signalling the failure as there are still no ways to interactively resolve them. In these cases a manual cherry-pick is needed, or alternatively users could manually resume the process in the cloned repository (here the user will have to resolve the conflicts, push the branch and create the pull request - all manually).
### Inputs
@@ -113,6 +117,8 @@ This tool comes with some inputs that allow users to override the default behavi
| 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 |
+| 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" |
| Dry Run | -d, --dry-run | N | If enabled the tool does not push nor create anything remotely, use this to skip PR creation | false |
> **NOTE**: `pull request` and `target branch` are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
diff --git a/action.yml b/action.yml
index d774a98..90bc2d5 100644
--- a/action.yml
+++ b/action.yml
@@ -59,6 +59,14 @@ inputs:
description: "If set to true the tool will backport all commits as part of the pull request instead of the suqashed one"
required: false
default: "false"
+ strategy:
+ description: "Cherry-pick merge strategy"
+ required: false
+ default: "recursive"
+ strategy-option:
+ description: "Cherry-pick merge strategy option"
+ required: false
+ default: "theirs"
runs:
using: node16
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 3929d5d..10fa964 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -61,6 +61,8 @@ class ArgsParser {
labels: this.getOrDefault(args.labels, []),
inheritLabels: this.getOrDefault(args.inheritLabels, false),
squash: this.getOrDefault(args.squash, true),
+ strategy: this.getOrDefault(args.strategy),
+ strategyOption: this.getOrDefault(args.strategyOption),
};
}
}
@@ -187,6 +189,8 @@ class CLIArgsParser extends args_parser_1.default {
.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("--strategy ", "cherry-pick merge strategy, default to 'recursive'", undefined)
+ .option("--strategy-option ", "cherry-pick merge strategy option, default to 'theirs'")
.option("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
readArgs() {
@@ -217,6 +221,8 @@ class CLIArgsParser extends args_parser_1.default {
labels: opts.labels,
inheritLabels: opts.inheritLabels,
squash: opts.squash,
+ strategy: opts.strategy,
+ strategyOption: opts.strategyOption,
};
}
return args;
@@ -295,6 +301,8 @@ class PullRequestConfigsParser extends configs_parser_1.default {
auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
targetBranch: args.targetBranch,
+ mergeStrategy: args.strategy,
+ mergeStrategyOption: args.strategyOption,
originalPullRequest: pr,
backportPullRequest: this.getDefaultBackportPullRequest(pr, args),
git: {
@@ -446,9 +454,19 @@ class GitCLIService {
* @param cwd repository in which the sha should be cherry picked to
* @param sha commit sha
*/
- async cherryPick(cwd, sha) {
+ async cherryPick(cwd, sha, strategy = "recursive", strategyOption = "theirs") {
this.logger.info(`Cherry picking ${sha}.`);
- await this.git(cwd).raw(["cherry-pick", "-m", "1", "--strategy=recursive", "--strategy-option=theirs", sha]);
+ const options = ["cherry-pick", "-m", "1", `--strategy=${strategy}`, `--strategy-option=${strategyOption}`, sha];
+ try {
+ await this.git(cwd).raw(options);
+ }
+ catch (error) {
+ const diff = await this.git(cwd).diff();
+ if (diff) {
+ throw new Error(`${error}\r\nShowing git diff:\r\n` + diff);
+ }
+ throw error;
+ }
}
/**
* Push a branch to a remote
@@ -1213,7 +1231,7 @@ class Runner {
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
for (const sha of originalPR.commits) {
- await git.cherryPick(configs.folder, sha);
+ await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
const backport = {
owner: originalPR.targetRepo.owner,
diff --git a/dist/gha/index.js b/dist/gha/index.js
index df80f9f..5778dce 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -61,6 +61,8 @@ class ArgsParser {
labels: this.getOrDefault(args.labels, []),
inheritLabels: this.getOrDefault(args.inheritLabels, false),
squash: this.getOrDefault(args.squash, true),
+ strategy: this.getOrDefault(args.strategy),
+ strategyOption: this.getOrDefault(args.strategyOption),
};
}
}
@@ -190,6 +192,8 @@ 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")),
+ strategy: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("strategy")),
+ strategyOption: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("strategy-option")),
};
}
return args;
@@ -268,6 +272,8 @@ class PullRequestConfigsParser extends configs_parser_1.default {
auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
targetBranch: args.targetBranch,
+ mergeStrategy: args.strategy,
+ mergeStrategyOption: args.strategyOption,
originalPullRequest: pr,
backportPullRequest: this.getDefaultBackportPullRequest(pr, args),
git: {
@@ -419,9 +425,19 @@ class GitCLIService {
* @param cwd repository in which the sha should be cherry picked to
* @param sha commit sha
*/
- async cherryPick(cwd, sha) {
+ async cherryPick(cwd, sha, strategy = "recursive", strategyOption = "theirs") {
this.logger.info(`Cherry picking ${sha}.`);
- await this.git(cwd).raw(["cherry-pick", "-m", "1", "--strategy=recursive", "--strategy-option=theirs", sha]);
+ const options = ["cherry-pick", "-m", "1", `--strategy=${strategy}`, `--strategy-option=${strategyOption}`, sha];
+ try {
+ await this.git(cwd).raw(options);
+ }
+ catch (error) {
+ const diff = await this.git(cwd).diff();
+ if (diff) {
+ throw new Error(`${error}\r\nShowing git diff:\r\n` + diff);
+ }
+ throw error;
+ }
}
/**
* Push a branch to a remote
@@ -1186,7 +1202,7 @@ class Runner {
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
for (const sha of originalPR.commits) {
- await git.cherryPick(configs.folder, sha);
+ await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
const backport = {
owner: originalPR.targetRepo.owner,
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index 265db2b..d70fa27 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -39,6 +39,8 @@ export default abstract class ArgsParser {
labels: this.getOrDefault(args.labels, []),
inheritLabels: this.getOrDefault(args.inheritLabels, false),
squash: this.getOrDefault(args.squash, true),
+ strategy: this.getOrDefault(args.strategy),
+ strategyOption: this.getOrDefault(args.strategyOption),
};
}
}
\ No newline at end of file
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index 6596bc3..b3c1860 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -19,4 +19,6 @@ export interface Args {
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
+ strategy?: string, // cherry-pick merge strategy
+ strategyOption?: string, // cherry-pick merge strategy option
}
\ 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 f37eee4..a6065dc 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -27,6 +27,8 @@ export default class CLIArgsParser extends ArgsParser {
.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("--strategy ", "cherry-pick merge strategy, default to 'recursive'", undefined)
+ .option("--strategy-option ", "cherry-pick merge strategy option, default to 'theirs'")
.option("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
@@ -58,6 +60,8 @@ export default class CLIArgsParser extends ArgsParser {
labels: opts.labels,
inheritLabels: opts.inheritLabels,
squash: opts.squash,
+ strategy: opts.strategy,
+ strategyOption: opts.strategyOption,
};
}
diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts
index 18a6b3c..e3d5ba0 100644
--- a/src/service/args/gha/gha-args-parser.ts
+++ b/src/service/args/gha/gha-args-parser.ts
@@ -30,6 +30,8 @@ export default class GHAArgsParser extends ArgsParser {
labels: getAsCommaSeparatedList(getInput("labels")),
inheritLabels: getAsBooleanOrDefault(getInput("inherit-labels")),
squash: !getAsBooleanOrDefault(getInput("no-squash")),
+ strategy: getOrUndefined(getInput("strategy")),
+ strategyOption: getOrUndefined(getInput("strategy-option")),
};
}
diff --git a/src/service/configs/configs.types.ts b/src/service/configs/configs.types.ts
index ff28a78..0f82cfc 100644
--- a/src/service/configs/configs.types.ts
+++ b/src/service/configs/configs.types.ts
@@ -16,6 +16,8 @@ export interface Configs {
git: LocalGit,
folder: string,
targetBranch: string,
+ mergeStrategy?: string, // cherry-pick merge strategy
+ mergeStrategyOption?: string, // cherry-pick merge strategy option
originalPullRequest: GitPullRequest,
backportPullRequest: GitPullRequest,
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 057912b..d83d9cd 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -30,6 +30,8 @@ export default class PullRequestConfigsParser extends ConfigsParser {
auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
targetBranch: args.targetBranch,
+ mergeStrategy: args.strategy,
+ mergeStrategyOption: args.strategyOption,
originalPullRequest: pr,
backportPullRequest: this.getDefaultBackportPullRequest(pr, args),
git: {
diff --git a/src/service/git/git-cli.ts b/src/service/git/git-cli.ts
index 9e639df..c0b439e 100644
--- a/src/service/git/git-cli.ts
+++ b/src/service/git/git-cli.ts
@@ -105,9 +105,20 @@ export default class GitCLIService {
* @param cwd repository in which the sha should be cherry picked to
* @param sha commit sha
*/
- async cherryPick(cwd: string, sha: string): Promise {
+ async cherryPick(cwd: string, sha: string, strategy = "recursive", strategyOption = "theirs"): Promise {
this.logger.info(`Cherry picking ${sha}.`);
- await this.git(cwd).raw(["cherry-pick", "-m", "1", "--strategy=recursive", "--strategy-option=theirs", sha]);
+
+ const options = ["cherry-pick", "-m", "1", `--strategy=${strategy}`, `--strategy-option=${strategyOption}`, sha];
+ try {
+ await this.git(cwd).raw(options);
+ } catch(error) {
+ const diff = await this.git(cwd).diff();
+ if (diff) {
+ throw new Error(`${error}\r\nShowing git diff:\r\n` + diff);
+ }
+
+ throw error;
+ }
}
/**
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index 7b0db39..2060e30 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -99,7 +99,7 @@ export default class Runner {
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
for (const sha of originalPR.commits!) {
- await git.cherryPick(configs.folder, sha);
+ await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
const backport: BackportPullRequest = {
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index b38d669..4f64187 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -77,6 +77,8 @@ describe("cli args parser", () => {
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("with config file [default, short]", () => {
@@ -103,6 +105,8 @@ describe("cli args parser", () => {
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("valid execution [default, long]", () => {
@@ -131,6 +135,8 @@ describe("cli args parser", () => {
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("with config file [default, long]", () => {
@@ -157,6 +163,8 @@ describe("cli args parser", () => {
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("valid execution [override, short]", () => {
@@ -192,6 +200,8 @@ describe("cli args parser", () => {
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("valid execution [override, long]", () => {
@@ -243,6 +253,8 @@ describe("cli args parser", () => {
expectArrayEqual(args.labels!, ["cherry-pick :cherries:", "another spaced label"]);
expect(args.inheritLabels).toEqual(true);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("override using config file", () => {
@@ -269,6 +281,8 @@ describe("cli args parser", () => {
expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
expect(args.inheritLabels).toEqual(true);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("ignore custom option when config file is set", () => {
@@ -322,6 +336,8 @@ describe("cli args parser", () => {
expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
expect(args.inheritLabels).toEqual(true);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("override squash to false", () => {
@@ -352,4 +368,38 @@ describe("cli args parser", () => {
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(false);
});
+
+ test("override cherry pick strategies", () => {
+ addProcessArgs([
+ "--target-branch",
+ "target",
+ "--pull-request",
+ "https://localhost/whatever/pulls/1",
+ "--strategy",
+ "ort",
+ "--strategy-option",
+ "ours",
+ ]);
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ 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);
+ expect(args.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual("ort");
+ expect(args.strategyOption).toEqual("ours");
+ });
});
\ 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 61a04bc..ebe6e81 100644
--- a/test/service/args/gha/gha-args-parser.test.ts
+++ b/test/service/args/gha/gha-args-parser.test.ts
@@ -70,6 +70,8 @@ describe("gha args parser", () => {
expect(args.labels).toEqual([]);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("valid execution [override]", () => {
@@ -109,6 +111,8 @@ describe("gha args parser", () => {
expectArrayEqual(args.labels!, ["cherry-pick :cherries:", "another spaced label"]);
expect(args.inheritLabels).toEqual(true);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("using config file", () => {
@@ -134,6 +138,8 @@ describe("gha args parser", () => {
expectArrayEqual(args.labels!, []);
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("ignore custom options when using config file", () => {
@@ -174,6 +180,8 @@ describe("gha args parser", () => {
expectArrayEqual(args.labels!, ["cherry-pick :cherries:"]);
expect(args.inheritLabels).toEqual(true);
expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
});
test("override squash to false", () => {
@@ -200,4 +208,32 @@ describe("gha args parser", () => {
expect(args.inheritLabels).toEqual(false);
expect(args.squash).toEqual(false);
});
+
+ test("override cherry pick strategy", () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://localhost/whatever/pulls/1",
+ "strategy": "ort",
+ "strategy-option": "ours",
+ });
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ 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.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual("ort");
+ expect(args.strategyOption).toEqual("ours");
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 0c203e7..39b5e83 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -86,7 +86,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
@@ -115,7 +115,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
@@ -149,7 +149,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
@@ -186,7 +186,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
@@ -217,7 +217,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -261,7 +261,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -317,7 +317,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9174896");
@@ -374,7 +374,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -430,7 +430,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -478,7 +478,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -525,7 +525,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -568,7 +568,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -614,7 +614,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -659,8 +659,8 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695");
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
@@ -712,7 +712,7 @@ describe("cli runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, truncatedBranch);
@@ -731,4 +731,54 @@ describe("cli runner", () => {
}
);
});
+
+ test("multiple commits pr with different strategy", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/8632",
+ "--no-squash",
+ "--strategy",
+ "ort",
+ "--strategy-option",
+ "find-renames",
+ ]);
+
+ 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(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695", "ort", "find-renames");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", "ort", "find-renames");
+
+ 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: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index 6db8612..c07e46d 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -97,7 +97,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
@@ -131,7 +131,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
@@ -165,7 +165,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674");
@@ -222,7 +222,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
@@ -280,7 +280,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -336,7 +336,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -385,7 +385,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
@@ -433,7 +433,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
@@ -477,7 +477,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-prod-ebb1eca");
@@ -523,8 +523,8 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11");
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index bafcf0e..9cbeeb9 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -80,7 +80,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
@@ -109,7 +109,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -161,7 +161,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9174896");
@@ -210,7 +210,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -260,7 +260,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -305,7 +305,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -350,7 +350,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -392,7 +392,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -436,7 +436,7 @@ describe("gha runner", () => {
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.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
@@ -479,8 +479,8 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695");
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "0404fb922ab75c3a8aecad5c97d9af388df04695", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
@@ -499,4 +499,49 @@ describe("gha runner", () => {
}
);
});
+
+ test("using github api url and different strategy", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://api.github.com/repos/owner/reponame/pulls/2368",
+ "strategy": "ort",
+ "strategy-option": "ours",
+ });
+
+ 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-28f63db");
+
+ 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", "ort", "ours");
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 65bc3a2..b408c2b 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -91,7 +91,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
@@ -120,7 +120,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674");
@@ -171,7 +171,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
@@ -220,7 +220,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -270,7 +270,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
@@ -314,7 +314,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
@@ -357,7 +357,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca");
@@ -400,7 +400,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-prod-ebb1eca");
@@ -444,8 +444,8 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11");
- expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7");
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7", undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
From e29dae5073d5b026781931f9be00fc19d0453acb Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 13 Jul 2023 10:10:47 +0200
Subject: [PATCH 10/75] chore: release v4.2.0 (#64)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 17 +++++++++++++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fe3ae0c..f15525d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,22 @@
# Changelog
+## [4.2.0](https://github.com/kiegroup/git-backporting/compare/v4.1.0...v4.2.0) (2023-07-13)
+
+
+### Features
+
+* **issue-62:** make cherry-pick strategy configurable ([#63](https://github.com/kiegroup/git-backporting/issues/63)) ([265955d](https://github.com/kiegroup/git-backporting/commit/265955dda77a8191fd1f64517fec20e8d5f8c5b4))
+
+
+### Bug Fixes
+
+* **issue-57:** truncate the bp branch name ([#58](https://github.com/kiegroup/git-backporting/issues/58)) ([ead1322](https://github.com/kiegroup/git-backporting/commit/ead1322c0f6bb5de96c487e8f6b6565734144853))
+
+
+### Performance Improvements
+
+* use concurrent promises instead of awaiting them one by one ([#59](https://github.com/kiegroup/git-backporting/issues/59)) ([49a7350](https://github.com/kiegroup/git-backporting/commit/49a73504066396ca2a074f55bb23815e13ae462e))
+
## [4.1.0](https://github.com/kiegroup/git-backporting/compare/v4.0.0...v4.1.0) (2023-07-11)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 10fa964..a8c74d3 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23423,7 +23423,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.1.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.2.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 470d0d8..7ae6ebf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.1.0",
+ "version": "4.2.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.1.0",
+ "version": "4.2.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index f34f623..b92c1a6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.1.0",
+ "version": "4.2.0",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From a8db0755a8de776d64483b1b0857d59f23ae3d1b Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 20 Jul 2023 10:05:07 +0200
Subject: [PATCH 11/75] refactor: updated logging messages (#65)
---
dist/cli/index.js | 53 ++++++++++---------
dist/gha/index.js | 53 ++++++++++---------
src/service/configs/configs-parser.ts | 6 +--
src/service/git/git-cli.ts | 12 ++---
src/service/git/git-client-factory.ts | 8 +--
src/service/git/github/github-client.ts | 4 +-
src/service/git/github/octokit-factory.ts | 1 -
src/service/git/gitlab/gitlab-client.ts | 2 +-
src/service/logger/console-logger-service.ts | 10 ++--
src/service/logger/logger.ts | 2 +-
src/service/runner/runner.ts | 8 +--
.../github-pr-configs-parser.test.ts | 2 +-
.../gitlab-pr-configs-parser.test.ts | 2 +-
test/service/runner/cli-github-runner.test.ts | 2 +-
test/service/runner/cli-gitlab-runner.test.ts | 2 +-
test/service/runner/gha-github-runner.test.ts | 2 +-
test/service/runner/gha-gitlab-runner.test.ts | 2 +-
test/support/mock/git-client-mock-support.ts | 2 +-
18 files changed, 88 insertions(+), 85 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index a8c74d3..4873d1c 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -256,11 +256,11 @@ class ConfigsParser {
// apply validation, throw errors if something is wrong
// if pr is opened check if the there exists one single commit
if (configs.originalPullRequest.state == "open") {
- this.logger.warn("Trying to backport an open pull request!");
+ this.logger.warn("Trying to backport an open pull request");
}
- // if PR is closed and not merged log a warning
+ // if PR is closed and not merged throw an error
if (configs.originalPullRequest.state == "closed" && !configs.originalPullRequest.merged) {
- throw new Error("Provided pull request is closed and not merged!");
+ throw new Error("Provided pull request is closed and not merged");
}
return Promise.resolve(configs);
}
@@ -412,7 +412,7 @@ class GitCLIService {
* @param branch branch which should be cloned
*/
async clone(from, to, branch) {
- this.logger.info(`Cloning repository ${from} to ${to}.`);
+ this.logger.info(`Cloning repository ${from} to ${to}`);
if (!fs_1.default.existsSync(to)) {
await (0, simple_git_1.default)().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
}
@@ -426,7 +426,7 @@ class GitCLIService {
* @param newBranch new branch name
*/
async createLocalBranch(cwd, newBranch) {
- this.logger.info(`Creating branch ${newBranch}.`);
+ this.logger.info(`Creating branch ${newBranch}`);
await this.git(cwd).checkoutLocalBranch(newBranch);
}
/**
@@ -436,7 +436,7 @@ class GitCLIService {
* @param remoteName [optional] name of the remote, by default 'fork' is used
*/
async addRemote(cwd, remote, remoteName = "fork") {
- this.logger.info(`Adding new remote ${remote}.`);
+ this.logger.info(`Adding new remote ${remote}`);
await this.git(cwd).addRemote(remoteName, this.remoteWithAuth(remote));
}
/**
@@ -446,7 +446,7 @@ class GitCLIService {
* @param remote [optional] the remote to fetch, by default origin
*/
async fetch(cwd, branch, remote = "origin") {
- this.logger.info(`Fetching ${remote} ${branch}.`);
+ this.logger.info(`Fetching ${remote} ${branch}`);
await this.git(cwd).fetch(remote, branch, ["--quiet"]);
}
/**
@@ -455,7 +455,7 @@ class GitCLIService {
* @param sha commit sha
*/
async cherryPick(cwd, sha, strategy = "recursive", strategyOption = "theirs") {
- this.logger.info(`Cherry picking ${sha}.`);
+ this.logger.info(`Cherry picking ${sha}`);
const options = ["cherry-pick", "-m", "1", `--strategy=${strategy}`, `--strategy-option=${strategyOption}`, sha];
try {
await this.git(cwd).raw(options);
@@ -475,7 +475,7 @@ class GitCLIService {
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
*/
async push(cwd, branch, remote = "origin", force = false) {
- this.logger.info(`Pushing ${branch} to ${remote}.`);
+ this.logger.info(`Pushing ${branch} to ${remote}`);
const options = ["--quiet"];
if (force) {
options.push("--force-with-lease");
@@ -505,9 +505,10 @@ const gitlab_client_1 = __importDefault(__nccwpck_require__(4077));
* Singleton git service factory class
*/
class GitClientFactory {
+ // this method assumes there already exists a singleton client instance, otherwise it will fail
static getClient() {
if (!GitClientFactory.instance) {
- throw new Error("You must call `getOrCreate` method first!");
+ throw new Error("You must call `getOrCreate` method first");
}
return GitClientFactory.instance;
}
@@ -518,7 +519,7 @@ class GitClientFactory {
*/
static getOrCreate(type, authToken, apiUrl) {
if (GitClientFactory.instance) {
- GitClientFactory.logger.warn("Git service already initialized!");
+ GitClientFactory.logger.warn("Git service already initialized");
return GitClientFactory.instance;
}
this.logger.debug(`Setting up ${type} client: apiUrl=${apiUrl}, token=****`);
@@ -534,8 +535,9 @@ class GitClientFactory {
}
return GitClientFactory.instance;
}
+ // this is used for testing purposes
static reset() {
- GitClientFactory.logger.warn("Resetting git service!");
+ GitClientFactory.logger.warn("Resetting git service");
GitClientFactory.instance = undefined;
}
}
@@ -641,7 +643,7 @@ class GitHubClient {
return "noreply@github.com";
}
async getPullRequest(owner, repo, prNumber, squash = true) {
- this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
+ this.logger.debug(`Fetching pull request ${owner}/${repo}/${prNumber}`);
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
@@ -670,7 +672,7 @@ class GitHubClient {
}
// WRITE
async createPullRequest(backport) {
- this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
+ this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}`);
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
const { data } = await this.octokit.pulls.create({
owner: backport.owner,
@@ -809,7 +811,6 @@ const rest_1 = __nccwpck_require__(5375);
class OctokitFactory {
static getOctokit(token, apiUrl) {
if (!OctokitFactory.octokit) {
- OctokitFactory.logger.info("Creating octokit instance.");
OctokitFactory.octokit = new rest_1.Octokit({
auth: token,
userAgent: "kiegroup/git-backporting",
@@ -885,7 +886,7 @@ class GitLabClient {
}
// WRITE
async createPullRequest(backport) {
- this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
+ this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}`);
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
const projectId = this.getProjectId(backport.owner, backport.repo);
const { data } = await this.client.post(`/projects/${projectId}/merge_requests`, {
@@ -1075,21 +1076,21 @@ class ConsoleLoggerService {
this.verbose = verbose;
}
trace(message) {
- this.logger.log("[TRACE]", message);
+ this.logger.log("TRACE", message);
}
debug(message) {
if (this.verbose) {
- this.logger.log("[DEBUG]", message);
+ this.logger.log("DEBUG", message);
}
}
info(message) {
- this.logger.log("[INFO]", message);
+ this.logger.log("INFO", message);
}
warn(message) {
- this.logger.log("[WARN]", message);
+ this.logger.log("WARN", message);
}
error(message) {
- this.logger.log("[ERROR]", message);
+ this.logger.log("ERROR", message);
}
}
exports["default"] = ConsoleLoggerService;
@@ -1135,7 +1136,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
class Logger {
log(prefix, ...str) {
// eslint-disable-next-line no-console
- console.log.apply(console, [prefix, ...str]);
+ console.log.apply(console, [`[${prefix.padEnd(5)}]`, ...str]);
}
emptyLine() {
this.log("", "");
@@ -1175,12 +1176,12 @@ class Runner {
async run() {
try {
await this.execute();
- this.logger.info("Process succeeded!");
+ this.logger.info("Process succeeded");
process.exit(0);
}
catch (error) {
this.logger.error(`${error}`);
- this.logger.info("Process failed!");
+ this.logger.info("Process failed");
process.exit(1);
}
}
@@ -1191,7 +1192,7 @@ class Runner {
// 1. parse args
const args = this.argsParser.parse();
if (args.dryRun) {
- this.logger.warn("Dry run enabled!");
+ this.logger.warn("Dry run enabled");
}
// 2. init git service
const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
@@ -1252,7 +1253,7 @@ class Runner {
this.logger.info(`Pull request created: ${prUrl}`);
}
else {
- this.logger.warn("Pull request creation and remote push skipped!");
+ this.logger.warn("Pull request creation and remote push skipped");
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
}
}
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 5778dce..cf28269 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -227,11 +227,11 @@ class ConfigsParser {
// apply validation, throw errors if something is wrong
// if pr is opened check if the there exists one single commit
if (configs.originalPullRequest.state == "open") {
- this.logger.warn("Trying to backport an open pull request!");
+ this.logger.warn("Trying to backport an open pull request");
}
- // if PR is closed and not merged log a warning
+ // if PR is closed and not merged throw an error
if (configs.originalPullRequest.state == "closed" && !configs.originalPullRequest.merged) {
- throw new Error("Provided pull request is closed and not merged!");
+ throw new Error("Provided pull request is closed and not merged");
}
return Promise.resolve(configs);
}
@@ -383,7 +383,7 @@ class GitCLIService {
* @param branch branch which should be cloned
*/
async clone(from, to, branch) {
- this.logger.info(`Cloning repository ${from} to ${to}.`);
+ this.logger.info(`Cloning repository ${from} to ${to}`);
if (!fs_1.default.existsSync(to)) {
await (0, simple_git_1.default)().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
}
@@ -397,7 +397,7 @@ class GitCLIService {
* @param newBranch new branch name
*/
async createLocalBranch(cwd, newBranch) {
- this.logger.info(`Creating branch ${newBranch}.`);
+ this.logger.info(`Creating branch ${newBranch}`);
await this.git(cwd).checkoutLocalBranch(newBranch);
}
/**
@@ -407,7 +407,7 @@ class GitCLIService {
* @param remoteName [optional] name of the remote, by default 'fork' is used
*/
async addRemote(cwd, remote, remoteName = "fork") {
- this.logger.info(`Adding new remote ${remote}.`);
+ this.logger.info(`Adding new remote ${remote}`);
await this.git(cwd).addRemote(remoteName, this.remoteWithAuth(remote));
}
/**
@@ -417,7 +417,7 @@ class GitCLIService {
* @param remote [optional] the remote to fetch, by default origin
*/
async fetch(cwd, branch, remote = "origin") {
- this.logger.info(`Fetching ${remote} ${branch}.`);
+ this.logger.info(`Fetching ${remote} ${branch}`);
await this.git(cwd).fetch(remote, branch, ["--quiet"]);
}
/**
@@ -426,7 +426,7 @@ class GitCLIService {
* @param sha commit sha
*/
async cherryPick(cwd, sha, strategy = "recursive", strategyOption = "theirs") {
- this.logger.info(`Cherry picking ${sha}.`);
+ this.logger.info(`Cherry picking ${sha}`);
const options = ["cherry-pick", "-m", "1", `--strategy=${strategy}`, `--strategy-option=${strategyOption}`, sha];
try {
await this.git(cwd).raw(options);
@@ -446,7 +446,7 @@ class GitCLIService {
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
*/
async push(cwd, branch, remote = "origin", force = false) {
- this.logger.info(`Pushing ${branch} to ${remote}.`);
+ this.logger.info(`Pushing ${branch} to ${remote}`);
const options = ["--quiet"];
if (force) {
options.push("--force-with-lease");
@@ -476,9 +476,10 @@ const gitlab_client_1 = __importDefault(__nccwpck_require__(4077));
* Singleton git service factory class
*/
class GitClientFactory {
+ // this method assumes there already exists a singleton client instance, otherwise it will fail
static getClient() {
if (!GitClientFactory.instance) {
- throw new Error("You must call `getOrCreate` method first!");
+ throw new Error("You must call `getOrCreate` method first");
}
return GitClientFactory.instance;
}
@@ -489,7 +490,7 @@ class GitClientFactory {
*/
static getOrCreate(type, authToken, apiUrl) {
if (GitClientFactory.instance) {
- GitClientFactory.logger.warn("Git service already initialized!");
+ GitClientFactory.logger.warn("Git service already initialized");
return GitClientFactory.instance;
}
this.logger.debug(`Setting up ${type} client: apiUrl=${apiUrl}, token=****`);
@@ -505,8 +506,9 @@ class GitClientFactory {
}
return GitClientFactory.instance;
}
+ // this is used for testing purposes
static reset() {
- GitClientFactory.logger.warn("Resetting git service!");
+ GitClientFactory.logger.warn("Resetting git service");
GitClientFactory.instance = undefined;
}
}
@@ -612,7 +614,7 @@ class GitHubClient {
return "noreply@github.com";
}
async getPullRequest(owner, repo, prNumber, squash = true) {
- this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
+ this.logger.debug(`Fetching pull request ${owner}/${repo}/${prNumber}`);
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
@@ -641,7 +643,7 @@ class GitHubClient {
}
// WRITE
async createPullRequest(backport) {
- this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
+ this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}`);
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
const { data } = await this.octokit.pulls.create({
owner: backport.owner,
@@ -780,7 +782,6 @@ const rest_1 = __nccwpck_require__(5375);
class OctokitFactory {
static getOctokit(token, apiUrl) {
if (!OctokitFactory.octokit) {
- OctokitFactory.logger.info("Creating octokit instance.");
OctokitFactory.octokit = new rest_1.Octokit({
auth: token,
userAgent: "kiegroup/git-backporting",
@@ -856,7 +857,7 @@ class GitLabClient {
}
// WRITE
async createPullRequest(backport) {
- this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
+ this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}`);
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
const projectId = this.getProjectId(backport.owner, backport.repo);
const { data } = await this.client.post(`/projects/${projectId}/merge_requests`, {
@@ -1046,21 +1047,21 @@ class ConsoleLoggerService {
this.verbose = verbose;
}
trace(message) {
- this.logger.log("[TRACE]", message);
+ this.logger.log("TRACE", message);
}
debug(message) {
if (this.verbose) {
- this.logger.log("[DEBUG]", message);
+ this.logger.log("DEBUG", message);
}
}
info(message) {
- this.logger.log("[INFO]", message);
+ this.logger.log("INFO", message);
}
warn(message) {
- this.logger.log("[WARN]", message);
+ this.logger.log("WARN", message);
}
error(message) {
- this.logger.log("[ERROR]", message);
+ this.logger.log("ERROR", message);
}
}
exports["default"] = ConsoleLoggerService;
@@ -1106,7 +1107,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
class Logger {
log(prefix, ...str) {
// eslint-disable-next-line no-console
- console.log.apply(console, [prefix, ...str]);
+ console.log.apply(console, [`[${prefix.padEnd(5)}]`, ...str]);
}
emptyLine() {
this.log("", "");
@@ -1146,12 +1147,12 @@ class Runner {
async run() {
try {
await this.execute();
- this.logger.info("Process succeeded!");
+ this.logger.info("Process succeeded");
process.exit(0);
}
catch (error) {
this.logger.error(`${error}`);
- this.logger.info("Process failed!");
+ this.logger.info("Process failed");
process.exit(1);
}
}
@@ -1162,7 +1163,7 @@ class Runner {
// 1. parse args
const args = this.argsParser.parse();
if (args.dryRun) {
- this.logger.warn("Dry run enabled!");
+ this.logger.warn("Dry run enabled");
}
// 2. init git service
const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
@@ -1223,7 +1224,7 @@ class Runner {
this.logger.info(`Pull request created: ${prUrl}`);
}
else {
- this.logger.warn("Pull request creation and remote push skipped!");
+ this.logger.warn("Pull request creation and remote push skipped");
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
}
}
diff --git a/src/service/configs/configs-parser.ts b/src/service/configs/configs-parser.ts
index e21ed08..5b901cb 100644
--- a/src/service/configs/configs-parser.ts
+++ b/src/service/configs/configs-parser.ts
@@ -24,12 +24,12 @@ import LoggerServiceFactory from "../logger/logger-service-factory";
// if pr is opened check if the there exists one single commit
if (configs.originalPullRequest.state == "open") {
- this.logger.warn("Trying to backport an open pull request!");
+ this.logger.warn("Trying to backport an open pull request");
}
- // if PR is closed and not merged log a warning
+ // if PR is closed and not merged throw an error
if (configs.originalPullRequest.state == "closed" && !configs.originalPullRequest.merged) {
- throw new Error("Provided pull request is closed and not merged!");
+ throw new Error("Provided pull request is closed and not merged");
}
return Promise.resolve(configs);
diff --git a/src/service/git/git-cli.ts b/src/service/git/git-cli.ts
index c0b439e..26239a7 100644
--- a/src/service/git/git-cli.ts
+++ b/src/service/git/git-cli.ts
@@ -60,7 +60,7 @@ export default class GitCLIService {
* @param branch branch which should be cloned
*/
async clone(from: string, to: string, branch: string): Promise {
- this.logger.info(`Cloning repository ${from} to ${to}.`);
+ this.logger.info(`Cloning repository ${from} to ${to}`);
if (!fs.existsSync(to)) {
await simpleGit().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
} else {
@@ -74,7 +74,7 @@ export default class GitCLIService {
* @param newBranch new branch name
*/
async createLocalBranch(cwd: string, newBranch: string): Promise {
- this.logger.info(`Creating branch ${newBranch}.`);
+ this.logger.info(`Creating branch ${newBranch}`);
await this.git(cwd).checkoutLocalBranch(newBranch);
}
@@ -85,7 +85,7 @@ export default class GitCLIService {
* @param remoteName [optional] name of the remote, by default 'fork' is used
*/
async addRemote(cwd: string, remote: string, remoteName = "fork"): Promise {
- this.logger.info(`Adding new remote ${remote}.`);
+ this.logger.info(`Adding new remote ${remote}`);
await this.git(cwd).addRemote(remoteName, this.remoteWithAuth(remote));
}
@@ -96,7 +96,7 @@ export default class GitCLIService {
* @param remote [optional] the remote to fetch, by default origin
*/
async fetch(cwd: string, branch: string, remote = "origin"): Promise {
- this.logger.info(`Fetching ${remote} ${branch}.`);
+ this.logger.info(`Fetching ${remote} ${branch}`);
await this.git(cwd).fetch(remote, branch, ["--quiet"]);
}
@@ -106,7 +106,7 @@ export default class GitCLIService {
* @param sha commit sha
*/
async cherryPick(cwd: string, sha: string, strategy = "recursive", strategyOption = "theirs"): Promise {
- this.logger.info(`Cherry picking ${sha}.`);
+ this.logger.info(`Cherry picking ${sha}`);
const options = ["cherry-pick", "-m", "1", `--strategy=${strategy}`, `--strategy-option=${strategyOption}`, sha];
try {
@@ -128,7 +128,7 @@ export default class GitCLIService {
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
*/
async push(cwd: string, branch: string, remote = "origin", force = false): Promise {
- this.logger.info(`Pushing ${branch} to ${remote}.`);
+ this.logger.info(`Pushing ${branch} to ${remote}`);
const options = ["--quiet"];
if (force) {
diff --git a/src/service/git/git-client-factory.ts b/src/service/git/git-client-factory.ts
index 890863a..fa63173 100644
--- a/src/service/git/git-client-factory.ts
+++ b/src/service/git/git-client-factory.ts
@@ -13,9 +13,10 @@ export default class GitClientFactory {
private static logger: LoggerService = LoggerServiceFactory.getLogger();
private static instance?: GitClient;
+ // this method assumes there already exists a singleton client instance, otherwise it will fail
public static getClient(): GitClient {
if (!GitClientFactory.instance) {
- throw new Error("You must call `getOrCreate` method first!");
+ throw new Error("You must call `getOrCreate` method first");
}
return GitClientFactory.instance;
@@ -29,7 +30,7 @@ export default class GitClientFactory {
public static getOrCreate(type: GitClientType, authToken: string | undefined, apiUrl: string): GitClient {
if (GitClientFactory.instance) {
- GitClientFactory.logger.warn("Git service already initialized!");
+ GitClientFactory.logger.warn("Git service already initialized");
return GitClientFactory.instance;
}
@@ -49,8 +50,9 @@ export default class GitClientFactory {
return GitClientFactory.instance;
}
+ // this is used for testing purposes
public static reset(): void {
- GitClientFactory.logger.warn("Resetting git service!");
+ GitClientFactory.logger.warn("Resetting git service");
GitClientFactory.instance = undefined;
}
}
\ No newline at end of file
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index 012736b..0da22df 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -32,7 +32,7 @@ export default class GitHubClient implements GitClient {
}
async getPullRequest(owner: string, repo: string, prNumber: number, squash = true): Promise {
- this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
+ this.logger.debug(`Fetching pull request ${owner}/${repo}/${prNumber}`);
const { data } = await this.octokit.rest.pulls.get({
owner: owner,
repo: repo,
@@ -66,7 +66,7 @@ export default class GitHubClient implements GitClient {
// WRITE
async createPullRequest(backport: BackportPullRequest): Promise {
- this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
+ this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}`);
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
const { data } = await this.octokit.pulls.create({
diff --git a/src/service/git/github/octokit-factory.ts b/src/service/git/github/octokit-factory.ts
index e63f486..7792ed6 100644
--- a/src/service/git/github/octokit-factory.ts
+++ b/src/service/git/github/octokit-factory.ts
@@ -12,7 +12,6 @@ export default class OctokitFactory {
public static getOctokit(token: string | undefined, apiUrl: string): Octokit {
if (!OctokitFactory.octokit) {
- OctokitFactory.logger.info("Creating octokit instance.");
OctokitFactory.octokit = new Octokit({
auth: token,
userAgent: "kiegroup/git-backporting",
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index 3607c45..725eacb 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -69,7 +69,7 @@ export default class GitLabClient implements GitClient {
// WRITE
async createPullRequest(backport: BackportPullRequest): Promise {
- this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
+ this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}`);
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
const projectId = this.getProjectId(backport.owner, backport.repo);
diff --git a/src/service/logger/console-logger-service.ts b/src/service/logger/console-logger-service.ts
index 3a313eb..ee9339b 100644
--- a/src/service/logger/console-logger-service.ts
+++ b/src/service/logger/console-logger-service.ts
@@ -12,25 +12,25 @@ export default class ConsoleLoggerService implements LoggerService {
}
trace(message: string): void {
- this.logger.log("[TRACE]", message);
+ this.logger.log("TRACE", message);
}
debug(message: string): void {
if (this.verbose) {
- this.logger.log("[DEBUG]", message);
+ this.logger.log("DEBUG", message);
}
}
info(message: string): void {
- this.logger.log("[INFO]", message);
+ this.logger.log("INFO", message);
}
warn(message: string): void {
- this.logger.log("[WARN]", message);
+ this.logger.log("WARN", message);
}
error(message: string): void {
- this.logger.log("[ERROR]", message);
+ this.logger.log("ERROR", message);
}
}
\ No newline at end of file
diff --git a/src/service/logger/logger.ts b/src/service/logger/logger.ts
index f058525..18f76e5 100644
--- a/src/service/logger/logger.ts
+++ b/src/service/logger/logger.ts
@@ -6,7 +6,7 @@
log(prefix: string, ...str: string[]) {
// eslint-disable-next-line no-console
- console.log.apply(console, [prefix, ...str]);
+ console.log.apply(console, [`[${prefix.padEnd(5)}]`, ...str]);
}
emptyLine() {
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index 2060e30..2ad5364 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -30,13 +30,13 @@ export default class Runner {
try {
await this.execute();
- this.logger.info("Process succeeded!");
+ this.logger.info("Process succeeded");
process.exit(0);
} catch (error) {
this.logger.error(`${error}`);
- this.logger.info("Process failed!");
+ this.logger.info("Process failed");
process.exit(1);
}
}
@@ -50,7 +50,7 @@ export default class Runner {
const args: Args = this.argsParser.parse();
if (args.dryRun) {
- this.logger.warn("Dry run enabled!");
+ this.logger.warn("Dry run enabled");
}
// 2. init git service
@@ -123,7 +123,7 @@ export default class Runner {
this.logger.info(`Pull request created: ${prUrl}`);
} else {
- this.logger.warn("Pull request creation and remote push skipped!");
+ this.logger.warn("Pull request creation and remote push skipped");
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
}
}
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 4b8b40b..950c01f 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -247,7 +247,7 @@ describe("github pull request config parser", () => {
inheritReviewers: true,
};
- await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged");
});
test("override backport pr data inheriting reviewers", async () => {
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 f180a78..8e10d17 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -253,7 +253,7 @@ describe("gitlab merge request config parser", () => {
inheritReviewers: true,
};
- await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged");
});
test("override backport pr data inheriting reviewers", async () => {
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 39b5e83..f70d446 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -289,7 +289,7 @@ describe("cli runner", () => {
"https://github.com/owner/reponame/pull/6666"
]);
- await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged");
});
test("open pull request", async () => {
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index c07e46d..c13be27 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -193,7 +193,7 @@ describe("cli runner", () => {
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3"
]);
- await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged");
});
test("merged pull request", async () => {
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 9cbeeb9..69de6d0 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -135,7 +135,7 @@ describe("gha runner", () => {
"pull-request": "https://github.com/owner/reponame/pull/6666"
});
- await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged");
});
test("open pull request", async () => {
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index b408c2b..4610cee 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -146,7 +146,7 @@ describe("gha runner", () => {
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3"
});
- await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
+ await expect(() => runner.execute()).rejects.toThrow("Provided pull request is closed and not merged");
});
test("merged pull request", async () => {
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index 6a3b4a8..02597f7 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -79,7 +79,7 @@ export const putAxiosMocked = async (url: string, _data?: unknown) => {
// GITHUB - OCTOKIT
export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit => {
- logger.debug("Setting up moctokit.");
+ logger.debug("Setting up moctokit..");
const mock = new Moctokit(apiUrl);
From cee5e32d0e6922d6b32e94f8c88806b24c6b732b Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 20 Jul 2023 10:21:22 +0200
Subject: [PATCH 12/75] ci: automated pull request test coverage report (#66)
---
.github/workflows/coverage.yml | 15 +++++++++++++++
1 file changed, 15 insertions(+)
create mode 100644 .github/workflows/coverage.yml
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 0000000..d5afeb5
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,15 @@
+name: 'coverage report'
+
+on:
+ pull_request_target:
+ branches:
+ - main
+
+jobs:
+ coverage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ArtiomTr/jest-coverage-report-action@v2
+ with:
+ test-script: npm test
\ No newline at end of file
From 9766bdb67be3c90c187ce87d669c5e1a256dae3c Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 20 Jul 2023 15:19:11 +0200
Subject: [PATCH 13/75] build(CVE-2023-37466): update release-it to 16.1.3
(#68)
Fix CVE-2023-37466: vm2 Sandbox Escape vulnerability
---
dist/cli/index.js | 2 +-
package-lock.json | 1106 ++++++++++++++++++++++-----------------------
package.json | 8 +-
3 files changed, 545 insertions(+), 571 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 4873d1c..b39241d 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23424,7 +23424,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.2.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@release-it/conventional-changelog":"^5.1.1","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^15.6.0","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3","@octokit/webhooks-types":"^6.8.0"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.2.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 7ae6ebf..99c7a30 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -26,7 +26,7 @@
"@gitbeaker/rest": "^39.1.0",
"@kie/mock-github": "^1.1.0",
"@octokit/webhooks-types": "^6.8.0",
- "@release-it/conventional-changelog": "^5.1.1",
+ "@release-it/conventional-changelog": "^7.0.0",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.2.4",
"@types/node": "^18.11.17",
@@ -37,7 +37,7 @@
"husky": "^8.0.2",
"jest": "^29.0.0",
"jest-sonar-reporter": "^2.0.0",
- "release-it": "^15.6.0",
+ "release-it": "^16.1.3",
"semver": "^7.3.8",
"ts-jest": "^29.0.0",
"ts-node": "^10.8.1",
@@ -1970,21 +1970,21 @@
}
},
"node_modules/@release-it/conventional-changelog": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-5.1.1.tgz",
- "integrity": "sha512-QtbDBe36dQfzexAfDYrbLPvd5Cb5bMWmLcjcGhCOWBss7fe1/gCjoxDULVz+7N7G5Nu2UMeBwHcUp/w8RDh5VQ==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-7.0.0.tgz",
+ "integrity": "sha512-DBzyVS6c4g8w+xomCsygkmLeQBUq41Wvzy0vGgbdCLOxYnwI0cDaF6HOLPkrifH1qLa1uJ9i1pYA+hNyHkNanQ==",
"dev": true,
"dependencies": {
"concat-stream": "^2.0.0",
- "conventional-changelog": "^3.1.25",
- "conventional-recommended-bump": "^6.1.0",
- "semver": "7.3.8"
+ "conventional-changelog": "^4.0.0",
+ "conventional-recommended-bump": "^7.0.1",
+ "semver": "7.5.1"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
},
"peerDependencies": {
- "release-it": "^15.4.1"
+ "release-it": "^16.0.0"
}
},
"node_modules/@sinclair/typebox": {
@@ -2035,6 +2035,12 @@
"node": ">=14.16"
}
},
+ "node_modules/@tootallnate/quickjs-emscripten": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
+ "dev": true
+ },
"node_modules/@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
@@ -3563,25 +3569,25 @@
}
},
"node_modules/conventional-changelog": {
- "version": "3.1.25",
- "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz",
- "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-4.0.0.tgz",
+ "integrity": "sha512-JbZjwE1PzxQCvm+HUTIr+pbSekS8qdOZzMakdFyPtdkEWwFvwEJYONzjgMm0txCb2yBcIcfKDmg8xtCKTdecNQ==",
"dev": true,
"dependencies": {
- "conventional-changelog-angular": "^5.0.12",
- "conventional-changelog-atom": "^2.0.8",
- "conventional-changelog-codemirror": "^2.0.8",
- "conventional-changelog-conventionalcommits": "^4.5.0",
- "conventional-changelog-core": "^4.2.1",
- "conventional-changelog-ember": "^2.0.9",
- "conventional-changelog-eslint": "^3.0.9",
- "conventional-changelog-express": "^2.0.6",
- "conventional-changelog-jquery": "^3.0.11",
- "conventional-changelog-jshint": "^2.0.9",
- "conventional-changelog-preset-loader": "^2.3.4"
+ "conventional-changelog-angular": "^6.0.0",
+ "conventional-changelog-atom": "^3.0.0",
+ "conventional-changelog-codemirror": "^3.0.0",
+ "conventional-changelog-conventionalcommits": "^6.0.0",
+ "conventional-changelog-core": "^5.0.0",
+ "conventional-changelog-ember": "^3.0.0",
+ "conventional-changelog-eslint": "^4.0.0",
+ "conventional-changelog-express": "^3.0.0",
+ "conventional-changelog-jquery": "^4.0.0",
+ "conventional-changelog-jshint": "^3.0.0",
+ "conventional-changelog-preset-loader": "^3.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-angular": {
@@ -3598,27 +3604,21 @@
}
},
"node_modules/conventional-changelog-atom": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz",
- "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-3.0.0.tgz",
+ "integrity": "sha512-pnN5bWpH+iTUWU3FaYdw5lJmfWeqSyrUkG+wyHBI9tC1dLNnHkbAOg1SzTQ7zBqiFrfo55h40VsGXWMdopwc5g==",
"dev": true,
- "dependencies": {
- "q": "^1.5.1"
- },
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-codemirror": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz",
- "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-3.0.0.tgz",
+ "integrity": "sha512-wzchZt9HEaAZrenZAUUHMCFcuYzGoZ1wG/kTRMICxsnW5AXohYMRxnyecP9ob42Gvn5TilhC0q66AtTPRSNMfw==",
"dev": true,
- "dependencies": {
- "q": "^1.5.1"
- },
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-conventionalcommits": {
@@ -3636,28 +3636,43 @@
}
},
"node_modules/conventional-changelog-core": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz",
- "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.2.tgz",
+ "integrity": "sha512-RhQOcDweXNWvlRwUDCpaqXzbZemKPKncCWZG50Alth72WITVd6nhVk9MJ6w1k9PFNBcZ3YwkdkChE+8+ZwtUug==",
"dev": true,
"dependencies": {
"add-stream": "^1.0.0",
- "conventional-changelog-writer": "^5.0.0",
- "conventional-commits-parser": "^3.2.0",
- "dateformat": "^3.0.0",
- "get-pkg-repo": "^4.0.0",
- "git-raw-commits": "^2.0.8",
+ "conventional-changelog-writer": "^6.0.0",
+ "conventional-commits-parser": "^4.0.0",
+ "dateformat": "^3.0.3",
+ "get-pkg-repo": "^4.2.1",
+ "git-raw-commits": "^3.0.0",
"git-remote-origin-url": "^2.0.0",
- "git-semver-tags": "^4.1.1",
- "lodash": "^4.17.15",
- "normalize-package-data": "^3.0.0",
- "q": "^1.5.1",
+ "git-semver-tags": "^5.0.0",
+ "normalize-package-data": "^3.0.3",
"read-pkg": "^3.0.0",
- "read-pkg-up": "^3.0.0",
- "through2": "^4.0.0"
+ "read-pkg-up": "^3.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/conventional-commits-parser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
+ "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "dev": true,
+ "dependencies": {
+ "is-text-path": "^1.0.1",
+ "JSONStream": "^1.3.5",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ },
+ "bin": {
+ "conventional-commits-parser": "cli.js"
+ },
+ "engines": {
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-core/node_modules/find-up": {
@@ -3672,6 +3687,23 @@
"node": ">=4"
}
},
+ "node_modules/conventional-changelog-core/node_modules/git-raw-commits": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
+ "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "dev": true,
+ "dependencies": {
+ "dargs": "^7.0.0",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ },
+ "bin": {
+ "git-raw-commits": "cli.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/conventional-changelog-core/node_modules/hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@@ -3794,141 +3826,127 @@
}
},
"node_modules/conventional-changelog-core/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/conventional-changelog-ember": {
- "version": "2.0.9",
- "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz",
- "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-3.0.0.tgz",
+ "integrity": "sha512-7PYthCoSxIS98vWhVcSphMYM322OxptpKAuHYdVspryI0ooLDehRXWeRWgN+zWSBXKl/pwdgAg8IpLNSM1/61A==",
"dev": true,
- "dependencies": {
- "q": "^1.5.1"
- },
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-eslint": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz",
- "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-4.0.0.tgz",
+ "integrity": "sha512-nEZ9byP89hIU0dMx37JXQkE1IpMmqKtsaR24X7aM3L6Yy/uAtbb+ogqthuNYJkeO1HyvK7JsX84z8649hvp43Q==",
"dev": true,
- "dependencies": {
- "q": "^1.5.1"
- },
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-express": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz",
- "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-3.0.0.tgz",
+ "integrity": "sha512-HqxihpUMfIuxvlPvC6HltA4ZktQEUan/v3XQ77+/zbu8No/fqK3rxSZaYeHYant7zRxQNIIli7S+qLS9tX9zQA==",
"dev": true,
- "dependencies": {
- "q": "^1.5.1"
- },
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-jquery": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz",
- "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-4.0.0.tgz",
+ "integrity": "sha512-TTIN5CyzRMf8PUwyy4IOLmLV2DFmPtasKN+x7EQKzwSX8086XYwo+NeaeA3VUT8bvKaIy5z/JoWUvi7huUOgaw==",
"dev": true,
- "dependencies": {
- "q": "^1.5.1"
- },
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-jshint": {
- "version": "2.0.9",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz",
- "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-3.0.0.tgz",
+ "integrity": "sha512-bQof4byF4q+n+dwFRkJ/jGf9dCNUv4/kCDcjeCizBvfF81TeimPZBB6fT4HYbXgxxfxWXNl/i+J6T0nI4by6DA==",
"dev": true,
"dependencies": {
- "compare-func": "^2.0.0",
- "q": "^1.5.1"
+ "compare-func": "^2.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-preset-loader": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz",
- "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz",
+ "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==",
"dev": true,
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-changelog-writer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz",
- "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz",
+ "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==",
"dev": true,
"dependencies": {
- "conventional-commits-filter": "^2.0.7",
- "dateformat": "^3.0.0",
+ "conventional-commits-filter": "^3.0.0",
+ "dateformat": "^3.0.3",
"handlebars": "^4.7.7",
"json-stringify-safe": "^5.0.1",
- "lodash": "^4.17.15",
- "meow": "^8.0.0",
- "semver": "^6.0.0",
- "split": "^1.0.0",
- "through2": "^4.0.0"
+ "meow": "^8.1.2",
+ "semver": "^7.0.0",
+ "split": "^1.0.1"
},
"bin": {
"conventional-changelog-writer": "cli.js"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
- "node_modules/conventional-changelog-writer/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "node_modules/conventional-changelog/node_modules/conventional-changelog-angular": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz",
+ "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==",
"dev": true,
- "bin": {
- "semver": "bin/semver.js"
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14"
}
},
"node_modules/conventional-changelog/node_modules/conventional-changelog-conventionalcommits": {
- "version": "4.6.3",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz",
- "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz",
+ "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==",
"dev": true,
"dependencies": {
- "compare-func": "^2.0.0",
- "lodash": "^4.17.15",
- "q": "^1.5.1"
+ "compare-func": "^2.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-commits-filter": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz",
- "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz",
+ "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==",
"dev": true,
"dependencies": {
"lodash.ismatch": "^4.4.0",
- "modify-values": "^1.0.0"
+ "modify-values": "^1.0.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/conventional-commits-parser": {
@@ -3952,25 +3970,59 @@
}
},
"node_modules/conventional-recommended-bump": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz",
- "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz",
+ "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==",
"dev": true,
"dependencies": {
"concat-stream": "^2.0.0",
- "conventional-changelog-preset-loader": "^2.3.4",
- "conventional-commits-filter": "^2.0.7",
- "conventional-commits-parser": "^3.2.0",
- "git-raw-commits": "^2.0.8",
- "git-semver-tags": "^4.1.1",
- "meow": "^8.0.0",
- "q": "^1.5.1"
+ "conventional-changelog-preset-loader": "^3.0.0",
+ "conventional-commits-filter": "^3.0.0",
+ "conventional-commits-parser": "^4.0.0",
+ "git-raw-commits": "^3.0.0",
+ "git-semver-tags": "^5.0.0",
+ "meow": "^8.1.2"
},
"bin": {
"conventional-recommended-bump": "cli.js"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/conventional-commits-parser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
+ "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "dev": true,
+ "dependencies": {
+ "is-text-path": "^1.0.1",
+ "JSONStream": "^1.3.5",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ },
+ "bin": {
+ "conventional-commits-parser": "cli.js"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/git-raw-commits": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
+ "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "dev": true,
+ "dependencies": {
+ "dargs": "^7.0.0",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ },
+ "bin": {
+ "git-raw-commits": "cli.js"
+ },
+ "engines": {
+ "node": ">=14"
}
},
"node_modules/convert-source-map": {
@@ -4409,15 +4461,14 @@
}
},
"node_modules/degenerator": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-4.0.4.tgz",
- "integrity": "sha512-MTZdZsuNxSBL92rsjx3VFWe57OpRlikyLbcx2B5Dmdv6oScqpMrvpY7zHLMymrUxo3U5+suPUMsNgW/+SZB1lg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
"dev": true,
"dependencies": {
"ast-types": "^0.13.4",
- "escodegen": "^1.14.3",
- "esprima": "^4.0.1",
- "vm2": "^3.9.19"
+ "escodegen": "^2.1.0",
+ "esprima": "^4.0.1"
},
"engines": {
"node": ">= 14"
@@ -4713,76 +4764,33 @@
}
},
"node_modules/escodegen": {
- "version": "1.14.3",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
- "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
"dev": true,
"dependencies": {
"esprima": "^4.0.1",
- "estraverse": "^4.2.0",
- "esutils": "^2.0.2",
- "optionator": "^0.8.1"
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2"
},
"bin": {
"escodegen": "bin/escodegen.js",
"esgenerate": "bin/esgenerate.js"
},
"engines": {
- "node": ">=4.0"
+ "node": ">=6.0"
},
"optionalDependencies": {
"source-map": "~0.6.1"
}
},
- "node_modules/escodegen/node_modules/levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/escodegen/node_modules/optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha512-oCOQ8AIC2ciLy/sE2ehafRBleBgDLvzGhBRRev87sP7ovnbvQfqpc3XFI0DhHey2OfVoNV91W+GPC6B3540/5Q==",
- "dev": true,
- "dependencies": {
- "deep-is": "~0.1.3",
- "fast-levenshtein": "~2.0.4",
- "levn": "~0.3.0",
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2",
- "wordwrap": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/escodegen/node_modules/prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "node_modules/escodegen/node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true,
"engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/escodegen/node_modules/type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
- "dev": true,
- "dependencies": {
- "prelude-ls": "~1.1.2"
- },
- "engines": {
- "node": ">= 0.8.0"
+ "node": ">=4.0"
}
},
"node_modules/eslint": {
@@ -5159,9 +5167,9 @@
"dev": true
},
"node_modules/fast-glob": {
- "version": "3.2.12",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
- "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
+ "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
"dev": true,
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@@ -5582,9 +5590,9 @@
"dev": true
},
"node_modules/get-pkg-repo/node_modules/readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
"dependencies": {
"core-util-is": "~1.0.0",
@@ -5756,28 +5764,19 @@
}
},
"node_modules/git-semver-tags": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz",
- "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz",
+ "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==",
"dev": true,
"dependencies": {
- "meow": "^8.0.0",
- "semver": "^6.0.0"
+ "meow": "^8.1.2",
+ "semver": "^7.0.0"
},
"bin": {
"git-semver-tags": "cli.js"
},
"engines": {
- "node": ">=10"
- }
- },
- "node_modules/git-semver-tags/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true,
- "bin": {
- "semver": "bin/semver.js"
+ "node": ">=14"
}
},
"node_modules/git-up": {
@@ -6157,9 +6156,9 @@
"integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg=="
},
"node_modules/https-proxy-agent": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz",
- "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz",
+ "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==",
"dev": true,
"dependencies": {
"agent-base": "^7.0.2",
@@ -6226,9 +6225,9 @@
]
},
"node_modules/ignore": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
- "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -6319,13 +6318,13 @@
"dev": true
},
"node_modules/inquirer": {
- "version": "9.2.6",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.6.tgz",
- "integrity": "sha512-y71l237eJJKS4rl7sQcEUiMhrR0pB/ZnRMMTxLpjJhWL4hdWCT03a6jJnC1w6qIPSRZWEozuieGt3v7XaEJYFw==",
+ "version": "9.2.8",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.8.tgz",
+ "integrity": "sha512-SJ0fVfgIzZL1AD6WvFhivlh5/3hN6WeAvpvPrpPXH/8MOcQHeXhinmSm5CDJNRC2Q+sLh9YJ5k8F8/5APMXSfw==",
"dev": true,
"dependencies": {
"ansi-escapes": "^4.3.2",
- "chalk": "^5.2.0",
+ "chalk": "^5.3.0",
"cli-cursor": "^3.1.0",
"cli-width": "^4.0.0",
"external-editor": "^3.0.3",
@@ -8908,17 +8907,18 @@
}
},
"node_modules/pac-proxy-agent": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-6.0.3.tgz",
- "integrity": "sha512-5Hr1KgPDoc21Vn3rsXBirwwDnF/iac1jN/zkpsOYruyT+ZgsUhUOgVwq3v9+ukjZd/yGm/0nzO1fDfl7rkGoHQ==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz",
+ "integrity": "sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==",
"dev": true,
"dependencies": {
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
"agent-base": "^7.0.2",
"debug": "^4.3.4",
"get-uri": "^6.0.1",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.0",
- "pac-resolver": "^6.0.1",
+ "pac-resolver": "^7.0.0",
"socks-proxy-agent": "^8.0.1"
},
"engines": {
@@ -8926,12 +8926,12 @@
}
},
"node_modules/pac-resolver": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-6.0.2.tgz",
- "integrity": "sha512-EQpuJ2ifOjpZY5sg1Q1ZeAxvtLwR7Mj3RgY8cysPGbsRu3RBXyJFWxnMus9PScjxya/0LzvVDxNh/gl0eXBU4w==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
+ "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
"dev": true,
"dependencies": {
- "degenerator": "^4.0.4",
+ "degenerator": "^5.0.0",
"ip": "^1.1.8",
"netmask": "^2.0.2"
},
@@ -9280,9 +9280,9 @@
}
},
"node_modules/proxy-agent": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.2.1.tgz",
- "integrity": "sha512-OIbBKlRAT+ycCm6wAYIzMwPejzRtjy8F3QiDX0eKOA3e4pe3U9F/IvzcHP42bmgQxVv97juG+J8/gx+JIeCX/Q==",
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz",
+ "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==",
"dev": true,
"dependencies": {
"agent-base": "^7.0.2",
@@ -9290,7 +9290,7 @@
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.0",
"lru-cache": "^7.14.1",
- "pac-proxy-agent": "^6.0.3",
+ "pac-proxy-agent": "^7.0.0",
"proxy-from-env": "^1.1.0",
"socks-proxy-agent": "^8.0.1"
},
@@ -9703,21 +9703,21 @@
}
},
"node_modules/release-it": {
- "version": "15.11.0",
- "resolved": "https://registry.npmjs.org/release-it/-/release-it-15.11.0.tgz",
- "integrity": "sha512-lZwoGEnKYKwGnfxxlA7vtR7vvozPrOSsIgQaHO4bgQ5ARbG3IA6Dmo0IVusv6nR1KmnjH70QIeNAgsWs6Ji/tw==",
+ "version": "16.1.3",
+ "resolved": "https://registry.npmjs.org/release-it/-/release-it-16.1.3.tgz",
+ "integrity": "sha512-NoK3gxOcAtnmp9tz9pbq+IgMFTaPly/B8FWzKObOAGDl5BAC5BDcbWqr3lXyjlLqI+vd/NtO6tQIduIlpNLALg==",
"dev": true,
"dependencies": {
"@iarna/toml": "2.2.5",
- "@octokit/rest": "19.0.11",
+ "@octokit/rest": "19.0.13",
"async-retry": "1.3.3",
- "chalk": "5.2.0",
- "cosmiconfig": "8.1.3",
+ "chalk": "5.3.0",
+ "cosmiconfig": "8.2.0",
"execa": "7.1.1",
"git-url-parse": "13.1.0",
- "globby": "13.1.4",
- "got": "12.6.1",
- "inquirer": "9.2.6",
+ "globby": "13.2.2",
+ "got": "13.0.0",
+ "inquirer": "9.2.8",
"is-ci": "3.0.1",
"issue-parser": "6.0.0",
"lodash": "4.17.21",
@@ -9728,8 +9728,8 @@
"ora": "6.3.1",
"os-name": "5.1.0",
"promise.allsettled": "1.0.6",
- "proxy-agent": "6.2.1",
- "semver": "7.5.1",
+ "proxy-agent": "6.3.0",
+ "semver": "7.5.4",
"shelljs": "0.8.5",
"update-notifier": "6.0.2",
"url-join": "5.0.0",
@@ -9740,7 +9740,7 @@
"release-it": "bin/release-it.js"
},
"engines": {
- "node": ">=14.9"
+ "node": ">=16"
}
},
"node_modules/release-it/node_modules/@octokit/openapi-types": {
@@ -9790,9 +9790,9 @@
}
},
"node_modules/release-it/node_modules/@octokit/rest": {
- "version": "19.0.11",
- "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz",
- "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==",
+ "version": "19.0.13",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
+ "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
"dev": true,
"dependencies": {
"@octokit/core": "^4.2.1",
@@ -9814,9 +9814,9 @@
}
},
"node_modules/release-it/node_modules/chalk": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz",
- "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
"dev": true,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
@@ -9825,24 +9825,6 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
- "node_modules/release-it/node_modules/cosmiconfig": {
- "version": "8.1.3",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz",
- "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==",
- "dev": true,
- "dependencies": {
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/d-fischer"
- }
- },
"node_modules/release-it/node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
@@ -9876,14 +9858,14 @@
}
},
"node_modules/release-it/node_modules/globby": {
- "version": "13.1.4",
- "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz",
- "integrity": "sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==",
+ "version": "13.2.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
+ "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
"dev": true,
"dependencies": {
"dir-glob": "^3.0.1",
- "fast-glob": "^3.2.11",
- "ignore": "^5.2.0",
+ "fast-glob": "^3.3.0",
+ "ignore": "^5.2.4",
"merge2": "^1.4.1",
"slash": "^4.0.0"
},
@@ -9894,6 +9876,31 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/release-it/node_modules/got": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz",
+ "integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^5.2.0",
+ "@szmarczak/http-timer": "^5.0.1",
+ "cacheable-lookup": "^7.0.0",
+ "cacheable-request": "^10.2.8",
+ "decompress-response": "^6.0.0",
+ "form-data-encoder": "^2.1.2",
+ "get-stream": "^6.0.1",
+ "http2-wrapper": "^2.1.10",
+ "lowercase-keys": "^3.0.0",
+ "p-cancelable": "^3.0.0",
+ "responselike": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/got?sponsor=1"
+ }
+ },
"node_modules/release-it/node_modules/human-signals": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
@@ -9988,9 +9995,9 @@
}
},
"node_modules/release-it/node_modules/semver": {
- "version": "7.5.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
- "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -10283,9 +10290,9 @@
"dev": true
},
"node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -11389,22 +11396,6 @@
"node": ">= 0.8"
}
},
- "node_modules/vm2": {
- "version": "3.9.19",
- "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz",
- "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==",
- "dev": true,
- "dependencies": {
- "acorn": "^8.7.0",
- "acorn-walk": "^8.2.0"
- },
- "bin": {
- "vm2": "bin/vm2"
- },
- "engines": {
- "node": ">=6.0"
- }
- },
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@@ -13271,15 +13262,15 @@
}
},
"@release-it/conventional-changelog": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-5.1.1.tgz",
- "integrity": "sha512-QtbDBe36dQfzexAfDYrbLPvd5Cb5bMWmLcjcGhCOWBss7fe1/gCjoxDULVz+7N7G5Nu2UMeBwHcUp/w8RDh5VQ==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-7.0.0.tgz",
+ "integrity": "sha512-DBzyVS6c4g8w+xomCsygkmLeQBUq41Wvzy0vGgbdCLOxYnwI0cDaF6HOLPkrifH1qLa1uJ9i1pYA+hNyHkNanQ==",
"dev": true,
"requires": {
"concat-stream": "^2.0.0",
- "conventional-changelog": "^3.1.25",
- "conventional-recommended-bump": "^6.1.0",
- "semver": "7.3.8"
+ "conventional-changelog": "^4.0.0",
+ "conventional-recommended-bump": "^7.0.1",
+ "semver": "7.5.1"
}
},
"@sinclair/typebox": {
@@ -13321,6 +13312,12 @@
"defer-to-connect": "^2.0.1"
}
},
+ "@tootallnate/quickjs-emscripten": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
+ "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
+ "dev": true
+ },
"@tsconfig/node10": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
@@ -14430,33 +14427,40 @@
"dev": true
},
"conventional-changelog": {
- "version": "3.1.25",
- "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz",
- "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-4.0.0.tgz",
+ "integrity": "sha512-JbZjwE1PzxQCvm+HUTIr+pbSekS8qdOZzMakdFyPtdkEWwFvwEJYONzjgMm0txCb2yBcIcfKDmg8xtCKTdecNQ==",
"dev": true,
"requires": {
- "conventional-changelog-angular": "^5.0.12",
- "conventional-changelog-atom": "^2.0.8",
- "conventional-changelog-codemirror": "^2.0.8",
- "conventional-changelog-conventionalcommits": "^4.5.0",
- "conventional-changelog-core": "^4.2.1",
- "conventional-changelog-ember": "^2.0.9",
- "conventional-changelog-eslint": "^3.0.9",
- "conventional-changelog-express": "^2.0.6",
- "conventional-changelog-jquery": "^3.0.11",
- "conventional-changelog-jshint": "^2.0.9",
- "conventional-changelog-preset-loader": "^2.3.4"
+ "conventional-changelog-angular": "^6.0.0",
+ "conventional-changelog-atom": "^3.0.0",
+ "conventional-changelog-codemirror": "^3.0.0",
+ "conventional-changelog-conventionalcommits": "^6.0.0",
+ "conventional-changelog-core": "^5.0.0",
+ "conventional-changelog-ember": "^3.0.0",
+ "conventional-changelog-eslint": "^4.0.0",
+ "conventional-changelog-express": "^3.0.0",
+ "conventional-changelog-jquery": "^4.0.0",
+ "conventional-changelog-jshint": "^3.0.0",
+ "conventional-changelog-preset-loader": "^3.0.0"
},
"dependencies": {
- "conventional-changelog-conventionalcommits": {
- "version": "4.6.3",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz",
- "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==",
+ "conventional-changelog-angular": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz",
+ "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==",
"dev": true,
"requires": {
- "compare-func": "^2.0.0",
- "lodash": "^4.17.15",
- "q": "^1.5.1"
+ "compare-func": "^2.0.0"
+ }
+ },
+ "conventional-changelog-conventionalcommits": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz",
+ "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==",
+ "dev": true,
+ "requires": {
+ "compare-func": "^2.0.0"
}
}
}
@@ -14472,22 +14476,16 @@
}
},
"conventional-changelog-atom": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz",
- "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==",
- "dev": true,
- "requires": {
- "q": "^1.5.1"
- }
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-3.0.0.tgz",
+ "integrity": "sha512-pnN5bWpH+iTUWU3FaYdw5lJmfWeqSyrUkG+wyHBI9tC1dLNnHkbAOg1SzTQ7zBqiFrfo55h40VsGXWMdopwc5g==",
+ "dev": true
},
"conventional-changelog-codemirror": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz",
- "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==",
- "dev": true,
- "requires": {
- "q": "^1.5.1"
- }
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-3.0.0.tgz",
+ "integrity": "sha512-wzchZt9HEaAZrenZAUUHMCFcuYzGoZ1wG/kTRMICxsnW5AXohYMRxnyecP9ob42Gvn5TilhC0q66AtTPRSNMfw==",
+ "dev": true
},
"conventional-changelog-conventionalcommits": {
"version": "5.0.0",
@@ -14501,27 +14499,36 @@
}
},
"conventional-changelog-core": {
- "version": "4.2.4",
- "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz",
- "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.2.tgz",
+ "integrity": "sha512-RhQOcDweXNWvlRwUDCpaqXzbZemKPKncCWZG50Alth72WITVd6nhVk9MJ6w1k9PFNBcZ3YwkdkChE+8+ZwtUug==",
"dev": true,
"requires": {
"add-stream": "^1.0.0",
- "conventional-changelog-writer": "^5.0.0",
- "conventional-commits-parser": "^3.2.0",
- "dateformat": "^3.0.0",
- "get-pkg-repo": "^4.0.0",
- "git-raw-commits": "^2.0.8",
+ "conventional-changelog-writer": "^6.0.0",
+ "conventional-commits-parser": "^4.0.0",
+ "dateformat": "^3.0.3",
+ "get-pkg-repo": "^4.2.1",
+ "git-raw-commits": "^3.0.0",
"git-remote-origin-url": "^2.0.0",
- "git-semver-tags": "^4.1.1",
- "lodash": "^4.17.15",
- "normalize-package-data": "^3.0.0",
- "q": "^1.5.1",
+ "git-semver-tags": "^5.0.0",
+ "normalize-package-data": "^3.0.3",
"read-pkg": "^3.0.0",
- "read-pkg-up": "^3.0.0",
- "through2": "^4.0.0"
+ "read-pkg-up": "^3.0.0"
},
"dependencies": {
+ "conventional-commits-parser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
+ "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "dev": true,
+ "requires": {
+ "is-text-path": "^1.0.1",
+ "JSONStream": "^1.3.5",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ }
+ },
"find-up": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
@@ -14531,6 +14538,17 @@
"locate-path": "^2.0.0"
}
},
+ "git-raw-commits": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
+ "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "dev": true,
+ "requires": {
+ "dargs": "^7.0.0",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ }
+ },
"hosted-git-info": {
"version": "2.8.9",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
@@ -14628,98 +14646,75 @@
}
},
"semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true
}
}
},
"conventional-changelog-ember": {
- "version": "2.0.9",
- "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz",
- "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==",
- "dev": true,
- "requires": {
- "q": "^1.5.1"
- }
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-3.0.0.tgz",
+ "integrity": "sha512-7PYthCoSxIS98vWhVcSphMYM322OxptpKAuHYdVspryI0ooLDehRXWeRWgN+zWSBXKl/pwdgAg8IpLNSM1/61A==",
+ "dev": true
},
"conventional-changelog-eslint": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz",
- "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==",
- "dev": true,
- "requires": {
- "q": "^1.5.1"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-4.0.0.tgz",
+ "integrity": "sha512-nEZ9byP89hIU0dMx37JXQkE1IpMmqKtsaR24X7aM3L6Yy/uAtbb+ogqthuNYJkeO1HyvK7JsX84z8649hvp43Q==",
+ "dev": true
},
"conventional-changelog-express": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz",
- "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==",
- "dev": true,
- "requires": {
- "q": "^1.5.1"
- }
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-3.0.0.tgz",
+ "integrity": "sha512-HqxihpUMfIuxvlPvC6HltA4ZktQEUan/v3XQ77+/zbu8No/fqK3rxSZaYeHYant7zRxQNIIli7S+qLS9tX9zQA==",
+ "dev": true
},
"conventional-changelog-jquery": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz",
- "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==",
- "dev": true,
- "requires": {
- "q": "^1.5.1"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-4.0.0.tgz",
+ "integrity": "sha512-TTIN5CyzRMf8PUwyy4IOLmLV2DFmPtasKN+x7EQKzwSX8086XYwo+NeaeA3VUT8bvKaIy5z/JoWUvi7huUOgaw==",
+ "dev": true
},
"conventional-changelog-jshint": {
- "version": "2.0.9",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz",
- "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-3.0.0.tgz",
+ "integrity": "sha512-bQof4byF4q+n+dwFRkJ/jGf9dCNUv4/kCDcjeCizBvfF81TeimPZBB6fT4HYbXgxxfxWXNl/i+J6T0nI4by6DA==",
"dev": true,
"requires": {
- "compare-func": "^2.0.0",
- "q": "^1.5.1"
+ "compare-func": "^2.0.0"
}
},
"conventional-changelog-preset-loader": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz",
- "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz",
+ "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==",
"dev": true
},
"conventional-changelog-writer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz",
- "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz",
+ "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==",
"dev": true,
"requires": {
- "conventional-commits-filter": "^2.0.7",
- "dateformat": "^3.0.0",
+ "conventional-commits-filter": "^3.0.0",
+ "dateformat": "^3.0.3",
"handlebars": "^4.7.7",
"json-stringify-safe": "^5.0.1",
- "lodash": "^4.17.15",
- "meow": "^8.0.0",
- "semver": "^6.0.0",
- "split": "^1.0.0",
- "through2": "^4.0.0"
- },
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true
- }
+ "meow": "^8.1.2",
+ "semver": "^7.0.0",
+ "split": "^1.0.1"
}
},
"conventional-commits-filter": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz",
- "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz",
+ "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==",
"dev": true,
"requires": {
"lodash.ismatch": "^4.4.0",
- "modify-values": "^1.0.0"
+ "modify-values": "^1.0.1"
}
},
"conventional-commits-parser": {
@@ -14737,19 +14732,43 @@
}
},
"conventional-recommended-bump": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz",
- "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz",
+ "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==",
"dev": true,
"requires": {
"concat-stream": "^2.0.0",
- "conventional-changelog-preset-loader": "^2.3.4",
- "conventional-commits-filter": "^2.0.7",
- "conventional-commits-parser": "^3.2.0",
- "git-raw-commits": "^2.0.8",
- "git-semver-tags": "^4.1.1",
- "meow": "^8.0.0",
- "q": "^1.5.1"
+ "conventional-changelog-preset-loader": "^3.0.0",
+ "conventional-commits-filter": "^3.0.0",
+ "conventional-commits-parser": "^4.0.0",
+ "git-raw-commits": "^3.0.0",
+ "git-semver-tags": "^5.0.0",
+ "meow": "^8.1.2"
+ },
+ "dependencies": {
+ "conventional-commits-parser": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
+ "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "dev": true,
+ "requires": {
+ "is-text-path": "^1.0.1",
+ "JSONStream": "^1.3.5",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ }
+ },
+ "git-raw-commits": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
+ "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "dev": true,
+ "requires": {
+ "dargs": "^7.0.0",
+ "meow": "^8.1.2",
+ "split2": "^3.2.2"
+ }
+ }
}
},
"convert-source-map": {
@@ -15041,15 +15060,14 @@
}
},
"degenerator": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-4.0.4.tgz",
- "integrity": "sha512-MTZdZsuNxSBL92rsjx3VFWe57OpRlikyLbcx2B5Dmdv6oScqpMrvpY7zHLMymrUxo3U5+suPUMsNgW/+SZB1lg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
+ "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
"dev": true,
"requires": {
"ast-types": "^0.13.4",
- "escodegen": "^1.14.3",
- "esprima": "^4.0.1",
- "vm2": "^3.9.19"
+ "escodegen": "^2.1.0",
+ "esprima": "^4.0.1"
}
},
"delayed-stream": {
@@ -15272,56 +15290,22 @@
"dev": true
},
"escodegen": {
- "version": "1.14.3",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
- "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
"dev": true,
"requires": {
"esprima": "^4.0.1",
- "estraverse": "^4.2.0",
+ "estraverse": "^5.2.0",
"esutils": "^2.0.2",
- "optionator": "^0.8.1",
"source-map": "~0.6.1"
},
"dependencies": {
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
- "dev": true,
- "requires": {
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2"
- }
- },
- "optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha512-oCOQ8AIC2ciLy/sE2ehafRBleBgDLvzGhBRRev87sP7ovnbvQfqpc3XFI0DhHey2OfVoNV91W+GPC6B3540/5Q==",
- "dev": true,
- "requires": {
- "deep-is": "~0.1.3",
- "fast-levenshtein": "~2.0.4",
- "levn": "~0.3.0",
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2",
- "wordwrap": "~1.0.0"
- }
- },
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
"dev": true
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
- "dev": true,
- "requires": {
- "prelude-ls": "~1.1.2"
- }
}
}
},
@@ -15620,9 +15604,9 @@
"dev": true
},
"fast-glob": {
- "version": "3.2.12",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
- "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
+ "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
"dev": true,
"requires": {
"@nodelib/fs.stat": "^2.0.2",
@@ -15934,9 +15918,9 @@
"dev": true
},
"readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"dev": true,
"requires": {
"core-util-is": "~1.0.0",
@@ -16076,21 +16060,13 @@
}
},
"git-semver-tags": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz",
- "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz",
+ "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==",
"dev": true,
"requires": {
- "meow": "^8.0.0",
- "semver": "^6.0.0"
- },
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "dev": true
- }
+ "meow": "^8.1.2",
+ "semver": "^7.0.0"
}
},
"git-up": {
@@ -16368,9 +16344,9 @@
"integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg=="
},
"https-proxy-agent": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.0.tgz",
- "integrity": "sha512-0euwPCRyAPSgGdzD1IVN9nJYHtBhJwb6XPfbpQcYbPCwrBidX6GzxmchnaF4sfF/jPb74Ojx5g4yTg3sixlyPw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz",
+ "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==",
"dev": true,
"requires": {
"agent-base": "^7.0.2",
@@ -16405,9 +16381,9 @@
"dev": true
},
"ignore": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.1.tgz",
- "integrity": "sha512-d2qQLzTJ9WxQftPAuEQpSPmKqzxePjzVbpAVv62AQ64NTL+wR4JkrVqR/LqFsFEUsHDAiId52mJteHDFuDkElA==",
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true
},
"import-fresh": {
@@ -16471,13 +16447,13 @@
"dev": true
},
"inquirer": {
- "version": "9.2.6",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.6.tgz",
- "integrity": "sha512-y71l237eJJKS4rl7sQcEUiMhrR0pB/ZnRMMTxLpjJhWL4hdWCT03a6jJnC1w6qIPSRZWEozuieGt3v7XaEJYFw==",
+ "version": "9.2.8",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-9.2.8.tgz",
+ "integrity": "sha512-SJ0fVfgIzZL1AD6WvFhivlh5/3hN6WeAvpvPrpPXH/8MOcQHeXhinmSm5CDJNRC2Q+sLh9YJ5k8F8/5APMXSfw==",
"dev": true,
"requires": {
"ansi-escapes": "^4.3.2",
- "chalk": "^5.2.0",
+ "chalk": "^5.3.0",
"cli-cursor": "^3.1.0",
"cli-width": "^4.0.0",
"external-editor": "^3.0.3",
@@ -18334,27 +18310,28 @@
"dev": true
},
"pac-proxy-agent": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-6.0.3.tgz",
- "integrity": "sha512-5Hr1KgPDoc21Vn3rsXBirwwDnF/iac1jN/zkpsOYruyT+ZgsUhUOgVwq3v9+ukjZd/yGm/0nzO1fDfl7rkGoHQ==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz",
+ "integrity": "sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==",
"dev": true,
"requires": {
+ "@tootallnate/quickjs-emscripten": "^0.23.0",
"agent-base": "^7.0.2",
"debug": "^4.3.4",
"get-uri": "^6.0.1",
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.0",
- "pac-resolver": "^6.0.1",
+ "pac-resolver": "^7.0.0",
"socks-proxy-agent": "^8.0.1"
}
},
"pac-resolver": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-6.0.2.tgz",
- "integrity": "sha512-EQpuJ2ifOjpZY5sg1Q1ZeAxvtLwR7Mj3RgY8cysPGbsRu3RBXyJFWxnMus9PScjxya/0LzvVDxNh/gl0eXBU4w==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
+ "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
"dev": true,
"requires": {
- "degenerator": "^4.0.4",
+ "degenerator": "^5.0.0",
"ip": "^1.1.8",
"netmask": "^2.0.2"
}
@@ -18617,9 +18594,9 @@
}
},
"proxy-agent": {
- "version": "6.2.1",
- "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.2.1.tgz",
- "integrity": "sha512-OIbBKlRAT+ycCm6wAYIzMwPejzRtjy8F3QiDX0eKOA3e4pe3U9F/IvzcHP42bmgQxVv97juG+J8/gx+JIeCX/Q==",
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz",
+ "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==",
"dev": true,
"requires": {
"agent-base": "^7.0.2",
@@ -18627,7 +18604,7 @@
"http-proxy-agent": "^7.0.0",
"https-proxy-agent": "^7.0.0",
"lru-cache": "^7.14.1",
- "pac-proxy-agent": "^6.0.3",
+ "pac-proxy-agent": "^7.0.0",
"proxy-from-env": "^1.1.0",
"socks-proxy-agent": "^8.0.1"
},
@@ -18918,21 +18895,21 @@
}
},
"release-it": {
- "version": "15.11.0",
- "resolved": "https://registry.npmjs.org/release-it/-/release-it-15.11.0.tgz",
- "integrity": "sha512-lZwoGEnKYKwGnfxxlA7vtR7vvozPrOSsIgQaHO4bgQ5ARbG3IA6Dmo0IVusv6nR1KmnjH70QIeNAgsWs6Ji/tw==",
+ "version": "16.1.3",
+ "resolved": "https://registry.npmjs.org/release-it/-/release-it-16.1.3.tgz",
+ "integrity": "sha512-NoK3gxOcAtnmp9tz9pbq+IgMFTaPly/B8FWzKObOAGDl5BAC5BDcbWqr3lXyjlLqI+vd/NtO6tQIduIlpNLALg==",
"dev": true,
"requires": {
"@iarna/toml": "2.2.5",
- "@octokit/rest": "19.0.11",
+ "@octokit/rest": "19.0.13",
"async-retry": "1.3.3",
- "chalk": "5.2.0",
- "cosmiconfig": "8.1.3",
+ "chalk": "5.3.0",
+ "cosmiconfig": "8.2.0",
"execa": "7.1.1",
"git-url-parse": "13.1.0",
- "globby": "13.1.4",
- "got": "12.6.1",
- "inquirer": "9.2.6",
+ "globby": "13.2.2",
+ "got": "13.0.0",
+ "inquirer": "9.2.8",
"is-ci": "3.0.1",
"issue-parser": "6.0.0",
"lodash": "4.17.21",
@@ -18943,8 +18920,8 @@
"ora": "6.3.1",
"os-name": "5.1.0",
"promise.allsettled": "1.0.6",
- "proxy-agent": "6.2.1",
- "semver": "7.5.1",
+ "proxy-agent": "6.3.0",
+ "semver": "7.5.4",
"shelljs": "0.8.5",
"update-notifier": "6.0.2",
"url-join": "5.0.0",
@@ -18989,9 +18966,9 @@
}
},
"@octokit/rest": {
- "version": "19.0.11",
- "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz",
- "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==",
+ "version": "19.0.13",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.13.tgz",
+ "integrity": "sha512-/EzVox5V9gYGdbAI+ovYj3nXQT1TtTHRT+0eZPcuC05UFSWO3mdO9UY1C0i2eLF9Un1ONJkAk+IEtYGAC+TahA==",
"dev": true,
"requires": {
"@octokit/core": "^4.2.1",
@@ -19010,23 +18987,11 @@
}
},
"chalk": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz",
- "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
"dev": true
},
- "cosmiconfig": {
- "version": "8.1.3",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz",
- "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==",
- "dev": true,
- "requires": {
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.0.0",
- "path-type": "^4.0.0"
- }
- },
"data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
@@ -19051,18 +19016,37 @@
}
},
"globby": {
- "version": "13.1.4",
- "resolved": "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz",
- "integrity": "sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==",
+ "version": "13.2.2",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
+ "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
"dev": true,
"requires": {
"dir-glob": "^3.0.1",
- "fast-glob": "^3.2.11",
- "ignore": "^5.2.0",
+ "fast-glob": "^3.3.0",
+ "ignore": "^5.2.4",
"merge2": "^1.4.1",
"slash": "^4.0.0"
}
},
+ "got": {
+ "version": "13.0.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-13.0.0.tgz",
+ "integrity": "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^5.2.0",
+ "@szmarczak/http-timer": "^5.0.1",
+ "cacheable-lookup": "^7.0.0",
+ "cacheable-request": "^10.2.8",
+ "decompress-response": "^6.0.0",
+ "form-data-encoder": "^2.1.2",
+ "get-stream": "^6.0.1",
+ "http2-wrapper": "^2.1.10",
+ "lowercase-keys": "^3.0.0",
+ "p-cancelable": "^3.0.0",
+ "responselike": "^3.0.0"
+ }
+ },
"human-signals": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
@@ -19117,9 +19101,9 @@
"dev": true
},
"semver": {
- "version": "7.5.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
- "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -19311,9 +19295,9 @@
"dev": true
},
"semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -20123,16 +20107,6 @@
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"dev": true
},
- "vm2": {
- "version": "3.9.19",
- "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.9.19.tgz",
- "integrity": "sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==",
- "dev": true,
- "requires": {
- "acorn": "^8.7.0",
- "acorn-walk": "^8.2.0"
- }
- },
"walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
diff --git a/package.json b/package.json
index b92c1a6..974ac19 100644
--- a/package.json
+++ b/package.json
@@ -54,7 +54,8 @@
"@commitlint/config-conventional": "^17.4.0",
"@gitbeaker/rest": "^39.1.0",
"@kie/mock-github": "^1.1.0",
- "@release-it/conventional-changelog": "^5.1.1",
+ "@octokit/webhooks-types": "^6.8.0",
+ "@release-it/conventional-changelog": "^7.0.0",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.2.4",
"@types/node": "^18.11.17",
@@ -65,14 +66,13 @@
"husky": "^8.0.2",
"jest": "^29.0.0",
"jest-sonar-reporter": "^2.0.0",
- "release-it": "^15.6.0",
+ "release-it": "^16.1.3",
"semver": "^7.3.8",
"ts-jest": "^29.0.0",
"ts-node": "^10.8.1",
"tsc-alias": "^1.8.2",
"tsconfig-paths": "^4.1.0",
- "typescript": "^4.9.3",
- "@octokit/webhooks-types": "^6.8.0"
+ "typescript": "^4.9.3"
},
"dependencies": {
"@actions/core": "^1.10.0",
From e13d1fbf00601240d82cd2164cdf6667a157449d Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 20 Jul 2023 15:45:17 +0200
Subject: [PATCH 14/75] docs: update readme
---
README.md | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 32955ae..15d8d58 100644
--- a/README.md
+++ b/README.md
@@ -14,10 +14,6 @@
---
-## :bangbang: Starting from v4 git-backporting has been moved under @kiegroup organization :bangbang:
-
----
-
**Git Backporting** is a [NodeJS](https://nodejs.org/) command line tool that provides capabilities to *backport* pull requests (on *GitHub*) and merge requests (on *GitLab*) in an automated way. This tool also comes with a predefined *GitHub* action in order to make CI/CD integration easier for all users.
@@ -43,14 +39,14 @@ Therefore this tools is for anybody who is working on projects where they have t
## CLI tool
+> All instructions provided below pertain to version `v4` of the tool. If you wish to use an earlier version, we strongly encourage you to consider migrating to version `v4` as there are no valid reason to keep using older versions. Please refer to [Migrating to v4](#migrating-to-v4) section for comprehensive details on how to properly migrate to version `v4`.
+
This tool is released on the [public npm registry](https://www.npmjs.com/), therefore it can be easily installed using `npm`:
```bash
$ npm install -g @kie/git-backporting
```
-> **NOTE**: if you want to download version 3 or older you must use the older package name `@lampajr/bper` instead of `@kie/git-backporting`.
-
Then you just have to choose the pull request (or merge request on *Gitlab*) that you would like to backport and the target branch and the simply run the following command:
```bash
@@ -64,8 +60,6 @@ $ git-backporting -tb develop -pr https://github.com/kiegroup/git-backporting-ex
This is the easiest invocation where you let the tool set / compute most of the backported pull request data. Obviously most of that data can be overridden with appropriate tool options, more details can be found in the [inputs](#inputs) section.
-> **NOTE**: if you are still using version 3 or older you must use the older CLI tool name `bper` instead of `git-backporting`.
-
### Requirements
* Node 16 or higher, more details on Node can be found [here](https://nodejs.org/en).
@@ -235,7 +229,7 @@ For a complete description of all inputs see [Inputs section](#inputs).
## Migrating to v4
-From version `v4.0.0` the project has been moved under [@kiegroup](https://github.com/kiegroup) organization. During this migration we changed some things that you should be aware of. I'll try to summarize them in the following table:
+From version `v4` the project has been moved under [@kiegroup](https://github.com/kiegroup) organization. During this migration we changed some things that you should be aware of. I'll try to summarize them in the following table:
> **NOTE**: these changes did not affect the tool features.
@@ -246,9 +240,9 @@ From version `v4.0.0` the project has been moved under [@kiegroup](https://githu
| NPM package | @kie/git-backporting | @lampajr/bper |
| CLI tool | git-backporting | bper |
-So everytime you would use older version keep in mind of these changes.
+So everytime you would use older version keep in mind that these changes are madnatory to make the tool working.
-> **REMARK**: since from capabilities point of view `v3.1.1` and `v4.0.0` are equivalent we would recommend to directly start using `v4`.
+> **NOTE**: Versions `v3.1.1` and `v4.0.0` offer identical features; the only distinction lies in the project's renaming and organization movement.
## Development
From 10a46551ee6855bec529aa45b494c1d5058235a1 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 27 Jul 2023 11:26:39 +0200
Subject: [PATCH 15/75] refactor: move backport data generation to configs
parser
---
dist/cli/index.js | 48 +++---
dist/gha/index.js | 48 +++---
src/service/configs/configs.types.ts | 4 +-
.../configs/pullrequest/pr-configs-parser.ts | 25 ++-
src/service/git/git-client.ts | 1 +
src/service/git/git.types.ts | 7 +-
src/service/git/gitlab/gitlab-client.ts | 1 -
src/service/runner/runner.ts | 33 +---
.../github-pr-configs-parser.test.ts | 155 +++++-------------
.../gitlab-pr-configs-parser.test.ts | 145 ++++++----------
test/service/git/gitlab/gitlab-client.test.ts | 41 +++++
test/service/runner/cli-github-runner.test.ts | 14 +-
test/service/runner/cli-gitlab-runner.test.ts | 8 +
test/service/runner/gha-github-runner.test.ts | 10 ++
test/service/runner/gha-gitlab-runner.test.ts | 8 +
15 files changed, 238 insertions(+), 310 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index b39241d..4d4cb2b 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -336,16 +336,27 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (args.inheritLabels) {
labels.push(...originalPullRequest.labels);
}
+ let backportBranch = args.bpBranchName;
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${args.targetBranch}-${concatenatedCommits}`;
+ }
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
return {
- author: args.gitUser ?? this.gitClient.getDefaultGitUser(),
+ owner: originalPullRequest.targetRepo.owner,
+ repo: originalPullRequest.targetRepo.project,
+ head: backportBranch,
+ base: args.targetBranch,
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
body: `${bodyPrefix}${body}`,
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- targetRepo: originalPullRequest.targetRepo,
- sourceRepo: originalPullRequest.targetRepo,
- branchName: args.bpBranchName,
+ comments: [], // TODO fix comments
};
}
}
@@ -1211,17 +1222,7 @@ class Runner {
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- let backportBranch = backportPR.branchName;
- if (backportBranch === undefined || backportBranch.trim() === "") {
- // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
- const concatenatedCommits = originalPR.commits.map(c => c.slice(0, 7)).join("-");
- backportBranch = `bp-${configs.targetBranch}-${concatenatedCommits}`;
- }
- if (backportBranch.length > 250) {
- this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
- backportBranch = backportBranch.slice(0, 250);
- }
- await git.createLocalBranch(configs.folder, backportBranch);
+ await git.createLocalBranch(configs.folder, backportPR.head);
// 6. fetch pull request remote if source owner != target owner or pull request still open
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
@@ -1234,27 +1235,16 @@ class Runner {
for (const sha of originalPR.commits) {
await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
- const backport = {
- owner: originalPR.targetRepo.owner,
- repo: originalPR.targetRepo.project,
- head: backportBranch,
- base: configs.targetBranch,
- title: backportPR.title,
- body: backportPR.body,
- reviewers: backportPR.reviewers,
- assignees: backportPR.assignees,
- labels: backportPR.labels,
- };
if (!configs.dryRun) {
// 8. push the new branch to origin
- await git.push(configs.folder, backportBranch);
+ await git.push(configs.folder, backportPR.head);
// 9. create pull request new branch -> target branch (using octokit)
- const prUrl = await gitApi.createPullRequest(backport);
+ const prUrl = await gitApi.createPullRequest(backportPR);
this.logger.info(`Pull request created: ${prUrl}`);
}
else {
this.logger.warn("Pull request creation and remote push skipped");
- this.logger.info(`${JSON.stringify(backport, null, 2)}`);
+ this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
}
}
}
diff --git a/dist/gha/index.js b/dist/gha/index.js
index cf28269..c89d340 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -307,16 +307,27 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (args.inheritLabels) {
labels.push(...originalPullRequest.labels);
}
+ let backportBranch = args.bpBranchName;
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${args.targetBranch}-${concatenatedCommits}`;
+ }
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
return {
- author: args.gitUser ?? this.gitClient.getDefaultGitUser(),
+ owner: originalPullRequest.targetRepo.owner,
+ repo: originalPullRequest.targetRepo.project,
+ head: backportBranch,
+ base: args.targetBranch,
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
body: `${bodyPrefix}${body}`,
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- targetRepo: originalPullRequest.targetRepo,
- sourceRepo: originalPullRequest.targetRepo,
- branchName: args.bpBranchName,
+ comments: [], // TODO fix comments
};
}
}
@@ -1182,17 +1193,7 @@ class Runner {
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- let backportBranch = backportPR.branchName;
- if (backportBranch === undefined || backportBranch.trim() === "") {
- // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
- const concatenatedCommits = originalPR.commits.map(c => c.slice(0, 7)).join("-");
- backportBranch = `bp-${configs.targetBranch}-${concatenatedCommits}`;
- }
- if (backportBranch.length > 250) {
- this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
- backportBranch = backportBranch.slice(0, 250);
- }
- await git.createLocalBranch(configs.folder, backportBranch);
+ await git.createLocalBranch(configs.folder, backportPR.head);
// 6. fetch pull request remote if source owner != target owner or pull request still open
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
@@ -1205,27 +1206,16 @@ class Runner {
for (const sha of originalPR.commits) {
await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
- const backport = {
- owner: originalPR.targetRepo.owner,
- repo: originalPR.targetRepo.project,
- head: backportBranch,
- base: configs.targetBranch,
- title: backportPR.title,
- body: backportPR.body,
- reviewers: backportPR.reviewers,
- assignees: backportPR.assignees,
- labels: backportPR.labels,
- };
if (!configs.dryRun) {
// 8. push the new branch to origin
- await git.push(configs.folder, backportBranch);
+ await git.push(configs.folder, backportPR.head);
// 9. create pull request new branch -> target branch (using octokit)
- const prUrl = await gitApi.createPullRequest(backport);
+ const prUrl = await gitApi.createPullRequest(backportPR);
this.logger.info(`Pull request created: ${prUrl}`);
}
else {
this.logger.warn("Pull request creation and remote push skipped");
- this.logger.info(`${JSON.stringify(backport, null, 2)}`);
+ this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
}
}
}
diff --git a/src/service/configs/configs.types.ts b/src/service/configs/configs.types.ts
index 0f82cfc..be46157 100644
--- a/src/service/configs/configs.types.ts
+++ b/src/service/configs/configs.types.ts
@@ -1,6 +1,6 @@
-import { GitPullRequest } from "@bp/service/git/git.types";
+import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
export interface LocalGit {
user: string, // local git user
@@ -19,6 +19,6 @@ export interface Configs {
mergeStrategy?: string, // cherry-pick merge strategy
mergeStrategyOption?: string, // cherry-pick merge strategy option
originalPullRequest: GitPullRequest,
- backportPullRequest: GitPullRequest,
+ backportPullRequest: BackportPullRequest,
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index d83d9cd..4eb1111 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -3,7 +3,7 @@ import ConfigsParser from "@bp/service/configs/configs-parser";
import { Configs } from "@bp/service/configs/configs.types";
import GitClient from "@bp/service/git/git-client";
import GitClientFactory from "@bp/service/git/git-client-factory";
-import { GitPullRequest } from "@bp/service/git/git.types";
+import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
export default class PullRequestConfigsParser extends ConfigsParser {
@@ -52,7 +52,7 @@ export default class PullRequestConfigsParser extends ConfigsParser {
* @param targetBranch target branch where the backport should be applied
* @returns {GitPullRequest}
*/
- private getDefaultBackportPullRequest(originalPullRequest: GitPullRequest, args: Args): GitPullRequest {
+ private getDefaultBackportPullRequest(originalPullRequest: GitPullRequest, args: Args): BackportPullRequest {
const reviewers = args.reviewers ?? [];
if (reviewers.length == 0 && args.inheritReviewers) {
// inherit only if args.reviewers is empty and args.inheritReviewers set to true
@@ -70,16 +70,29 @@ export default class PullRequestConfigsParser extends ConfigsParser {
labels.push(...originalPullRequest.labels);
}
+ let backportBranch = args.bpBranchName;
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits: string = originalPullRequest.commits!.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${args.targetBranch}-${concatenatedCommits}`;
+ }
+
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
+
return {
- author: args.gitUser ?? this.gitClient.getDefaultGitUser(),
+ owner: originalPullRequest.targetRepo.owner,
+ repo: originalPullRequest.targetRepo.project,
+ head: backportBranch,
+ base: args.targetBranch,
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
body: `${bodyPrefix}${body}`,
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- targetRepo: originalPullRequest.targetRepo,
- sourceRepo: originalPullRequest.targetRepo,
- branchName: args.bpBranchName,
+ comments: [], // TODO fix comments
};
}
}
\ No newline at end of file
diff --git a/src/service/git/git-client.ts b/src/service/git/git-client.ts
index b14f603..7b98c1b 100644
--- a/src/service/git/git-client.ts
+++ b/src/service/git/git-client.ts
@@ -38,4 +38,5 @@ import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
* @returns {Promise} the pull request url
*/
createPullRequest(backport: BackportPullRequest): Promise;
+
}
\ No newline at end of file
diff --git a/src/service/git/git.types.ts b/src/service/git/git.types.ts
index 4ca5405..6370eee 100644
--- a/src/service/git/git.types.ts
+++ b/src/service/git/git.types.ts
@@ -13,8 +13,8 @@ export interface GitPullRequest {
labels: string[],
targetRepo: GitRepository,
sourceRepo: GitRepository,
- nCommits?: number, // number of commits in the pr
- commits?: string[], // merge commit or last one
+ nCommits: number, // number of commits in the pr
+ commits: string[], // merge commit or last one
branchName?: string,
}
@@ -34,7 +34,8 @@ export interface BackportPullRequest {
reviewers: string[], // pr list of reviewers
assignees: string[], // pr list of assignees
labels: string[], // pr list of assigned labels
- branchName?: string,
+ comments: string[], // pr list of additional comments
+ // branchName?: string,
}
export enum GitClientType {
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index 725eacb..af4c626 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -141,7 +141,6 @@ export default class GitLabClient implements GitClient {
return mr.web_url;
}
-
/**
* Retrieve a gitlab user given its username
* @param username
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index 2ad5364..e5d0db0 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -63,7 +63,7 @@ export default class Runner {
this.logger.debug("Parsing configs..");
const configs: Configs = await new PullRequestConfigsParser().parseAndValidate(args);
const originalPR: GitPullRequest = configs.originalPullRequest;
- const backportPR: GitPullRequest = configs.backportPullRequest;
+ const backportPR: BackportPullRequest = configs.backportPullRequest;
// start local git operations
const git: GitCLIService = new GitCLIService(configs.auth, configs.git);
@@ -74,19 +74,8 @@ export default class Runner {
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- let backportBranch = backportPR.branchName;
- if (backportBranch === undefined || backportBranch.trim() === "") {
- // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
- const concatenatedCommits: string = originalPR.commits!.map(c => c.slice(0, 7)).join("-");
- backportBranch = `bp-${configs.targetBranch}-${concatenatedCommits}`;
- }
- if (backportBranch.length > 250) {
- this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
- backportBranch = backportBranch.slice(0, 250);
- }
-
- await git.createLocalBranch(configs.folder, backportBranch);
+ await git.createLocalBranch(configs.folder, backportPR.head);
// 6. fetch pull request remote if source owner != target owner or pull request still open
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
@@ -102,29 +91,17 @@ export default class Runner {
await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
- const backport: BackportPullRequest = {
- owner: originalPR.targetRepo.owner,
- repo: originalPR.targetRepo.project,
- head: backportBranch,
- base: configs.targetBranch,
- title: backportPR.title,
- body: backportPR.body,
- reviewers: backportPR.reviewers,
- assignees: backportPR.assignees,
- labels: backportPR.labels,
- };
-
if (!configs.dryRun) {
// 8. push the new branch to origin
- await git.push(configs.folder, backportBranch);
+ await git.push(configs.folder, backportPR.head);
// 9. create pull request new branch -> target branch (using octokit)
- const prUrl = await gitApi.createPullRequest(backport);
+ const prUrl = await gitApi.createPullRequest(backportPR);
this.logger.info(`Pull request created: ${prUrl}`);
} else {
this.logger.warn("Pull request creation and remote push skipped");
- this.logger.info(`${JSON.stringify(backport, null, 2)}`);
+ this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
}
}
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 950c01f..ce432b9 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -129,25 +129,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]
});
expect(configs.backportPullRequest).toEqual({
- author: "GitHub",
- url: undefined,
- htmlUrl: undefined,
- title: "[prod] PR Title",
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
+ title: "[prod] 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: [],
- 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,
+ comments: [],
});
});
@@ -264,6 +255,7 @@ describe("github pull request config parser", () => {
reviewers: [],
assignees: [],
inheritReviewers: true,
+ bpBranchName: "custom-branch"
};
const configs: Configs = await configParser.parseAndValidate(args);
@@ -309,25 +301,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
- 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,
+ comments: [],
});
});
@@ -390,25 +373,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
- 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,
+ comments: [],
});
});
@@ -471,25 +445,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
labels: [],
- 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,
+ comments: [],
});
});
@@ -554,25 +519,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
labels: ["custom-label", "original-label"],
- 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,
+ comments: [],
});
});
@@ -625,25 +581,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]
});
expect(configs.backportPullRequest).toEqual({
- author: "GitHub",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
title: "[prod] 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: [],
- 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,
+ comments: [],
});
});
@@ -697,25 +644,16 @@ describe("github pull request config parser", () => {
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: ["cherry-pick :cherries:", "original-label"],
- 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,
+ comments: [],
});
});
@@ -775,25 +713,16 @@ describe("github pull request config parser", () => {
commits: ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"]
});
expect(configs.backportPullRequest).toEqual({
- author: "GitHub",
- url: undefined,
- htmlUrl: undefined,
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-0404fb9-11da4e3",
+ base: "prod",
title: "[prod] PR Title",
body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
- 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,
+ comments: [],
});
});
});
\ No newline at end of file
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 8e10d17..8eb269b 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -129,25 +129,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Gitlab",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "[prod] Update test.txt",
body: "**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1\r\n\r\nThis is the body",
reviewers: ["superuser"],
assignees: [],
labels: [],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -314,25 +305,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["superuser"],
assignees: [],
labels: [],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -394,25 +376,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -474,25 +447,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
labels: [],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -556,25 +520,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
labels: ["custom-label", "gitlab-original-label"],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -626,25 +581,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Gitlab",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "[prod] Update test.txt",
body: "**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1\r\n\r\nThis is the body",
reviewers: ["superuser"],
assignees: [],
labels: [],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -696,25 +642,16 @@ describe("gitlab merge request config parser", () => {
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
- author: "Me",
- url: undefined,
- htmlUrl: undefined,
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
labels: ["cherry-pick :cherries:", "gitlab-original-label"],
- targetRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- sourceRepo: {
- owner: "superuser",
- project: "backporting-example",
- cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
- },
- bpBranchName: undefined,
+ comments: [],
});
});
@@ -773,5 +710,17 @@ describe("gitlab merge request config parser", () => {
nCommits: 2,
commits: ["e4dd336a4a20f394df6665994df382fb1d193a11", "974519f65c9e0ed65277cd71026657a09fca05e7"]
});
+ expect(configs.backportPullRequest).toEqual({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-e4dd336-974519f",
+ base: "prod",
+ title: "[prod] Update test.txt opened",
+ body: "**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2\r\n\r\nStill opened mr body",
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ });
});
});
\ No newline at end of file
diff --git a/test/service/git/gitlab/gitlab-client.test.ts b/test/service/git/gitlab/gitlab-client.test.ts
index affe096..c4f4816 100644
--- a/test/service/git/gitlab/gitlab-client.test.ts
+++ b/test/service/git/gitlab/gitlab-client.test.ts
@@ -89,6 +89,7 @@ describe("github service", () => {
reviewers: [],
assignees: [],
labels: [],
+ comments: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -119,6 +120,7 @@ describe("github service", () => {
reviewers: ["superuser", "invalid"],
assignees: [],
labels: [],
+ comments: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -154,6 +156,7 @@ describe("github service", () => {
reviewers: [],
assignees: ["superuser", "invalid"],
labels: [],
+ comments: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -189,6 +192,7 @@ describe("github service", () => {
reviewers: ["superuser", "invalid"],
assignees: [],
labels: [],
+ comments: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -224,6 +228,7 @@ describe("github service", () => {
reviewers: [],
assignees: ["superuser", "invalid"],
labels: [],
+ comments: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -259,6 +264,7 @@ describe("github service", () => {
reviewers: [],
assignees: [],
labels: ["label1", "label2"],
+ comments: [],
};
const url: string = await gitClient.createPullRequest(backport);
@@ -280,4 +286,39 @@ describe("github service", () => {
labels: "label1,label2",
});
});
+
+ test("create backport pull request with post comments", async () => {
+ const backport: BackportPullRequest = {
+ title: "Backport Title",
+ body: "Backport Body",
+ owner: "superuser",
+ repo: "backporting-example",
+ base: "old/branch",
+ head: "bp-branch-2",
+ reviewers: [],
+ assignees: [],
+ labels: [],
+ comments: ["this is first comment", "this is second comment"],
+ };
+
+ const url: string = await gitClient.createPullRequest(backport);
+ expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
+
+ // check axios invocation
+ expect(axiosInstanceSpy.post).toBeCalledTimes(1);
+ expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
+ source_branch: "bp-branch-2",
+ target_branch: "old/branch",
+ title: "Backport Title",
+ description: "Backport Body",
+ reviewer_ids: [],
+ assignee_ids: [],
+ }));
+ expect(axiosInstanceSpy.get).toBeCalledTimes(0);
+ // FIXME
+ // expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just comments
+ // expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
+ // labels: "label1,label2",
+ // });
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index f70d446..3aa82ef 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -233,6 +233,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -277,6 +278,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -333,6 +335,7 @@ describe("cli runner", () => {
reviewers: ["gh-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -390,6 +393,7 @@ describe("cli runner", () => {
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -446,6 +450,7 @@ describe("cli runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -494,11 +499,12 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: ["cherry-pick :cherries:", "original-label"],
+ comments: [],
}
);
});
- test("set custom lables without inheritance", async () => {
+ test("set custom labels without inheritance", async () => {
addProcessArgs([
"-tb",
"target",
@@ -541,6 +547,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: ["first-label", "second-label"],
+ comments: [],
}
);
});
@@ -584,6 +591,7 @@ describe("cli runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: ["cli github cherry pick :cherries:", "original-label"],
+ comments: [],
}
);
});
@@ -630,6 +638,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -676,6 +685,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -728,6 +738,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -778,6 +789,7 @@ describe("cli runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index c13be27..ab6f72b 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -181,6 +181,7 @@ describe("cli runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -238,6 +239,7 @@ describe("cli runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -296,6 +298,7 @@ describe("cli runner", () => {
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -352,6 +355,7 @@ describe("cli runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -401,6 +405,7 @@ describe("cli runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: ["cherry-pick :cherries:", "another-label", "gitlab-original-label"],
+ comments: [],
}
);
});
@@ -449,6 +454,7 @@ describe("cli runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: ["cherry-pick :cherries:", "another-label"],
+ comments: [],
}
);
});
@@ -493,6 +499,7 @@ describe("cli runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: ["cli gitlab cherry pick :cherries:", "gitlab-original-label"],
+ comments: [],
}
);
});
@@ -540,6 +547,7 @@ describe("cli runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 69de6d0..1f412ba 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -125,6 +125,7 @@ describe("gha runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -177,6 +178,7 @@ describe("gha runner", () => {
reviewers: ["gh-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -226,6 +228,7 @@ describe("gha runner", () => {
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -276,6 +279,7 @@ describe("gha runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -321,6 +325,7 @@ describe("gha runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: ["cherry-pick :cherries:", "another-label", "original-label"],
+ comments: [],
}
);
});
@@ -366,6 +371,7 @@ describe("gha runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: ["cherry-pick :cherries:", "another-label"],
+ comments: [],
}
);
});
@@ -408,6 +414,7 @@ describe("gha runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: ["gha github cherry pick :cherries:", "original-label"],
+ comments: [],
}
);
});
@@ -452,6 +459,7 @@ describe("gha runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -496,6 +504,7 @@ describe("gha runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -541,6 +550,7 @@ describe("gha runner", () => {
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 4610cee..8158818 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -136,6 +136,7 @@ describe("gha runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -187,6 +188,7 @@ describe("gha runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
@@ -236,6 +238,7 @@ describe("gha runner", () => {
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -286,6 +289,7 @@ describe("gha runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: [],
+ comments: [],
}
);
});
@@ -330,6 +334,7 @@ describe("gha runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: ["cherry-pick :cherries:", "another-label", "gitlab-original-label"],
+ comments: [],
}
);
});
@@ -373,6 +378,7 @@ describe("gha runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: ["cherry-pick :cherries:", "another-label"],
+ comments: [],
}
);
});
@@ -416,6 +422,7 @@ describe("gha runner", () => {
reviewers: [],
assignees: ["user3", "user4"],
labels: ["gha gitlab cherry pick :cherries:", "gitlab-original-label"],
+ comments: [],
}
);
});
@@ -461,6 +468,7 @@ describe("gha runner", () => {
reviewers: ["superuser"],
assignees: [],
labels: [],
+ comments: [],
}
);
});
From bed7e29ddc1ba5498faa2c7cc33ec3b127947dcf Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 27 Jul 2023 12:31:04 +0200
Subject: [PATCH 16/75] feat(issue-70): additional pr comments
---
README.md | 1 +
action.yml | 3 +
dist/cli/index.js | 32 +++++++-
dist/gha/index.js | 31 +++++++-
src/service/args/args-parser.ts | 1 +
src/service/args/args-utils.ts | 6 ++
src/service/args/args.types.ts | 1 +
src/service/args/cli/cli-args-parser.ts | 4 +-
src/service/args/gha/gha-args-parser.ts | 3 +-
.../configs/pullrequest/pr-configs-parser.ts | 2 +-
src/service/git/github/github-client.ts | 13 ++++
src/service/git/gitlab/gitlab-client.ts | 12 +++
test/service/args/cli/cli-args-parser.test.ts | 31 ++++++++
test/service/args/gha/gha-args-parser.test.ts | 26 +++++++
.../github-pr-configs-parser.test.ts | 75 +++++++++++++++++++
.../gitlab-pr-configs-parser.test.ts | 74 ++++++++++++++++++
test/service/git/gitlab/gitlab-client.test.ts | 14 ++--
test/service/runner/cli-github-runner.test.ts | 47 ++++++++++++
test/service/runner/gha-github-runner.test.ts | 45 +++++++++++
test/support/mock/git-client-mock-support.ts | 19 ++++-
20 files changed, 424 insertions(+), 16 deletions(-)
diff --git a/README.md b/README.md
index 15d8d58..1988232 100644
--- a/README.md
+++ b/README.md
@@ -113,6 +113,7 @@ This tool comes with some inputs that allow users to override the default behavi
| No squash | --no-squash | N | If provided the backporting will try to backport all pull request commits without squashing | false |
| 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" |
+| Additional comments | --comments | N | Semicolon separated list of additional comments to be posted to the backported pull request | [] |
| Dry Run | -d, --dry-run | N | If enabled the tool does not push nor create anything remotely, use this to skip PR creation | false |
> **NOTE**: `pull request` and `target branch` are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
diff --git a/action.yml b/action.yml
index 90bc2d5..5deca80 100644
--- a/action.yml
+++ b/action.yml
@@ -67,6 +67,9 @@ inputs:
description: "Cherry-pick merge strategy option"
required: false
default: "theirs"
+ comments:
+ description: "Semicolon separated list of additional comments to be posted to the backported pull request"
+ required: false
runs:
using: node16
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 4d4cb2b..87e057f 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -63,6 +63,7 @@ class ArgsParser {
squash: this.getOrDefault(args.squash, true),
strategy: this.getOrDefault(args.strategy),
strategyOption: this.getOrDefault(args.strategyOption),
+ comments: this.getOrDefault(args.comments)
};
}
}
@@ -100,7 +101,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.getAsBooleanOrDefault = exports.getAsCommaSeparatedList = exports.getAsCleanedCommaSeparatedList = exports.getOrUndefined = exports.readConfigFile = exports.parseArgs = void 0;
+exports.getAsBooleanOrDefault = exports.getAsSemicolonSeparatedList = exports.getAsCommaSeparatedList = exports.getAsCleanedCommaSeparatedList = exports.getOrUndefined = exports.readConfigFile = exports.parseArgs = void 0;
const fs = __importStar(__nccwpck_require__(7147));
/**
* Parse the input configuation string as json object and
@@ -145,6 +146,12 @@ function getAsCommaSeparatedList(value) {
return trimmed !== "" ? trimmed.split(",").map(v => v.trim()) : undefined;
}
exports.getAsCommaSeparatedList = getAsCommaSeparatedList;
+function getAsSemicolonSeparatedList(value) {
+ // trim the value
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.split(";").map(v => v.trim()) : undefined;
+}
+exports.getAsSemicolonSeparatedList = getAsSemicolonSeparatedList;
function getAsBooleanOrDefault(value) {
const trimmed = value.trim();
return trimmed !== "" ? trimmed.toLowerCase() === "true" : undefined;
@@ -191,6 +198,7 @@ class CLIArgsParser extends args_parser_1.default {
.option("--no-squash", "if provided the tool will backport all commits as part of the pull request")
.option("--strategy ", "cherry-pick merge strategy, default to 'recursive'", undefined)
.option("--strategy-option ", "cherry-pick merge strategy option, default to 'theirs'")
+ .option("--comments ", "semicolon separated list of additional comments to be posted to the backported pull request", args_utils_1.getAsSemicolonSeparatedList)
.option("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
readArgs() {
@@ -223,6 +231,7 @@ class CLIArgsParser extends args_parser_1.default {
squash: opts.squash,
strategy: opts.strategy,
strategyOption: opts.strategyOption,
+ comments: opts.comments,
};
}
return args;
@@ -356,7 +365,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- comments: [], // TODO fix comments
+ comments: args.comments ?? [],
};
}
}
@@ -721,6 +730,16 @@ class GitHubClient {
assignees: backport.assignees,
}).catch(error => this.logger.error(`Error setting assignees: ${error}`)));
}
+ if (backport.comments.length > 0) {
+ backport.comments.forEach(c => {
+ promises.push(this.octokit.issues.createComment({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ body: c,
+ }).catch(error => this.logger.error(`Error posting comment: ${error}`)));
+ });
+ }
await Promise.all(promises);
return data.html_url;
}
@@ -917,6 +936,15 @@ class GitLabClient {
labels: backport.labels.join(","),
}).catch(error => this.logger.warn("Failure trying to update labels. " + error)));
}
+ // comments
+ if (backport.comments.length > 0) {
+ this.logger.info("Posting comments: " + backport.comments);
+ backport.comments.forEach(c => {
+ promises.push(this.client.post(`/projects/${projectId}/merge_requests/${mr.iid}/notes`, {
+ body: c,
+ }).catch(error => this.logger.warn("Failure trying to post comment. " + error)));
+ });
+ }
// reviewers
const reviewerIds = await Promise.all(backport.reviewers.map(async (r) => {
this.logger.debug("Retrieving user: " + r);
diff --git a/dist/gha/index.js b/dist/gha/index.js
index c89d340..a4d41a2 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -63,6 +63,7 @@ class ArgsParser {
squash: this.getOrDefault(args.squash, true),
strategy: this.getOrDefault(args.strategy),
strategyOption: this.getOrDefault(args.strategyOption),
+ comments: this.getOrDefault(args.comments)
};
}
}
@@ -100,7 +101,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result;
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.getAsBooleanOrDefault = exports.getAsCommaSeparatedList = exports.getAsCleanedCommaSeparatedList = exports.getOrUndefined = exports.readConfigFile = exports.parseArgs = void 0;
+exports.getAsBooleanOrDefault = exports.getAsSemicolonSeparatedList = exports.getAsCommaSeparatedList = exports.getAsCleanedCommaSeparatedList = exports.getOrUndefined = exports.readConfigFile = exports.parseArgs = void 0;
const fs = __importStar(__nccwpck_require__(7147));
/**
* Parse the input configuation string as json object and
@@ -145,6 +146,12 @@ function getAsCommaSeparatedList(value) {
return trimmed !== "" ? trimmed.split(",").map(v => v.trim()) : undefined;
}
exports.getAsCommaSeparatedList = getAsCommaSeparatedList;
+function getAsSemicolonSeparatedList(value) {
+ // trim the value
+ const trimmed = value.trim();
+ return trimmed !== "" ? trimmed.split(";").map(v => v.trim()) : undefined;
+}
+exports.getAsSemicolonSeparatedList = getAsSemicolonSeparatedList;
function getAsBooleanOrDefault(value) {
const trimmed = value.trim();
return trimmed !== "" ? trimmed.toLowerCase() === "true" : undefined;
@@ -194,6 +201,7 @@ class GHAArgsParser extends args_parser_1.default {
squash: !(0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("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")),
+ comments: (0, args_utils_1.getAsSemicolonSeparatedList)((0, core_1.getInput)("comments")),
};
}
return args;
@@ -327,7 +335,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- comments: [], // TODO fix comments
+ comments: args.comments ?? [],
};
}
}
@@ -692,6 +700,16 @@ class GitHubClient {
assignees: backport.assignees,
}).catch(error => this.logger.error(`Error setting assignees: ${error}`)));
}
+ if (backport.comments.length > 0) {
+ backport.comments.forEach(c => {
+ promises.push(this.octokit.issues.createComment({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: data.number,
+ body: c,
+ }).catch(error => this.logger.error(`Error posting comment: ${error}`)));
+ });
+ }
await Promise.all(promises);
return data.html_url;
}
@@ -888,6 +906,15 @@ class GitLabClient {
labels: backport.labels.join(","),
}).catch(error => this.logger.warn("Failure trying to update labels. " + error)));
}
+ // comments
+ if (backport.comments.length > 0) {
+ this.logger.info("Posting comments: " + backport.comments);
+ backport.comments.forEach(c => {
+ promises.push(this.client.post(`/projects/${projectId}/merge_requests/${mr.iid}/notes`, {
+ body: c,
+ }).catch(error => this.logger.warn("Failure trying to post comment. " + error)));
+ });
+ }
// reviewers
const reviewerIds = await Promise.all(backport.reviewers.map(async (r) => {
this.logger.debug("Retrieving user: " + r);
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index d70fa27..5aee4a6 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -41,6 +41,7 @@ export default abstract class ArgsParser {
squash: this.getOrDefault(args.squash, true),
strategy: this.getOrDefault(args.strategy),
strategyOption: this.getOrDefault(args.strategyOption),
+ comments: this.getOrDefault(args.comments)
};
}
}
\ No newline at end of file
diff --git a/src/service/args/args-utils.ts b/src/service/args/args-utils.ts
index 13a3606..9f6165c 100644
--- a/src/service/args/args-utils.ts
+++ b/src/service/args/args-utils.ts
@@ -44,6 +44,12 @@ export function getAsCommaSeparatedList(value: string): string[] | undefined {
return trimmed !== "" ? trimmed.split(",").map(v => v.trim()) : undefined;
}
+export function getAsSemicolonSeparatedList(value: string): string[] | undefined {
+ // trim the value
+ const trimmed: string = value.trim();
+ return trimmed !== "" ? trimmed.split(";").map(v => v.trim()) : undefined;
+}
+
export function getAsBooleanOrDefault(value: string): boolean | undefined {
const trimmed = value.trim();
return trimmed !== "" ? trimmed.toLowerCase() === "true" : undefined;
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index b3c1860..880257c 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -21,4 +21,5 @@ export interface Args {
squash?: boolean, // if false use squashed/merged commit otherwise backport all commits as part of the pr
strategy?: string, // cherry-pick merge strategy
strategyOption?: string, // cherry-pick merge strategy option
+ comments?: string[], // additional comments to be posted
}
\ 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 a6065dc..0e8b4e3 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -2,7 +2,7 @@ import ArgsParser from "@bp/service/args/args-parser";
import { Args } from "@bp/service/args/args.types";
import { Command } from "commander";
import { name, version, description } from "@bp/../package.json";
-import { getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, readConfigFile } from "@bp/service/args/args-utils";
+import { getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, getAsSemicolonSeparatedList, readConfigFile } from "@bp/service/args/args-utils";
export default class CLIArgsParser extends ArgsParser {
@@ -29,6 +29,7 @@ export default class CLIArgsParser extends ArgsParser {
.option("--no-squash", "if provided the tool will backport all commits as part of the pull request")
.option("--strategy ", "cherry-pick merge strategy, default to 'recursive'", undefined)
.option("--strategy-option ", "cherry-pick merge strategy option, default to 'theirs'")
+ .option("--comments ", "semicolon separated list of additional comments to be posted to the backported pull request", getAsSemicolonSeparatedList)
.option("-cf, --config-file ", "configuration file containing all valid options, the json must match Args interface");
}
@@ -62,6 +63,7 @@ export default class CLIArgsParser extends ArgsParser {
squash: opts.squash,
strategy: opts.strategy,
strategyOption: opts.strategyOption,
+ comments: opts.comments,
};
}
diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts
index e3d5ba0..a6c2534 100644
--- a/src/service/args/gha/gha-args-parser.ts
+++ b/src/service/args/gha/gha-args-parser.ts
@@ -1,7 +1,7 @@
import ArgsParser from "@bp/service/args/args-parser";
import { Args } from "@bp/service/args/args.types";
import { getInput } from "@actions/core";
-import { getAsBooleanOrDefault, getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, getOrUndefined, readConfigFile } from "@bp/service/args/args-utils";
+import { getAsBooleanOrDefault, getAsCleanedCommaSeparatedList, getAsCommaSeparatedList, getAsSemicolonSeparatedList, getOrUndefined, readConfigFile } from "@bp/service/args/args-utils";
export default class GHAArgsParser extends ArgsParser {
@@ -32,6 +32,7 @@ export default class GHAArgsParser extends ArgsParser {
squash: !getAsBooleanOrDefault(getInput("no-squash")),
strategy: getOrUndefined(getInput("strategy")),
strategyOption: getOrUndefined(getInput("strategy-option")),
+ comments: getAsSemicolonSeparatedList(getInput("comments")),
};
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 4eb1111..3cc81ce 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -92,7 +92,7 @@ export default class PullRequestConfigsParser extends ConfigsParser {
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- comments: [], // TODO fix comments
+ comments: args.comments ?? [],
};
}
}
\ No newline at end of file
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index 0da22df..297052d 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -117,6 +117,19 @@ export default class GitHubClient implements GitClient {
);
}
+ if (backport.comments.length > 0) {
+ backport.comments.forEach(c => {
+ promises.push(
+ this.octokit.issues.createComment({
+ owner: backport.owner,
+ repo: backport.repo,
+ issue_number: (data as PullRequest).number,
+ body: c,
+ }).catch(error => this.logger.error(`Error posting comment: ${error}`))
+ );
+ });
+ }
+
await Promise.all(promises);
return data.html_url;
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index af4c626..a6d21b8 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -96,6 +96,18 @@ export default class GitLabClient implements GitClient {
);
}
+ // comments
+ if (backport.comments.length > 0) {
+ this.logger.info("Posting comments: " + backport.comments);
+ backport.comments.forEach(c => {
+ promises.push(
+ this.client.post(`/projects/${projectId}/merge_requests/${mr.iid}/notes`, {
+ body: c,
+ }).catch(error => this.logger.warn("Failure trying to post comment. " + error))
+ );
+ });
+ }
+
// reviewers
const reviewerIds = await Promise.all(backport.reviewers.map(async r => {
this.logger.debug("Retrieving user: " + r);
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index 4f64187..2951bf3 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -402,4 +402,35 @@ describe("cli args parser", () => {
expect(args.strategy).toEqual("ort");
expect(args.strategyOption).toEqual("ours");
});
+
+ test("additional pr comments", () => {
+ addProcessArgs([
+ "--target-branch",
+ "target",
+ "--pull-request",
+ "https://localhost/whatever/pulls/1",
+ "--comments",
+ "first comment;second comment",
+ ]);
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ 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);
+ expect(args.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
+ expectArrayEqual(args.comments!,["first comment", "second comment"]);
+ });
});
\ 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 ebe6e81..76efa13 100644
--- a/test/service/args/gha/gha-args-parser.test.ts
+++ b/test/service/args/gha/gha-args-parser.test.ts
@@ -236,4 +236,30 @@ describe("gha args parser", () => {
expect(args.strategy).toEqual("ort");
expect(args.strategyOption).toEqual("ours");
});
+
+ test("additional pr comments", () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://localhost/whatever/pulls/1",
+ "comments": "first comment;second comment",
+ });
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ 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.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
+ expectArrayEqual(args.comments!,["first comment", "second comment"]);
+ });
});
\ No newline at end of file
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 ce432b9..bca5d75 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -725,4 +725,79 @@ describe("github pull request config parser", () => {
comments: [],
});
});
+
+ test("override backport pr with additional comments", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: ["First comment", "Second comment"],
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.git).toEqual({
+ user: "Me",
+ email: "me@email.com"
+ });
+ 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"],
+ assignees: [],
+ labels: ["original-label"],
+ 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({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: ["First comment", "Second comment"],
+ });
+ });
});
\ No newline at end of file
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 8eb269b..691f061 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -723,4 +723,78 @@ describe("gitlab merge request config parser", () => {
comments: [],
});
});
+
+ test("override backport pr with additional comments", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: ["First comment", "Second comment"],
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.git).toEqual({
+ user: "Me",
+ email: "me@email.com"
+ });
+ expect(configs.auth).toEqual("");
+ expect(configs.targetBranch).toEqual("prod");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.originalPullRequest).toEqual({
+ number: 1,
+ author: "superuser",
+ url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ state: "merged",
+ merged: true,
+ mergedBy: "superuser",
+ title: "Update test.txt",
+ body: "This is the body",
+ reviewers: ["superuser1", "superuser2"],
+ assignees: ["superuser"],
+ labels: ["gitlab-original-label"],
+ targetRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ sourceRepo: {
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
+ },
+ nCommits: 1,
+ commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
+ });
+ expect(configs.backportPullRequest).toEqual({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-prod-ebb1eca",
+ base: "prod",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: ["First comment", "Second comment"],
+ });
+ });
});
\ No newline at end of file
diff --git a/test/service/git/gitlab/gitlab-client.test.ts b/test/service/git/gitlab/gitlab-client.test.ts
index c4f4816..57aa125 100644
--- a/test/service/git/gitlab/gitlab-client.test.ts
+++ b/test/service/git/gitlab/gitlab-client.test.ts
@@ -305,7 +305,7 @@ describe("github service", () => {
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
// check axios invocation
- expect(axiosInstanceSpy.post).toBeCalledTimes(1);
+ expect(axiosInstanceSpy.post).toBeCalledTimes(3); // also comments
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch-2",
target_branch: "old/branch",
@@ -315,10 +315,12 @@ describe("github service", () => {
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(0);
- // FIXME
- // expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just comments
- // expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
- // labels: "label1,label2",
- // });
+
+ expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID + "/notes", {
+ body: "this is first comment",
+ });
+ expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID + "/notes", {
+ body: "this is second comment",
+ });
});
});
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 3aa82ef..27c78aa 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -793,4 +793,51 @@ describe("cli runner", () => {
}
);
});
+
+ test("additional pr comments", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/8632",
+ "--comments",
+ "first comment; second comment"
+ ]);
+
+ 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-28f63db");
+
+ expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ comments: ["first comment", "second comment"],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 1f412ba..44e11a3 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -554,4 +554,49 @@ describe("gha runner", () => {
}
);
});
+
+ test("additional pr comments", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://github.com/owner/reponame/pull/2368",
+ "comments": "first comment; second comment",
+ });
+
+ 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-28f63db");
+
+ 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", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-target-28f63db",
+ base: "target",
+ title: "[target] PR Title",
+ body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ comments: ["first comment", "second comment"],
+ }
+ );
+ });
});
\ No newline at end of file
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index 02597f7..e36db5e 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -34,18 +34,24 @@ export const getAxiosMocked = (url: string) => {
export const NEW_GITLAB_MR_ID = 999;
export const SECOND_NEW_GITLAB_MR_ID = 1000;
-export const postAxiosMocked = (_url: string, data?: {source_branch: string,}) => {
+export const postAxiosMocked = async (url: string, data?: {source_branch: string,}) => {
let responseData = undefined;
// gitlab
- if (data?.source_branch === "bp-branch") {
+ if (url.includes("notes")) {
+ // creating comments
+ responseData = {
+ // we do not need the whole response
+ iid: NEW_GITLAB_MR_ID,
+ };
+ } else if (data?.source_branch === "bp-branch") {
responseData = {
// we do not need the whole response
iid: NEW_GITLAB_MR_ID,
web_url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID
};
- } if (data?.source_branch === "bp-branch-2") {
+ } else if (data?.source_branch === "bp-branch-2") {
responseData = {
// we do not need the whole response
iid: SECOND_NEW_GITLAB_MR_ID,
@@ -169,6 +175,13 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
data: {}
});
+ mock.rest.issues
+ .createComment()
+ .reply({
+ status: 201,
+ data: {}
+ });
+
// invalid requests
mock.rest.pulls
.get({
From fa43ffc1dc5572a06309c28e93ee6ab5fba14780 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 27 Jul 2023 15:35:23 +0200
Subject: [PATCH 17/75] fix: preserve new lines in body and comments (#72)
---
.gitignore | 3 +-
action.yml | 8 +++---
dist/cli/index.js | 7 +++--
dist/gha/index.js | 7 +++--
.../configs/pullrequest/pr-configs-parser.ts | 9 +++---
test/service/runner/cli-github-runner.test.ts | 28 ++++++++++---------
test/service/runner/gha-github-runner.test.ts | 20 ++++++-------
7 files changed, 44 insertions(+), 38 deletions(-)
diff --git a/.gitignore b/.gitignore
index f3c41a9..115c77e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,5 @@ build/
.npmrc
# temporary files created during tests
-*test*.json
\ No newline at end of file
+*test*.json
+bp
diff --git a/action.yml b/action.yml
index 5deca80..cb4fd89 100644
--- a/action.yml
+++ b/action.yml
@@ -29,11 +29,11 @@ inputs:
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: `"
+ description: "Backporting PR body prefix. Default is `Backport: `"
+ required: false
+ body:
+ description: "Backporting PR body. Default is the original PR body"
required: false
bp-branch-name:
description: "Backporting PR branch name. Default is auto-generated from commit"
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 87e057f..234f055 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -340,7 +340,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
}
}
const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`;
- const body = args.body ?? `${originalPullRequest.body}`;
+ const body = bodyPrefix + (args.body ?? `${originalPullRequest.body}`);
const labels = args.labels ?? [];
if (args.inheritLabels) {
labels.push(...originalPullRequest.labels);
@@ -361,11 +361,12 @@ class PullRequestConfigsParser extends configs_parser_1.default {
head: backportBranch,
base: args.targetBranch,
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
- body: `${bodyPrefix}${body}`,
+ // preserve new line chars
+ body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- comments: args.comments ?? [],
+ comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
};
}
}
diff --git a/dist/gha/index.js b/dist/gha/index.js
index a4d41a2..c7464fa 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -310,7 +310,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
}
}
const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`;
- const body = args.body ?? `${originalPullRequest.body}`;
+ const body = bodyPrefix + (args.body ?? `${originalPullRequest.body}`);
const labels = args.labels ?? [];
if (args.inheritLabels) {
labels.push(...originalPullRequest.labels);
@@ -331,11 +331,12 @@ class PullRequestConfigsParser extends configs_parser_1.default {
head: backportBranch,
base: args.targetBranch,
title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
- body: `${bodyPrefix}${body}`,
+ // preserve new line chars
+ body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- comments: args.comments ?? [],
+ comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
};
}
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 3cc81ce..39d39e7 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -63,7 +63,7 @@ export default class PullRequestConfigsParser extends ConfigsParser {
}
const bodyPrefix = args.bodyPrefix ?? `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n`;
- const body = args.body ?? `${originalPullRequest.body}`;
+ const body = bodyPrefix + (args.body ?? `${originalPullRequest.body}`);
const labels = args.labels ?? [];
if (args.inheritLabels) {
@@ -87,12 +87,13 @@ export default class PullRequestConfigsParser extends ConfigsParser {
repo: originalPullRequest.targetRepo.project,
head: backportBranch,
base: args.targetBranch,
- title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
- body: `${bodyPrefix}${body}`,
+ title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
+ // preserve new line chars
+ body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
reviewers: [...new Set(reviewers)],
assignees: [...new Set(args.assignees)],
labels: [...new Set(labels)],
- comments: args.comments ?? [],
+ comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
};
}
}
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index 27c78aa..f5ebe36 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -229,7 +229,7 @@ describe("cli runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
@@ -274,7 +274,7 @@ describe("cli runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
@@ -331,7 +331,7 @@ describe("cli runner", () => {
head: "bp-target-9174896",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/4444\r\n\r\nPlease review and merge",
reviewers: ["gh-user"],
assignees: [],
labels: [],
@@ -351,7 +351,7 @@ describe("cli runner", () => {
"--body",
"New Body",
"--body-prefix",
- "New Body Prefix - ",
+ "New Body Prefix\\r\\n\\r\\n",
"--bp-branch-name",
"bp_branch_name",
"--reviewers",
@@ -389,7 +389,7 @@ describe("cli runner", () => {
head: "bp_branch_name",
base: "target",
title: "New Title",
- body: "New Body Prefix - New Body",
+ body: "New Body Prefix\r\n\r\nNew Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
@@ -495,7 +495,7 @@ describe("cli runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: ["cherry-pick :cherries:", "original-label"],
@@ -543,7 +543,7 @@ describe("cli runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: ["first-label", "second-label"],
@@ -634,7 +634,7 @@ describe("cli runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
@@ -681,7 +681,7 @@ describe("cli runner", () => {
head: "bp-target-0404fb9-11da4e3",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
@@ -734,7 +734,7 @@ describe("cli runner", () => {
head: truncatedBranch,
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
@@ -785,7 +785,7 @@ describe("cli runner", () => {
head: "bp-target-0404fb9-11da4e3",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
@@ -801,7 +801,9 @@ describe("cli runner", () => {
"-pr",
"https://github.com/owner/reponame/pull/8632",
"--comments",
- "first comment; second comment"
+ "first comment; second comment",
+ "--body",
+ "New body"
]);
await runner.execute();
@@ -832,7 +834,7 @@ describe("cli runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nNew body",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 44e11a3..44f098b 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -121,7 +121,7 @@ describe("gha runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
@@ -174,7 +174,7 @@ describe("gha runner", () => {
head: "bp-target-9174896",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/4444\r\n\r\nPlease review and merge",
reviewers: ["gh-user"],
assignees: [],
labels: [],
@@ -189,7 +189,7 @@ describe("gha runner", () => {
"pull-request": "https://github.com/owner/reponame/pull/2368",
"title": "New Title",
"body": "New Body",
- "body-prefix": "New Body Prefix - ",
+ "body-prefix": "New Body Prefix\\r\\n\\r\\n",
"bp-branch-name": "bp_branch_name",
"reviewers": "user1, user2",
"assignees": "user3, user4",
@@ -224,7 +224,7 @@ describe("gha runner", () => {
head: "bp_branch_name",
base: "target",
title: "New Title",
- body: "New Body Prefix - New Body",
+ body: "New Body Prefix\r\n\r\nNew Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
labels: [],
@@ -321,7 +321,7 @@ describe("gha runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: ["cherry-pick :cherries:", "another-label", "original-label"],
@@ -367,7 +367,7 @@ describe("gha runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: ["cherry-pick :cherries:", "another-label"],
@@ -455,7 +455,7 @@ describe("gha runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
@@ -500,7 +500,7 @@ describe("gha runner", () => {
head: "bp-target-0404fb9-11da4e3",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"),
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
reviewers: ["gh-user", "that-s-a-user"],
assignees: [],
labels: [],
@@ -546,7 +546,7 @@ describe("gha runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
@@ -591,7 +591,7 @@ describe("gha runner", () => {
head: "bp-target-28f63db",
base: "target",
title: "[target] PR Title",
- body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/2368"),
+ 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: [],
From 29589a63b503b30820a13a442de533239dec06f4 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 27 Jul 2023 17:38:45 +0200
Subject: [PATCH 18/75] fix: gha skip whitespace trim on body (#73)
this also added a github workflow example
---
dist/gha/index.js | 4 +-
examples/on-pr-merge/automated-workflow.yaml | 53 +++++++++++++
examples/on-pr-merge/pr-merge-event.json | 79 ++++++++++++++++++++
src/service/args/gha/gha-args-parser.ts | 4 +-
4 files changed, 136 insertions(+), 4 deletions(-)
create mode 100644 examples/on-pr-merge/automated-workflow.yaml
create mode 100644 examples/on-pr-merge/pr-merge-event.json
diff --git a/dist/gha/index.js b/dist/gha/index.js
index c7464fa..0261515 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -190,8 +190,8 @@ class GHAArgsParser extends args_parser_1.default {
gitUser: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-user")),
gitEmail: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-email")),
title: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("title")),
- body: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("body")),
- bodyPrefix: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("body-prefix")),
+ body: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("body", { trimWhitespace: false })),
+ bodyPrefix: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("body-prefix", { trimWhitespace: false })),
bpBranchName: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("bp-branch-name")),
reviewers: (0, args_utils_1.getAsCleanedCommaSeparatedList)((0, core_1.getInput)("reviewers")),
assignees: (0, args_utils_1.getAsCleanedCommaSeparatedList)((0, core_1.getInput)("assignees")),
diff --git a/examples/on-pr-merge/automated-workflow.yaml b/examples/on-pr-merge/automated-workflow.yaml
new file mode 100644
index 0000000..191a21f
--- /dev/null
+++ b/examples/on-pr-merge/automated-workflow.yaml
@@ -0,0 +1,53 @@
+name: Automated Backporting on PR merge using Git Backporting
+
+on:
+ pull_request_target:
+ types: [closed, labeled]
+ branches:
+ - main
+
+env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+jobs:
+ compute-targets:
+ if: ${{ github.event.pull_request.state == 'closed' && github.event.pull_request.merged }}
+ runs-on: ubuntu-latest
+ outputs:
+ target-branches: ${{ steps.set-targets.outputs.targets }}
+ env:
+ LABELS: ${{ toJSON(github.event.pull_request.labels) }}
+ steps:
+ - name: Set target branches
+ id: set-targets
+ uses: kiegroup/kie-ci/.ci/actions/parse-labels@main
+ with:
+ labels: ${LABELS}
+
+ backporting:
+ if: ${{ github.event.pull_request.state == 'closed' && github.event.pull_request.merged && needs.compute-targets.outputs.target-branches != '[]' }}
+ name: "[${{ matrix.target-branch }}] - Backporting"
+ runs-on: ubuntu-latest
+ needs: compute-targets
+ strategy:
+ matrix:
+ target-branch: ${{ fromJSON(needs.compute-targets.outputs.target-branches) }}
+ fail-fast: true
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - name: Backporting
+ uses: ./
+ with:
+ dry-run: true
+ pull-request: ${{ github.event.pull_request.html_url }}
+ target-branch: ${{ matrix.target-branch }}
+ auth: "${{ env.GITHUB_TOKEN }}"
+ title: "[${{ matrix.target-branch }}] ${{ github.event.pull_request.title }}"
+ body-prefix: "**Backport:** ${{ github.event.pull_request.html_url }}\r\n\r\n**Note**: comment 'ok to test' to properly launch Jenkins jobs\r\n\r\n"
+ body: "${{ github.event.pull_request.body }}"
+ labels: "cherry-pick :cherries:"
+ inherit-labels: false
+ bp-branch-name: "${{ matrix.target-branch }}_${{ github.event.pull_request.head.ref }}"
\ No newline at end of file
diff --git a/examples/on-pr-merge/pr-merge-event.json b/examples/on-pr-merge/pr-merge-event.json
new file mode 100644
index 0000000..a30b31f
--- /dev/null
+++ b/examples/on-pr-merge/pr-merge-event.json
@@ -0,0 +1,79 @@
+{
+ "pull_request": {
+ "url": "https://api.github.com/repos/lampajr/backporting-example/pulls/66",
+ "html_url": "https://github.com/lampajr/backporting-example/pull/66",
+ "diff_url": "https://github.com/lampajr/backporting-example/pull/66.diff",
+ "patch_url": "https://github.com/lampajr/backporting-example/pull/66.patch",
+ "issue_url": "https://api.github.com/repos/lampajr/backporting-example/issues/66",
+ "number": 66,
+ "state": "closed",
+ "title": "Feature1: multiple changes",
+ "user": {
+ "login": "lampajr"
+ },
+ "body": "This is the body of multiple change",
+ "merge_commit_sha": "0bcaa01cdd509ca434e123d2e2b9ce7f66234bd7",
+ "assignee": null,
+ "assignees": [
+
+ ],
+ "requested_reviewers": [
+
+ ],
+ "requested_teams": [
+
+ ],
+ "labels": [
+ {
+ "name": "backport-develop",
+ "color": "AB975B",
+ "default": false,
+ "description": ""
+ }
+ ],
+ "head": {
+ "label": "lampajr:feature1",
+ "ref": "feature1",
+ "sha": "69e49388ea2ca9be272b188a9271806d487bf01e",
+ "user": {
+ "login": "lampajr"
+ },
+ "repo": {
+ "name": "backporting-example",
+ "full_name": "lampajr/backporting-example",
+ "owner": {
+ "login": "lampajr"
+ },
+ "html_url": "https://github.com/lampajr/backporting-example",
+ "clone_url": "https://github.com/lampajr/backporting-example.git"
+ }
+ },
+ "base": {
+ "label": "lampajr:main",
+ "ref": "main",
+ "sha": "c85b8fcdb741814b3e90e6e5729455cf46ff26ea",
+ "user": {
+ "login": "lampajr"
+ },
+ "repo": {
+ "name": "backporting-example",
+ "full_name": "lampajr/backporting-example",
+ "owner": {
+ "login": "lampajr"
+ },
+ "html_url": "https://github.com/lampajr/backporting-example",
+ "description": "Playground repository for automated backporting testing",
+ "url": "https://api.github.com/repos/lampajr/backporting-example",
+ "issues_url": "https://api.github.com/repos/lampajr/backporting-example/issues{/number}",
+ "pulls_url": "https://api.github.com/repos/lampajr/backporting-example/pulls{/number}",
+ "clone_url": "https://github.com/lampajr/backporting-example.git"
+ }
+ },
+ "merged": true,
+ "merged_by": {
+ "login": "lampajr"
+ },
+ "comments": 0,
+ "commits": 2
+ }
+}
\ No newline at end of file
diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts
index a6c2534..29580ab 100644
--- a/src/service/args/gha/gha-args-parser.ts
+++ b/src/service/args/gha/gha-args-parser.ts
@@ -21,8 +21,8 @@ export default class GHAArgsParser extends ArgsParser {
gitUser: getOrUndefined(getInput("git-user")),
gitEmail: getOrUndefined(getInput("git-email")),
title: getOrUndefined(getInput("title")),
- body: getOrUndefined(getInput("body")),
- bodyPrefix: getOrUndefined(getInput("body-prefix")),
+ body: getOrUndefined(getInput("body", { trimWhitespace: false })),
+ bodyPrefix: getOrUndefined(getInput("body-prefix", { trimWhitespace: false })),
bpBranchName: getOrUndefined(getInput("bp-branch-name")),
reviewers: getAsCleanedCommaSeparatedList(getInput("reviewers")),
assignees: getAsCleanedCommaSeparatedList(getInput("assignees")),
From c19a56a9ad85adf9c74df7b416ec47257f1f8e91 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Thu, 27 Jul 2023 17:45:18 +0200
Subject: [PATCH 19/75] chore: release v4.3.0 (#74)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 13 +++++++++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f15525d..154421a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## [4.3.0](https://github.com/kiegroup/git-backporting/compare/v4.2.0...v4.3.0) (2023-07-27)
+
+
+### Features
+
+* **issue-70:** additional pr comments ([bed7e29](https://github.com/kiegroup/git-backporting/commit/bed7e29ddc1ba5498faa2c7cc33ec3b127947dcf))
+
+
+### Bug Fixes
+
+* gha skip whitespace trim on body ([#73](https://github.com/kiegroup/git-backporting/issues/73)) ([29589a6](https://github.com/kiegroup/git-backporting/commit/29589a63b503b30820a13a442de533239dec06f4))
+* preserve new lines in body and comments ([#72](https://github.com/kiegroup/git-backporting/issues/72)) ([fa43ffc](https://github.com/kiegroup/git-backporting/commit/fa43ffc1dc5572a06309c28e93ee6ab5fba14780))
+
## [4.2.0](https://github.com/kiegroup/git-backporting/compare/v4.1.0...v4.2.0) (2023-07-13)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 234f055..e436752 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23443,7 +23443,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.2.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.3.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 99c7a30..bd1b9ad 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.2.0",
+ "version": "4.3.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.2.0",
+ "version": "4.3.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index 974ac19..73b09af 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.2.0",
+ "version": "4.3.0",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From 5fc72e127bedb3177f4e17ff1182827c78154ef1 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 3 Aug 2023 21:57:11 +0200
Subject: [PATCH 20/75] feat(issue-77): handle multiple target branches (#78)
fix: https://github.com/kiegroup/git-backporting/issues/77
This enhancement allow users to backport the same change to multiple
branches with one single tool invocation
---
README.md | 4 +-
action.yml | 4 +-
dist/cli/index.js | 141 ++++--
dist/gha/index.js | 137 ++++--
src/service/args/args-parser.ts | 4 +-
src/service/args/args.types.ts | 8 +-
src/service/args/cli/cli-args-parser.ts | 4 +-
src/service/configs/configs.types.ts | 3 +-
.../configs/pullrequest/pr-configs-parser.ts | 73 +--
src/service/git/git-cli.ts | 8 +-
src/service/logger/console-logger-service.ts | 22 +-
src/service/logger/logger-service.ts | 4 +
src/service/runner/runner.ts | 52 ++-
test/service/args/cli/cli-args-parser.test.ts | 59 +++
test/service/args/gha/gha-args-parser.test.ts | 52 +++
.../github-pr-configs-parser-multiple.test.ts | 422 ++++++++++++++++++
.../github-pr-configs-parser.test.ts | 94 ++--
.../gitlab-pr-configs-parser-multiple.test.ts | 349 +++++++++++++++
.../gitlab-pr-configs-parser.test.ts | 38 +-
test/service/git/git-cli.test.ts | 9 +
test/service/git/github/github-client.test.ts | 4 +-
test/service/runner/cli-github-runner.test.ts | 264 ++++++++++-
test/service/runner/gha-github-runner.test.ts | 166 +++++++
test/support/mock/git-client-mock-support.ts | 67 +--
test/support/mock/github-data.ts | 20 +-
25 files changed, 1774 insertions(+), 234 deletions(-)
create mode 100644 test/service/configs/pullrequest/github-pr-configs-parser-multiple.test.ts
create mode 100644 test/service/configs/pullrequest/gitlab-pr-configs-parser-multiple.test.ts
diff --git a/README.md b/README.md
index 1988232..9ee9fb9 100644
--- a/README.md
+++ b/README.md
@@ -94,7 +94,7 @@ This tool comes with some inputs that allow users to override the default behavi
|---------------|----------------------|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|-------------|
| Version | -V, --version | - | Current version of the tool | |
| Help | -h, --help | - | Display the help message | |
-| Target Branch | -tb, --target-branch | N | Branch where the changes must be backported to | |
+| Target Branches | -tb, --target-branch | N | Comma separated list of branches where the changes must be backported to | |
| Pull Request | -pr, --pull-request | N | Original pull request url, the one that must be backported, e.g., https://github.com/kiegroup/git-backporting/pull/1 | |
| Configuration File | -cf, --config-file | N | Configuration file, in JSON format, containing all options to be overridded, note that if provided all other CLI options will be ignored | |
| Auth | -a, --auth | N | `GITHUB_TOKEN`, `GITLAB_TOKEN` or a `repo` scoped [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) | "" |
@@ -107,7 +107,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Reviewers | --reviewers | N | Backporting pull request comma-separated reviewers list | [] |
| Assignees | --assignes | N | Backporting pull request comma-separated assignees list | [] |
| No Reviewers Inheritance | --no-inherit-reviewers | N | Considered only if reviewers is empty, if true keep reviewers as empty list, otherwise inherit from original pull request | false |
-| Backport Branch Name | --bp-branch-name | N | Name of the backporting pull request branch, if it exceeds 250 chars it will be truncated | bp-{target-branch}-{sha1}...{shaN} |
+| 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 |
diff --git a/action.yml b/action.yml
index cb4fd89..6f69528 100644
--- a/action.yml
+++ b/action.yml
@@ -5,7 +5,7 @@ inputs:
description: "URL of the pull request to backport, e.g., https://github.com/kiegroup/git-backporting/pull/1"
required: false
target-branch:
- description: "Branch where the pull request must be backported to"
+ description: "Comma separated list of branches where the pull request must be backported to"
required: false
config-file:
description: "Path to a file containing the json configuration for this tool, the object must match the Args interface"
@@ -36,7 +36,7 @@ inputs:
description: "Backporting PR body. Default is the original PR body"
required: false
bp-branch-name:
- description: "Backporting PR branch name. Default is auto-generated from commit"
+ description: "Comma separated list of backporting PR branch names. Default is auto-generated from commit and target branches"
required: false
reviewers:
description: "Comma separated list of reviewers for the backporting pull request"
diff --git a/dist/cli/index.js b/dist/cli/index.js
index e436752..aab00ba 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -40,8 +40,8 @@ class ArgsParser {
parse() {
const args = this.readArgs();
// validate and fill with defaults
- if (!args.pullRequest || !args.targetBranch) {
- throw new Error("Missing option: pull request and target branch must be provided");
+ if (!args.pullRequest || !args.targetBranch || args.targetBranch.trim().length == 0) {
+ throw new Error("Missing option: pull request and target branches must be provided");
}
return {
pullRequest: args.pullRequest,
@@ -179,7 +179,7 @@ class CLIArgsParser extends args_parser_1.default {
return new commander_1.Command(package_json_1.name)
.version(package_json_1.version)
.description(package_json_1.description)
- .option("-tb, --target-branch ", "branch where changes must be backported to")
+ .option("-tb, --target-branch ", "comma separated list of branches where changes must be backported to")
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth ", "git service authentication string, e.g., github token")
@@ -189,7 +189,7 @@ class CLIArgsParser extends args_parser_1.default {
.option("--title ", "backport pr title, default original pr title prefixed by target branch")
.option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix")
.option("--body-prefix ", "backport pr body prefix, default `backport `")
- .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit")
+ .option("--bp-branch-name ", "comma separated list of backport pr branch names, default auto-generated by the commit and target branch")
.option("--reviewers ", "comma separated list of reviewers for the backporting pull request", args_utils_1.getAsCleanedCommaSeparatedList)
.option("--assignees ", "comma separated list of assignees for the backporting pull request", args_utils_1.getAsCleanedCommaSeparatedList)
.option("--no-inherit-reviewers", "if provided and reviewers option is empty then inherit them from original pull request")
@@ -288,6 +288,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const args_utils_1 = __nccwpck_require__(8048);
const configs_parser_1 = __importDefault(__nccwpck_require__(5799));
const git_client_factory_1 = __importDefault(__nccwpck_require__(8550));
class PullRequestConfigsParser extends configs_parser_1.default {
@@ -305,15 +306,19 @@ class PullRequestConfigsParser extends configs_parser_1.default {
throw error;
}
const folder = args.folder ?? this.getDefaultFolder();
+ const targetBranches = [...new Set((0, args_utils_1.getAsCommaSeparatedList)(args.targetBranch))];
+ const bpBranchNames = [...new Set(args.bpBranchName ? ((0, args_utils_1.getAsCleanedCommaSeparatedList)(args.bpBranchName) ?? []) : [])];
+ if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
+ throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
+ }
return {
dryRun: args.dryRun,
auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
- targetBranch: args.targetBranch,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
originalPullRequest: pr,
- backportPullRequest: this.getDefaultBackportPullRequest(pr, args),
+ backportPullRequests: this.generateBackportPullRequestsData(pr, args, targetBranches, bpBranchNames),
git: {
user: args.gitUser ?? this.gitClient.getDefaultGitUser(),
email: args.gitEmail ?? this.gitClient.getDefaultGitEmail(),
@@ -330,7 +335,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
* @param targetBranch target branch where the backport should be applied
* @returns {GitPullRequest}
*/
- getDefaultBackportPullRequest(originalPullRequest, args) {
+ generateBackportPullRequestsData(originalPullRequest, args, targetBranches, bpBranchNames) {
const reviewers = args.reviewers ?? [];
if (reviewers.length == 0 && args.inheritReviewers) {
// inherit only if args.reviewers is empty and args.inheritReviewers set to true
@@ -345,29 +350,37 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (args.inheritLabels) {
labels.push(...originalPullRequest.labels);
}
- let backportBranch = args.bpBranchName;
- if (backportBranch === undefined || backportBranch.trim() === "") {
- // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
- const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
- backportBranch = `bp-${args.targetBranch}-${concatenatedCommits}`;
- }
- if (backportBranch.length > 250) {
- this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
- backportBranch = backportBranch.slice(0, 250);
- }
- return {
- owner: originalPullRequest.targetRepo.owner,
- repo: originalPullRequest.targetRepo.project,
- head: backportBranch,
- base: args.targetBranch,
- title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
- // preserve new line chars
- body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
- reviewers: [...new Set(reviewers)],
- assignees: [...new Set(args.assignees)],
- labels: [...new Set(labels)],
- comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
- };
+ return targetBranches.map((tb, idx) => {
+ // if there multiple branch names take the corresponding one, otherwise get the the first one if it exists
+ let backportBranch = bpBranchNames.length > 1 ? bpBranchNames[idx] : bpBranchNames[0];
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${tb}-${concatenatedCommits}`;
+ }
+ else if (bpBranchNames.length == 1 && targetBranches.length > 1) {
+ // multiple targets and single custom backport branch name we need to differentiate branch names
+ // so append "-${tb}" to the provided name
+ backportBranch = backportBranch + `-${tb}`;
+ }
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
+ return {
+ owner: originalPullRequest.targetRepo.owner,
+ repo: originalPullRequest.targetRepo.project,
+ head: backportBranch,
+ base: tb,
+ title: args.title ?? `[${tb}] ${originalPullRequest.title}`,
+ // preserve new line chars
+ body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
+ reviewers: [...new Set(reviewers)],
+ assignees: [...new Set(args.assignees)],
+ labels: [...new Set(labels)],
+ comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
+ };
+ });
}
}
exports["default"] = PullRequestConfigsParser;
@@ -436,10 +449,12 @@ class GitCLIService {
this.logger.info(`Cloning repository ${from} to ${to}`);
if (!fs_1.default.existsSync(to)) {
await (0, simple_git_1.default)().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
+ return;
}
- else {
- this.logger.warn(`Folder ${to} already exist. Won't clone`);
- }
+ this.logger.info(`Folder ${to} already exist. Won't clone`);
+ // checkout to the proper branch
+ this.logger.info(`Checking out branch ${branch}`);
+ await this.git(to).checkout(branch);
}
/**
* Create a new branch starting from the current one and checkout in it
@@ -1115,22 +1130,31 @@ class ConsoleLoggerService {
this.logger = new logger_1.default();
this.verbose = verbose;
}
+ setContext(newContext) {
+ this.context = newContext;
+ }
+ clearContext() {
+ this.context = undefined;
+ }
trace(message) {
- this.logger.log("TRACE", message);
+ this.logger.log("TRACE", this.fromContext(message));
}
debug(message) {
if (this.verbose) {
- this.logger.log("DEBUG", message);
+ this.logger.log("DEBUG", this.fromContext(message));
}
}
info(message) {
- this.logger.log("INFO", message);
+ this.logger.log("INFO", this.fromContext(message));
}
warn(message) {
- this.logger.log("WARN", message);
+ this.logger.log("WARN", this.fromContext(message));
}
error(message) {
- this.logger.log("ERROR", message);
+ this.logger.log("ERROR", this.fromContext(message));
+ }
+ fromContext(msg) {
+ return this.context ? `[${this.context}] ${msg}` : msg;
}
}
exports["default"] = ConsoleLoggerService;
@@ -1242,39 +1266,62 @@ class Runner {
// 3. parse configs
this.logger.debug("Parsing configs..");
const configs = await new pr_configs_parser_1.default().parseAndValidate(args);
- const originalPR = configs.originalPullRequest;
- const backportPR = configs.backportPullRequest;
+ const backportPRs = configs.backportPullRequests;
// start local git operations
const git = new git_cli_1.default(configs.auth, configs.git);
+ const failures = [];
+ // we need sequential backporting as they will operate on the same folder
+ // avoid cloning the same repo multiple times
+ for (const pr of backportPRs) {
+ try {
+ await this.executeBackport(configs, pr, {
+ gitClientType: gitClientType,
+ gitClientApi: gitApi,
+ gitCli: git,
+ });
+ }
+ catch (error) {
+ this.logger.error(`Something went wrong backporting to ${pr.base}: ${error}`);
+ failures.push(error);
+ }
+ }
+ if (failures.length > 0) {
+ throw new Error(`Failure occurred during one of the backports: [${failures.join(" ; ")}]`);
+ }
+ }
+ async executeBackport(configs, backportPR, git) {
+ this.logger.setContext(backportPR.base);
+ const originalPR = configs.originalPullRequest;
// 4. clone the repository
this.logger.debug("Cloning repo..");
- await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
+ await git.gitCli.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, backportPR.base);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- await git.createLocalBranch(configs.folder, backportPR.head);
+ await git.gitCli.createLocalBranch(configs.folder, backportPR.head);
// 6. fetch pull request remote if source owner != target owner or pull request still open
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
this.logger.debug("Fetching pull request remote..");
- const prefix = gitClientType === git_types_1.GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
- await git.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
+ const prefix = git.gitClientType === git_types_1.GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
+ await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
}
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
for (const sha of originalPR.commits) {
- await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
+ await git.gitCli.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
if (!configs.dryRun) {
// 8. push the new branch to origin
- await git.push(configs.folder, backportPR.head);
+ await git.gitCli.push(configs.folder, backportPR.head);
// 9. create pull request new branch -> target branch (using octokit)
- const prUrl = await gitApi.createPullRequest(backportPR);
+ const prUrl = await git.gitClientApi.createPullRequest(backportPR);
this.logger.info(`Pull request created: ${prUrl}`);
}
else {
this.logger.warn("Pull request creation and remote push skipped");
this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
}
+ this.logger.clearContext();
}
}
exports["default"] = Runner;
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 0261515..f8f564c 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -40,8 +40,8 @@ class ArgsParser {
parse() {
const args = this.readArgs();
// validate and fill with defaults
- if (!args.pullRequest || !args.targetBranch) {
- throw new Error("Missing option: pull request and target branch must be provided");
+ if (!args.pullRequest || !args.targetBranch || args.targetBranch.trim().length == 0) {
+ throw new Error("Missing option: pull request and target branches must be provided");
}
return {
pullRequest: args.pullRequest,
@@ -258,6 +258,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const args_utils_1 = __nccwpck_require__(8048);
const configs_parser_1 = __importDefault(__nccwpck_require__(5799));
const git_client_factory_1 = __importDefault(__nccwpck_require__(8550));
class PullRequestConfigsParser extends configs_parser_1.default {
@@ -275,15 +276,19 @@ class PullRequestConfigsParser extends configs_parser_1.default {
throw error;
}
const folder = args.folder ?? this.getDefaultFolder();
+ const targetBranches = [...new Set((0, args_utils_1.getAsCommaSeparatedList)(args.targetBranch))];
+ const bpBranchNames = [...new Set(args.bpBranchName ? ((0, args_utils_1.getAsCleanedCommaSeparatedList)(args.bpBranchName) ?? []) : [])];
+ if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
+ throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
+ }
return {
dryRun: args.dryRun,
auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
- targetBranch: args.targetBranch,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
originalPullRequest: pr,
- backportPullRequest: this.getDefaultBackportPullRequest(pr, args),
+ backportPullRequests: this.generateBackportPullRequestsData(pr, args, targetBranches, bpBranchNames),
git: {
user: args.gitUser ?? this.gitClient.getDefaultGitUser(),
email: args.gitEmail ?? this.gitClient.getDefaultGitEmail(),
@@ -300,7 +305,7 @@ class PullRequestConfigsParser extends configs_parser_1.default {
* @param targetBranch target branch where the backport should be applied
* @returns {GitPullRequest}
*/
- getDefaultBackportPullRequest(originalPullRequest, args) {
+ generateBackportPullRequestsData(originalPullRequest, args, targetBranches, bpBranchNames) {
const reviewers = args.reviewers ?? [];
if (reviewers.length == 0 && args.inheritReviewers) {
// inherit only if args.reviewers is empty and args.inheritReviewers set to true
@@ -315,29 +320,37 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (args.inheritLabels) {
labels.push(...originalPullRequest.labels);
}
- let backportBranch = args.bpBranchName;
- if (backportBranch === undefined || backportBranch.trim() === "") {
- // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
- const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
- backportBranch = `bp-${args.targetBranch}-${concatenatedCommits}`;
- }
- if (backportBranch.length > 250) {
- this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
- backportBranch = backportBranch.slice(0, 250);
- }
- return {
- owner: originalPullRequest.targetRepo.owner,
- repo: originalPullRequest.targetRepo.project,
- head: backportBranch,
- base: args.targetBranch,
- title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
- // preserve new line chars
- body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
- reviewers: [...new Set(reviewers)],
- assignees: [...new Set(args.assignees)],
- labels: [...new Set(labels)],
- comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
- };
+ return targetBranches.map((tb, idx) => {
+ // if there multiple branch names take the corresponding one, otherwise get the the first one if it exists
+ let backportBranch = bpBranchNames.length > 1 ? bpBranchNames[idx] : bpBranchNames[0];
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${tb}-${concatenatedCommits}`;
+ }
+ else if (bpBranchNames.length == 1 && targetBranches.length > 1) {
+ // multiple targets and single custom backport branch name we need to differentiate branch names
+ // so append "-${tb}" to the provided name
+ backportBranch = backportBranch + `-${tb}`;
+ }
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
+ return {
+ owner: originalPullRequest.targetRepo.owner,
+ repo: originalPullRequest.targetRepo.project,
+ head: backportBranch,
+ base: tb,
+ title: args.title ?? `[${tb}] ${originalPullRequest.title}`,
+ // preserve new line chars
+ body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
+ reviewers: [...new Set(reviewers)],
+ assignees: [...new Set(args.assignees)],
+ labels: [...new Set(labels)],
+ comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
+ };
+ });
}
}
exports["default"] = PullRequestConfigsParser;
@@ -406,10 +419,12 @@ class GitCLIService {
this.logger.info(`Cloning repository ${from} to ${to}`);
if (!fs_1.default.existsSync(to)) {
await (0, simple_git_1.default)().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
+ return;
}
- else {
- this.logger.warn(`Folder ${to} already exist. Won't clone`);
- }
+ this.logger.info(`Folder ${to} already exist. Won't clone`);
+ // checkout to the proper branch
+ this.logger.info(`Checking out branch ${branch}`);
+ await this.git(to).checkout(branch);
}
/**
* Create a new branch starting from the current one and checkout in it
@@ -1085,22 +1100,31 @@ class ConsoleLoggerService {
this.logger = new logger_1.default();
this.verbose = verbose;
}
+ setContext(newContext) {
+ this.context = newContext;
+ }
+ clearContext() {
+ this.context = undefined;
+ }
trace(message) {
- this.logger.log("TRACE", message);
+ this.logger.log("TRACE", this.fromContext(message));
}
debug(message) {
if (this.verbose) {
- this.logger.log("DEBUG", message);
+ this.logger.log("DEBUG", this.fromContext(message));
}
}
info(message) {
- this.logger.log("INFO", message);
+ this.logger.log("INFO", this.fromContext(message));
}
warn(message) {
- this.logger.log("WARN", message);
+ this.logger.log("WARN", this.fromContext(message));
}
error(message) {
- this.logger.log("ERROR", message);
+ this.logger.log("ERROR", this.fromContext(message));
+ }
+ fromContext(msg) {
+ return this.context ? `[${this.context}] ${msg}` : msg;
}
}
exports["default"] = ConsoleLoggerService;
@@ -1212,39 +1236,62 @@ class Runner {
// 3. parse configs
this.logger.debug("Parsing configs..");
const configs = await new pr_configs_parser_1.default().parseAndValidate(args);
- const originalPR = configs.originalPullRequest;
- const backportPR = configs.backportPullRequest;
+ const backportPRs = configs.backportPullRequests;
// start local git operations
const git = new git_cli_1.default(configs.auth, configs.git);
+ const failures = [];
+ // we need sequential backporting as they will operate on the same folder
+ // avoid cloning the same repo multiple times
+ for (const pr of backportPRs) {
+ try {
+ await this.executeBackport(configs, pr, {
+ gitClientType: gitClientType,
+ gitClientApi: gitApi,
+ gitCli: git,
+ });
+ }
+ catch (error) {
+ this.logger.error(`Something went wrong backporting to ${pr.base}: ${error}`);
+ failures.push(error);
+ }
+ }
+ if (failures.length > 0) {
+ throw new Error(`Failure occurred during one of the backports: [${failures.join(" ; ")}]`);
+ }
+ }
+ async executeBackport(configs, backportPR, git) {
+ this.logger.setContext(backportPR.base);
+ const originalPR = configs.originalPullRequest;
// 4. clone the repository
this.logger.debug("Cloning repo..");
- await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
+ await git.gitCli.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, backportPR.base);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- await git.createLocalBranch(configs.folder, backportPR.head);
+ await git.gitCli.createLocalBranch(configs.folder, backportPR.head);
// 6. fetch pull request remote if source owner != target owner or pull request still open
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
this.logger.debug("Fetching pull request remote..");
- const prefix = gitClientType === git_types_1.GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
- await git.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
+ const prefix = git.gitClientType === git_types_1.GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
+ await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
}
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
for (const sha of originalPR.commits) {
- await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
+ await git.gitCli.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
if (!configs.dryRun) {
// 8. push the new branch to origin
- await git.push(configs.folder, backportPR.head);
+ await git.gitCli.push(configs.folder, backportPR.head);
// 9. create pull request new branch -> target branch (using octokit)
- const prUrl = await gitApi.createPullRequest(backportPR);
+ const prUrl = await git.gitClientApi.createPullRequest(backportPR);
this.logger.info(`Pull request created: ${prUrl}`);
}
else {
this.logger.warn("Pull request creation and remote push skipped");
this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
}
+ this.logger.clearContext();
}
}
exports["default"] = Runner;
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index 5aee4a6..1c8cb51 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -17,8 +17,8 @@ export default abstract class ArgsParser {
const args = this.readArgs();
// validate and fill with defaults
- if (!args.pullRequest || !args.targetBranch) {
- throw new Error("Missing option: pull request and target branch must be provided");
+ if (!args.pullRequest || !args.targetBranch || args.targetBranch.trim().length == 0) {
+ throw new Error("Missing option: pull request and target branches must be provided");
}
return {
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index 880257c..1a38562 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -1,8 +1,9 @@
/**
- * Input arguments
+ * Tool's input arguments interface
*/
export interface Args {
- targetBranch: string, // branch on the target repo where the change should be backported to
+ // NOTE: keep targetBranch as singular and of type string for backward compatibilities
+ targetBranch: string, // comma separated list of branches on the target repo where the change should be backported to
pullRequest: string, // url of the pull request to backport
dryRun?: boolean, // if enabled do not push anything remotely
auth?: string, // git service auth, like github token
@@ -12,7 +13,8 @@ export interface Args {
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
+ // NOTE: keep bpBranchName as singular and of type string for backward compatibilities
+ bpBranchName?: string, // comma separated list of backport pr branch names, default computed from commit and target branches
reviewers?: string[], // backport pr reviewers
assignees?: string[], // backport pr assignees
inheritReviewers?: boolean, // if true and reviewers == [] then inherit reviewers from original pr
diff --git a/src/service/args/cli/cli-args-parser.ts b/src/service/args/cli/cli-args-parser.ts
index 0e8b4e3..9a9b348 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -10,7 +10,7 @@ export default class CLIArgsParser extends ArgsParser {
return new Command(name)
.version(version)
.description(description)
- .option("-tb, --target-branch ", "branch where changes must be backported to")
+ .option("-tb, --target-branch ", "comma separated list of branches where changes must be backported to")
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth ", "git service authentication string, e.g., github token")
@@ -20,7 +20,7 @@ export default class CLIArgsParser extends ArgsParser {
.option("--title ", "backport pr title, default original pr title prefixed by target branch")
.option("--body ", "backport pr title, default original pr body prefixed by bodyPrefix")
.option("--body-prefix ", "backport pr body prefix, default `backport `")
- .option("--bp-branch-name ", "backport pr branch name, default auto-generated by the commit")
+ .option("--bp-branch-name ", "comma separated list of backport pr branch names, default auto-generated by the commit and target branch")
.option("--reviewers ", "comma separated list of reviewers for the backporting pull request", getAsCleanedCommaSeparatedList)
.option("--assignees ", "comma separated list of assignees for the backporting pull request", getAsCleanedCommaSeparatedList)
.option("--no-inherit-reviewers", "if provided and reviewers option is empty then inherit them from original pull request")
diff --git a/src/service/configs/configs.types.ts b/src/service/configs/configs.types.ts
index be46157..fa44e51 100644
--- a/src/service/configs/configs.types.ts
+++ b/src/service/configs/configs.types.ts
@@ -15,10 +15,9 @@ export interface Configs {
auth?: string,
git: LocalGit,
folder: string,
- targetBranch: string,
mergeStrategy?: string, // cherry-pick merge strategy
mergeStrategyOption?: string, // cherry-pick merge strategy option
originalPullRequest: GitPullRequest,
- backportPullRequest: BackportPullRequest,
+ backportPullRequests: BackportPullRequest[],
}
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 39d39e7..00e220e 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -1,3 +1,4 @@
+import { getAsCleanedCommaSeparatedList, getAsCommaSeparatedList } from "@bp/service/args/args-utils";
import { Args } from "@bp/service/args/args.types";
import ConfigsParser from "@bp/service/configs/configs-parser";
import { Configs } from "@bp/service/configs/configs.types";
@@ -25,15 +26,21 @@ export default class PullRequestConfigsParser extends ConfigsParser {
const folder: string = args.folder ?? this.getDefaultFolder();
+ const targetBranches: string[] = [...new Set(getAsCommaSeparatedList(args.targetBranch)!)];
+ const bpBranchNames: string[] = [...new Set(args.bpBranchName ? (getAsCleanedCommaSeparatedList(args.bpBranchName) ?? []) : [])];
+
+ if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
+ throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
+ }
+
return {
dryRun: args.dryRun!,
auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
- targetBranch: args.targetBranch,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
originalPullRequest: pr,
- backportPullRequest: this.getDefaultBackportPullRequest(pr, args),
+ backportPullRequests: this.generateBackportPullRequestsData(pr, args, targetBranches, bpBranchNames),
git: {
user: args.gitUser ?? this.gitClient.getDefaultGitUser(),
email: args.gitEmail ?? this.gitClient.getDefaultGitEmail(),
@@ -52,7 +59,13 @@ export default class PullRequestConfigsParser extends ConfigsParser {
* @param targetBranch target branch where the backport should be applied
* @returns {GitPullRequest}
*/
- private getDefaultBackportPullRequest(originalPullRequest: GitPullRequest, args: Args): BackportPullRequest {
+ private generateBackportPullRequestsData(
+ originalPullRequest: GitPullRequest,
+ args: Args,
+ targetBranches: string[],
+ bpBranchNames: string[]
+ ): BackportPullRequest[] {
+
const reviewers = args.reviewers ?? [];
if (reviewers.length == 0 && args.inheritReviewers) {
// inherit only if args.reviewers is empty and args.inheritReviewers set to true
@@ -70,30 +83,38 @@ export default class PullRequestConfigsParser extends ConfigsParser {
labels.push(...originalPullRequest.labels);
}
- let backportBranch = args.bpBranchName;
- if (backportBranch === undefined || backportBranch.trim() === "") {
- // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
- const concatenatedCommits: string = originalPullRequest.commits!.map(c => c.slice(0, 7)).join("-");
- backportBranch = `bp-${args.targetBranch}-${concatenatedCommits}`;
- }
+ return targetBranches.map((tb, idx) => {
- if (backportBranch.length > 250) {
- this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
- backportBranch = backportBranch.slice(0, 250);
- }
+ // if there multiple branch names take the corresponding one, otherwise get the the first one if it exists
+ let backportBranch = bpBranchNames.length > 1 ? bpBranchNames[idx] : bpBranchNames[0];
+ if (backportBranch === undefined || backportBranch.trim() === "") {
+ // for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
+ const concatenatedCommits: string = originalPullRequest.commits!.map(c => c.slice(0, 7)).join("-");
+ backportBranch = `bp-${tb}-${concatenatedCommits}`;
+ } else if (bpBranchNames.length == 1 && targetBranches.length > 1) {
+ // multiple targets and single custom backport branch name we need to differentiate branch names
+ // so append "-${tb}" to the provided name
+ backportBranch = backportBranch + `-${tb}`;
+ }
+
+ if (backportBranch.length > 250) {
+ this.logger.warn(`Backport branch (length=${backportBranch.length}) exceeded the max length of 250 chars, branch name truncated!`);
+ backportBranch = backportBranch.slice(0, 250);
+ }
- return {
- owner: originalPullRequest.targetRepo.owner,
- repo: originalPullRequest.targetRepo.project,
- head: backportBranch,
- base: args.targetBranch,
- title: args.title ?? `[${args.targetBranch}] ${originalPullRequest.title}`,
- // preserve new line chars
- body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
- reviewers: [...new Set(reviewers)],
- assignees: [...new Set(args.assignees)],
- labels: [...new Set(labels)],
- comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
- };
+ return {
+ owner: originalPullRequest.targetRepo.owner,
+ repo: originalPullRequest.targetRepo.project,
+ head: backportBranch,
+ base: tb,
+ title: args.title ?? `[${tb}] ${originalPullRequest.title}`,
+ // preserve new line chars
+ body: body.replace(/\\n/g, "\n").replace(/\\r/g, "\r"),
+ reviewers: [...new Set(reviewers)],
+ assignees: [...new Set(args.assignees)],
+ labels: [...new Set(labels)],
+ comments: args.comments?.map(c => c.replace(/\\n/g, "\n").replace(/\\r/g, "\r")) ?? [],
+ };
+ }) as BackportPullRequest[];
}
}
\ No newline at end of file
diff --git a/src/service/git/git-cli.ts b/src/service/git/git-cli.ts
index 26239a7..76f6fc3 100644
--- a/src/service/git/git-cli.ts
+++ b/src/service/git/git-cli.ts
@@ -63,9 +63,13 @@ export default class GitCLIService {
this.logger.info(`Cloning repository ${from} to ${to}`);
if (!fs.existsSync(to)) {
await simpleGit().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
- } else {
- this.logger.warn(`Folder ${to} already exist. Won't clone`);
+ return;
}
+
+ this.logger.info(`Folder ${to} already exist. Won't clone`);
+ // checkout to the proper branch
+ this.logger.info(`Checking out branch ${branch}`);
+ await this.git(to).checkout(branch);
}
/**
diff --git a/src/service/logger/console-logger-service.ts b/src/service/logger/console-logger-service.ts
index ee9339b..4a3088e 100644
--- a/src/service/logger/console-logger-service.ts
+++ b/src/service/logger/console-logger-service.ts
@@ -5,32 +5,44 @@ export default class ConsoleLoggerService implements LoggerService {
private readonly logger: Logger;
private readonly verbose: boolean;
+ private context?: string;
constructor(verbose = true) {
this.logger = new Logger();
this.verbose = verbose;
}
+
+ setContext(newContext: string) {
+ this.context = newContext;
+ }
+
+ clearContext() {
+ this.context = undefined;
+ }
trace(message: string): void {
- this.logger.log("TRACE", message);
+ this.logger.log("TRACE", this.fromContext(message));
}
debug(message: string): void {
if (this.verbose) {
- this.logger.log("DEBUG", message);
+ this.logger.log("DEBUG", this.fromContext(message));
}
}
info(message: string): void {
- this.logger.log("INFO", message);
+ this.logger.log("INFO", this.fromContext(message));
}
warn(message: string): void {
- this.logger.log("WARN", message);
+ this.logger.log("WARN", this.fromContext(message));
}
error(message: string): void {
- this.logger.log("ERROR", message);
+ this.logger.log("ERROR", this.fromContext(message));
}
+ private fromContext(msg: string): string {
+ return this.context ? `[${this.context}] ${msg}` : msg;
+ }
}
\ No newline at end of file
diff --git a/src/service/logger/logger-service.ts b/src/service/logger/logger-service.ts
index 34b1895..0488ac6 100644
--- a/src/service/logger/logger-service.ts
+++ b/src/service/logger/logger-service.ts
@@ -3,6 +3,10 @@
*/
export default interface LoggerService {
+ setContext(newContext: string): void;
+
+ clearContext(): void;
+
trace(message: string): void;
debug(message: string): void;
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index e5d0db0..6f256b4 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -10,6 +10,12 @@ import LoggerService from "@bp/service/logger/logger-service";
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
import { inferGitClient, inferGitApiUrl } from "@bp/service/git/git-util";
+interface Git {
+ gitClientType: GitClientType;
+ gitClientApi: GitClient;
+ gitCli: GitCLIService;
+}
+
/**
* Main runner implementation, it implements the core logic flow
*/
@@ -62,47 +68,73 @@ export default class Runner {
// 3. parse configs
this.logger.debug("Parsing configs..");
const configs: Configs = await new PullRequestConfigsParser().parseAndValidate(args);
- const originalPR: GitPullRequest = configs.originalPullRequest;
- const backportPR: BackportPullRequest = configs.backportPullRequest;
+ const backportPRs: BackportPullRequest[] = configs.backportPullRequests;
// start local git operations
const git: GitCLIService = new GitCLIService(configs.auth, configs.git);
+ const failures: string[] = [];
+ // we need sequential backporting as they will operate on the same folder
+ // avoid cloning the same repo multiple times
+ for(const pr of backportPRs) {
+ try {
+ await this.executeBackport(configs, pr, {
+ gitClientType: gitClientType,
+ gitClientApi: gitApi,
+ gitCli: git,
+ });
+ } catch(error) {
+ this.logger.error(`Something went wrong backporting to ${pr.base}: ${error}`);
+ failures.push(error as string);
+ }
+ }
+
+ if (failures.length > 0) {
+ throw new Error(`Failure occurred during one of the backports: [${failures.join(" ; ")}]`);
+ }
+ }
+
+ async executeBackport(configs: Configs, backportPR: BackportPullRequest, git: Git): Promise {
+ this.logger.setContext(backportPR.base);
+
+ const originalPR: GitPullRequest = configs.originalPullRequest;
+
// 4. clone the repository
this.logger.debug("Cloning repo..");
- await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
+ await git.gitCli.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, backportPR.base);
// 5. create new branch from target one and checkout
this.logger.debug("Creating local branch..");
- await git.createLocalBranch(configs.folder, backportPR.head);
+ await git.gitCli.createLocalBranch(configs.folder, backportPR.head);
// 6. fetch pull request remote if source owner != target owner or pull request still open
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
this.logger.debug("Fetching pull request remote..");
- const prefix = gitClientType === GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
- await git.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
+ const prefix = git.gitClientType === GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
+ await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
}
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
for (const sha of originalPR.commits!) {
- await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
+ await git.gitCli.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
}
if (!configs.dryRun) {
// 8. push the new branch to origin
- await git.push(configs.folder, backportPR.head);
+ await git.gitCli.push(configs.folder, backportPR.head);
// 9. create pull request new branch -> target branch (using octokit)
- const prUrl = await gitApi.createPullRequest(backportPR);
+ const prUrl = await git.gitClientApi.createPullRequest(backportPR);
this.logger.info(`Pull request created: ${prUrl}`);
} else {
this.logger.warn("Pull request creation and remote push skipped");
this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
}
- }
+ this.logger.clearContext();
+ }
}
\ No newline at end of file
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index 2951bf3..bf82586 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -433,4 +433,63 @@ describe("cli args parser", () => {
expect(args.squash).toEqual(true);
expectArrayEqual(args.comments!,["first comment", "second comment"]);
});
+
+ test("valid execution with multiple branches", () => {
+ addProcessArgs([
+ "-tb",
+ "target, old",
+ "-pr",
+ "https://localhost/whatever/pulls/1"
+ ]);
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ expect(args.folder).toEqual(undefined);
+ expect(args.targetBranch).toEqual("target, old");
+ 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);
+ expect(args.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
+ });
+
+ test("invalid execution with empty target branch", () => {
+ addProcessArgs([
+ "-tb",
+ " ",
+ "-pr",
+ "https://localhost/whatever/pulls/1"
+ ]);
+
+ expect(() => parser.parse()).toThrowError("Missing option: pull request and target branches must be provided");
+ });
+
+ test("invalid execution with missing mandatory target branch", () => {
+ addProcessArgs([
+ "-pr",
+ "https://localhost/whatever/pulls/1"
+ ]);
+
+ expect(() => parser.parse()).toThrowError("Missing option: pull request and target branches must be provided");
+ });
+
+ test("invalid execution with missin mandatory pull request", () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ ]);
+
+ expect(() => parser.parse()).toThrowError("Missing option: pull request and target branches must be provided");
+ });
});
\ 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 76efa13..20642d9 100644
--- a/test/service/args/gha/gha-args-parser.test.ts
+++ b/test/service/args/gha/gha-args-parser.test.ts
@@ -262,4 +262,56 @@ describe("gha args parser", () => {
expect(args.squash).toEqual(true);
expectArrayEqual(args.comments!,["first comment", "second comment"]);
});
+
+ test("valid execution with multiple branches", () => {
+ spyGetInput({
+ "target-branch": "target,old",
+ "pull-request": "https://localhost/whatever/pulls/1"
+ });
+
+ const args: Args = parser.parse();
+ expect(args.dryRun).toEqual(false);
+ expect(args.auth).toEqual(undefined);
+ expect(args.gitUser).toEqual(undefined);
+ expect(args.gitEmail).toEqual(undefined);
+ expect(args.folder).toEqual(undefined);
+ expect(args.targetBranch).toEqual("target,old");
+ expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
+ expect(args.title).toEqual(undefined);
+ expect(args.body).toEqual(undefined);
+ expect(args.reviewers).toEqual([]);
+ expect(args.assignees).toEqual([]);
+ expect(args.inheritReviewers).toEqual(true);
+ expect(args.labels).toEqual([]);
+ expect(args.inheritLabels).toEqual(false);
+ expect(args.squash).toEqual(true);
+ expect(args.strategy).toEqual(undefined);
+ expect(args.strategyOption).toEqual(undefined);
+ });
+
+
+ test("invalid execution with empty target branch", () => {
+ spyGetInput({
+ "target-branch": " ",
+ "pull-request": "https://localhost/whatever/pulls/1"
+ });
+
+ expect(() => parser.parse()).toThrowError("Missing option: pull request and target branches must be provided");
+ });
+
+ test("invalid execution with missing mandatory target branch", () => {
+ spyGetInput({
+ "pull-request": "https://localhost/whatever/pulls/1"
+ });
+
+ expect(() => parser.parse()).toThrowError("Missing option: pull request and target branches must be provided");
+ });
+
+ test("invalid execution with missin mandatory pull request", () => {
+ spyGetInput({
+ "target-branch": "target,old",
+ });
+
+ expect(() => parser.parse()).toThrowError("Missing option: pull request and target branches must be provided");
+ });
});
\ No newline at end of file
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
new file mode 100644
index 0000000..e1f7289
--- /dev/null
+++ b/test/service/configs/pullrequest/github-pr-configs-parser-multiple.test.ts
@@ -0,0 +1,422 @@
+import { Args } from "@bp/service/args/args.types";
+import { Configs } from "@bp/service/configs/configs.types";
+import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
+import GitClientFactory from "@bp/service/git/git-client-factory";
+import { GitClientType } from "@bp/service/git/git.types";
+import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
+import { resetProcessArgs } from "../../../support/utils";
+import { MERGED_PR_FIXTURE, REPO, TARGET_OWNER, MULT_COMMITS_PR_FIXTURE } from "../../../support/mock/github-data";
+import GitHubMapper from "@bp/service/git/github/github-mapper";
+import GitHubClient from "@bp/service/git/github/github-client";
+
+jest.spyOn(GitHubMapper.prototype, "mapPullRequest");
+jest.spyOn(GitHubClient.prototype, "getPullRequest");
+
+describe("github pull request config parser", () => {
+
+ const mergedPRUrl = `https://github.com/${TARGET_OWNER}/${REPO}/pull/${MERGED_PR_FIXTURE.number}`;
+ const multipleCommitsPRUrl = `https://github.com/${TARGET_OWNER}/${REPO}/pull/${MULT_COMMITS_PR_FIXTURE.number}`;
+
+ let configParser: PullRequestConfigsParser;
+
+ beforeAll(() => {
+ GitClientFactory.reset();
+ GitClientFactory.getOrCreate(GitClientType.GITHUB, "whatever", "http://localhost/api/v3");
+ });
+
+ beforeEach(() => {
+ // reset process.env variables
+ resetProcessArgs();
+
+ // mock octokit
+ mockGitHubClient("http://localhost/api/v3");
+
+ // create a fresh new instance every time
+ configParser = new PullRequestConfigsParser();
+ });
+
+ test("multiple backports", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v1-28f63db",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v2-28f63db",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v3-28f63db",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ ])
+ );
+ });
+
+ test("multiple backports ignore duplicates", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v1-28f63db",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v2-28f63db",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v3-28f63db",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ ])
+ );
+ });
+
+ test("multiple backports with custom branch name", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ bpBranchName: "custom-branch",
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch-v1",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch-v2",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch-v3",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ ])
+ );
+ });
+
+ test("multiple backports with multiple custom branch names", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ bpBranchName: "custom-branch1, custom-branch2, custom-branch3",
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch1",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch2",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-branch3",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ ])
+ );
+ });
+
+ test("multiple backports with incorrect number of bp branch names", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ bpBranchName: "custom-branch1, custom-branch2",
+ };
+
+ await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("The number of backport branch names, if provided, must match the number of target branches or just one, provided 2 branch names instead");
+ });
+
+ test("multiple backports and multiple commits", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: multipleCommitsPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "GitHub",
+ gitEmail: "noreply@github.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ squash: false,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 8632, false);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"]);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.git).toEqual({
+ user: "GitHub",
+ email: "noreply@github.com"
+ });
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v1-0404fb9-11da4e3",
+ base: "v1",
+ title: "[v1] PR Title",
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v2-0404fb9-11da4e3",
+ base: "v2",
+ title: "[v2] PR Title",
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v3-0404fb9-11da4e3",
+ base: "v3",
+ title: "[v3] PR Title",
+ body: "**Backport:** https://github.com/owner/reponame/pull/8632\r\n\r\nPlease review and merge",
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ },
+ ])
+ );
+ });
+
+});
\ No newline at end of file
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 bca5d75..974a02b 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -5,7 +5,7 @@ import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../../support/utils";
-import { mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner, multipleCommitsPullRequestFixture } from "../../../support/mock/github-data";
+import { MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, REPO, TARGET_OWNER, MULT_COMMITS_PR_FIXTURE } from "../../../support/mock/github-data";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import GitHubMapper from "@bp/service/git/github/github-mapper";
import GitHubClient from "@bp/service/git/github/github-client";
@@ -13,14 +13,14 @@ import GitHubClient from "@bp/service/git/github/github-client";
const GITHUB_MERGED_PR_SIMPLE_CONFIG_FILE_CONTENT_PATHNAME = "./github-pr-configs-parser-simple-pr-merged.json";
const GITHUB_MERGED_PR_SIMPLE_CONFIG_FILE_CONTENT = {
"targetBranch": "prod",
- "pullRequest": `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`,
+ "pullRequest": `https://github.com/${TARGET_OWNER}/${REPO}/pull/${MERGED_PR_FIXTURE.number}`,
};
const GITHUB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT_PATHNAME = "./github-pr-configs-parser-complex-pr-merged.json";
const GITHUB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
"dryRun": false,
"auth": "my-auth-token",
- "pullRequest": `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`,
+ "pullRequest": `https://github.com/${TARGET_OWNER}/${REPO}/pull/${MERGED_PR_FIXTURE.number}`,
"targetBranch": "prod",
"gitUser": "Me",
"gitEmail": "me@email.com",
@@ -39,10 +39,10 @@ jest.spyOn(GitHubClient.prototype, "getPullRequest");
describe("github pull request config parser", () => {
- const mergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`;
- const openPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${openPullRequestFixture.number}`;
- const notMergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${notMergedPullRequestFixture.number}`;
- const multipleCommitsPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${multipleCommitsPullRequestFixture.number}`;
+ const mergedPRUrl = `https://github.com/${TARGET_OWNER}/${REPO}/pull/${MERGED_PR_FIXTURE.number}`;
+ const openPRUrl = `https://github.com/${TARGET_OWNER}/${REPO}/pull/${OPEN_PR_FIXTURE.number}`;
+ const notMergedPRUrl = `https://github.com/${TARGET_OWNER}/${REPO}/pull/${NOT_MERGED_PR_FIXTURE.number}`;
+ const multipleCommitsPRUrl = `https://github.com/${TARGET_OWNER}/${REPO}/pull/${MULT_COMMITS_PR_FIXTURE.number}`;
let argsParser: CLIArgsParser;
let configParser: PullRequestConfigsParser;
@@ -100,7 +100,6 @@ describe("github pull request config parser", () => {
email: "noreply@github.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -128,7 +127,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
@@ -160,7 +160,6 @@ describe("github pull request config parser", () => {
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual("/tmp/test");
expect(configs.git).toEqual({
user: "GitHub",
@@ -190,7 +189,6 @@ describe("github pull request config parser", () => {
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.git).toEqual({
user: "GitHub",
email: "noreply@github.com"
@@ -271,7 +269,6 @@ describe("github pull request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -300,7 +297,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "custom-branch",
@@ -314,6 +312,48 @@ describe("github pull request config parser", () => {
});
});
+ test("override backport with empty bp branch name", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ bpBranchName: " "
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitHubClient.prototype.getPullRequest).toBeCalledWith("owner", "reponame", 2368, true);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitHubMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-prod-28f63db",
+ base: "prod",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: ["gh-user", "that-s-a-user"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ });
+ });
+
test("override backport pr reviewers and assignees", async () => {
const args: Args = {
dryRun: false,
@@ -343,7 +383,6 @@ describe("github pull request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -372,7 +411,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
@@ -415,7 +455,6 @@ describe("github pull request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -444,7 +483,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
@@ -489,7 +529,6 @@ describe("github pull request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -518,7 +557,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
@@ -552,7 +592,6 @@ describe("github pull request config parser", () => {
email: "noreply@github.com"
});
expect(configs.auth).toEqual(undefined);
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -580,7 +619,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
@@ -614,7 +654,6 @@ describe("github pull request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("my-auth-token");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -643,7 +682,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
@@ -684,7 +724,6 @@ describe("github pull request config parser", () => {
email: "noreply@github.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 8632,
@@ -712,7 +751,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["0404fb922ab75c3a8aecad5c97d9af388df04695", "11da4e38aa3e577ffde6d546f1c52e53b04d3151"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-0404fb9-11da4e3",
@@ -758,7 +798,6 @@ describe("github pull request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -787,7 +826,8 @@ describe("github pull request config parser", () => {
nCommits: 2,
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"],
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "owner",
repo: "reponame",
head: "bp-prod-28f63db",
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
new file mode 100644
index 0000000..deff8de
--- /dev/null
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser-multiple.test.ts
@@ -0,0 +1,349 @@
+import { Args } from "@bp/service/args/args.types";
+import { Configs } from "@bp/service/configs/configs.types";
+import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
+import GitClientFactory from "@bp/service/git/git-client-factory";
+import { GitClientType } from "@bp/service/git/git.types";
+import { getAxiosMocked } from "../../../support/mock/git-client-mock-support";
+import { MERGED_SQUASHED_MR } from "../../../support/mock/gitlab-data";
+import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
+import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
+
+jest.spyOn(GitLabMapper.prototype, "mapPullRequest");
+jest.spyOn(GitLabClient.prototype, "getPullRequest");
+
+jest.mock("axios", () => {
+ return {
+ create: jest.fn(() => ({
+ get: getAxiosMocked,
+ })),
+ };
+});
+
+describe("gitlab merge request config parser", () => {
+
+ const mergedPRUrl = `https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/${MERGED_SQUASHED_MR.iid}`;
+
+ let configParser: PullRequestConfigsParser;
+
+ beforeAll(() => {
+ GitClientFactory.reset();
+ GitClientFactory.getOrCreate(GitClientType.GITLAB, "whatever", "my.gitlab.host.com");
+ });
+
+ beforeEach(() => {
+ configParser = new PullRequestConfigsParser();
+ });
+
+ test("multiple backports", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-v1-ebb1eca",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-v2-ebb1eca",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-v3-ebb1eca",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ }
+ ])
+ );
+ });
+
+ test("multiple backports ignore duplicates", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3, v1",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-v1-ebb1eca",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-v2-ebb1eca",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-v3-ebb1eca",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ }
+ ])
+ );
+ });
+
+ test("multiple backports with custom branch name", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ bpBranchName: "custom-branch"
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "custom-branch-v1",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "custom-branch-v2",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "custom-branch-v3",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ }
+ ])
+ );
+ });
+
+ test("multiple backports with multiple custom branch names", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ bpBranchName: "custom1, custom2, custom3"
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(false);
+ expect(configs.auth).toEqual("");
+ expect(configs.folder).toEqual(process.cwd() + "/bp");
+ expect(configs.backportPullRequests.length).toEqual(3);
+ expect(configs.backportPullRequests).toEqual(
+ expect.arrayContaining([
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "custom1",
+ base: "v1",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "custom2",
+ base: "v2",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ },
+ {
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "custom3",
+ base: "v3",
+ title: "New Title",
+ body: "New Body Prefix -New Body",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ labels: [],
+ comments: [],
+ }
+ ])
+ );
+ });
+
+ test("multiple backports with incorrect number of bp branch names", async () => {
+ const args: Args = {
+ dryRun: false,
+ auth: "",
+ pullRequest: mergedPRUrl,
+ targetBranch: "v1, v2, v3",
+ gitUser: "Me",
+ gitEmail: "me@email.com",
+ title: "New Title",
+ body: "New Body",
+ bodyPrefix: "New Body Prefix -",
+ reviewers: [],
+ assignees: ["user3", "user4"],
+ inheritReviewers: false,
+ labels: [],
+ inheritLabels: false,
+ comments: [],
+ bpBranchName: "custom-branch1, custom-branch2, custom-branch2, custom-branch3, custom-branch4",
+ };
+
+ await expect(() => configParser.parseAndValidate(args)).rejects.toThrow("The number of backport branch names, if provided, must match the number of target branches or just one, provided 4 branch names instead");
+ });
+});
\ No newline at end of file
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 691f061..75057ca 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -100,7 +100,6 @@ describe("gitlab merge request config parser", () => {
email: "noreply@gitlab.com"
});
expect(configs.auth).toEqual(undefined);
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -128,7 +127,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -166,7 +166,6 @@ describe("gitlab merge request config parser", () => {
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual("/tmp/test");
expect(configs.git).toEqual({
user: "Gitlab",
@@ -196,7 +195,6 @@ describe("gitlab merge request config parser", () => {
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.git).toEqual({
user: "Gitlab",
email: "noreply@gitlab.com"
@@ -276,7 +274,6 @@ describe("gitlab merge request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -304,7 +301,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -347,7 +345,6 @@ describe("gitlab merge request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -375,7 +372,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -418,7 +416,6 @@ describe("gitlab merge request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -446,7 +443,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -491,7 +489,6 @@ describe("gitlab merge request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -519,7 +516,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -552,7 +550,6 @@ describe("gitlab merge request config parser", () => {
email: "noreply@gitlab.com"
});
expect(configs.auth).toEqual(undefined);
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -580,7 +577,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -613,7 +611,6 @@ describe("gitlab merge request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("my-token");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -641,7 +638,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
@@ -678,7 +676,6 @@ describe("gitlab merge request config parser", () => {
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.git).toEqual({
user: "Gitlab",
email: "noreply@gitlab.com"
@@ -710,7 +707,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 2,
commits: ["e4dd336a4a20f394df6665994df382fb1d193a11", "974519f65c9e0ed65277cd71026657a09fca05e7"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-e4dd336-974519f",
@@ -756,7 +754,6 @@ describe("gitlab merge request config parser", () => {
email: "me@email.com"
});
expect(configs.auth).toEqual("");
- expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
@@ -784,7 +781,8 @@ describe("gitlab merge request config parser", () => {
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
- expect(configs.backportPullRequest).toEqual({
+ expect(configs.backportPullRequests.length).toEqual(1);
+ expect(configs.backportPullRequests[0]).toEqual({
owner: "superuser",
repo: "backporting-example",
head: "bp-prod-ebb1eca",
diff --git a/test/service/git/git-cli.test.ts b/test/service/git/git-cli.test.ts
index 04c069f..2b9c364 100644
--- a/test/service/git/git-cli.test.ts
+++ b/test/service/git/git-cli.test.ts
@@ -114,4 +114,13 @@ describe("git cli service", () => {
const output = spawnSync("git", ["cherry", "-v"], { cwd }).stdout.toString();
expect(output.includes(expressionToTest)).toBe(false);
});
+
+
+ test("git clone on already created repo", async () => {
+ await git.clone("remote", cwd, "tbranch");
+
+ // use rev-parse to double check the current branch is the expected one
+ const post = spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd }).stdout.toString().trim();
+ expect(post).toEqual("tbranch");
+ });
});
\ No newline at end of file
diff --git a/test/service/git/github/github-client.test.ts b/test/service/git/github/github-client.test.ts
index 093ce07..97fc996 100644
--- a/test/service/git/github/github-client.test.ts
+++ b/test/service/git/github/github-client.test.ts
@@ -1,7 +1,7 @@
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitPullRequest, GitClientType } from "@bp/service/git/git.types";
import GitHubClient from "@bp/service/git/github/github-client";
-import { mergedPullRequestFixture, repo, targetOwner } from "../../../support/mock/github-data";
+import { MERGED_PR_FIXTURE, REPO, TARGET_OWNER } from "../../../support/mock/github-data";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
describe("github service", () => {
@@ -22,7 +22,7 @@ describe("github service", () => {
});
test("get pull request: success", async () => {
- const res: GitPullRequest = await gitClient.getPullRequest(targetOwner, repo, mergedPullRequestFixture.number);
+ const res: GitPullRequest = await gitClient.getPullRequest(TARGET_OWNER, REPO, MERGED_PR_FIXTURE.number);
expect(res.sourceRepo).toEqual({
owner: "fork",
project: "reponame",
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index f5ebe36..bbd31da 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -6,7 +6,7 @@ import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../support/utils";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
import GitClientFactory from "@bp/service/git/git-client-factory";
-import { GitClientType } from "@bp/service/git/git.types";
+import { BackportPullRequest, GitClientType } from "@bp/service/git/git.types";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT_PATHNAME = "./cli-github-runner-pr-merged-with-overrides.json";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
@@ -236,6 +236,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("same owner", async () => {
@@ -281,6 +282,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("closed and not merged pull request", async () => {
@@ -338,6 +340,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("override backporting pr data", async () => {
@@ -396,6 +399,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("set empty reviewers", async () => {
@@ -453,6 +457,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("set custom labels with inheritance", async () => {
@@ -502,6 +507,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("set custom labels without inheritance", async () => {
@@ -550,6 +556,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("using config file with overrides", async () => {
@@ -594,6 +601,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
// to check: https://github.com/kiegroup/git-backporting/issues/52
@@ -641,6 +649,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("multiple commits pr", async () => {
@@ -688,6 +697,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("too long bp branch name", async () => {
@@ -741,6 +751,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("multiple commits pr with different strategy", async () => {
@@ -792,6 +803,7 @@ describe("cli runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("additional pr comments", async () => {
@@ -841,5 +853,255 @@ describe("cli runner", () => {
comments: ["first comment", "second comment"],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
+ });
+
+ test("with multiple target branches", async () => {
+ addProcessArgs([
+ "-tb",
+ "v1, v2, v3",
+ "-pr",
+ "https://github.com/owner/reponame/pull/2368",
+ "-f",
+ "/tmp/folder"
+ ]);
+
+ await runner.execute();
+
+ 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, "bp-v1-28f63db");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-v2-28f63db");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-v3-28f63db");
+
+ 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);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(3);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-v1-28f63db");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-v2-28f63db");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-v3-28f63db");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(3);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v1-28f63db",
+ 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: "bp-v2-28f63db",
+ 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: "bp-v3-28f63db",
+ 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).toReturnTimes(3);
+ });
+
+ test("with multiple target branches and multiple bp names", async () => {
+ addProcessArgs([
+ "-tb",
+ "v1, v2, v3",
+ "-pr",
+ "https://github.com/owner/reponame/pull/2368",
+ "-f",
+ "/tmp/folder",
+ "--bp-branch-name",
+ "custom1, custom1, custom2, custom3",
+ ]);
+
+ await runner.execute();
+
+ 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, "custom1");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom2");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom3");
+
+ 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);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(3);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom1");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom2");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom3");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(3);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "custom1",
+ 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: "custom2",
+ 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: "custom3",
+ 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).toReturnTimes(3);
+ });
+
+ test("with multiple target branches and one failure", async () => {
+ jest.spyOn(GitHubClient.prototype, "createPullRequest").mockImplementation((_backport: BackportPullRequest) => {
+
+ throw new Error("Mocked error");
+ });
+
+ addProcessArgs([
+ "-tb",
+ "v1, v2, v3",
+ "-pr",
+ "https://github.com/owner/reponame/pull/2368",
+ "-f",
+ "/tmp/folder",
+ "--bp-branch-name",
+ "custom-failure-head",
+ ]);
+
+ await expect(() => runner.execute()).rejects.toThrowError("Failure occurred during one of the backports: [Error: Mocked error ; Error: Mocked error ; Error: Mocked error]");
+
+ 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);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", 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();
});
});
\ No newline at end of file
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 44f098b..3e9fd73 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -128,6 +128,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("closed and not merged pull request", async () => {
@@ -181,6 +182,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("override backporting pr data", async () => {
@@ -231,6 +233,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("set empty reviewers", async () => {
@@ -282,6 +285,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("set custom labels with inheritance", async () => {
@@ -328,6 +332,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("set custom labels without inheritance", async () => {
@@ -374,6 +379,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("using config file with overrides", async () => {
@@ -417,6 +423,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
// to check: https://github.com/kiegroup/git-backporting/issues/52
@@ -462,6 +469,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("multiple commits pr", async () => {
@@ -507,6 +515,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("using github api url and different strategy", async () => {
@@ -553,6 +562,7 @@ describe("gha runner", () => {
comments: [],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
});
test("additional pr comments", async () => {
@@ -598,5 +608,161 @@ describe("gha runner", () => {
comments: ["first comment", "second comment"],
}
);
+ expect(GitHubClient.prototype.createPullRequest).toReturnTimes(1);
+ });
+
+ test("with multiple target branches", async () => {
+ spyGetInput({
+ "target-branch": "v1, v2, v3",
+ "pull-request": "https://github.com/owner/reponame/pull/2368",
+ "folder": "/tmp/folder",
+ });
+
+ await runner.execute();
+
+ 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, "bp-v1-28f63db");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-v2-28f63db");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-v3-28f63db");
+
+ 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);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(3);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-v1-28f63db");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-v2-28f63db");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-v3-28f63db");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(3);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "bp-v1-28f63db",
+ 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: "bp-v2-28f63db",
+ 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: "bp-v3-28f63db",
+ 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).toReturnTimes(3);
+ });
+
+ test("with multiple target branches and single custom bp branch", async () => {
+ spyGetInput({
+ "target-branch": "v1, v2, v3",
+ "pull-request": "https://github.com/owner/reponame/pull/2368",
+ "folder": "/tmp/folder",
+ "bp-branch-name": "custom"
+ });
+
+ await runner.execute();
+
+ 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-v1");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom-v2");
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "custom-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);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(3);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom-v1");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom-v2");
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "custom-v3");
+
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(3);
+ expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "owner",
+ repo: "reponame",
+ head: "custom-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-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-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).toReturnTimes(3);
});
});
\ No newline at end of file
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index e36db5e..985f799 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -1,8 +1,12 @@
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
import { Moctokit } from "@kie/mock-github";
-import { targetOwner, repo, mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber, multipleCommitsPullRequestFixture, multipleCommitsPullRequestCommits } 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 } from "./github-data";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
+// high number, for each test we are not expecting
+// to send more than 3 reqs per api endpoint
+const REPEAT = 20;
+
const logger = LoggerServiceFactory.getLogger();
// AXIOS
@@ -94,76 +98,82 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
// valid requests
mock.rest.pulls
.get({
- owner: targetOwner,
- repo: repo,
- pull_number: mergedPullRequestFixture.number
+ owner: TARGET_OWNER,
+ repo: REPO,
+ pull_number: MERGED_PR_FIXTURE.number
})
.reply({
status: 200,
- data: mergedPullRequestFixture
+ data: MERGED_PR_FIXTURE
});
mock.rest.pulls
.get({
- owner: targetOwner,
- repo: repo,
- pull_number: multipleCommitsPullRequestFixture.number
+ owner: TARGET_OWNER,
+ repo: REPO,
+ pull_number: MULT_COMMITS_PR_FIXTURE.number
})
.reply({
status: 200,
- data: multipleCommitsPullRequestFixture
+ data: MULT_COMMITS_PR_FIXTURE
});
mock.rest.pulls
.get({
- owner: targetOwner,
- repo: repo,
- pull_number: openPullRequestFixture.number
+ owner: TARGET_OWNER,
+ repo: REPO,
+ pull_number: OPEN_PR_FIXTURE.number
})
.reply({
status: 200,
- data: openPullRequestFixture
+ data: OPEN_PR_FIXTURE
});
mock.rest.pulls
.get({
- owner: targetOwner,
- repo: repo,
- pull_number: notMergedPullRequestFixture.number
+ owner: TARGET_OWNER,
+ repo: REPO,
+ pull_number: NOT_MERGED_PR_FIXTURE.number
})
.reply({
status: 200,
- data: notMergedPullRequestFixture
+ data: NOT_MERGED_PR_FIXTURE
});
mock.rest.pulls
.listCommits({
- owner: targetOwner,
- repo: repo,
- pull_number: multipleCommitsPullRequestFixture.number
+ owner: TARGET_OWNER,
+ repo: REPO,
+ pull_number: MULT_COMMITS_PR_FIXTURE.number
})
.reply({
status: 200,
- data: multipleCommitsPullRequestCommits
+ data: MULT_COMMITS_PR_COMMITS
});
mock.rest.pulls
.create()
.reply({
+ repeat: REPEAT,
status: 201,
- data: mergedPullRequestFixture
+ data: {
+ number: NEW_PR_NUMBER,
+ html_url: NEW_PR_URL,
+ }
});
mock.rest.pulls
.requestReviewers()
.reply({
+ repeat: REPEAT,
status: 201,
- data: mergedPullRequestFixture
+ data: MERGED_PR_FIXTURE
});
mock.rest.issues
.addAssignees()
.reply({
+ repeat: REPEAT,
status: 201,
data: {}
});
@@ -171,6 +181,7 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
mock.rest.issues
.addLabels()
.reply({
+ repeat: REPEAT,
status: 200,
data: {}
});
@@ -178,6 +189,7 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
mock.rest.issues
.createComment()
.reply({
+ repeat: REPEAT,
status: 201,
data: {}
});
@@ -185,16 +197,17 @@ export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit =>
// invalid requests
mock.rest.pulls
.get({
- owner: targetOwner,
- repo: repo,
- pull_number: notFoundPullRequestNumber
+ owner: TARGET_OWNER,
+ repo: REPO,
+ pull_number: NOT_FOUND_PR_NUMBER
})
.reply({
+ repeat: REPEAT,
status: 404,
data: {
message: "Not found"
}
});
-
+
return mock;
};
diff --git a/test/support/mock/github-data.ts b/test/support/mock/github-data.ts
index e91b723..8407834 100644
--- a/test/support/mock/github-data.ts
+++ b/test/support/mock/github-data.ts
@@ -1,9 +1,11 @@
-export const targetOwner = "owner";
-export const sourceOwner = "fork";
-export const repo = "reponame";
-export const notFoundPullRequestNumber = 1;
+export const TARGET_OWNER = "owner";
+export const SOURCE_OWNER = "fork";
+export const REPO = "reponame";
+export const NOT_FOUND_PR_NUMBER = 1;
+export const NEW_PR_URL = "new_pr_url";
+export const NEW_PR_NUMBER = 9999;
-export const mergedPullRequestFixture = {
+export const MERGED_PR_FIXTURE = {
"url": "https://api.github.com/repos/owner/reponame/pulls/2368",
"id": 1137188271,
"node_id": "PR_kwDOABTq6s5DyB2v",
@@ -474,7 +476,7 @@ export const mergedPullRequestFixture = {
"changed_files": 2
};
-export const openPullRequestFixture = {
+export const OPEN_PR_FIXTURE = {
"url": "https://api.github.com/repos/owner/reponame/pulls/4444",
"id": 1137188271,
"node_id": "PR_kwDOABTq6s5DyB2v",
@@ -898,7 +900,7 @@ export const openPullRequestFixture = {
"changed_files": 2
};
-export const notMergedPullRequestFixture = {
+export const NOT_MERGED_PR_FIXTURE = {
"url": "https://api.github.com/repos/owner/reponame/pulls/6666",
"id": 1137188271,
"node_id": "PR_kwDOABTq6s5DyB2v",
@@ -1341,7 +1343,7 @@ export const notMergedPullRequestFixture = {
"changed_files": 2
};
-export const multipleCommitsPullRequestFixture = {
+export const MULT_COMMITS_PR_FIXTURE = {
"url": "https://api.github.com/repos/owner/reponame/pulls/8632",
"id": 1137188271,
"node_id": "PR_kwDOABTq6s5DyB2v",
@@ -1804,7 +1806,7 @@ export const multipleCommitsPullRequestFixture = {
"changed_files": 2
};
-export const multipleCommitsPullRequestCommits = [
+export const MULT_COMMITS_PR_COMMITS = [
{
"sha": "0404fb922ab75c3a8aecad5c97d9af388df04695",
"node_id": "C_kwDOImgs99oAKDA0MDRmYjkyMmFiNzVjM2E4YWVjYWQ1Yzk3ZDlhZjM4OGRmMDQ2OTU",
From eecbff34b7adf6b8b46bcbaaf9aa488d885b56b5 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Fri, 18 Aug 2023 13:11:20 +0200
Subject: [PATCH 21/75] chore: update README (#79)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 9ee9fb9..8524dac 100644
--- a/README.md
+++ b/README.md
@@ -306,4 +306,4 @@ Every change must be submitted through a *GitHub* pull request (PR). Backporting
## License
-Backporting (BPer) open source project is licensed under the [MIT](./LICENSE) license.
\ No newline at end of file
+Git backporting open source project is licensed under the [MIT](./LICENSE) license.
\ No newline at end of file
From 9f0fbc0b2fd8d449207660323be87f6d2fa8c017 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Fri, 18 Aug 2023 13:15:38 +0200
Subject: [PATCH 22/75] feat: integrate with codeberg (#80)
---
README.md | 4 +++-
dist/cli/index.js | 22 ++++++++++++++-------
dist/gha/index.js | 22 ++++++++++++++-------
src/service/git/git-client-factory.ts | 3 +++
src/service/git/git-util.ts | 2 ++
src/service/git/git.types.ts | 1 +
src/service/git/github/github-client.ts | 4 ++--
src/service/git/github/github-mapper.ts | 6 +++---
src/service/runner/runner.ts | 6 +++---
test/service/git/git-client-factory.test.ts | 11 +++++++++++
test/service/git/git-util.test.ts | 16 +++++++++++++--
11 files changed, 72 insertions(+), 25 deletions(-)
diff --git a/README.md b/README.md
index 8524dac..fba7fb3 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ Table of content
## Who is this tool for?
-`git-backporting` is a tool that provides capabilities to *backport* pull requests (on *GitHub*) and merge requests (on *GitLab*) in an automated way.
+`git-backporting` is a fully configurable tool that provides capabilities to *backport* pull requests (on *GitHub*) and merge requests (on *GitLab*) in an automated way.
> *What is backporting?* - backporting is an action aiming to move a change (usually a commit) from a branch (usually the main one) to another one, which is generally referring to a still maintained release branch. Keeping it simple: it is about to move a specific change or a set of them from one branch to another.
@@ -139,6 +139,8 @@ Right now **Git Backporting** supports the following git management services:
* ***GITLAB***: This has been introduced since version `3.0.0`, it works for both public and private *GitLab* servers. The interaction with this service is performed using plain [*axios*](https://axios-http.com) requests. The *gitlab* api version that is used to make requests is `v4`, at the moment there is no possibility to override it.
+ * ***CODEBERG***: Introduced since version `4.4.0`, it works for public [codeberg.org](https://codeberg.org/) platform. Thanks to the api compatibility with GitHub, the interaction with this service is performed using using [*octokit*](https://octokit.github.io/rest.js) client library.
+
> **NOTE**: by default, all gitlab requests are performed setting `rejectUnauthorized=false`, planning to make this configurable too.
## GitHub action
diff --git a/dist/cli/index.js b/dist/cli/index.js
index aab00ba..83a0c2c 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -566,6 +566,9 @@ class GitClientFactory {
case git_types_1.GitClientType.GITLAB:
GitClientFactory.instance = new gitlab_client_1.default(authToken, apiUrl);
break;
+ case git_types_1.GitClientType.CODEBERG:
+ GitClientFactory.instance = new github_client_1.default(authToken, apiUrl);
+ break;
default:
throw new Error(`Invalid git service type received: ${type}`);
}
@@ -607,6 +610,9 @@ const inferGitClient = (prUrl) => {
else if (stdPrUrl.includes(git_types_1.GitClientType.GITLAB.toString())) {
return git_types_1.GitClientType.GITLAB;
}
+ else if (stdPrUrl.includes(git_types_1.GitClientType.CODEBERG.toString())) {
+ return git_types_1.GitClientType.CODEBERG;
+ }
throw new Error(`Remote git service not recognized from pr url: ${prUrl}`);
};
exports.inferGitClient = inferGitClient;
@@ -640,6 +646,7 @@ var GitClientType;
(function (GitClientType) {
GitClientType["GITHUB"] = "github";
GitClientType["GITLAB"] = "gitlab";
+ GitClientType["CODEBERG"] = "codeberg";
})(GitClientType = exports.GitClientType || (exports.GitClientType = {}));
var GitRepoState;
(function (GitRepoState) {
@@ -661,6 +668,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const git_types_1 = __nccwpck_require__(750);
const github_mapper_1 = __importDefault(__nccwpck_require__(5764));
const octokit_factory_1 = __importDefault(__nccwpck_require__(4257));
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
@@ -673,7 +681,7 @@ class GitHubClient {
}
// READ
getDefaultGitUser() {
- return "GitHub";
+ return this.apiUrl.includes(git_types_1.GitClientType.CODEBERG.toString()) ? "Codeberg" : "GitHub";
}
getDefaultGitEmail() {
return "noreply@github.com";
@@ -806,9 +814,9 @@ class GitHubMapper {
state: this.mapGitState(pr.state),
merged: pr.merged ?? false,
mergedBy: pr.merged_by?.login,
- reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
- assignees: pr.assignees.filter(r => "login" in r).map(r => r.login),
- labels: pr.labels.map(l => l.name),
+ reviewers: pr.requested_reviewers?.filter(r => "login" in r).map((r => r?.login)) ?? [],
+ assignees: pr.assignees?.filter(r => "login" in r).map(r => r.login) ?? [],
+ labels: pr.labels?.map(l => l.name) ?? [],
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
@@ -1260,8 +1268,8 @@ class Runner {
}
// 2. init git service
const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
- // right now the apiVersion is set to v4
- const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest);
+ // the api version is ignored in case of github
+ const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
const gitApi = git_client_factory_1.default.getOrCreate(gitClientType, args.auth, apiUrl);
// 3. parse configs
this.logger.debug("Parsing configs..");
@@ -1302,7 +1310,7 @@ class Runner {
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
this.logger.debug("Fetching pull request remote..");
- const prefix = git.gitClientType === git_types_1.GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
+ const prefix = git.gitClientType === git_types_1.GitClientType.GITLAB ? "merge-requests" : "pull"; // default is for gitlab
await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
}
// 7. apply all changes to the new branch
diff --git a/dist/gha/index.js b/dist/gha/index.js
index f8f564c..29dd2b5 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -536,6 +536,9 @@ class GitClientFactory {
case git_types_1.GitClientType.GITLAB:
GitClientFactory.instance = new gitlab_client_1.default(authToken, apiUrl);
break;
+ case git_types_1.GitClientType.CODEBERG:
+ GitClientFactory.instance = new github_client_1.default(authToken, apiUrl);
+ break;
default:
throw new Error(`Invalid git service type received: ${type}`);
}
@@ -577,6 +580,9 @@ const inferGitClient = (prUrl) => {
else if (stdPrUrl.includes(git_types_1.GitClientType.GITLAB.toString())) {
return git_types_1.GitClientType.GITLAB;
}
+ else if (stdPrUrl.includes(git_types_1.GitClientType.CODEBERG.toString())) {
+ return git_types_1.GitClientType.CODEBERG;
+ }
throw new Error(`Remote git service not recognized from pr url: ${prUrl}`);
};
exports.inferGitClient = inferGitClient;
@@ -610,6 +616,7 @@ var GitClientType;
(function (GitClientType) {
GitClientType["GITHUB"] = "github";
GitClientType["GITLAB"] = "gitlab";
+ GitClientType["CODEBERG"] = "codeberg";
})(GitClientType = exports.GitClientType || (exports.GitClientType = {}));
var GitRepoState;
(function (GitRepoState) {
@@ -631,6 +638,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const git_types_1 = __nccwpck_require__(750);
const github_mapper_1 = __importDefault(__nccwpck_require__(5764));
const octokit_factory_1 = __importDefault(__nccwpck_require__(4257));
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
@@ -643,7 +651,7 @@ class GitHubClient {
}
// READ
getDefaultGitUser() {
- return "GitHub";
+ return this.apiUrl.includes(git_types_1.GitClientType.CODEBERG.toString()) ? "Codeberg" : "GitHub";
}
getDefaultGitEmail() {
return "noreply@github.com";
@@ -776,9 +784,9 @@ class GitHubMapper {
state: this.mapGitState(pr.state),
merged: pr.merged ?? false,
mergedBy: pr.merged_by?.login,
- reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
- assignees: pr.assignees.filter(r => "login" in r).map(r => r.login),
- labels: pr.labels.map(l => l.name),
+ reviewers: pr.requested_reviewers?.filter(r => "login" in r).map((r => r?.login)) ?? [],
+ assignees: pr.assignees?.filter(r => "login" in r).map(r => r.login) ?? [],
+ labels: pr.labels?.map(l => l.name) ?? [],
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
@@ -1230,8 +1238,8 @@ class Runner {
}
// 2. init git service
const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
- // right now the apiVersion is set to v4
- const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest);
+ // the api version is ignored in case of github
+ const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
const gitApi = git_client_factory_1.default.getOrCreate(gitClientType, args.auth, apiUrl);
// 3. parse configs
this.logger.debug("Parsing configs..");
@@ -1272,7 +1280,7 @@ class Runner {
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
this.logger.debug("Fetching pull request remote..");
- const prefix = git.gitClientType === git_types_1.GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
+ const prefix = git.gitClientType === git_types_1.GitClientType.GITLAB ? "merge-requests" : "pull"; // default is for gitlab
await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
}
// 7. apply all changes to the new branch
diff --git a/src/service/git/git-client-factory.ts b/src/service/git/git-client-factory.ts
index fa63173..ed66a75 100644
--- a/src/service/git/git-client-factory.ts
+++ b/src/service/git/git-client-factory.ts
@@ -43,6 +43,9 @@ export default class GitClientFactory {
case GitClientType.GITLAB:
GitClientFactory.instance = new GitLabClient(authToken, apiUrl);
break;
+ case GitClientType.CODEBERG:
+ GitClientFactory.instance = new GitHubService(authToken, apiUrl);
+ break;
default:
throw new Error(`Invalid git service type received: ${type}`);
}
diff --git a/src/service/git/git-util.ts b/src/service/git/git-util.ts
index 6d459b2..2ac1f2b 100644
--- a/src/service/git/git-util.ts
+++ b/src/service/git/git-util.ts
@@ -16,6 +16,8 @@ export const inferGitClient = (prUrl: string): GitClientType => {
return GitClientType.GITHUB;
} else if (stdPrUrl.includes(GitClientType.GITLAB.toString())) {
return GitClientType.GITLAB;
+ } else if (stdPrUrl.includes(GitClientType.CODEBERG.toString())) {
+ return GitClientType.CODEBERG;
}
throw new Error(`Remote git service not recognized from pr url: ${prUrl}`);
diff --git a/src/service/git/git.types.ts b/src/service/git/git.types.ts
index 6370eee..696b29d 100644
--- a/src/service/git/git.types.ts
+++ b/src/service/git/git.types.ts
@@ -41,6 +41,7 @@ export interface BackportPullRequest {
export enum GitClientType {
GITHUB = "github",
GITLAB = "gitlab",
+ CODEBERG = "codeberg",
}
export enum GitRepoState {
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index 297052d..f83f3e2 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -1,5 +1,5 @@
import GitClient from "@bp/service/git/git-client";
-import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
+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";
import LoggerService from "@bp/service/logger/logger-service";
@@ -24,7 +24,7 @@ export default class GitHubClient implements GitClient {
// READ
getDefaultGitUser(): string {
- return "GitHub";
+ return this.apiUrl.includes(GitClientType.CODEBERG.toString()) ? "Codeberg" : "GitHub";
}
getDefaultGitEmail(): string {
diff --git a/src/service/git/github/github-mapper.ts b/src/service/git/github/github-mapper.ts
index a79cb3d..3ae0ca4 100644
--- a/src/service/git/github/github-mapper.ts
+++ b/src/service/git/github/github-mapper.ts
@@ -24,9 +24,9 @@ export default class GitHubMapper implements GitResponseMapper "login" in r).map((r => (r as User)?.login)),
- assignees: pr.assignees.filter(r => "login" in r).map(r => r.login),
- labels: pr.labels.map(l => l.name),
+ reviewers: pr.requested_reviewers?.filter(r => "login" in r).map((r => (r as User)?.login)) ?? [],
+ assignees: pr.assignees?.filter(r => "login" in r).map(r => r.login) ?? [],
+ labels: pr.labels?.map(l => l.name) ?? [],
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),
nCommits: pr.commits,
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index 6f256b4..ce6d543 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -61,8 +61,8 @@ export default class Runner {
// 2. init git service
const gitClientType: GitClientType = inferGitClient(args.pullRequest);
- // right now the apiVersion is set to v4
- const apiUrl = inferGitApiUrl(args.pullRequest);
+ // the api version is ignored in case of github
+ const apiUrl = inferGitApiUrl(args.pullRequest, gitClientType === GitClientType.CODEBERG ? "v1" : undefined);
const gitApi: GitClient = GitClientFactory.getOrCreate(gitClientType, args.auth, apiUrl);
// 3. parse configs
@@ -112,7 +112,7 @@ export default class Runner {
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
configs.originalPullRequest.state === "open") {
this.logger.debug("Fetching pull request remote..");
- const prefix = git.gitClientType === GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
+ const prefix = git.gitClientType === GitClientType.GITLAB ? "merge-requests" : "pull" ; // default is for gitlab
await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
}
diff --git a/test/service/git/git-client-factory.test.ts b/test/service/git/git-client-factory.test.ts
index 0d05ea3..df64e40 100644
--- a/test/service/git/git-client-factory.test.ts
+++ b/test/service/git/git-client-factory.test.ts
@@ -20,6 +20,11 @@ describe("git client factory test", () => {
expect(client).toBeInstanceOf(GitLabClient);
});
+ test("correctly create codeberg client", () => {
+ const client = GitClientFactory.getOrCreate(GitClientType.CODEBERG, "auth", "apiurl");
+ expect(client).toBeInstanceOf(GitHubClient);
+ });
+
test("check get service github", () => {
const create = GitClientFactory.getOrCreate(GitClientType.GITHUB, "auth", "apiurl");
const get = GitClientFactory.getClient();
@@ -31,4 +36,10 @@ describe("git client factory test", () => {
const get = GitClientFactory.getClient();
expect(create).toStrictEqual(get);
});
+
+ test("check get service codeberg", () => {
+ const create = GitClientFactory.getOrCreate(GitClientType.CODEBERG, "auth", "apiurl");
+ const get = GitClientFactory.getClient();
+ expect(create).toStrictEqual(get);
+ });
});
\ No newline at end of file
diff --git a/test/service/git/git-util.test.ts b/test/service/git/git-util.test.ts
index cf083c6..5e202e6 100644
--- a/test/service/git/git-util.test.ts
+++ b/test/service/git/git-util.test.ts
@@ -23,6 +23,18 @@ describe("check git utilities", () => {
expect(inferGitApiUrl("http://github.acme-inc.com/superuser/backporting-example/pull/4", "v3")).toStrictEqual("http://github.acme-inc.com/api/v3");
});
+ test("check infer github api from github api url", ()=> {
+ expect(inferGitApiUrl("https://api.github.com/repos/owner/repo/pulls/1")).toStrictEqual("https://api.github.com");
+ });
+
+ test("check infer codeberg api", ()=> {
+ expect(inferGitApiUrl("https://codeberg.org/lampajr/backporting-example/pulls/1", "v1")).toStrictEqual("https://codeberg.org/api/v1");
+ });
+
+ test("check infer codeberg api", ()=> {
+ expect(inferGitApiUrl("https://codeberg.org/lampajr/backporting-example/pulls/1", undefined)).toStrictEqual("https://codeberg.org/api/v4");
+ });
+
test("check infer github client", ()=> {
expect(inferGitClient("https://github.com/superuser/backporting-example/pull/4")).toStrictEqual(GitClientType.GITHUB);
});
@@ -39,7 +51,7 @@ describe("check git utilities", () => {
expect(inferGitClient("https://api.github.com/repos/owner/repo/pulls/1")).toStrictEqual(GitClientType.GITHUB);
});
- test("check infer github api from github api url", ()=> {
- expect(inferGitApiUrl("https://api.github.com/repos/owner/repo/pulls/1")).toStrictEqual("https://api.github.com");
+ test("check infer codeberg client", ()=> {
+ expect(inferGitClient("https://codeberg.org/lampajr/backporting-example/pulls/1")).toStrictEqual(GitClientType.CODEBERG);
});
});
\ No newline at end of file
From 4313be48e73b299a20b3c8290fd1ea8704e8dd5e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 18 Aug 2023 13:24:39 +0200
Subject: [PATCH 23/75] chore: release v4.4.0 (#81)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 8 ++++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 154421a..9bb5765 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## [4.4.0](https://github.com/kiegroup/git-backporting/compare/v4.3.0...v4.4.0) (2023-08-18)
+
+
+### Features
+
+* integrate with codeberg ([#80](https://github.com/kiegroup/git-backporting/issues/80)) ([9f0fbc0](https://github.com/kiegroup/git-backporting/commit/9f0fbc0b2fd8d449207660323be87f6d2fa8c017))
+* **issue-77:** handle multiple target branches ([#78](https://github.com/kiegroup/git-backporting/issues/78)) ([5fc72e1](https://github.com/kiegroup/git-backporting/commit/5fc72e127bedb3177f4e17ff1182827c78154ef1))
+
## [4.3.0](https://github.com/kiegroup/git-backporting/compare/v4.2.0...v4.3.0) (2023-07-27)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 83a0c2c..9025d4e 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23498,7 +23498,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.3.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.4.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index bd1b9ad..23d1a83 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.3.0",
+ "version": "4.4.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.3.0",
+ "version": "4.4.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index 73b09af..45a3226 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.3.0",
+ "version": "4.4.0",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From 2db9eb3ef2df34be248ac331b14a49b42b4562d2 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 19 Oct 2023 11:56:17 +0200
Subject: [PATCH 24/75] build(deps-dev): bump @babel/traverse from 7.22.5 to
7.23.2 (#82)
Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.22.5 to 7.23.2.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-traverse)
---
updated-dependencies:
- dependency-name: "@babel/traverse"
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 331 ++++++++++++++++++++++++++++++++--------------
1 file changed, 231 insertions(+), 100 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 23d1a83..c6698c3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -86,17 +86,89 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
- "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dev": true,
"dependencies": {
- "@babel/highlight": "^7.22.5"
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
},
"engines": {
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/code-frame/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/code-frame/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/@babel/compat-data": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz",
@@ -152,12 +224,12 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz",
- "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.22.5",
+ "@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
@@ -210,22 +282,22 @@
"dev": true
},
"node_modules/@babel/helper-environment-visitor": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
- "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
- "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"dependencies": {
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
},
"engines": {
"node": ">=6.9.0"
@@ -296,9 +368,9 @@
}
},
"node_modules/@babel/helper-split-export-declaration": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz",
- "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==",
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"dependencies": {
"@babel/types": "^7.22.5"
@@ -317,9 +389,9 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
- "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -349,13 +421,13 @@
}
},
"node_modules/@babel/highlight": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz",
- "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.5",
- "chalk": "^2.0.0",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"engines": {
@@ -434,9 +506,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz",
- "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -623,33 +695,33 @@
}
},
"node_modules/@babel/template": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
- "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"dependencies": {
- "@babel/code-frame": "^7.22.5",
- "@babel/parser": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz",
- "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
"dev": true,
"dependencies": {
- "@babel/code-frame": "^7.22.5",
- "@babel/generator": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.5",
- "@babel/parser": "^7.22.5",
- "@babel/types": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -667,13 +739,13 @@
}
},
"node_modules/@babel/types": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz",
- "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dev": true,
"dependencies": {
"@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -11747,12 +11819,71 @@
}
},
"@babel/code-frame": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz",
- "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==",
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.22.5"
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"@babel/compat-data": {
@@ -11799,12 +11930,12 @@
}
},
"@babel/generator": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz",
- "integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dev": true,
"requires": {
- "@babel/types": "^7.22.5",
+ "@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
"@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
@@ -11847,19 +11978,19 @@
}
},
"@babel/helper-environment-visitor": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz",
- "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true
},
"@babel/helper-function-name": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz",
- "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"requires": {
- "@babel/template": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
}
},
"@babel/helper-hoist-variables": {
@@ -11912,9 +12043,9 @@
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz",
- "integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==",
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"requires": {
"@babel/types": "^7.22.5"
@@ -11927,9 +12058,9 @@
"dev": true
},
"@babel/helper-validator-identifier": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz",
- "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true
},
"@babel/helper-validator-option": {
@@ -11950,13 +12081,13 @@
}
},
"@babel/highlight": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz",
- "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.22.5",
- "chalk": "^2.0.0",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"dependencies": {
@@ -12019,9 +12150,9 @@
}
},
"@babel/parser": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz",
- "integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"dev": true
},
"@babel/plugin-syntax-async-generators": {
@@ -12151,30 +12282,30 @@
}
},
"@babel/template": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz",
- "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.22.5",
- "@babel/parser": "^7.22.5",
- "@babel/types": "^7.22.5"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
}
},
"@babel/traverse": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz",
- "integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.22.5",
- "@babel/generator": "^7.22.5",
- "@babel/helper-environment-visitor": "^7.22.5",
- "@babel/helper-function-name": "^7.22.5",
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
- "@babel/helper-split-export-declaration": "^7.22.5",
- "@babel/parser": "^7.22.5",
- "@babel/types": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -12188,13 +12319,13 @@
}
},
"@babel/types": {
- "version": "7.22.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.5.tgz",
- "integrity": "sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dev": true,
"requires": {
"@babel/helper-string-parser": "^7.22.5",
- "@babel/helper-validator-identifier": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
}
},
From e7c9b4795b00b433cacd0f54daa628022aa002b2 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Sat, 11 Nov 2023 22:33:56 +0100
Subject: [PATCH 25/75] build(deps): bump axios from 1.4.0 to 1.6.0 (#83)
Bumps [axios](https://github.com/axios/axios) from 1.4.0 to 1.6.0.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.4.0...v1.6.0)
---
updated-dependencies:
- dependency-name: axios
dependency-type: direct:production
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index c6698c3..54f86cd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2745,9 +2745,9 @@
}
},
"node_modules/axios": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
- "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz",
+ "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
@@ -13927,9 +13927,9 @@
"dev": true
},
"axios": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
- "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz",
+ "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
From ed32d2275b6008d31e456c41beecd536eceb23dc Mon Sep 17 00:00:00 2001
From: Shyim
Date: Tue, 5 Dec 2023 16:08:49 +0100
Subject: [PATCH 26/75] fix: namespace parsing in gitlab (#84)
* fix: namespace parsing in gitlab
* test: add test for nested namespace
---------
Co-authored-by: Andrea Lamparelli
---
dist/cli/index.js | 154 +++++----
dist/gha/index.js | 154 +++++----
src/service/git/gitlab/gitlab-client.ts | 13 +-
test/service/git/gitlab/gitlab-client.test.ts | 25 ++
test/support/mock/git-client-mock-support.ts | 6 +-
test/support/mock/gitlab-data.ts | 295 ++++++++++++++++++
6 files changed, 538 insertions(+), 109 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 9025d4e..69be712 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -1024,9 +1024,15 @@ class GitLabClient {
* @returns {{owner: string, project: string}}
*/
extractMergeRequestData(mrUrl) {
- const elems = mrUrl.replace("/-/", "/").split("/");
+ const { pathname } = new URL(mrUrl);
+ const elems = pathname.substring(1).replace("/-/", "/").split("/");
+ let namespace = "";
+ for (let i = 0; i < elems.length - 3; i++) {
+ namespace += elems[i] + "/";
+ }
+ namespace = namespace.substring(0, namespace.length - 1);
return {
- namespace: elems[elems.length - 4],
+ namespace: namespace,
project: elems[elems.length - 3],
id: parseInt(mrUrl.substring(mrUrl.lastIndexOf("/") + 1, mrUrl.length)),
};
@@ -19253,7 +19259,7 @@ exports.suggestSimilar = suggestSimilar;
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
"use strict";
-// Axios v1.4.0 Copyright (c) 2023 Matt Zabriskie and contributors
+// Axios v1.6.0 Copyright (c) 2023 Matt Zabriskie and contributors
const FormData$1 = __nccwpck_require__(4334);
@@ -19823,8 +19829,9 @@ const reduceDescriptors = (obj, reducer) => {
const reducedDescriptors = {};
forEach(descriptors, (descriptor, name) => {
- if (reducer(descriptor, name, obj) !== false) {
- reducedDescriptors[name] = descriptor;
+ let ret;
+ if ((ret = reducer(descriptor, name, obj)) !== false) {
+ reducedDescriptors[name] = ret || descriptor;
}
});
@@ -20608,10 +20615,6 @@ function formDataToJSON(formData) {
return null;
}
-const DEFAULT_CONTENT_TYPE = {
- 'Content-Type': undefined
-};
-
/**
* It takes a string, tries to parse it, and if it fails, it returns the stringified version
* of the input
@@ -20750,19 +20753,16 @@ const defaults = {
headers: {
common: {
- 'Accept': 'application/json, text/plain, */*'
+ 'Accept': 'application/json, text/plain, */*',
+ 'Content-Type': undefined
}
}
};
-utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
+utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {
defaults.headers[method] = {};
});
-utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
- defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
-});
-
const defaults$1 = defaults;
// RawAxiosHeaders whose duplicates are ignored by node
@@ -21096,7 +21096,17 @@ class AxiosHeaders {
AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);
-utils.freezeMethods(AxiosHeaders.prototype);
+// reserved names hotfix
+utils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {
+ let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`
+ return {
+ get: () => value,
+ set(headerValue) {
+ this[mapped] = headerValue;
+ }
+ }
+});
+
utils.freezeMethods(AxiosHeaders);
const AxiosHeaders$1 = AxiosHeaders;
@@ -21216,7 +21226,7 @@ function buildFullPath(baseURL, requestedURL) {
return requestedURL;
}
-const VERSION = "1.4.0";
+const VERSION = "1.6.0";
function parseProtocol(url) {
const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
@@ -21820,6 +21830,18 @@ const wrapAsync = (asyncExecutor) => {
})
};
+const resolveFamily = ({address, family}) => {
+ if (!utils.isString(address)) {
+ throw TypeError('address must be a string');
+ }
+ return ({
+ address,
+ family: family || (address.indexOf('.') < 0 ? 6 : 4)
+ });
+};
+
+const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});
+
/*eslint consistent-return:0*/
const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
@@ -21830,15 +21852,16 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
let rejected = false;
let req;
- if (lookup && utils.isAsyncFn(lookup)) {
- lookup = callbackify$1(lookup, (entry) => {
- if(utils.isString(entry)) {
- entry = [entry, entry.indexOf('.') < 0 ? 6 : 4];
- } else if (!utils.isArray(entry)) {
- throw new TypeError('lookup async function must return an array [ip: string, family: number]]')
- }
- return entry;
- });
+ if (lookup) {
+ const _lookup = callbackify$1(lookup, (value) => utils.isArray(value) ? value : [value]);
+ // hotfix to support opt.all option which is required for node 20.x
+ lookup = (hostname, opt, cb) => {
+ _lookup(hostname, opt, (err, arg0, arg1) => {
+ const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];
+
+ opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);
+ });
+ };
}
// temporary internal emitter until the AxiosRequest class will be implemented
@@ -22065,11 +22088,13 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
auth,
protocol,
family,
- lookup,
beforeRedirect: dispatchBeforeRedirect,
beforeRedirects: {}
};
+ // cacheable-lookup integration hotfix
+ !utils.isUndefined(lookup) && (options.lookup = lookup);
+
if (config.socketPath) {
options.socketPath = config.socketPath;
} else {
@@ -22143,7 +22168,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
delete res.headers['content-encoding'];
}
- switch (res.headers['content-encoding']) {
+ switch ((res.headers['content-encoding'] || '').toLowerCase()) {
/*eslint default-case:0*/
case 'gzip':
case 'x-gzip':
@@ -22239,7 +22264,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
}
response.data = responseData;
} catch (err) {
- reject(AxiosError.from(err, null, config, response.request, response));
+ return reject(AxiosError.from(err, null, config, response.request, response));
}
settle(resolve, reject, response);
});
@@ -22276,7 +22301,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
// This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
const timeout = parseInt(config.timeout, 10);
- if (isNaN(timeout)) {
+ if (Number.isNaN(timeout)) {
reject(new AxiosError(
'error trying to parse `config.timeout` to int',
AxiosError.ERR_BAD_OPTION_VALUE,
@@ -22495,11 +22520,16 @@ const xhrAdapter = isXHRAdapterSupported && function (config) {
}
}
+ let contentType;
+
if (utils.isFormData(requestData)) {
if (platform.isStandardBrowserEnv || platform.isStandardBrowserWebWorkerEnv) {
requestHeaders.setContentType(false); // Let the browser set it
- } else {
- requestHeaders.setContentType('multipart/form-data;', false); // mobile/desktop app frameworks
+ } else if(!requestHeaders.getContentType(/^\s*multipart\/form-data/)){
+ requestHeaders.setContentType('multipart/form-data'); // mobile/desktop app frameworks
+ } else if(utils.isString(contentType = requestHeaders.getContentType())){
+ // fix semicolon duplication issue for ReactNative FormData implementation
+ requestHeaders.setContentType(contentType.replace(/^\s*(multipart\/form-data);+/, '$1'));
}
}
@@ -22617,8 +22647,8 @@ const xhrAdapter = isXHRAdapterSupported && function (config) {
// Specifically not if we're in a web worker, or react-native.
if (platform.isStandardBrowserEnv) {
// Add xsrf header
- const xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath))
- && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
+ // regarding CVE-2023-45857 config.withCredentials condition was removed temporarily
+ const xsrfValue = isURLSameOrigin(fullPath) && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
if (xsrfValue) {
requestHeaders.set(config.xsrfHeaderName, xsrfValue);
@@ -22692,7 +22722,7 @@ const knownAdapters = {
};
utils.forEach(knownAdapters, (fn, value) => {
- if(fn) {
+ if (fn) {
try {
Object.defineProperty(fn, 'name', {value});
} catch (e) {
@@ -22702,6 +22732,10 @@ utils.forEach(knownAdapters, (fn, value) => {
}
});
+const renderReason = (reason) => `- ${reason}`;
+
+const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;
+
const adapters = {
getAdapter: (adapters) => {
adapters = utils.isArray(adapters) ? adapters : [adapters];
@@ -22710,32 +22744,46 @@ const adapters = {
let nameOrAdapter;
let adapter;
+ const rejectedReasons = {};
+
for (let i = 0; i < length; i++) {
nameOrAdapter = adapters[i];
- if((adapter = utils.isString(nameOrAdapter) ? knownAdapters[nameOrAdapter.toLowerCase()] : nameOrAdapter)) {
+ let id;
+
+ adapter = nameOrAdapter;
+
+ if (!isResolvedHandle(nameOrAdapter)) {
+ adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
+
+ if (adapter === undefined) {
+ throw new AxiosError(`Unknown adapter '${id}'`);
+ }
+ }
+
+ if (adapter) {
break;
}
+
+ rejectedReasons[id || '#' + i] = adapter;
}
if (!adapter) {
- if (adapter === false) {
- throw new AxiosError(
- `Adapter ${nameOrAdapter} is not supported by the environment`,
- 'ERR_NOT_SUPPORT'
+
+ const reasons = Object.entries(rejectedReasons)
+ .map(([id, state]) => `adapter ${id} ` +
+ (state === false ? 'is not supported by the environment' : 'is not available in the build')
);
- }
- throw new Error(
- utils.hasOwnProp(knownAdapters, nameOrAdapter) ?
- `Adapter '${nameOrAdapter}' is not available in the build` :
- `Unknown adapter '${nameOrAdapter}'`
+ let s = length ?
+ (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
+ 'as no adapter specified';
+
+ throw new AxiosError(
+ `There is no suitable adapter to dispatch the request ` + s,
+ 'ERR_NOT_SUPPORT'
);
}
- if (!utils.isFunction(adapter)) {
- throw new TypeError('adapter is not a function');
- }
-
return adapter;
},
adapters: knownAdapters
@@ -23066,15 +23114,13 @@ class Axios {
// Set config.method
config.method = (config.method || this.defaults.method || 'get').toLowerCase();
- let contextHeaders;
-
// Flatten headers
- contextHeaders = headers && utils.merge(
+ let contextHeaders = headers && utils.merge(
headers.common,
headers[config.method]
);
- contextHeaders && utils.forEach(
+ headers && utils.forEach(
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
(method) => {
delete headers[method];
@@ -23484,6 +23530,8 @@ axios.AxiosHeaders = AxiosHeaders$1;
axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
+axios.getAdapter = adapters.getAdapter;
+
axios.HttpStatusCode = HttpStatusCode$1;
axios.default = axios;
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 29dd2b5..72b2528 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -994,9 +994,15 @@ class GitLabClient {
* @returns {{owner: string, project: string}}
*/
extractMergeRequestData(mrUrl) {
- const elems = mrUrl.replace("/-/", "/").split("/");
+ const { pathname } = new URL(mrUrl);
+ const elems = pathname.substring(1).replace("/-/", "/").split("/");
+ let namespace = "";
+ for (let i = 0; i < elems.length - 3; i++) {
+ namespace += elems[i] + "/";
+ }
+ namespace = namespace.substring(0, namespace.length - 1);
return {
- namespace: elems[elems.length - 4],
+ namespace: namespace,
project: elems[elems.length - 3],
id: parseInt(mrUrl.substring(mrUrl.lastIndexOf("/") + 1, mrUrl.length)),
};
@@ -18666,7 +18672,7 @@ module.exports = require("zlib");
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
"use strict";
-// Axios v1.4.0 Copyright (c) 2023 Matt Zabriskie and contributors
+// Axios v1.6.0 Copyright (c) 2023 Matt Zabriskie and contributors
const FormData$1 = __nccwpck_require__(4334);
@@ -19236,8 +19242,9 @@ const reduceDescriptors = (obj, reducer) => {
const reducedDescriptors = {};
forEach(descriptors, (descriptor, name) => {
- if (reducer(descriptor, name, obj) !== false) {
- reducedDescriptors[name] = descriptor;
+ let ret;
+ if ((ret = reducer(descriptor, name, obj)) !== false) {
+ reducedDescriptors[name] = ret || descriptor;
}
});
@@ -20021,10 +20028,6 @@ function formDataToJSON(formData) {
return null;
}
-const DEFAULT_CONTENT_TYPE = {
- 'Content-Type': undefined
-};
-
/**
* It takes a string, tries to parse it, and if it fails, it returns the stringified version
* of the input
@@ -20163,19 +20166,16 @@ const defaults = {
headers: {
common: {
- 'Accept': 'application/json, text/plain, */*'
+ 'Accept': 'application/json, text/plain, */*',
+ 'Content-Type': undefined
}
}
};
-utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) {
+utils.forEach(['delete', 'get', 'head', 'post', 'put', 'patch'], (method) => {
defaults.headers[method] = {};
});
-utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
- defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
-});
-
const defaults$1 = defaults;
// RawAxiosHeaders whose duplicates are ignored by node
@@ -20509,7 +20509,17 @@ class AxiosHeaders {
AxiosHeaders.accessor(['Content-Type', 'Content-Length', 'Accept', 'Accept-Encoding', 'User-Agent', 'Authorization']);
-utils.freezeMethods(AxiosHeaders.prototype);
+// reserved names hotfix
+utils.reduceDescriptors(AxiosHeaders.prototype, ({value}, key) => {
+ let mapped = key[0].toUpperCase() + key.slice(1); // map `set` => `Set`
+ return {
+ get: () => value,
+ set(headerValue) {
+ this[mapped] = headerValue;
+ }
+ }
+});
+
utils.freezeMethods(AxiosHeaders);
const AxiosHeaders$1 = AxiosHeaders;
@@ -20629,7 +20639,7 @@ function buildFullPath(baseURL, requestedURL) {
return requestedURL;
}
-const VERSION = "1.4.0";
+const VERSION = "1.6.0";
function parseProtocol(url) {
const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
@@ -21233,6 +21243,18 @@ const wrapAsync = (asyncExecutor) => {
})
};
+const resolveFamily = ({address, family}) => {
+ if (!utils.isString(address)) {
+ throw TypeError('address must be a string');
+ }
+ return ({
+ address,
+ family: family || (address.indexOf('.') < 0 ? 6 : 4)
+ });
+};
+
+const buildAddressEntry = (address, family) => resolveFamily(utils.isObject(address) ? address : {address, family});
+
/*eslint consistent-return:0*/
const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
return wrapAsync(async function dispatchHttpRequest(resolve, reject, onDone) {
@@ -21243,15 +21265,16 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
let rejected = false;
let req;
- if (lookup && utils.isAsyncFn(lookup)) {
- lookup = callbackify$1(lookup, (entry) => {
- if(utils.isString(entry)) {
- entry = [entry, entry.indexOf('.') < 0 ? 6 : 4];
- } else if (!utils.isArray(entry)) {
- throw new TypeError('lookup async function must return an array [ip: string, family: number]]')
- }
- return entry;
- });
+ if (lookup) {
+ const _lookup = callbackify$1(lookup, (value) => utils.isArray(value) ? value : [value]);
+ // hotfix to support opt.all option which is required for node 20.x
+ lookup = (hostname, opt, cb) => {
+ _lookup(hostname, opt, (err, arg0, arg1) => {
+ const addresses = utils.isArray(arg0) ? arg0.map(addr => buildAddressEntry(addr)) : [buildAddressEntry(arg0, arg1)];
+
+ opt.all ? cb(err, addresses) : cb(err, addresses[0].address, addresses[0].family);
+ });
+ };
}
// temporary internal emitter until the AxiosRequest class will be implemented
@@ -21478,11 +21501,13 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
auth,
protocol,
family,
- lookup,
beforeRedirect: dispatchBeforeRedirect,
beforeRedirects: {}
};
+ // cacheable-lookup integration hotfix
+ !utils.isUndefined(lookup) && (options.lookup = lookup);
+
if (config.socketPath) {
options.socketPath = config.socketPath;
} else {
@@ -21556,7 +21581,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
delete res.headers['content-encoding'];
}
- switch (res.headers['content-encoding']) {
+ switch ((res.headers['content-encoding'] || '').toLowerCase()) {
/*eslint default-case:0*/
case 'gzip':
case 'x-gzip':
@@ -21652,7 +21677,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
}
response.data = responseData;
} catch (err) {
- reject(AxiosError.from(err, null, config, response.request, response));
+ return reject(AxiosError.from(err, null, config, response.request, response));
}
settle(resolve, reject, response);
});
@@ -21689,7 +21714,7 @@ const httpAdapter = isHttpAdapterSupported && function httpAdapter(config) {
// This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types.
const timeout = parseInt(config.timeout, 10);
- if (isNaN(timeout)) {
+ if (Number.isNaN(timeout)) {
reject(new AxiosError(
'error trying to parse `config.timeout` to int',
AxiosError.ERR_BAD_OPTION_VALUE,
@@ -21908,11 +21933,16 @@ const xhrAdapter = isXHRAdapterSupported && function (config) {
}
}
+ let contentType;
+
if (utils.isFormData(requestData)) {
if (platform.isStandardBrowserEnv || platform.isStandardBrowserWebWorkerEnv) {
requestHeaders.setContentType(false); // Let the browser set it
- } else {
- requestHeaders.setContentType('multipart/form-data;', false); // mobile/desktop app frameworks
+ } else if(!requestHeaders.getContentType(/^\s*multipart\/form-data/)){
+ requestHeaders.setContentType('multipart/form-data'); // mobile/desktop app frameworks
+ } else if(utils.isString(contentType = requestHeaders.getContentType())){
+ // fix semicolon duplication issue for ReactNative FormData implementation
+ requestHeaders.setContentType(contentType.replace(/^\s*(multipart\/form-data);+/, '$1'));
}
}
@@ -22030,8 +22060,8 @@ const xhrAdapter = isXHRAdapterSupported && function (config) {
// Specifically not if we're in a web worker, or react-native.
if (platform.isStandardBrowserEnv) {
// Add xsrf header
- const xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath))
- && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
+ // regarding CVE-2023-45857 config.withCredentials condition was removed temporarily
+ const xsrfValue = isURLSameOrigin(fullPath) && config.xsrfCookieName && cookies.read(config.xsrfCookieName);
if (xsrfValue) {
requestHeaders.set(config.xsrfHeaderName, xsrfValue);
@@ -22105,7 +22135,7 @@ const knownAdapters = {
};
utils.forEach(knownAdapters, (fn, value) => {
- if(fn) {
+ if (fn) {
try {
Object.defineProperty(fn, 'name', {value});
} catch (e) {
@@ -22115,6 +22145,10 @@ utils.forEach(knownAdapters, (fn, value) => {
}
});
+const renderReason = (reason) => `- ${reason}`;
+
+const isResolvedHandle = (adapter) => utils.isFunction(adapter) || adapter === null || adapter === false;
+
const adapters = {
getAdapter: (adapters) => {
adapters = utils.isArray(adapters) ? adapters : [adapters];
@@ -22123,32 +22157,46 @@ const adapters = {
let nameOrAdapter;
let adapter;
+ const rejectedReasons = {};
+
for (let i = 0; i < length; i++) {
nameOrAdapter = adapters[i];
- if((adapter = utils.isString(nameOrAdapter) ? knownAdapters[nameOrAdapter.toLowerCase()] : nameOrAdapter)) {
+ let id;
+
+ adapter = nameOrAdapter;
+
+ if (!isResolvedHandle(nameOrAdapter)) {
+ adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
+
+ if (adapter === undefined) {
+ throw new AxiosError(`Unknown adapter '${id}'`);
+ }
+ }
+
+ if (adapter) {
break;
}
+
+ rejectedReasons[id || '#' + i] = adapter;
}
if (!adapter) {
- if (adapter === false) {
- throw new AxiosError(
- `Adapter ${nameOrAdapter} is not supported by the environment`,
- 'ERR_NOT_SUPPORT'
+
+ const reasons = Object.entries(rejectedReasons)
+ .map(([id, state]) => `adapter ${id} ` +
+ (state === false ? 'is not supported by the environment' : 'is not available in the build')
);
- }
- throw new Error(
- utils.hasOwnProp(knownAdapters, nameOrAdapter) ?
- `Adapter '${nameOrAdapter}' is not available in the build` :
- `Unknown adapter '${nameOrAdapter}'`
+ let s = length ?
+ (reasons.length > 1 ? 'since :\n' + reasons.map(renderReason).join('\n') : ' ' + renderReason(reasons[0])) :
+ 'as no adapter specified';
+
+ throw new AxiosError(
+ `There is no suitable adapter to dispatch the request ` + s,
+ 'ERR_NOT_SUPPORT'
);
}
- if (!utils.isFunction(adapter)) {
- throw new TypeError('adapter is not a function');
- }
-
return adapter;
},
adapters: knownAdapters
@@ -22479,15 +22527,13 @@ class Axios {
// Set config.method
config.method = (config.method || this.defaults.method || 'get').toLowerCase();
- let contextHeaders;
-
// Flatten headers
- contextHeaders = headers && utils.merge(
+ let contextHeaders = headers && utils.merge(
headers.common,
headers[config.method]
);
- contextHeaders && utils.forEach(
+ headers && utils.forEach(
['delete', 'get', 'head', 'post', 'put', 'patch', 'common'],
(method) => {
delete headers[method];
@@ -22897,6 +22943,8 @@ axios.AxiosHeaders = AxiosHeaders$1;
axios.formToJSON = thing => formDataToJSON(utils.isHTMLForm(thing) ? new FormData(thing) : thing);
+axios.getAdapter = adapters.getAdapter;
+
axios.HttpStatusCode = HttpStatusCode$1;
axios.default = axios;
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index a6d21b8..0d1f962 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -181,9 +181,18 @@ export default class GitLabClient implements GitClient {
* @returns {{owner: string, project: string}}
*/
private extractMergeRequestData(mrUrl: string): {namespace: string, project: string, id: number} {
- const elems: string[] = mrUrl.replace("/-/", "/").split("/");
+ const { pathname } = new URL(mrUrl);
+ const elems: string[] = pathname.substring(1).replace("/-/", "/").split("/");
+ let namespace = "";
+
+ for (let i = 0; i < elems.length - 3; i++) {
+ namespace += elems[i] + "/";
+ }
+
+ namespace = namespace.substring(0, namespace.length - 1);
+
return {
- namespace: elems[elems.length - 4],
+ namespace: namespace,
project: elems[elems.length - 3],
id: parseInt(mrUrl.substring(mrUrl.lastIndexOf("/") + 1, mrUrl.length)),
};
diff --git a/test/service/git/gitlab/gitlab-client.test.ts b/test/service/git/gitlab/gitlab-client.test.ts
index 57aa125..b33ab9e 100644
--- a/test/service/git/gitlab/gitlab-client.test.ts
+++ b/test/service/git/gitlab/gitlab-client.test.ts
@@ -323,4 +323,29 @@ describe("github service", () => {
body: "this is second comment",
});
});
+
+ 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");
+
+ // check content
+ expect(res.sourceRepo).toEqual({
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example.git"
+ });
+ expect(res.targetRepo).toEqual({
+ owner: "superuser",
+ project: "backporting-example",
+ cloneUrl: "https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example.git"
+ });
+ expect(res.title).toBe("Update test.txt");
+ expect(res.commits!.length).toBe(1);
+ expect(res.commits).toEqual(["ebb1eca696c42fd067658bd9b5267709f78ef38e"]);
+
+ // check axios invocation
+ expect(axiosInstanceSpy.get).toBeCalledTimes(3); // merge request and 2 repos
+ expect(axiosInstanceSpy.get).toBeCalledWith("/projects/mysuperorg%2F6%2Fmysuperproduct%2Fmysuperunit%2Fbackporting-example/merge_requests/4");
+ expect(axiosInstanceSpy.get).toBeCalledWith("/projects/1645");
+ expect(axiosInstanceSpy.get).toBeCalledWith("/projects/1645");
+ });
});
\ No newline at end of file
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index 985f799..b1c2886 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -1,7 +1,7 @@
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 { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
+import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
// high number, for each test we are not expecting
// to send more than 3 reqs per api endpoint
@@ -22,8 +22,12 @@ export const getAxiosMocked = (url: string) => {
data = OPEN_MR;
} else if (url.endsWith("merge_requests/3")) {
data = CLOSED_NOT_MERGED_MR;
+ } else if (url.endsWith("merge_requests/4")) {
+ data = NESTED_NAMESPACE_MR;
} else if (url.endsWith("projects/76316")) {
data = PROJECT_EXAMPLE;
+ } else if (url.endsWith("projects/1645")) {
+ data = NESTED_PROJECT_EXAMPLE;
} else if (url.endsWith("users?username=superuser")) {
data = [SUPERUSER];
} else if (url.endsWith("merge_requests/2/commits")) {
diff --git a/test/support/mock/gitlab-data.ts b/test/support/mock/gitlab-data.ts
index 119913a..a7455fc 100644
--- a/test/support/mock/gitlab-data.ts
+++ b/test/support/mock/gitlab-data.ts
@@ -161,6 +161,166 @@ export const PROJECT_EXAMPLE = {
}
};
+export const NESTED_PROJECT_EXAMPLE = {
+ "id":1645,
+ "description":null,
+ "name":"Backporting Example",
+ "name_with_namespace":"Super User / Backporting Example",
+ "path":"backporting-example",
+ "path_with_namespace":"mysuperorg/6/mysuperproduct/mysuperunit/backporting-example",
+ "created_at":"2023-06-23T13:45:15.121Z",
+ "default_branch":"main",
+ "tag_list":[
+
+ ],
+ "topics":[
+
+ ],
+ "ssh_url_to_repo":"git@my.gitlab.host.com:mysuperorg/6/mysuperproduct/mysuperunit/backporting-example.git",
+ "http_url_to_repo":"https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example.git",
+ "web_url":"https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example",
+ "readme_url":"https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example/-/blob/main/README.md",
+ "forks_count":0,
+ "avatar_url":null,
+ "star_count":0,
+ "last_activity_at":"2023-06-28T14:05:42.596Z",
+ "namespace":{
+ "id":70747,
+ "name":"Super User",
+ "path":"superuser",
+ "kind":"user",
+ "full_path":"superuser",
+ "parent_id":null,
+ "avatar_url":"/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ "_links":{
+ "self":"https://my.gitlab.host.com/api/v4/projects/1645",
+ "issues":"https://my.gitlab.host.com/api/v4/projects/1645/issues",
+ "merge_requests":"https://my.gitlab.host.com/api/v4/projects/1645/merge_requests",
+ "repo_branches":"https://my.gitlab.host.com/api/v4/projects/1645/repository/branches",
+ "labels":"https://my.gitlab.host.com/api/v4/projects/1645/labels",
+ "events":"https://my.gitlab.host.com/api/v4/projects/1645/events",
+ "members":"https://my.gitlab.host.com/api/v4/projects/1645/members",
+ "cluster_agents":"https://my.gitlab.host.com/api/v4/projects/1645/cluster_agents"
+ },
+ "packages_enabled":true,
+ "empty_repo":false,
+ "archived":false,
+ "visibility":"private",
+ "owner":{
+ "id":14041,
+ "username":"superuser",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ "resolve_outdated_diff_discussions":false,
+ "container_expiration_policy":{
+ "cadence":"1d",
+ "enabled":false,
+ "keep_n":10,
+ "older_than":"90d",
+ "name_regex":".*",
+ "name_regex_keep":null,
+ "next_run_at":"2023-06-24T13:45:15.167Z"
+ },
+ "issues_enabled":true,
+ "merge_requests_enabled":true,
+ "wiki_enabled":true,
+ "jobs_enabled":true,
+ "snippets_enabled":true,
+ "container_registry_enabled":true,
+ "service_desk_enabled":false,
+ "service_desk_address":null,
+ "can_create_merge_request_in":true,
+ "issues_access_level":"enabled",
+ "repository_access_level":"enabled",
+ "merge_requests_access_level":"enabled",
+ "forking_access_level":"enabled",
+ "wiki_access_level":"enabled",
+ "builds_access_level":"enabled",
+ "snippets_access_level":"enabled",
+ "pages_access_level":"private",
+ "analytics_access_level":"enabled",
+ "container_registry_access_level":"enabled",
+ "security_and_compliance_access_level":"private",
+ "releases_access_level":"enabled",
+ "environments_access_level":"enabled",
+ "feature_flags_access_level":"enabled",
+ "infrastructure_access_level":"enabled",
+ "monitor_access_level":"enabled",
+ "emails_disabled":null,
+ "shared_runners_enabled":true,
+ "lfs_enabled":true,
+ "creator_id":14041,
+ "import_url":null,
+ "import_type":null,
+ "import_status":"none",
+ "import_error":null,
+ "open_issues_count":0,
+ "description_html":"",
+ "updated_at":"2023-06-28T14:05:42.596Z",
+ "ci_default_git_depth":20,
+ "ci_forward_deployment_enabled":true,
+ "ci_job_token_scope_enabled":false,
+ "ci_separated_caches":true,
+ "ci_allow_fork_pipelines_to_run_in_parent_project":true,
+ "build_git_strategy":"fetch",
+ "keep_latest_artifact":true,
+ "restrict_user_defined_variables":false,
+ "runners_token":"TOKEN",
+ "runner_token_expiration_interval":null,
+ "group_runners_enabled":true,
+ "auto_cancel_pending_pipelines":"enabled",
+ "build_timeout":3600,
+ "auto_devops_enabled":false,
+ "auto_devops_deploy_strategy":"continuous",
+ "ci_config_path":"",
+ "public_jobs":true,
+ "shared_with_groups":[
+
+ ],
+ "only_allow_merge_if_pipeline_succeeds":false,
+ "allow_merge_on_skipped_pipeline":null,
+ "request_access_enabled":true,
+ "only_allow_merge_if_all_discussions_are_resolved":false,
+ "remove_source_branch_after_merge":true,
+ "printing_merge_request_link_enabled":true,
+ "merge_method":"merge",
+ "squash_option":"default_off",
+ "enforce_auth_checks_on_uploads":true,
+ "suggestion_commit_message":null,
+ "merge_commit_template":null,
+ "squash_commit_template":null,
+ "issue_branch_template":null,
+ "autoclose_referenced_issues":true,
+ "approvals_before_merge":0,
+ "mirror":false,
+ "external_authorization_classification_label":null,
+ "marked_for_deletion_at":null,
+ "marked_for_deletion_on":null,
+ "requirements_enabled":false,
+ "requirements_access_level":"enabled",
+ "security_and_compliance_enabled":true,
+ "compliance_frameworks":[
+
+ ],
+ "issues_template":null,
+ "merge_requests_template":null,
+ "merge_pipelines_enabled":false,
+ "merge_trains_enabled":false,
+ "allow_pipeline_trigger_approve_deployment":false,
+ "permissions":{
+ "project_access":{
+ "access_level":50,
+ "notification_level":3
+ },
+ "group_access":null
+ }
+ };
+
export const MERGED_SQUASHED_MR = {
"id":807106,
"iid":1,
@@ -580,3 +740,138 @@ export const SUPERUSER = {
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
};
+
+export const NESTED_NAMESPACE_MR = {
+ "id":807106,
+ "iid":1,
+ "project_id":1645,
+ "title":"Update test.txt",
+ "description":"This is the body",
+ "state":"merged",
+ "created_at":"2023-06-28T14:32:40.943Z",
+ "updated_at":"2023-06-28T14:37:12.108Z",
+ "merged_by":{
+ "id":14041,
+ "username":"superuser",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ "merge_user":{
+ "id":14041,
+ "username":"superuser",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ "merged_at":"2023-06-28T14:37:11.667Z",
+ "closed_by":null,
+ "closed_at":null,
+ "target_branch":"main",
+ "source_branch":"feature",
+ "user_notes_count":0,
+ "upvotes":0,
+ "downvotes":0,
+ "author":{
+ "id":14041,
+ "username":"superuser",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ "assignees":[
+ {
+ "id":14041,
+ "username":"superuser",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ }
+ ],
+ "assignee":{
+ "id":14041,
+ "username":"superuser",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ "reviewers":[
+ {
+ "id":1404188,
+ "username":"superuser1",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ },
+ {
+ "id":1404199,
+ "username":"superuser2",
+ "name":"Super User",
+ "state":"active",
+ "avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
+ "web_url":"https://my.gitlab.host.com/superuser"
+ }
+ ],
+ "source_project_id":1645,
+ "target_project_id":1645,
+ "labels":[
+ "gitlab-original-label"
+ ],
+ "draft":false,
+ "work_in_progress":false,
+ "milestone":null,
+ "merge_when_pipeline_succeeds":false,
+ "merge_status":"can_be_merged",
+ "detailed_merge_status":"not_open",
+ "sha":"9e15674ebd48e05c6e428a1fa31dbb60a778d644",
+ "merge_commit_sha":"4d369c3e9a8d1d5b7e56c892a8ab2a7666583ac3",
+ "squash_commit_sha":"ebb1eca696c42fd067658bd9b5267709f78ef38e",
+ "discussion_locked":null,
+ "should_remove_source_branch":true,
+ "force_remove_source_branch":true,
+ "reference":"!2",
+ "references":{
+ "short":"!2",
+ "relative":"!2",
+ "full":"superuser/backporting-example!2"
+ },
+ "web_url":"https://my.gitlab.host.com/mysuperorg/6/mysuperproduct/mysuperunit/backporting-example/-/merge_requests/4",
+ "time_stats":{
+ "time_estimate":0,
+ "total_time_spent":0,
+ "human_time_estimate":null,
+ "human_total_time_spent":null
+ },
+ "squash":true,
+ "squash_on_merge":true,
+ "task_completion_status":{
+ "count":0,
+ "completed_count":0
+ },
+ "has_conflicts":false,
+ "blocking_discussions_resolved":true,
+ "approvals_before_merge":null,
+ "subscribed":true,
+ "changes_count":"1",
+ "latest_build_started_at":null,
+ "latest_build_finished_at":null,
+ "first_deployed_to_production_at":null,
+ "pipeline":null,
+ "head_pipeline":null,
+ "diff_refs":{
+ "base_sha":"2c553a0c4c133a51806badce5fa4842b7253cb3b",
+ "head_sha":"9e15674ebd48e05c6e428a1fa31dbb60a778d644",
+ "start_sha":"2c553a0c4c133a51806badce5fa4842b7253cb3b"
+ },
+ "merge_error":null,
+ "first_contribution":false,
+ "user":{
+ "can_merge":true
+ }
+ };
From aac73bf7c5fd0e94086d421b6b9646d77efdad76 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Tue, 5 Dec 2023 16:25:50 +0100
Subject: [PATCH 27/75] chore: release v4.4.1 (#87)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 7 +++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9bb5765..92d6197 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [4.4.1](https://github.com/kiegroup/git-backporting/compare/v4.4.0...v4.4.1) (2023-12-05)
+
+
+### Bug Fixes
+
+* namespace parsing in gitlab ([#84](https://github.com/kiegroup/git-backporting/issues/84)) ([ed32d22](https://github.com/kiegroup/git-backporting/commit/ed32d2275b6008d31e456c41beecd536eceb23dc))
+
## [4.4.0](https://github.com/kiegroup/git-backporting/compare/v4.3.0...v4.4.0) (2023-08-18)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 69be712..d213c76 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23546,7 +23546,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.4.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.4.1","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 54f86cd..41a0f02 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.4.0",
+ "version": "4.4.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.4.0",
+ "version": "4.4.1",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index 45a3226..16177bb 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.4.0",
+ "version": "4.4.1",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From 70da575afce603190eafed927637922a37fbd087 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Sun, 10 Dec 2023 22:05:53 +0100
Subject: [PATCH 28/75] feat(gh-85): take git tokens from environment (#88)
---
README.md | 17 ++-
action.yml | 2 +-
dist/cli/index.js | 85 ++++++++++++++-
dist/gha/index.js | 83 ++++++++++++++-
src/service/args/cli/cli-args-parser.ts | 2 +-
src/service/configs/configs-parser.ts | 41 ++++++-
src/service/configs/configs.types.ts | 10 ++
.../configs/pullrequest/pr-configs-parser.ts | 12 ++-
src/service/git/git-client-factory.ts | 2 +-
src/service/git/git-client.ts | 7 +-
src/service/git/github/github-client.ts | 8 +-
src/service/git/gitlab/gitlab-client.ts | 6 +-
.../github-pr-configs-parser-multiple.test.ts | 5 +-
.../github-pr-configs-parser.test.ts | 88 ++++++++++++++-
.../gitlab-pr-configs-parser-multiple.test.ts | 4 +
.../gitlab-pr-configs-parser.test.ts | 100 +++++++++++++++++-
test/support/utils.ts | 8 ++
17 files changed, 456 insertions(+), 24 deletions(-)
diff --git a/README.md b/README.md
index fba7fb3..57734a5 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Target Branches | -tb, --target-branch | N | Comma separated list of branches where the changes must be backported to | |
| Pull Request | -pr, --pull-request | N | Original pull request url, the one that must be backported, e.g., https://github.com/kiegroup/git-backporting/pull/1 | |
| Configuration File | -cf, --config-file | N | Configuration file, in JSON format, containing all options to be overridded, note that if provided all other CLI options will be ignored | |
-| Auth | -a, --auth | N | `GITHUB_TOKEN`, `GITLAB_TOKEN` or a `repo` scoped [Personal Access Token](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) | "" |
+| Auth | -a, --auth | N | Git access/authorization token, if provided all token env variables will be ignored. See [auth token](#authorization-token) section for more details | "" |
| Folder | -f, --folder | N | Local folder full name of the repository that will be checked out, e.g., /tmp/folder | {cwd}/bp |
| Git User | -gu, --git-user | N | Local git user name | "GitHub" |
| Git Email | -ge, --git-email | N | Local git user email | "noreply@github.com" |
@@ -118,6 +118,17 @@ This tool comes with some inputs that allow users to override the default behavi
> **NOTE**: `pull request` and `target branch` are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
+#### Authorization token
+
+Since version `4.5.0` we introduced a new feature that allows user to provide the git access token through environment variables. These env variables are taken into consideration only if the `--auth/-a` is not provided as argument/input.
+Here the supported list of env variables:
+- `GITHUB_TOKEN`: this is checked only if backporting on Github platform.
+- `GITLAB_TOKEN`: this is checked only if backporting on Gitlab platform.
+- `CODEBERG_TOKEN`: this is checked only if backporting on Codeberg platform.
+- `GIT_TOKEN`: this is considered if none of the previous envs are set.
+
+> **NOTE**: if `--auth` argument is provided, all env variables will be ignored even if not empty.
+
#### Configuration file example
This is an example of a configuration file that can be used.
@@ -194,6 +205,9 @@ on:
- closed
- labeled
+env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
jobs:
backporting:
name: "Backporting"
@@ -216,7 +230,6 @@ jobs:
with:
target-branch: v1
pull-request: ${{ github.event.pull_request.url }}
- auth: ${{ secrets.GITHUB_TOKEN }}
```
For a complete description of all inputs see [Inputs section](#inputs).
diff --git a/action.yml b/action.yml
index 6f69528..aad7087 100644
--- a/action.yml
+++ b/action.yml
@@ -15,7 +15,7 @@ inputs:
required: false
default: "false"
auth:
- description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)"
+ description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT), if not provided will look for existing env variables like GITHUB_TOKEN"
default: ${{ github.token }}
required: false
git-user:
diff --git a/dist/cli/index.js b/dist/cli/index.js
index d213c76..24e6781 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -182,7 +182,7 @@ class CLIArgsParser extends args_parser_1.default {
.option("-tb, --target-branch ", "comma separated list of branches where changes must be backported to")
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
- .option("-a, --auth ", "git service authentication string, e.g., github token")
+ .option("-a, --auth ", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
.option("-gu, --git-user ", "local git user name, default is 'GitHub'")
.option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'")
.option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder")
@@ -251,7 +251,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const configs_types_1 = __nccwpck_require__(4753);
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
+const git_types_1 = __nccwpck_require__(750);
/**
* Abstract configuration parser class in charge to parse
* Args and produces a common Configs object
@@ -273,10 +275,68 @@ class ConfigsParser {
}
return Promise.resolve(configs);
}
+ /**
+ * 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.
+ * @param gitType
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+ getGitTokenFromEnv(gitType) {
+ let [token] = this.getEnv(configs_types_1.AuthTokenId.GIT_TOKEN);
+ let [specToken, specOk] = [undefined, false];
+ if (git_types_1.GitClientType.GITHUB == gitType) {
+ [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITHUB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.GITLAB == gitType) {
+ [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITLAB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.CODEBERG == gitType) {
+ [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
+ }
+ if (specOk) {
+ token = specToken;
+ }
+ return token;
+ }
+ /**
+ * Get process env variable given the input key string
+ * @param key
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+ getEnv(key) {
+ const val = process.env[key];
+ return [val, val !== undefined && val !== ""];
+ }
}
exports["default"] = ConfigsParser;
+/***/ }),
+
+/***/ 4753:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.AuthTokenId = void 0;
+var AuthTokenId;
+(function (AuthTokenId) {
+ // github specific token
+ AuthTokenId["GITHUB_TOKEN"] = "GITHUB_TOKEN";
+ // gitlab specific token
+ AuthTokenId["GITLAB_TOKEN"] = "GITLAB_TOKEN";
+ // codeberg specific token
+ AuthTokenId["CODEBERG_TOKEN"] = "CODEBERG_TOKEN";
+ // generic git token
+ AuthTokenId["GIT_TOKEN"] = "GIT_TOKEN";
+})(AuthTokenId = exports.AuthTokenId || (exports.AuthTokenId = {}));
+
+
/***/ }),
/***/ 6618:
@@ -311,9 +371,18 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
}
+ // setup the auth token
+ let token = args.auth;
+ if (token === undefined) {
+ this.logger.info("Auth argument not provided, checking available tokens from env..");
+ token = this.getGitTokenFromEnv(this.gitClient.getClientType());
+ if (!token) {
+ this.logger.info("Git token not set in the env");
+ }
+ }
return {
dryRun: args.dryRun,
- auth: args.auth,
+ auth: token,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
@@ -567,7 +636,7 @@ class GitClientFactory {
GitClientFactory.instance = new gitlab_client_1.default(authToken, apiUrl);
break;
case git_types_1.GitClientType.CODEBERG:
- GitClientFactory.instance = new github_client_1.default(authToken, apiUrl);
+ GitClientFactory.instance = new github_client_1.default(authToken, apiUrl, true);
break;
default:
throw new Error(`Invalid git service type received: ${type}`);
@@ -673,12 +742,16 @@ const github_mapper_1 = __importDefault(__nccwpck_require__(5764));
const octokit_factory_1 = __importDefault(__nccwpck_require__(4257));
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
class GitHubClient {
- constructor(token, apiUrl) {
+ constructor(token, apiUrl, isForCodeberg = false) {
this.apiUrl = apiUrl;
+ this.isForCodeberg = isForCodeberg;
this.logger = logger_service_factory_1.default.getLogger();
this.octokit = octokit_factory_1.default.getOctokit(token, this.apiUrl);
this.mapper = new github_mapper_1.default();
}
+ getClientType() {
+ return this.isForCodeberg ? git_types_1.GitClientType.CODEBERG : git_types_1.GitClientType.GITHUB;
+ }
// READ
getDefaultGitUser() {
return this.apiUrl.includes(git_types_1.GitClientType.CODEBERG.toString()) ? "Codeberg" : "GitHub";
@@ -889,6 +962,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const git_types_1 = __nccwpck_require__(750);
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
const gitlab_mapper_1 = __importDefault(__nccwpck_require__(2675));
const axios_1 = __importDefault(__nccwpck_require__(8757));
@@ -909,6 +983,9 @@ class GitLabClient {
});
this.mapper = new gitlab_mapper_1.default(this.client);
}
+ getClientType() {
+ return git_types_1.GitClientType.GITLAB;
+ }
getDefaultGitUser() {
return "Gitlab";
}
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 72b2528..344c82f 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -221,7 +221,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const configs_types_1 = __nccwpck_require__(4753);
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
+const git_types_1 = __nccwpck_require__(750);
/**
* Abstract configuration parser class in charge to parse
* Args and produces a common Configs object
@@ -243,10 +245,68 @@ class ConfigsParser {
}
return Promise.resolve(configs);
}
+ /**
+ * 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.
+ * @param gitType
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+ getGitTokenFromEnv(gitType) {
+ let [token] = this.getEnv(configs_types_1.AuthTokenId.GIT_TOKEN);
+ let [specToken, specOk] = [undefined, false];
+ if (git_types_1.GitClientType.GITHUB == gitType) {
+ [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITHUB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.GITLAB == gitType) {
+ [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITLAB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.CODEBERG == gitType) {
+ [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
+ }
+ if (specOk) {
+ token = specToken;
+ }
+ return token;
+ }
+ /**
+ * Get process env variable given the input key string
+ * @param key
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+ getEnv(key) {
+ const val = process.env[key];
+ return [val, val !== undefined && val !== ""];
+ }
}
exports["default"] = ConfigsParser;
+/***/ }),
+
+/***/ 4753:
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.AuthTokenId = void 0;
+var AuthTokenId;
+(function (AuthTokenId) {
+ // github specific token
+ AuthTokenId["GITHUB_TOKEN"] = "GITHUB_TOKEN";
+ // gitlab specific token
+ AuthTokenId["GITLAB_TOKEN"] = "GITLAB_TOKEN";
+ // codeberg specific token
+ AuthTokenId["CODEBERG_TOKEN"] = "CODEBERG_TOKEN";
+ // generic git token
+ AuthTokenId["GIT_TOKEN"] = "GIT_TOKEN";
+})(AuthTokenId = exports.AuthTokenId || (exports.AuthTokenId = {}));
+
+
/***/ }),
/***/ 6618:
@@ -281,9 +341,18 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
}
+ // setup the auth token
+ let token = args.auth;
+ if (token === undefined) {
+ this.logger.info("Auth argument not provided, checking available tokens from env..");
+ token = this.getGitTokenFromEnv(this.gitClient.getClientType());
+ if (!token) {
+ this.logger.info("Git token not set in the env");
+ }
+ }
return {
dryRun: args.dryRun,
- auth: args.auth,
+ auth: token,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
@@ -537,7 +606,7 @@ class GitClientFactory {
GitClientFactory.instance = new gitlab_client_1.default(authToken, apiUrl);
break;
case git_types_1.GitClientType.CODEBERG:
- GitClientFactory.instance = new github_client_1.default(authToken, apiUrl);
+ GitClientFactory.instance = new github_client_1.default(authToken, apiUrl, true);
break;
default:
throw new Error(`Invalid git service type received: ${type}`);
@@ -643,12 +712,16 @@ const github_mapper_1 = __importDefault(__nccwpck_require__(5764));
const octokit_factory_1 = __importDefault(__nccwpck_require__(4257));
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
class GitHubClient {
- constructor(token, apiUrl) {
+ constructor(token, apiUrl, isForCodeberg = false) {
this.apiUrl = apiUrl;
+ this.isForCodeberg = isForCodeberg;
this.logger = logger_service_factory_1.default.getLogger();
this.octokit = octokit_factory_1.default.getOctokit(token, this.apiUrl);
this.mapper = new github_mapper_1.default();
}
+ getClientType() {
+ return this.isForCodeberg ? git_types_1.GitClientType.CODEBERG : git_types_1.GitClientType.GITHUB;
+ }
// READ
getDefaultGitUser() {
return this.apiUrl.includes(git_types_1.GitClientType.CODEBERG.toString()) ? "Codeberg" : "GitHub";
@@ -859,6 +932,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
+const git_types_1 = __nccwpck_require__(750);
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
const gitlab_mapper_1 = __importDefault(__nccwpck_require__(2675));
const axios_1 = __importDefault(__nccwpck_require__(8757));
@@ -879,6 +953,9 @@ class GitLabClient {
});
this.mapper = new gitlab_mapper_1.default(this.client);
}
+ getClientType() {
+ return git_types_1.GitClientType.GITLAB;
+ }
getDefaultGitUser() {
return "Gitlab";
}
diff --git a/src/service/args/cli/cli-args-parser.ts b/src/service/args/cli/cli-args-parser.ts
index 9a9b348..c8ebc92 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -13,7 +13,7 @@ export default class CLIArgsParser extends ArgsParser {
.option("-tb, --target-branch ", "comma separated list of branches where changes must be backported to")
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
- .option("-a, --auth ", "git service authentication string, e.g., github token")
+ .option("-a, --auth ", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
.option("-gu, --git-user ", "local git user name, default is 'GitHub'")
.option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'")
.option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder")
diff --git a/src/service/configs/configs-parser.ts b/src/service/configs/configs-parser.ts
index 5b901cb..379e39b 100644
--- a/src/service/configs/configs-parser.ts
+++ b/src/service/configs/configs-parser.ts
@@ -1,7 +1,8 @@
import { Args } from "@bp/service/args/args.types";
-import { Configs } from "@bp/service/configs/configs.types";
+import { AuthTokenId, Configs } from "@bp/service/configs/configs.types";
import LoggerService from "../logger/logger-service";
import LoggerServiceFactory from "../logger/logger-service-factory";
+import { GitClientType } from "../git/git.types";
/**
* Abstract configuration parser class in charge to parse
@@ -34,4 +35,42 @@ import LoggerServiceFactory from "../logger/logger-service-factory";
return Promise.resolve(configs);
}
+
+ /**
+ * 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.
+ * @param gitType
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+ public getGitTokenFromEnv(gitType: GitClientType): string | undefined {
+ let [token] = this.getEnv(AuthTokenId.GIT_TOKEN);
+ let [specToken, specOk]: [string | undefined, boolean] = [undefined, false];
+ if (GitClientType.GITHUB == gitType) {
+ [specToken, specOk] = this.getEnv(AuthTokenId.GITHUB_TOKEN);
+ } else if (GitClientType.GITLAB == gitType) {
+ [specToken, specOk] = this.getEnv(AuthTokenId.GITLAB_TOKEN);
+ } else if (GitClientType.CODEBERG == gitType) {
+ [specToken, specOk] = this.getEnv(AuthTokenId.CODEBERG_TOKEN);
+ }
+
+ if (specOk) {
+ token = specToken;
+ }
+
+ return token;
+ }
+
+ /**
+ * Get process env variable given the input key string
+ * @param key
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+ public getEnv(key: string): [string | undefined, boolean] {
+ const val = process.env[key];
+ return [val, val !== undefined && val !== ""];
+ }
}
\ No newline at end of file
diff --git a/src/service/configs/configs.types.ts b/src/service/configs/configs.types.ts
index fa44e51..b7ed0e8 100644
--- a/src/service/configs/configs.types.ts
+++ b/src/service/configs/configs.types.ts
@@ -21,3 +21,13 @@ export interface Configs {
backportPullRequests: BackportPullRequest[],
}
+export enum AuthTokenId {
+ // github specific token
+ GITHUB_TOKEN = "GITHUB_TOKEN",
+ // gitlab specific token
+ GITLAB_TOKEN = "GITLAB_TOKEN",
+ // codeberg specific token
+ CODEBERG_TOKEN = "CODEBERG_TOKEN",
+ // generic git token
+ GIT_TOKEN = "GIT_TOKEN",
+}
\ No newline at end of file
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 00e220e..34c3c88 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -33,9 +33,19 @@ export default class PullRequestConfigsParser extends ConfigsParser {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
}
+ // setup the auth token
+ let token = args.auth;
+ if (token === undefined) {
+ this.logger.info("Auth argument not provided, checking available tokens from env..");
+ token = this.getGitTokenFromEnv(this.gitClient.getClientType());
+ if (!token) {
+ this.logger.info("Git token not set in the env");
+ }
+ }
+
return {
dryRun: args.dryRun!,
- auth: args.auth,
+ auth: token,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
diff --git a/src/service/git/git-client-factory.ts b/src/service/git/git-client-factory.ts
index ed66a75..7b38308 100644
--- a/src/service/git/git-client-factory.ts
+++ b/src/service/git/git-client-factory.ts
@@ -44,7 +44,7 @@ export default class GitClientFactory {
GitClientFactory.instance = new GitLabClient(authToken, apiUrl);
break;
case GitClientType.CODEBERG:
- GitClientFactory.instance = new GitHubService(authToken, apiUrl);
+ GitClientFactory.instance = new GitHubService(authToken, apiUrl, true);
break;
default:
throw new Error(`Invalid git service type received: ${type}`);
diff --git a/src/service/git/git-client.ts b/src/service/git/git-client.ts
index 7b98c1b..c9d0f10 100644
--- a/src/service/git/git-client.ts
+++ b/src/service/git/git-client.ts
@@ -1,4 +1,4 @@
-import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
+import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/git/git.types";
/**
* Git management service interface, which provides a common API for interacting
@@ -6,6 +6,11 @@ import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
*/
export default interface GitClient {
+ /**
+ * @returns {GitClientType} specific git client enum type
+ */
+ getClientType(): GitClientType
+
// READ
getDefaultGitUser(): string;
diff --git a/src/service/git/github/github-client.ts b/src/service/git/github/github-client.ts
index f83f3e2..40f1831 100644
--- a/src/service/git/github/github-client.ts
+++ b/src/service/git/github/github-client.ts
@@ -11,16 +11,22 @@ export default class GitHubClient implements GitClient {
private logger: LoggerService;
private apiUrl: string;
+ private isForCodeberg: boolean;
private octokit: Octokit;
private mapper: GitHubMapper;
- constructor(token: string | undefined, apiUrl: string) {
+ constructor(token: string | undefined, apiUrl: string, isForCodeberg = false) {
this.apiUrl = apiUrl;
+ this.isForCodeberg = isForCodeberg;
this.logger = LoggerServiceFactory.getLogger();
this.octokit = OctokitFactory.getOctokit(token, this.apiUrl);
this.mapper = new GitHubMapper();
}
+ getClientType(): GitClientType {
+ return this.isForCodeberg ? GitClientType.CODEBERG : GitClientType.GITHUB;
+ }
+
// READ
getDefaultGitUser(): string {
diff --git a/src/service/git/gitlab/gitlab-client.ts b/src/service/git/gitlab/gitlab-client.ts
index 0d1f962..c874b70 100644
--- a/src/service/git/gitlab/gitlab-client.ts
+++ b/src/service/git/gitlab/gitlab-client.ts
@@ -1,6 +1,6 @@
import LoggerService from "@bp/service/logger/logger-service";
import GitClient from "@bp/service/git/git-client";
-import { GitPullRequest, BackportPullRequest } from "@bp/service/git/git.types";
+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";
import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
@@ -30,6 +30,10 @@ export default class GitLabClient implements GitClient {
this.mapper = new GitLabMapper(this.client);
}
+ getClientType(): GitClientType {
+ return GitClientType.GITLAB;
+ }
+
getDefaultGitUser(): string {
return "Gitlab";
}
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 e1f7289..38adb10 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
@@ -4,7 +4,7 @@ import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
-import { resetProcessArgs } from "../../../support/utils";
+import { resetEnvTokens, resetProcessArgs } from "../../../support/utils";
import { MERGED_PR_FIXTURE, REPO, TARGET_OWNER, MULT_COMMITS_PR_FIXTURE } from "../../../support/mock/github-data";
import GitHubMapper from "@bp/service/git/github/github-mapper";
import GitHubClient from "@bp/service/git/github/github-client";
@@ -28,6 +28,9 @@ describe("github pull request config parser", () => {
// reset process.env variables
resetProcessArgs();
+ // reset env tokens
+ resetEnvTokens();
+
// mock octokit
mockGitHubClient("http://localhost/api/v3");
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 974a02b..a45def3 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -1,10 +1,10 @@
import { Args } from "@bp/service/args/args.types";
-import { Configs } from "@bp/service/configs/configs.types";
+import { AuthTokenId, Configs } from "@bp/service/configs/configs.types";
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
-import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../../support/utils";
+import { addProcessArgs, createTestFile, removeTestFile, resetEnvTokens, resetProcessArgs } from "../../../support/utils";
import { MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, REPO, TARGET_OWNER, MULT_COMMITS_PR_FIXTURE } from "../../../support/mock/github-data";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import GitHubMapper from "@bp/service/git/github/github-mapper";
@@ -66,6 +66,9 @@ describe("github pull request config parser", () => {
// reset process.env variables
resetProcessArgs();
+ // reset env tokens
+ resetEnvTokens();
+
// mock octokit
mockGitHubClient("http://localhost/api/v3");
@@ -77,7 +80,6 @@ describe("github pull request config parser", () => {
test("parse configs from pull request", async () => {
const args: Args = {
dryRun: false,
- auth: "",
pullRequest: mergedPRUrl,
targetBranch: "prod",
gitUser: "GitHub",
@@ -99,7 +101,7 @@ describe("github pull request config parser", () => {
user: "GitHub",
email: "noreply@github.com"
});
- expect(configs.auth).toEqual("");
+ expect(configs.auth).toEqual(undefined);
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 2368,
@@ -840,4 +842,82 @@ describe("github pull request config parser", () => {
comments: ["First comment", "Second comment"],
});
});
+
+ test("override token using auth arg", async () => {
+ process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
+ const args: Args = {
+ dryRun: true,
+ auth: "whatever",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ folder: "/tmp/test",
+ gitUser: "GitHub",
+ gitEmail: "noreply@github.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual("whatever");
+ expect(configs.folder).toEqual("/tmp/test");
+ expect(configs.git).toEqual({
+ user: "GitHub",
+ email: "noreply@github.com"
+ });
+ });
+
+ test("auth using GITHUB_TOKEN has precedence over GIT_TOKEN env variable", async () => {
+ process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
+ process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
+ const args: Args = {
+ dryRun: true,
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ folder: "/tmp/test",
+ gitUser: "GitHub",
+ gitEmail: "noreply@github.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual("mygithubtoken");
+ expect(configs.folder).toEqual("/tmp/test");
+ expect(configs.git).toEqual({
+ user: "GitHub",
+ email: "noreply@github.com"
+ });
+ });
+
+ test("ignore env variables related to other git platforms", async () => {
+ process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
+ process.env[AuthTokenId.CODEBERG_TOKEN] = "mycodebergtoken";
+ const args: Args = {
+ dryRun: true,
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ folder: "/tmp/test",
+ gitUser: "GitHub",
+ gitEmail: "noreply@github.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual(undefined);
+ expect(configs.folder).toEqual("/tmp/test");
+ expect(configs.git).toEqual({
+ user: "GitHub",
+ email: "noreply@github.com"
+ });
+ });
});
\ No newline at end of file
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..842a9ca 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
@@ -7,6 +7,7 @@ import { getAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { MERGED_SQUASHED_MR } from "../../../support/mock/gitlab-data";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
+import { resetEnvTokens } from "../../../support/utils";
jest.spyOn(GitLabMapper.prototype, "mapPullRequest");
jest.spyOn(GitLabClient.prototype, "getPullRequest");
@@ -31,6 +32,9 @@ describe("gitlab merge request config parser", () => {
});
beforeEach(() => {
+ // reset env tokens
+ resetEnvTokens();
+
configParser = new PullRequestConfigsParser();
});
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 75057ca..0c9248d 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -1,12 +1,12 @@
import { Args } from "@bp/service/args/args.types";
-import { Configs } from "@bp/service/configs/configs.types";
+import { AuthTokenId, Configs } from "@bp/service/configs/configs.types";
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { getAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR } from "../../../support/mock/gitlab-data";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
-import { createTestFile, removeTestFile, spyGetInput } from "../../../support/utils";
+import { createTestFile, removeTestFile, resetEnvTokens, spyGetInput } from "../../../support/utils";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
@@ -70,6 +70,9 @@ describe("gitlab merge request config parser", () => {
});
beforeEach(() => {
+ // reset env tokens
+ resetEnvTokens();
+
argsParser = new GHAArgsParser();
configParser = new PullRequestConfigsParser();
});
@@ -795,4 +798,97 @@ describe("gitlab merge request config parser", () => {
comments: ["First comment", "Second comment"],
});
});
+
+ test("override token using auth arg", async () => {
+ process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
+ const args: Args = {
+ dryRun: true,
+ auth: "whatever",
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ folder: "/tmp/test",
+ gitUser: "Gitlab",
+ gitEmail: "noreply@gitlab.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual("whatever");
+ expect(configs.folder).toEqual("/tmp/test");
+ expect(configs.git).toEqual({
+ user: "Gitlab",
+ email: "noreply@gitlab.com"
+ });
+ });
+
+ test("auth using GITLAB_TOKEN has precedence over GIT_TOKEN env variable", async () => {
+ process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
+ process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
+ const args: Args = {
+ dryRun: true,
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ folder: "/tmp/test",
+ gitUser: "Gitlab",
+ gitEmail: "noreply@gitlab.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual("mygitlabtoken");
+ expect(configs.folder).toEqual("/tmp/test");
+ expect(configs.git).toEqual({
+ user: "Gitlab",
+ email: "noreply@gitlab.com"
+ });
+ });
+
+ test("ignore env variables related to other git platforms", async () => {
+ process.env[AuthTokenId.CODEBERG_TOKEN] = "mycodebergtoken";
+ process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
+ const args: Args = {
+ dryRun: true,
+ pullRequest: mergedPRUrl,
+ targetBranch: "prod",
+ folder: "/tmp/test",
+ gitUser: "Gitlab",
+ gitEmail: "noreply@gitlab.com",
+ reviewers: [],
+ assignees: [],
+ inheritReviewers: true,
+ };
+
+ const configs: Configs = await configParser.parseAndValidate(args);
+
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
+ expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
+
+ expect(configs.dryRun).toEqual(true);
+ expect(configs.auth).toEqual(undefined);
+ expect(configs.folder).toEqual("/tmp/test");
+ expect(configs.git).toEqual({
+ user: "Gitlab",
+ email: "noreply@gitlab.com"
+ });
+ });
});
\ No newline at end of file
diff --git a/test/support/utils.ts b/test/support/utils.ts
index 693610d..e470906 100644
--- a/test/support/utils.ts
+++ b/test/support/utils.ts
@@ -1,4 +1,5 @@
import * as core from "@actions/core";
+import { AuthTokenId } from "@bp/service/configs/configs.types";
import * as fs from "fs";
export const addProcessArgs = (args: string[]) => {
@@ -9,6 +10,13 @@ export const resetProcessArgs = () => {
process.argv = ["node", "backporting"];
};
+export const resetEnvTokens = () => {
+ delete process.env[AuthTokenId.GITHUB_TOKEN];
+ delete process.env[AuthTokenId.GITLAB_TOKEN];
+ delete process.env[AuthTokenId.CODEBERG_TOKEN];
+ delete process.env[AuthTokenId.GIT_TOKEN];
+};
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const spyGetInput = (obj: any) => {
const mock = jest.spyOn(core, "getInput");
From 204ebd4376d7501696d52aec8fea2a2f6e09328f Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sun, 10 Dec 2023 23:18:55 +0100
Subject: [PATCH 29/75] chore: release v4.5.0 (#89)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 7 +++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 92d6197..151bcb9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [4.5.0](https://github.com/kiegroup/git-backporting/compare/v4.4.1...v4.5.0) (2023-12-10)
+
+
+### Features
+
+* **gh-85:** take git tokens from environment ([#88](https://github.com/kiegroup/git-backporting/issues/88)) ([70da575](https://github.com/kiegroup/git-backporting/commit/70da575afce603190eafed927637922a37fbd087))
+
## [4.4.1](https://github.com/kiegroup/git-backporting/compare/v4.4.0...v4.4.1) (2023-12-05)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 24e6781..72d9723 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23623,7 +23623,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.4.1","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.5.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 41a0f02..eae5853 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.4.1",
+ "version": "4.5.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.4.1",
+ "version": "4.5.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index 16177bb..4668492 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.4.1",
+ "version": "4.5.0",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From b7df1f80dcae86d513f0a7576c6140c8c675389a Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 11 Jan 2024 10:01:35 +0100
Subject: [PATCH 30/75] build(deps): bump follow-redirects from 1.15.2 to
1.15.4 (#92)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4)
---
updated-dependencies:
- dependency-name: follow-redirects
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index eae5853..e6899c8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5440,9 +5440,9 @@
"dev": true
},
"node_modules/follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
+ "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"funding": [
{
"type": "individual",
@@ -15893,9 +15893,9 @@
"dev": true
},
"follow-redirects": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
- "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
+ "version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
+ "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
},
"for-each": {
"version": "0.3.3",
From 300fa91a8ae065b7f6f6370882b10929bbde6309 Mon Sep 17 00:00:00 2001
From: Ratchanan Srirattanamet
Date: Tue, 20 Feb 2024 20:24:08 +0700
Subject: [PATCH 31/75] fix: --no-squash on single-commit GitLab MR (#93)
Due to off-by-one error in GitLabMapper, --no-squash was not effective
on an MR containing single commit. Fix by using the same condition as
GitHubMapper.
---
dist/cli/index.js | 212 +++++++++++-------
dist/gha/index.js | 212 +++++++++++-------
src/service/git/gitlab/gitlab-mapper.ts | 4 +-
test/service/runner/cli-gitlab-runner.test.ts | 44 ++++
test/service/runner/gha-gitlab-runner.test.ts | 42 ++++
test/support/mock/git-client-mock-support.ts | 4 +-
test/support/mock/gitlab-data.ts | 23 ++
7 files changed, 376 insertions(+), 165 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 72d9723..5a84866 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -1165,8 +1165,8 @@ class GitLabMapper {
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
// if commits list is provided use that as source
- nCommits: (commits && commits.length > 1) ? commits.length : 1,
- commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
+ nCommits: (commits && commits.length > 0) ? commits.length : 1,
+ commits: (commits && commits.length > 0) ? commits : this.getSha(mr)
};
}
getSha(mr) {
@@ -5847,6 +5847,29 @@ var Writable = (__nccwpck_require__(2781).Writable);
var assert = __nccwpck_require__(9491);
var debug = __nccwpck_require__(1133);
+// Whether to use the native URL object or the legacy url module
+var useNativeURL = false;
+try {
+ assert(new URL());
+}
+catch (error) {
+ useNativeURL = error.code === "ERR_INVALID_URL";
+}
+
+// URL fields to preserve in copy operations
+var preservedUrlFields = [
+ "auth",
+ "host",
+ "hostname",
+ "href",
+ "path",
+ "pathname",
+ "port",
+ "protocol",
+ "query",
+ "search",
+];
+
// Create handlers that pass events from native requests
var events = ["abort", "aborted", "connect", "error", "socket", "timeout"];
var eventHandlers = Object.create(null);
@@ -5856,19 +5879,20 @@ events.forEach(function (event) {
};
});
+// Error types with codes
var InvalidUrlError = createErrorType(
"ERR_INVALID_URL",
"Invalid URL",
TypeError
);
-// Error types with codes
var RedirectionError = createErrorType(
"ERR_FR_REDIRECTION_FAILURE",
"Redirected request failed"
);
var TooManyRedirectsError = createErrorType(
"ERR_FR_TOO_MANY_REDIRECTS",
- "Maximum number of redirects exceeded"
+ "Maximum number of redirects exceeded",
+ RedirectionError
);
var MaxBodyLengthExceededError = createErrorType(
"ERR_FR_MAX_BODY_LENGTH_EXCEEDED",
@@ -5879,6 +5903,9 @@ var WriteAfterEndError = createErrorType(
"write after end"
);
+// istanbul ignore next
+var destroy = Writable.prototype.destroy || noop;
+
// An HTTP(S) request that can be redirected
function RedirectableRequest(options, responseCallback) {
// Initialize the request
@@ -5900,7 +5927,13 @@ function RedirectableRequest(options, responseCallback) {
// React to responses of native requests
var self = this;
this._onNativeResponse = function (response) {
- self._processResponse(response);
+ try {
+ self._processResponse(response);
+ }
+ catch (cause) {
+ self.emit("error", cause instanceof RedirectionError ?
+ cause : new RedirectionError({ cause: cause }));
+ }
};
// Perform the first request
@@ -5909,10 +5942,17 @@ function RedirectableRequest(options, responseCallback) {
RedirectableRequest.prototype = Object.create(Writable.prototype);
RedirectableRequest.prototype.abort = function () {
- abortRequest(this._currentRequest);
+ destroyRequest(this._currentRequest);
+ this._currentRequest.abort();
this.emit("abort");
};
+RedirectableRequest.prototype.destroy = function (error) {
+ destroyRequest(this._currentRequest, error);
+ destroy.call(this, error);
+ return this;
+};
+
// Writes buffered data to the current native request
RedirectableRequest.prototype.write = function (data, encoding, callback) {
// Writing is not allowed if end has been called
@@ -6025,6 +6065,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
self.removeListener("abort", clearTimer);
self.removeListener("error", clearTimer);
self.removeListener("response", clearTimer);
+ self.removeListener("close", clearTimer);
if (callback) {
self.removeListener("timeout", callback);
}
@@ -6051,6 +6092,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
this.on("abort", clearTimer);
this.on("error", clearTimer);
this.on("response", clearTimer);
+ this.on("close", clearTimer);
return this;
};
@@ -6109,8 +6151,7 @@ RedirectableRequest.prototype._performRequest = function () {
var protocol = this._options.protocol;
var nativeProtocol = this._options.nativeProtocols[protocol];
if (!nativeProtocol) {
- this.emit("error", new TypeError("Unsupported protocol " + protocol));
- return;
+ throw new TypeError("Unsupported protocol " + protocol);
}
// If specified, use the agent corresponding to the protocol
@@ -6202,15 +6243,14 @@ RedirectableRequest.prototype._processResponse = function (response) {
}
// The response is a redirect, so abort the current request
- abortRequest(this._currentRequest);
+ destroyRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
// RFC7231§6.4: A client SHOULD detect and intervene
// in cyclical redirections (i.e., "infinite" redirection loops).
if (++this._redirectCount > this._options.maxRedirects) {
- this.emit("error", new TooManyRedirectsError());
- return;
+ throw new TooManyRedirectsError();
}
// Store the request headers if applicable
@@ -6244,33 +6284,23 @@ RedirectableRequest.prototype._processResponse = function (response) {
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
// If the redirect is relative, carry over the host of the last request
- var currentUrlParts = url.parse(this._currentUrl);
+ var currentUrlParts = parseUrl(this._currentUrl);
var currentHost = currentHostHeader || currentUrlParts.host;
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
url.format(Object.assign(currentUrlParts, { host: currentHost }));
- // Determine the URL of the redirection
- var redirectUrl;
- try {
- redirectUrl = url.resolve(currentUrl, location);
- }
- catch (cause) {
- this.emit("error", new RedirectionError({ cause: cause }));
- return;
- }
-
// Create the redirected request
- debug("redirecting to", redirectUrl);
+ var redirectUrl = resolveUrl(location, currentUrl);
+ debug("redirecting to", redirectUrl.href);
this._isRedirect = true;
- var redirectUrlParts = url.parse(redirectUrl);
- Object.assign(this._options, redirectUrlParts);
+ spreadUrlObject(redirectUrl, this._options);
// Drop confidential headers when redirecting to a less secure protocol
// or to a different domain that is not a superdomain
- if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
- redirectUrlParts.protocol !== "https:" ||
- redirectUrlParts.host !== currentHost &&
- !isSubdomain(redirectUrlParts.host, currentHost)) {
+ if (redirectUrl.protocol !== currentUrlParts.protocol &&
+ redirectUrl.protocol !== "https:" ||
+ redirectUrl.host !== currentHost &&
+ !isSubdomain(redirectUrl.host, currentHost)) {
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
}
@@ -6285,23 +6315,12 @@ RedirectableRequest.prototype._processResponse = function (response) {
method: method,
headers: requestHeaders,
};
- try {
- beforeRedirect(this._options, responseDetails, requestDetails);
- }
- catch (err) {
- this.emit("error", err);
- return;
- }
+ beforeRedirect(this._options, responseDetails, requestDetails);
this._sanitizeOptions(this._options);
}
// Perform the redirected request
- try {
- this._performRequest();
- }
- catch (cause) {
- this.emit("error", new RedirectionError({ cause: cause }));
- }
+ this._performRequest();
};
// Wraps the key/value object of protocols with redirect functionality
@@ -6321,27 +6340,16 @@ function wrap(protocols) {
// Executes a request, following redirects
function request(input, options, callback) {
- // Parse parameters
- if (isString(input)) {
- var parsed;
- try {
- parsed = urlToOptions(new URL(input));
- }
- catch (err) {
- /* istanbul ignore next */
- parsed = url.parse(input);
- }
- if (!isString(parsed.protocol)) {
- throw new InvalidUrlError({ input });
- }
- input = parsed;
+ // Parse parameters, ensuring that input is an object
+ if (isURL(input)) {
+ input = spreadUrlObject(input);
}
- else if (URL && (input instanceof URL)) {
- input = urlToOptions(input);
+ else if (isString(input)) {
+ input = spreadUrlObject(parseUrl(input));
}
else {
callback = options;
- options = input;
+ options = validateUrl(input);
input = { protocol: protocol };
}
if (isFunction(options)) {
@@ -6380,27 +6388,57 @@ function wrap(protocols) {
return exports;
}
-/* istanbul ignore next */
function noop() { /* empty */ }
-// from https://github.com/nodejs/node/blob/master/lib/internal/url.js
-function urlToOptions(urlObject) {
- var options = {
- protocol: urlObject.protocol,
- hostname: urlObject.hostname.startsWith("[") ?
- /* istanbul ignore next */
- urlObject.hostname.slice(1, -1) :
- urlObject.hostname,
- hash: urlObject.hash,
- search: urlObject.search,
- pathname: urlObject.pathname,
- path: urlObject.pathname + urlObject.search,
- href: urlObject.href,
- };
- if (urlObject.port !== "") {
- options.port = Number(urlObject.port);
+function parseUrl(input) {
+ var parsed;
+ /* istanbul ignore else */
+ if (useNativeURL) {
+ parsed = new URL(input);
}
- return options;
+ else {
+ // Ensure the URL is valid and absolute
+ parsed = validateUrl(url.parse(input));
+ if (!isString(parsed.protocol)) {
+ throw new InvalidUrlError({ input });
+ }
+ }
+ return parsed;
+}
+
+function resolveUrl(relative, base) {
+ /* istanbul ignore next */
+ return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative));
+}
+
+function validateUrl(input) {
+ if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
+ throw new InvalidUrlError({ input: input.href || input });
+ }
+ if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) {
+ throw new InvalidUrlError({ input: input.href || input });
+ }
+ return input;
+}
+
+function spreadUrlObject(urlObject, target) {
+ var spread = target || {};
+ for (var key of preservedUrlFields) {
+ spread[key] = urlObject[key];
+ }
+
+ // Fix IPv6 hostname
+ if (spread.hostname.startsWith("[")) {
+ spread.hostname = spread.hostname.slice(1, -1);
+ }
+ // Ensure port is a number
+ if (spread.port !== "") {
+ spread.port = Number(spread.port);
+ }
+ // Concatenate path
+ spread.path = spread.search ? spread.pathname + spread.search : spread.pathname;
+
+ return spread;
}
function removeMatchingHeaders(regex, headers) {
@@ -6426,17 +6464,25 @@ function createErrorType(code, message, baseClass) {
// Attach constructor and set default properties
CustomError.prototype = new (baseClass || Error)();
- CustomError.prototype.constructor = CustomError;
- CustomError.prototype.name = "Error [" + code + "]";
+ Object.defineProperties(CustomError.prototype, {
+ constructor: {
+ value: CustomError,
+ enumerable: false,
+ },
+ name: {
+ value: "Error [" + code + "]",
+ enumerable: false,
+ },
+ });
return CustomError;
}
-function abortRequest(request) {
+function destroyRequest(request, error) {
for (var event of events) {
request.removeListener(event, eventHandlers[event]);
}
request.on("error", noop);
- request.abort();
+ request.destroy(error);
}
function isSubdomain(subdomain, domain) {
@@ -6457,6 +6503,10 @@ function isBuffer(value) {
return typeof value === "object" && ("length" in value);
}
+function isURL(value) {
+ return URL && value instanceof URL;
+}
+
// Exports
module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap;
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 344c82f..9f2c8e4 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -1135,8 +1135,8 @@ class GitLabMapper {
sourceRepo: await this.mapSourceRepo(mr),
targetRepo: await this.mapTargetRepo(mr),
// if commits list is provided use that as source
- nCommits: (commits && commits.length > 1) ? commits.length : 1,
- commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
+ nCommits: (commits && commits.length > 0) ? commits.length : 1,
+ commits: (commits && commits.length > 0) ? commits : this.getSha(mr)
};
}
getSha(mr) {
@@ -7578,6 +7578,29 @@ var Writable = (__nccwpck_require__(2781).Writable);
var assert = __nccwpck_require__(9491);
var debug = __nccwpck_require__(1133);
+// Whether to use the native URL object or the legacy url module
+var useNativeURL = false;
+try {
+ assert(new URL());
+}
+catch (error) {
+ useNativeURL = error.code === "ERR_INVALID_URL";
+}
+
+// URL fields to preserve in copy operations
+var preservedUrlFields = [
+ "auth",
+ "host",
+ "hostname",
+ "href",
+ "path",
+ "pathname",
+ "port",
+ "protocol",
+ "query",
+ "search",
+];
+
// Create handlers that pass events from native requests
var events = ["abort", "aborted", "connect", "error", "socket", "timeout"];
var eventHandlers = Object.create(null);
@@ -7587,19 +7610,20 @@ events.forEach(function (event) {
};
});
+// Error types with codes
var InvalidUrlError = createErrorType(
"ERR_INVALID_URL",
"Invalid URL",
TypeError
);
-// Error types with codes
var RedirectionError = createErrorType(
"ERR_FR_REDIRECTION_FAILURE",
"Redirected request failed"
);
var TooManyRedirectsError = createErrorType(
"ERR_FR_TOO_MANY_REDIRECTS",
- "Maximum number of redirects exceeded"
+ "Maximum number of redirects exceeded",
+ RedirectionError
);
var MaxBodyLengthExceededError = createErrorType(
"ERR_FR_MAX_BODY_LENGTH_EXCEEDED",
@@ -7610,6 +7634,9 @@ var WriteAfterEndError = createErrorType(
"write after end"
);
+// istanbul ignore next
+var destroy = Writable.prototype.destroy || noop;
+
// An HTTP(S) request that can be redirected
function RedirectableRequest(options, responseCallback) {
// Initialize the request
@@ -7631,7 +7658,13 @@ function RedirectableRequest(options, responseCallback) {
// React to responses of native requests
var self = this;
this._onNativeResponse = function (response) {
- self._processResponse(response);
+ try {
+ self._processResponse(response);
+ }
+ catch (cause) {
+ self.emit("error", cause instanceof RedirectionError ?
+ cause : new RedirectionError({ cause: cause }));
+ }
};
// Perform the first request
@@ -7640,10 +7673,17 @@ function RedirectableRequest(options, responseCallback) {
RedirectableRequest.prototype = Object.create(Writable.prototype);
RedirectableRequest.prototype.abort = function () {
- abortRequest(this._currentRequest);
+ destroyRequest(this._currentRequest);
+ this._currentRequest.abort();
this.emit("abort");
};
+RedirectableRequest.prototype.destroy = function (error) {
+ destroyRequest(this._currentRequest, error);
+ destroy.call(this, error);
+ return this;
+};
+
// Writes buffered data to the current native request
RedirectableRequest.prototype.write = function (data, encoding, callback) {
// Writing is not allowed if end has been called
@@ -7756,6 +7796,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
self.removeListener("abort", clearTimer);
self.removeListener("error", clearTimer);
self.removeListener("response", clearTimer);
+ self.removeListener("close", clearTimer);
if (callback) {
self.removeListener("timeout", callback);
}
@@ -7782,6 +7823,7 @@ RedirectableRequest.prototype.setTimeout = function (msecs, callback) {
this.on("abort", clearTimer);
this.on("error", clearTimer);
this.on("response", clearTimer);
+ this.on("close", clearTimer);
return this;
};
@@ -7840,8 +7882,7 @@ RedirectableRequest.prototype._performRequest = function () {
var protocol = this._options.protocol;
var nativeProtocol = this._options.nativeProtocols[protocol];
if (!nativeProtocol) {
- this.emit("error", new TypeError("Unsupported protocol " + protocol));
- return;
+ throw new TypeError("Unsupported protocol " + protocol);
}
// If specified, use the agent corresponding to the protocol
@@ -7933,15 +7974,14 @@ RedirectableRequest.prototype._processResponse = function (response) {
}
// The response is a redirect, so abort the current request
- abortRequest(this._currentRequest);
+ destroyRequest(this._currentRequest);
// Discard the remainder of the response to avoid waiting for data
response.destroy();
// RFC7231§6.4: A client SHOULD detect and intervene
// in cyclical redirections (i.e., "infinite" redirection loops).
if (++this._redirectCount > this._options.maxRedirects) {
- this.emit("error", new TooManyRedirectsError());
- return;
+ throw new TooManyRedirectsError();
}
// Store the request headers if applicable
@@ -7975,33 +8015,23 @@ RedirectableRequest.prototype._processResponse = function (response) {
var currentHostHeader = removeMatchingHeaders(/^host$/i, this._options.headers);
// If the redirect is relative, carry over the host of the last request
- var currentUrlParts = url.parse(this._currentUrl);
+ var currentUrlParts = parseUrl(this._currentUrl);
var currentHost = currentHostHeader || currentUrlParts.host;
var currentUrl = /^\w+:/.test(location) ? this._currentUrl :
url.format(Object.assign(currentUrlParts, { host: currentHost }));
- // Determine the URL of the redirection
- var redirectUrl;
- try {
- redirectUrl = url.resolve(currentUrl, location);
- }
- catch (cause) {
- this.emit("error", new RedirectionError({ cause: cause }));
- return;
- }
-
// Create the redirected request
- debug("redirecting to", redirectUrl);
+ var redirectUrl = resolveUrl(location, currentUrl);
+ debug("redirecting to", redirectUrl.href);
this._isRedirect = true;
- var redirectUrlParts = url.parse(redirectUrl);
- Object.assign(this._options, redirectUrlParts);
+ spreadUrlObject(redirectUrl, this._options);
// Drop confidential headers when redirecting to a less secure protocol
// or to a different domain that is not a superdomain
- if (redirectUrlParts.protocol !== currentUrlParts.protocol &&
- redirectUrlParts.protocol !== "https:" ||
- redirectUrlParts.host !== currentHost &&
- !isSubdomain(redirectUrlParts.host, currentHost)) {
+ if (redirectUrl.protocol !== currentUrlParts.protocol &&
+ redirectUrl.protocol !== "https:" ||
+ redirectUrl.host !== currentHost &&
+ !isSubdomain(redirectUrl.host, currentHost)) {
removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
}
@@ -8016,23 +8046,12 @@ RedirectableRequest.prototype._processResponse = function (response) {
method: method,
headers: requestHeaders,
};
- try {
- beforeRedirect(this._options, responseDetails, requestDetails);
- }
- catch (err) {
- this.emit("error", err);
- return;
- }
+ beforeRedirect(this._options, responseDetails, requestDetails);
this._sanitizeOptions(this._options);
}
// Perform the redirected request
- try {
- this._performRequest();
- }
- catch (cause) {
- this.emit("error", new RedirectionError({ cause: cause }));
- }
+ this._performRequest();
};
// Wraps the key/value object of protocols with redirect functionality
@@ -8052,27 +8071,16 @@ function wrap(protocols) {
// Executes a request, following redirects
function request(input, options, callback) {
- // Parse parameters
- if (isString(input)) {
- var parsed;
- try {
- parsed = urlToOptions(new URL(input));
- }
- catch (err) {
- /* istanbul ignore next */
- parsed = url.parse(input);
- }
- if (!isString(parsed.protocol)) {
- throw new InvalidUrlError({ input });
- }
- input = parsed;
+ // Parse parameters, ensuring that input is an object
+ if (isURL(input)) {
+ input = spreadUrlObject(input);
}
- else if (URL && (input instanceof URL)) {
- input = urlToOptions(input);
+ else if (isString(input)) {
+ input = spreadUrlObject(parseUrl(input));
}
else {
callback = options;
- options = input;
+ options = validateUrl(input);
input = { protocol: protocol };
}
if (isFunction(options)) {
@@ -8111,27 +8119,57 @@ function wrap(protocols) {
return exports;
}
-/* istanbul ignore next */
function noop() { /* empty */ }
-// from https://github.com/nodejs/node/blob/master/lib/internal/url.js
-function urlToOptions(urlObject) {
- var options = {
- protocol: urlObject.protocol,
- hostname: urlObject.hostname.startsWith("[") ?
- /* istanbul ignore next */
- urlObject.hostname.slice(1, -1) :
- urlObject.hostname,
- hash: urlObject.hash,
- search: urlObject.search,
- pathname: urlObject.pathname,
- path: urlObject.pathname + urlObject.search,
- href: urlObject.href,
- };
- if (urlObject.port !== "") {
- options.port = Number(urlObject.port);
+function parseUrl(input) {
+ var parsed;
+ /* istanbul ignore else */
+ if (useNativeURL) {
+ parsed = new URL(input);
}
- return options;
+ else {
+ // Ensure the URL is valid and absolute
+ parsed = validateUrl(url.parse(input));
+ if (!isString(parsed.protocol)) {
+ throw new InvalidUrlError({ input });
+ }
+ }
+ return parsed;
+}
+
+function resolveUrl(relative, base) {
+ /* istanbul ignore next */
+ return useNativeURL ? new URL(relative, base) : parseUrl(url.resolve(base, relative));
+}
+
+function validateUrl(input) {
+ if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
+ throw new InvalidUrlError({ input: input.href || input });
+ }
+ if (/^\[/.test(input.host) && !/^\[[:0-9a-f]+\](:\d+)?$/i.test(input.host)) {
+ throw new InvalidUrlError({ input: input.href || input });
+ }
+ return input;
+}
+
+function spreadUrlObject(urlObject, target) {
+ var spread = target || {};
+ for (var key of preservedUrlFields) {
+ spread[key] = urlObject[key];
+ }
+
+ // Fix IPv6 hostname
+ if (spread.hostname.startsWith("[")) {
+ spread.hostname = spread.hostname.slice(1, -1);
+ }
+ // Ensure port is a number
+ if (spread.port !== "") {
+ spread.port = Number(spread.port);
+ }
+ // Concatenate path
+ spread.path = spread.search ? spread.pathname + spread.search : spread.pathname;
+
+ return spread;
}
function removeMatchingHeaders(regex, headers) {
@@ -8157,17 +8195,25 @@ function createErrorType(code, message, baseClass) {
// Attach constructor and set default properties
CustomError.prototype = new (baseClass || Error)();
- CustomError.prototype.constructor = CustomError;
- CustomError.prototype.name = "Error [" + code + "]";
+ Object.defineProperties(CustomError.prototype, {
+ constructor: {
+ value: CustomError,
+ enumerable: false,
+ },
+ name: {
+ value: "Error [" + code + "]",
+ enumerable: false,
+ },
+ });
return CustomError;
}
-function abortRequest(request) {
+function destroyRequest(request, error) {
for (var event of events) {
request.removeListener(event, eventHandlers[event]);
}
request.on("error", noop);
- request.abort();
+ request.destroy(error);
}
function isSubdomain(subdomain, domain) {
@@ -8188,6 +8234,10 @@ function isBuffer(value) {
return typeof value === "object" && ("length" in value);
}
+function isURL(value) {
+ return URL && value instanceof URL;
+}
+
// Exports
module.exports = wrap({ http: http, https: https });
module.exports.wrap = wrap;
diff --git a/src/service/git/gitlab/gitlab-mapper.ts b/src/service/git/gitlab/gitlab-mapper.ts
index 5765ba6..9efe2a0 100644
--- a/src/service/git/gitlab/gitlab-mapper.ts
+++ b/src/service/git/gitlab/gitlab-mapper.ts
@@ -41,8 +41,8 @@ export default class GitLabMapper implements GitResponseMapper 1) ? commits.length : 1,
- commits: (commits && commits.length > 1) ? commits : this.getSha(mr)
+ nCommits: (commits && commits.length > 0) ? commits.length : 1,
+ commits: (commits && commits.length > 0) ? commits : this.getSha(mr)
};
}
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index ab6f72b..92dc4d7 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -504,6 +504,50 @@ describe("cli runner", () => {
);
});
+ test("single commit without squash", async () => {
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ "--no-squash",
+ ]);
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336");
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-e4dd336",
+ base: "target",
+ title: "[target] Update test.txt",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ }
+ );
+ });
+
test("multiple commits without squash", async () => {
addProcessArgs([
"-tb",
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 8158818..748ca15 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -427,6 +427,48 @@ describe("gha runner", () => {
);
});
+ test("single commit without squash", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
+ "no-squash": "true",
+ });
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
+
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-e4dd336");
+
+ expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined);
+
+ expect(GitCLIService.prototype.push).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336");
+
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
+ expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
+ owner: "superuser",
+ repo: "backporting-example",
+ head: "bp-target-e4dd336",
+ base: "target",
+ title: "[target] Update test.txt",
+ body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
+ reviewers: ["superuser"],
+ assignees: [],
+ labels: [],
+ comments: [],
+ }
+ );
+ });
+
test("multiple commits without squash", async () => {
spyGetInput({
"target-branch": "target",
diff --git a/test/support/mock/git-client-mock-support.ts b/test/support/mock/git-client-mock-support.ts
index b1c2886..7dceabc 100644
--- a/test/support/mock/git-client-mock-support.ts
+++ b/test/support/mock/git-client-mock-support.ts
@@ -1,7 +1,7 @@
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 { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-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
// to send more than 3 reqs per api endpoint
@@ -30,6 +30,8 @@ export const getAxiosMocked = (url: string) => {
data = NESTED_PROJECT_EXAMPLE;
} else if (url.endsWith("users?username=superuser")) {
data = [SUPERUSER];
+ } else if (url.endsWith("merge_requests/1/commits")) {
+ data = MERGED_SQUASHED_MR_COMMITS;
} else if (url.endsWith("merge_requests/2/commits")) {
data = OPEN_PR_COMMITS;
}
diff --git a/test/support/mock/gitlab-data.ts b/test/support/mock/gitlab-data.ts
index a7455fc..3f32b81 100644
--- a/test/support/mock/gitlab-data.ts
+++ b/test/support/mock/gitlab-data.ts
@@ -689,6 +689,29 @@ export const CLOSED_NOT_MERGED_MR = {
}
};
+export const MERGED_SQUASHED_MR_COMMITS = [
+ {
+ "id":"e4dd336a4a20f394df6665994df382fb1d193a11",
+ "short_id":"e4dd336a",
+ "created_at":"2023-06-29T09:59:10.000Z",
+ "parent_ids":[
+
+ ],
+ "title":"Add new file",
+ "message":"Add new file",
+ "author_name":"Super User",
+ "author_email":"superuser@email.com",
+ "authored_date":"2023-06-29T09:59:10.000Z",
+ "committer_name":"Super User",
+ "committer_email":"superuser@email.com",
+ "committed_date":"2023-06-29T09:59:10.000Z",
+ "trailers":{
+
+ },
+ "web_url":"https://gitlab.com/superuser/backporting-example/-/commit/e4dd336a4a20f394df6665994df382fb1d193a11"
+ },
+];
+
export const OPEN_PR_COMMITS = [
{
"id":"974519f65c9e0ed65277cd71026657a09fca05e7",
From d4dc510af17d7b56c449a8085139f290880b1ca6 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Tue, 20 Feb 2024 14:41:12 +0100
Subject: [PATCH 32/75] build: upgrade release-it (#94)
---
package-lock.json | 1802 +++++++++++++++++++++------------------------
1 file changed, 831 insertions(+), 971 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index e6899c8..5988a6e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -215,9 +215,9 @@
"dev": true
},
"node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -267,9 +267,9 @@
}
},
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -1217,12 +1217,12 @@
"dev": true
},
"node_modules/@hutson/parse-repository-url": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz",
- "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-5.0.0.tgz",
+ "integrity": "sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==",
"dev": true,
"engines": {
- "node": ">=6.9.0"
+ "node": ">=10.13.0"
}
},
"node_modules/@iarna/toml": {
@@ -2042,15 +2042,15 @@
}
},
"node_modules/@release-it/conventional-changelog": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-7.0.0.tgz",
- "integrity": "sha512-DBzyVS6c4g8w+xomCsygkmLeQBUq41Wvzy0vGgbdCLOxYnwI0cDaF6HOLPkrifH1qLa1uJ9i1pYA+hNyHkNanQ==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-7.0.2.tgz",
+ "integrity": "sha512-rsUKWNnU39xivgC2IanjRkEOPsTu2X2jgJGpNHF+mndpOUr1WAROmIaix1o3ne2zseT+GLyZII2NC8FgYaM7xA==",
"dev": true,
"dependencies": {
"concat-stream": "^2.0.0",
- "conventional-changelog": "^4.0.0",
- "conventional-recommended-bump": "^7.0.1",
- "semver": "7.5.1"
+ "conventional-changelog": "^5.1.0",
+ "conventional-recommended-bump": "^8.0.0",
+ "semver": "^7.5.4"
},
"engines": {
"node": ">=16"
@@ -3641,25 +3641,25 @@
}
},
"node_modules/conventional-changelog": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-4.0.0.tgz",
- "integrity": "sha512-JbZjwE1PzxQCvm+HUTIr+pbSekS8qdOZzMakdFyPtdkEWwFvwEJYONzjgMm0txCb2yBcIcfKDmg8xtCKTdecNQ==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-5.1.0.tgz",
+ "integrity": "sha512-aWyE/P39wGYRPllcCEZDxTVEmhyLzTc9XA6z6rVfkuCD2UBnhV/sgSOKbQrEG5z9mEZJjnopjgQooTKxEg8mAg==",
"dev": true,
"dependencies": {
- "conventional-changelog-angular": "^6.0.0",
- "conventional-changelog-atom": "^3.0.0",
- "conventional-changelog-codemirror": "^3.0.0",
- "conventional-changelog-conventionalcommits": "^6.0.0",
- "conventional-changelog-core": "^5.0.0",
- "conventional-changelog-ember": "^3.0.0",
- "conventional-changelog-eslint": "^4.0.0",
- "conventional-changelog-express": "^3.0.0",
- "conventional-changelog-jquery": "^4.0.0",
- "conventional-changelog-jshint": "^3.0.0",
- "conventional-changelog-preset-loader": "^3.0.0"
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-changelog-atom": "^4.0.0",
+ "conventional-changelog-codemirror": "^4.0.0",
+ "conventional-changelog-conventionalcommits": "^7.0.2",
+ "conventional-changelog-core": "^7.0.0",
+ "conventional-changelog-ember": "^4.0.0",
+ "conventional-changelog-eslint": "^5.0.0",
+ "conventional-changelog-express": "^4.0.0",
+ "conventional-changelog-jquery": "^5.0.0",
+ "conventional-changelog-jshint": "^4.0.0",
+ "conventional-changelog-preset-loader": "^4.1.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-angular": {
@@ -3676,21 +3676,21 @@
}
},
"node_modules/conventional-changelog-atom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-3.0.0.tgz",
- "integrity": "sha512-pnN5bWpH+iTUWU3FaYdw5lJmfWeqSyrUkG+wyHBI9tC1dLNnHkbAOg1SzTQ7zBqiFrfo55h40VsGXWMdopwc5g==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-4.0.0.tgz",
+ "integrity": "sha512-q2YtiN7rnT1TGwPTwjjBSIPIzDJCRE+XAUahWxnh+buKK99Kks4WLMHoexw38GXx9OUxAsrp44f9qXe5VEMYhw==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-codemirror": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-3.0.0.tgz",
- "integrity": "sha512-wzchZt9HEaAZrenZAUUHMCFcuYzGoZ1wG/kTRMICxsnW5AXohYMRxnyecP9ob42Gvn5TilhC0q66AtTPRSNMfw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-4.0.0.tgz",
+ "integrity": "sha512-hQSojc/5imn1GJK3A75m9hEZZhc3urojA5gMpnar4JHmgLnuM3CUIARPpEk86glEKr3c54Po3WV/vCaO/U8g3Q==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-conventionalcommits": {
@@ -3708,317 +3708,461 @@
}
},
"node_modules/conventional-changelog-core": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.2.tgz",
- "integrity": "sha512-RhQOcDweXNWvlRwUDCpaqXzbZemKPKncCWZG50Alth72WITVd6nhVk9MJ6w1k9PFNBcZ3YwkdkChE+8+ZwtUug==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-7.0.0.tgz",
+ "integrity": "sha512-UYgaB1F/COt7VFjlYKVE/9tTzfU3VUq47r6iWf6lM5T7TlOxr0thI63ojQueRLIpVbrtHK4Ffw+yQGduw2Bhdg==",
"dev": true,
"dependencies": {
+ "@hutson/parse-repository-url": "^5.0.0",
"add-stream": "^1.0.0",
- "conventional-changelog-writer": "^6.0.0",
- "conventional-commits-parser": "^4.0.0",
- "dateformat": "^3.0.3",
- "get-pkg-repo": "^4.2.1",
- "git-raw-commits": "^3.0.0",
- "git-remote-origin-url": "^2.0.0",
- "git-semver-tags": "^5.0.0",
- "normalize-package-data": "^3.0.3",
- "read-pkg": "^3.0.0",
- "read-pkg-up": "^3.0.0"
+ "conventional-changelog-writer": "^7.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "git-raw-commits": "^4.0.0",
+ "git-semver-tags": "^7.0.0",
+ "hosted-git-info": "^7.0.0",
+ "normalize-package-data": "^6.0.0",
+ "read-pkg": "^8.0.0",
+ "read-pkg-up": "^10.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-core/node_modules/conventional-commits-parser": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
- "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
"dev": true,
"dependencies": {
- "is-text-path": "^1.0.1",
+ "is-text-path": "^2.0.0",
"JSONStream": "^1.3.5",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
},
"bin": {
- "conventional-commits-parser": "cli.js"
+ "conventional-commits-parser": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-changelog-core/node_modules/find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz",
+ "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
"dev": true,
"dependencies": {
- "locate-path": "^2.0.0"
+ "locate-path": "^7.1.0",
+ "path-exists": "^5.0.0"
},
"engines": {
- "node": ">=4"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-changelog-core/node_modules/git-raw-commits": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
- "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
"dev": true,
"dependencies": {
- "dargs": "^7.0.0",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
},
"bin": {
- "git-raw-commits": "cli.js"
+ "git-raw-commits": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-core/node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
- "dev": true
- },
- "node_modules/conventional-changelog-core/node_modules/locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz",
+ "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==",
"dev": true,
"dependencies": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
+ "lru-cache": "^10.0.1"
},
"engines": {
- "node": ">=4"
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "dependencies": {
+ "text-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz",
+ "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==",
+ "dev": true,
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/lines-and-columns": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz",
+ "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/locate-path": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+ "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^6.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/lru-cache": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/normalize-package-data": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz",
+ "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
}
},
"node_modules/conventional-changelog-core/node_modules/p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+ "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
"dev": true,
"dependencies": {
- "p-try": "^1.0.0"
+ "yocto-queue": "^1.0.0"
},
"engines": {
- "node": ">=4"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-changelog-core/node_modules/p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+ "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
"dev": true,
"dependencies": {
- "p-limit": "^1.1.0"
+ "p-limit": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/conventional-changelog-core/node_modules/p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "node_modules/conventional-changelog-core/node_modules/parse-json": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz",
+ "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.21.4",
+ "error-ex": "^1.3.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "lines-and-columns": "^2.0.3",
+ "type-fest": "^3.8.0"
+ },
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/parse-json/node_modules/type-fest": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz",
+ "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
"dev": true,
"engines": {
- "node": ">=4"
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-changelog-core/node_modules/path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
"dev": true,
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/conventional-changelog-core/node_modules/path-type": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
- "dev": true,
- "dependencies": {
- "pify": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/conventional-changelog-core/node_modules/pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
- "dev": true,
- "engines": {
- "node": ">=4"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/conventional-changelog-core/node_modules/read-pkg": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
- "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz",
+ "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==",
"dev": true,
"dependencies": {
- "load-json-file": "^4.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^3.0.0"
+ "@types/normalize-package-data": "^2.4.1",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^7.0.0",
+ "type-fest": "^4.2.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-changelog-core/node_modules/read-pkg-up": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
- "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz",
+ "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==",
"dev": true,
"dependencies": {
- "find-up": "^2.0.0",
- "read-pkg": "^3.0.0"
+ "find-up": "^6.3.0",
+ "read-pkg": "^8.1.0",
+ "type-fest": "^4.2.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "node_modules/conventional-changelog-core/node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
"dev": true,
- "dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
+ "engines": {
+ "node": ">= 10.x"
}
},
- "node_modules/conventional-changelog-core/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "node_modules/conventional-changelog-core/node_modules/text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
"dev": true,
- "bin": {
- "semver": "bin/semver"
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/type-fest": {
+ "version": "4.10.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz",
+ "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-changelog-core/node_modules/yocto-queue": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
+ "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-changelog-ember": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-3.0.0.tgz",
- "integrity": "sha512-7PYthCoSxIS98vWhVcSphMYM322OxptpKAuHYdVspryI0ooLDehRXWeRWgN+zWSBXKl/pwdgAg8IpLNSM1/61A==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-4.0.0.tgz",
+ "integrity": "sha512-D0IMhwcJUg1Y8FSry6XAplEJcljkHVlvAZddhhsdbL1rbsqRsMfGx/PIkPYq0ru5aDgn+OxhQ5N5yR7P9mfsvA==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-eslint": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-4.0.0.tgz",
- "integrity": "sha512-nEZ9byP89hIU0dMx37JXQkE1IpMmqKtsaR24X7aM3L6Yy/uAtbb+ogqthuNYJkeO1HyvK7JsX84z8649hvp43Q==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-5.0.0.tgz",
+ "integrity": "sha512-6JtLWqAQIeJLn/OzUlYmzd9fKeNSWmQVim9kql+v4GrZwLx807kAJl3IJVc3jTYfVKWLxhC3BGUxYiuVEcVjgA==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-express": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-3.0.0.tgz",
- "integrity": "sha512-HqxihpUMfIuxvlPvC6HltA4ZktQEUan/v3XQ77+/zbu8No/fqK3rxSZaYeHYant7zRxQNIIli7S+qLS9tX9zQA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-4.0.0.tgz",
+ "integrity": "sha512-yWyy5c7raP9v7aTvPAWzqrztACNO9+FEI1FSYh7UP7YT1AkWgv5UspUeB5v3Ibv4/o60zj2o9GF2tqKQ99lIsw==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-jquery": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-4.0.0.tgz",
- "integrity": "sha512-TTIN5CyzRMf8PUwyy4IOLmLV2DFmPtasKN+x7EQKzwSX8086XYwo+NeaeA3VUT8bvKaIy5z/JoWUvi7huUOgaw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-5.0.0.tgz",
+ "integrity": "sha512-slLjlXLRNa/icMI3+uGLQbtrgEny3RgITeCxevJB+p05ExiTgHACP5p3XiMKzjBn80n+Rzr83XMYfRInEtCPPw==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-jshint": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-3.0.0.tgz",
- "integrity": "sha512-bQof4byF4q+n+dwFRkJ/jGf9dCNUv4/kCDcjeCizBvfF81TeimPZBB6fT4HYbXgxxfxWXNl/i+J6T0nI4by6DA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-4.0.0.tgz",
+ "integrity": "sha512-LyXq1bbl0yG0Ai1SbLxIk8ZxUOe3AjnlwE6sVRQmMgetBk+4gY9EO3d00zlEt8Y8gwsITytDnPORl8al7InTjg==",
"dev": true,
"dependencies": {
"compare-func": "^2.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-preset-loader": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz",
- "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-4.1.0.tgz",
+ "integrity": "sha512-HozQjJicZTuRhCRTq4rZbefaiCzRM2pr6u2NL3XhrmQm4RMnDXfESU6JKu/pnKwx5xtdkYfNCsbhN5exhiKGJA==",
"dev": true,
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog-writer": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz",
- "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz",
+ "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==",
"dev": true,
"dependencies": {
- "conventional-commits-filter": "^3.0.0",
- "dateformat": "^3.0.3",
+ "conventional-commits-filter": "^4.0.0",
"handlebars": "^4.7.7",
"json-stringify-safe": "^5.0.1",
- "meow": "^8.1.2",
- "semver": "^7.0.0",
- "split": "^1.0.1"
+ "meow": "^12.0.1",
+ "semver": "^7.5.2",
+ "split2": "^4.0.0"
},
"bin": {
- "conventional-changelog-writer": "cli.js"
+ "conventional-changelog-writer": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-changelog-writer/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-changelog-writer/node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.x"
}
},
"node_modules/conventional-changelog/node_modules/conventional-changelog-angular": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz",
- "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+ "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
"dev": true,
"dependencies": {
"compare-func": "^2.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-changelog/node_modules/conventional-changelog-conventionalcommits": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz",
- "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz",
+ "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==",
"dev": true,
"dependencies": {
"compare-func": "^2.0.0"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-commits-filter": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz",
- "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz",
+ "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==",
"dev": true,
- "dependencies": {
- "lodash.ismatch": "^4.4.0",
- "modify-values": "^1.0.1"
- },
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-commits-parser": {
@@ -4042,59 +4186,132 @@
}
},
"node_modules/conventional-recommended-bump": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz",
- "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-8.0.0.tgz",
+ "integrity": "sha512-yvGN+VMy00WIe/pJufpmN+I4B2cM/WFK+CFCmDcjyVLyQR6J1KT2iecmA4NQ58gQAiNkvStEjcZp/W9h1JDM1A==",
"dev": true,
"dependencies": {
"concat-stream": "^2.0.0",
- "conventional-changelog-preset-loader": "^3.0.0",
- "conventional-commits-filter": "^3.0.0",
- "conventional-commits-parser": "^4.0.0",
- "git-raw-commits": "^3.0.0",
- "git-semver-tags": "^5.0.0",
- "meow": "^8.1.2"
+ "conventional-changelog-preset-loader": "^4.0.0",
+ "conventional-commits-filter": "^4.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "git-raw-commits": "^4.0.0",
+ "git-semver-tags": "^6.0.0",
+ "meow": "^12.0.1"
},
"bin": {
- "conventional-recommended-bump": "cli.js"
+ "conventional-recommended-bump": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
}
},
"node_modules/conventional-recommended-bump/node_modules/conventional-commits-parser": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
- "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
"dev": true,
"dependencies": {
- "is-text-path": "^1.0.1",
+ "is-text-path": "^2.0.0",
"JSONStream": "^1.3.5",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
},
"bin": {
- "conventional-commits-parser": "cli.js"
+ "conventional-commits-parser": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/conventional-recommended-bump/node_modules/git-raw-commits": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
- "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
"dev": true,
"dependencies": {
- "dargs": "^7.0.0",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
},
"bin": {
- "git-raw-commits": "cli.js"
+ "git-raw-commits": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/git-semver-tags": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-6.0.0.tgz",
+ "integrity": "sha512-v5BL6psuUy+Ftuo99141XlOIDoJtKw5+YyDANS7fknSP0iT4cVIanc3toDsH4K+VpIWc19l2/xkwQmXMfloeUA==",
+ "dev": true,
+ "dependencies": {
+ "meow": "^12.0.1",
+ "semver": "^7.5.2"
+ },
+ "bin": {
+ "git-semver-tags": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "dependencies": {
+ "text-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/conventional-recommended-bump/node_modules/text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/convert-source-map": {
@@ -4118,12 +4335,6 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
- "node_modules/core-util-is": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
- "dev": true
- },
"node_modules/cosmiconfig": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
@@ -4223,15 +4434,6 @@
"node": ">= 14"
}
},
- "node_modules/dateformat": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
- "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
- "dev": true,
- "engines": {
- "node": "*"
- }
- },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -5626,108 +5828,6 @@
"node": ">=8.0.0"
}
},
- "node_modules/get-pkg-repo": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz",
- "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==",
- "dev": true,
- "dependencies": {
- "@hutson/parse-repository-url": "^3.0.0",
- "hosted-git-info": "^4.0.0",
- "through2": "^2.0.0",
- "yargs": "^16.2.0"
- },
- "bin": {
- "get-pkg-repo": "src/cli.js"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-pkg-repo/node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "node_modules/get-pkg-repo/node_modules/isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
- "dev": true
- },
- "node_modules/get-pkg-repo/node_modules/readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "dependencies": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "node_modules/get-pkg-repo/node_modules/safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "node_modules/get-pkg-repo/node_modules/string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "dependencies": {
- "safe-buffer": "~5.1.0"
- }
- },
- "node_modules/get-pkg-repo/node_modules/through2": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
- "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
- "dev": true,
- "dependencies": {
- "readable-stream": "~2.3.6",
- "xtend": "~4.0.1"
- }
- },
- "node_modules/get-pkg-repo/node_modules/yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "dev": true,
- "dependencies": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/get-pkg-repo/node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -5822,33 +5922,32 @@
"node": ">=10"
}
},
- "node_modules/git-remote-origin-url": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz",
- "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==",
- "dev": true,
- "dependencies": {
- "gitconfiglocal": "^1.0.0",
- "pify": "^2.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/git-semver-tags": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz",
- "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-7.0.1.tgz",
+ "integrity": "sha512-NY0ZHjJzyyNXHTDZmj+GG7PyuAKtMsyWSwh07CR2hOZFa+/yoTsXci/nF2obzL8UDhakFNkD9gNdt/Ed+cxh2Q==",
"dev": true,
"dependencies": {
- "meow": "^8.1.2",
- "semver": "^7.0.0"
+ "meow": "^12.0.1",
+ "semver": "^7.5.2"
},
"bin": {
- "git-semver-tags": "cli.js"
+ "git-semver-tags": "cli.mjs"
},
"engines": {
- "node": ">=14"
+ "node": ">=16"
+ }
+ },
+ "node_modules/git-semver-tags/node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/git-up": {
@@ -5870,15 +5969,6 @@
"git-up": "^7.0.0"
}
},
- "node_modules/gitconfiglocal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz",
- "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==",
- "dev": true,
- "dependencies": {
- "ini": "^1.3.2"
- }
- },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -6022,13 +6112,13 @@
"dev": true
},
"node_modules/handlebars": {
- "version": "4.7.7",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
- "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5",
- "neo-async": "^2.6.0",
+ "neo-async": "^2.6.2",
"source-map": "^0.6.1",
"wordwrap": "^1.0.0"
},
@@ -6592,9 +6682,9 @@
}
},
"node_modules/ip": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
- "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz",
+ "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==",
"dev": true
},
"node_modules/ipaddr.js": {
@@ -7187,9 +7277,9 @@
}
},
"node_modules/istanbul-lib-instrument/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -7874,12 +7964,6 @@
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true
},
- "node_modules/json-parse-better-errors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
- "dev": true
- },
"node_modules/json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
@@ -8022,52 +8106,6 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
- "node_modules/load-json-file": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
- "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^4.0.0",
- "pify": "^3.0.0",
- "strip-bom": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/load-json-file/node_modules/parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
- "dev": true,
- "dependencies": {
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/load-json-file/node_modules/pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/load-json-file/node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -8113,12 +8151,6 @@
"integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==",
"dev": true
},
- "node_modules/lodash.ismatch": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
- "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==",
- "dev": true
- },
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -8265,9 +8297,9 @@
}
},
"node_modules/make-dir/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
@@ -8494,15 +8526,6 @@
"node": ">= 6"
}
},
- "node_modules/modify-values": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
- "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -8998,13 +9021,12 @@
}
},
"node_modules/pac-resolver": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
- "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
"dev": true,
"dependencies": {
"degenerator": "^5.0.0",
- "ip": "^1.1.8",
"netmask": "^2.0.2"
},
"engines": {
@@ -9152,15 +9174,6 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
- "node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/pirates": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
@@ -9278,12 +9291,6 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
- "node_modules/process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "dev": true
- },
"node_modules/promise.allsettled": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.6.tgz",
@@ -9650,9 +9657,9 @@
}
},
"node_modules/read-pkg/node_modules/semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
"bin": {
"semver": "bin/semver"
@@ -10362,9 +10369,9 @@
"dev": true
},
"node_modules/semver": {
- "version": "7.5.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
- "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -10582,12 +10589,6 @@
"node": ">= 14"
}
},
- "node_modules/socks/node_modules/ip": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
- "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
- "dev": true
- },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -10639,18 +10640,6 @@
"integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
"dev": true
},
- "node_modules/split": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
- "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
- "dev": true,
- "dependencies": {
- "through": "2"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
@@ -11023,21 +11012,6 @@
}
}
},
- "node_modules/ts-jest/node_modules/semver": {
- "version": "7.5.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
- "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/ts-node": {
"version": "10.9.1",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
@@ -11711,15 +11685,6 @@
"integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
"dev": true
},
- "node_modules/xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true,
- "engines": {
- "node": ">=0.4"
- }
- },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -11922,9 +11887,9 @@
"dev": true
},
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -11964,9 +11929,9 @@
}
},
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
},
"yallist": {
@@ -12697,9 +12662,9 @@
"dev": true
},
"@hutson/parse-repository-url": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz",
- "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-5.0.0.tgz",
+ "integrity": "sha512-e5+YUKENATs1JgYHMzTr2MW/NDcXGfYFAuOQU8gJgF/kEh4EqKgfGrfLI67bMD4tbhZVlkigz/9YYwWcbOFthg==",
"dev": true
},
"@iarna/toml": {
@@ -13393,15 +13358,15 @@
}
},
"@release-it/conventional-changelog": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-7.0.0.tgz",
- "integrity": "sha512-DBzyVS6c4g8w+xomCsygkmLeQBUq41Wvzy0vGgbdCLOxYnwI0cDaF6HOLPkrifH1qLa1uJ9i1pYA+hNyHkNanQ==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@release-it/conventional-changelog/-/conventional-changelog-7.0.2.tgz",
+ "integrity": "sha512-rsUKWNnU39xivgC2IanjRkEOPsTu2X2jgJGpNHF+mndpOUr1WAROmIaix1o3ne2zseT+GLyZII2NC8FgYaM7xA==",
"dev": true,
"requires": {
"concat-stream": "^2.0.0",
- "conventional-changelog": "^4.0.0",
- "conventional-recommended-bump": "^7.0.1",
- "semver": "7.5.1"
+ "conventional-changelog": "^5.1.0",
+ "conventional-recommended-bump": "^8.0.0",
+ "semver": "^7.5.4"
}
},
"@sinclair/typebox": {
@@ -14558,37 +14523,37 @@
"dev": true
},
"conventional-changelog": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-4.0.0.tgz",
- "integrity": "sha512-JbZjwE1PzxQCvm+HUTIr+pbSekS8qdOZzMakdFyPtdkEWwFvwEJYONzjgMm0txCb2yBcIcfKDmg8xtCKTdecNQ==",
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-5.1.0.tgz",
+ "integrity": "sha512-aWyE/P39wGYRPllcCEZDxTVEmhyLzTc9XA6z6rVfkuCD2UBnhV/sgSOKbQrEG5z9mEZJjnopjgQooTKxEg8mAg==",
"dev": true,
"requires": {
- "conventional-changelog-angular": "^6.0.0",
- "conventional-changelog-atom": "^3.0.0",
- "conventional-changelog-codemirror": "^3.0.0",
- "conventional-changelog-conventionalcommits": "^6.0.0",
- "conventional-changelog-core": "^5.0.0",
- "conventional-changelog-ember": "^3.0.0",
- "conventional-changelog-eslint": "^4.0.0",
- "conventional-changelog-express": "^3.0.0",
- "conventional-changelog-jquery": "^4.0.0",
- "conventional-changelog-jshint": "^3.0.0",
- "conventional-changelog-preset-loader": "^3.0.0"
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-changelog-atom": "^4.0.0",
+ "conventional-changelog-codemirror": "^4.0.0",
+ "conventional-changelog-conventionalcommits": "^7.0.2",
+ "conventional-changelog-core": "^7.0.0",
+ "conventional-changelog-ember": "^4.0.0",
+ "conventional-changelog-eslint": "^5.0.0",
+ "conventional-changelog-express": "^4.0.0",
+ "conventional-changelog-jquery": "^5.0.0",
+ "conventional-changelog-jshint": "^4.0.0",
+ "conventional-changelog-preset-loader": "^4.1.0"
},
"dependencies": {
"conventional-changelog-angular": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz",
- "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+ "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
"dev": true,
"requires": {
"compare-func": "^2.0.0"
}
},
"conventional-changelog-conventionalcommits": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz",
- "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz",
+ "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==",
"dev": true,
"requires": {
"compare-func": "^2.0.0"
@@ -14607,15 +14572,15 @@
}
},
"conventional-changelog-atom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-3.0.0.tgz",
- "integrity": "sha512-pnN5bWpH+iTUWU3FaYdw5lJmfWeqSyrUkG+wyHBI9tC1dLNnHkbAOg1SzTQ7zBqiFrfo55h40VsGXWMdopwc5g==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-4.0.0.tgz",
+ "integrity": "sha512-q2YtiN7rnT1TGwPTwjjBSIPIzDJCRE+XAUahWxnh+buKK99Kks4WLMHoexw38GXx9OUxAsrp44f9qXe5VEMYhw==",
"dev": true
},
"conventional-changelog-codemirror": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-3.0.0.tgz",
- "integrity": "sha512-wzchZt9HEaAZrenZAUUHMCFcuYzGoZ1wG/kTRMICxsnW5AXohYMRxnyecP9ob42Gvn5TilhC0q66AtTPRSNMfw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-4.0.0.tgz",
+ "integrity": "sha512-hQSojc/5imn1GJK3A75m9hEZZhc3urojA5gMpnar4JHmgLnuM3CUIARPpEk86glEKr3c54Po3WV/vCaO/U8g3Q==",
"dev": true
},
"conventional-changelog-conventionalcommits": {
@@ -14630,223 +14595,291 @@
}
},
"conventional-changelog-core": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.2.tgz",
- "integrity": "sha512-RhQOcDweXNWvlRwUDCpaqXzbZemKPKncCWZG50Alth72WITVd6nhVk9MJ6w1k9PFNBcZ3YwkdkChE+8+ZwtUug==",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-7.0.0.tgz",
+ "integrity": "sha512-UYgaB1F/COt7VFjlYKVE/9tTzfU3VUq47r6iWf6lM5T7TlOxr0thI63ojQueRLIpVbrtHK4Ffw+yQGduw2Bhdg==",
"dev": true,
"requires": {
+ "@hutson/parse-repository-url": "^5.0.0",
"add-stream": "^1.0.0",
- "conventional-changelog-writer": "^6.0.0",
- "conventional-commits-parser": "^4.0.0",
- "dateformat": "^3.0.3",
- "get-pkg-repo": "^4.2.1",
- "git-raw-commits": "^3.0.0",
- "git-remote-origin-url": "^2.0.0",
- "git-semver-tags": "^5.0.0",
- "normalize-package-data": "^3.0.3",
- "read-pkg": "^3.0.0",
- "read-pkg-up": "^3.0.0"
+ "conventional-changelog-writer": "^7.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "git-raw-commits": "^4.0.0",
+ "git-semver-tags": "^7.0.0",
+ "hosted-git-info": "^7.0.0",
+ "normalize-package-data": "^6.0.0",
+ "read-pkg": "^8.0.0",
+ "read-pkg-up": "^10.0.0"
},
"dependencies": {
"conventional-commits-parser": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
- "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
"dev": true,
"requires": {
- "is-text-path": "^1.0.1",
+ "is-text-path": "^2.0.0",
"JSONStream": "^1.3.5",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
}
},
+ "dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true
+ },
"find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz",
+ "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==",
"dev": true,
"requires": {
- "locate-path": "^2.0.0"
+ "locate-path": "^7.1.0",
+ "path-exists": "^5.0.0"
}
},
"git-raw-commits": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
- "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
"dev": true,
"requires": {
- "dargs": "^7.0.0",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
}
},
"hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz",
+ "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^10.0.1"
+ }
+ },
+ "is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "requires": {
+ "text-extensions": "^2.0.0"
+ }
+ },
+ "json-parse-even-better-errors": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz",
+ "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==",
+ "dev": true
+ },
+ "lines-and-columns": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz",
+ "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==",
"dev": true
},
"locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+ "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
"dev": true,
"requires": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
+ "p-locate": "^6.0.0"
+ }
+ },
+ "lru-cache": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "dev": true
+ },
+ "meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true
+ },
+ "normalize-package-data": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz",
+ "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
}
},
"p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+ "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
"dev": true,
"requires": {
- "p-try": "^1.0.0"
+ "yocto-queue": "^1.0.0"
}
},
"p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+ "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
"dev": true,
"requires": {
- "p-limit": "^1.1.0"
+ "p-limit": "^4.0.0"
}
},
- "p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
- "dev": true
- },
- "path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
- "dev": true
- },
- "path-type": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
- "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "parse-json": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-7.1.1.tgz",
+ "integrity": "sha512-SgOTCX/EZXtZxBE5eJ97P4yGM5n37BwRU+YMsH4vNzFqJV/oWFXXCmwFlgWUM4PrakybVOueJJ6pwHqSVhTFDw==",
"dev": true,
"requires": {
- "pify": "^3.0.0"
- }
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
- "dev": true
- },
- "read-pkg": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
- "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==",
- "dev": true,
- "requires": {
- "load-json-file": "^4.0.0",
- "normalize-package-data": "^2.3.2",
- "path-type": "^3.0.0"
+ "@babel/code-frame": "^7.21.4",
+ "error-ex": "^1.3.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "lines-and-columns": "^2.0.3",
+ "type-fest": "^3.8.0"
},
"dependencies": {
- "normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
- "dev": true,
- "requires": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
+ "type-fest": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz",
+ "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
+ "dev": true
}
}
},
- "read-pkg-up": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
- "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==",
+ "path-exists": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-8.1.0.tgz",
+ "integrity": "sha512-PORM8AgzXeskHO/WEv312k9U03B8K9JSiWF/8N9sUuFjBa+9SF2u6K7VClzXwDXab51jCd8Nd36CNM+zR97ScQ==",
"dev": true,
"requires": {
- "find-up": "^2.0.0",
- "read-pkg": "^3.0.0"
+ "@types/normalize-package-data": "^2.4.1",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^7.0.0",
+ "type-fest": "^4.2.0"
}
},
- "semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "read-pkg-up": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-10.1.0.tgz",
+ "integrity": "sha512-aNtBq4jR8NawpKJQldrQcSW9y/d+KWH4v24HWkHljOZ7H0av+YTGANBzRh9A5pw7v/bLVsLVPpOhJ7gHNVy8lA==",
+ "dev": true,
+ "requires": {
+ "find-up": "^6.3.0",
+ "read-pkg": "^8.1.0",
+ "type-fest": "^4.2.0"
+ }
+ },
+ "split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true
+ },
+ "text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "4.10.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.2.tgz",
+ "integrity": "sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==",
+ "dev": true
+ },
+ "yocto-queue": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz",
+ "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==",
"dev": true
}
}
},
"conventional-changelog-ember": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-3.0.0.tgz",
- "integrity": "sha512-7PYthCoSxIS98vWhVcSphMYM322OxptpKAuHYdVspryI0ooLDehRXWeRWgN+zWSBXKl/pwdgAg8IpLNSM1/61A==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-4.0.0.tgz",
+ "integrity": "sha512-D0IMhwcJUg1Y8FSry6XAplEJcljkHVlvAZddhhsdbL1rbsqRsMfGx/PIkPYq0ru5aDgn+OxhQ5N5yR7P9mfsvA==",
"dev": true
},
"conventional-changelog-eslint": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-4.0.0.tgz",
- "integrity": "sha512-nEZ9byP89hIU0dMx37JXQkE1IpMmqKtsaR24X7aM3L6Yy/uAtbb+ogqthuNYJkeO1HyvK7JsX84z8649hvp43Q==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-5.0.0.tgz",
+ "integrity": "sha512-6JtLWqAQIeJLn/OzUlYmzd9fKeNSWmQVim9kql+v4GrZwLx807kAJl3IJVc3jTYfVKWLxhC3BGUxYiuVEcVjgA==",
"dev": true
},
"conventional-changelog-express": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-3.0.0.tgz",
- "integrity": "sha512-HqxihpUMfIuxvlPvC6HltA4ZktQEUan/v3XQ77+/zbu8No/fqK3rxSZaYeHYant7zRxQNIIli7S+qLS9tX9zQA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-4.0.0.tgz",
+ "integrity": "sha512-yWyy5c7raP9v7aTvPAWzqrztACNO9+FEI1FSYh7UP7YT1AkWgv5UspUeB5v3Ibv4/o60zj2o9GF2tqKQ99lIsw==",
"dev": true
},
"conventional-changelog-jquery": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-4.0.0.tgz",
- "integrity": "sha512-TTIN5CyzRMf8PUwyy4IOLmLV2DFmPtasKN+x7EQKzwSX8086XYwo+NeaeA3VUT8bvKaIy5z/JoWUvi7huUOgaw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-5.0.0.tgz",
+ "integrity": "sha512-slLjlXLRNa/icMI3+uGLQbtrgEny3RgITeCxevJB+p05ExiTgHACP5p3XiMKzjBn80n+Rzr83XMYfRInEtCPPw==",
"dev": true
},
"conventional-changelog-jshint": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-3.0.0.tgz",
- "integrity": "sha512-bQof4byF4q+n+dwFRkJ/jGf9dCNUv4/kCDcjeCizBvfF81TeimPZBB6fT4HYbXgxxfxWXNl/i+J6T0nI4by6DA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-4.0.0.tgz",
+ "integrity": "sha512-LyXq1bbl0yG0Ai1SbLxIk8ZxUOe3AjnlwE6sVRQmMgetBk+4gY9EO3d00zlEt8Y8gwsITytDnPORl8al7InTjg==",
"dev": true,
"requires": {
"compare-func": "^2.0.0"
}
},
"conventional-changelog-preset-loader": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz",
- "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-4.1.0.tgz",
+ "integrity": "sha512-HozQjJicZTuRhCRTq4rZbefaiCzRM2pr6u2NL3XhrmQm4RMnDXfESU6JKu/pnKwx5xtdkYfNCsbhN5exhiKGJA==",
"dev": true
},
"conventional-changelog-writer": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz",
- "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz",
+ "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==",
"dev": true,
"requires": {
- "conventional-commits-filter": "^3.0.0",
- "dateformat": "^3.0.3",
+ "conventional-commits-filter": "^4.0.0",
"handlebars": "^4.7.7",
"json-stringify-safe": "^5.0.1",
- "meow": "^8.1.2",
- "semver": "^7.0.0",
- "split": "^1.0.1"
+ "meow": "^12.0.1",
+ "semver": "^7.5.2",
+ "split2": "^4.0.0"
+ },
+ "dependencies": {
+ "meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true
+ },
+ "split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true
+ }
}
},
"conventional-commits-filter": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz",
- "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==",
- "dev": true,
- "requires": {
- "lodash.ismatch": "^4.4.0",
- "modify-values": "^1.0.1"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz",
+ "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==",
+ "dev": true
},
"conventional-commits-parser": {
"version": "3.2.4",
@@ -14863,42 +14896,85 @@
}
},
"conventional-recommended-bump": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz",
- "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-8.0.0.tgz",
+ "integrity": "sha512-yvGN+VMy00WIe/pJufpmN+I4B2cM/WFK+CFCmDcjyVLyQR6J1KT2iecmA4NQ58gQAiNkvStEjcZp/W9h1JDM1A==",
"dev": true,
"requires": {
"concat-stream": "^2.0.0",
- "conventional-changelog-preset-loader": "^3.0.0",
- "conventional-commits-filter": "^3.0.0",
- "conventional-commits-parser": "^4.0.0",
- "git-raw-commits": "^3.0.0",
- "git-semver-tags": "^5.0.0",
- "meow": "^8.1.2"
+ "conventional-changelog-preset-loader": "^4.0.0",
+ "conventional-commits-filter": "^4.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "git-raw-commits": "^4.0.0",
+ "git-semver-tags": "^6.0.0",
+ "meow": "^12.0.1"
},
"dependencies": {
"conventional-commits-parser": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz",
- "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
"dev": true,
"requires": {
- "is-text-path": "^1.0.1",
+ "is-text-path": "^2.0.0",
"JSONStream": "^1.3.5",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
}
},
+ "dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true
+ },
"git-raw-commits": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz",
- "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
"dev": true,
"requires": {
- "dargs": "^7.0.0",
- "meow": "^8.1.2",
- "split2": "^3.2.2"
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
}
+ },
+ "git-semver-tags": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-6.0.0.tgz",
+ "integrity": "sha512-v5BL6psuUy+Ftuo99141XlOIDoJtKw5+YyDANS7fknSP0iT4cVIanc3toDsH4K+VpIWc19l2/xkwQmXMfloeUA==",
+ "dev": true,
+ "requires": {
+ "meow": "^12.0.1",
+ "semver": "^7.5.2"
+ }
+ },
+ "is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "requires": {
+ "text-extensions": "^2.0.0"
+ }
+ },
+ "meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true
+ },
+ "split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true
+ },
+ "text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true
}
}
},
@@ -14920,12 +14996,6 @@
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"dev": true
},
- "core-util-is": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
- "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
- "dev": true
- },
"cosmiconfig": {
"version": "8.2.0",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.2.0.tgz",
@@ -14991,12 +15061,6 @@
"integrity": "sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==",
"dev": true
},
- "dateformat": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
- "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
- "dev": true
- },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -16019,98 +16083,6 @@
"integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
"dev": true
},
- "get-pkg-repo": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz",
- "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==",
- "dev": true,
- "requires": {
- "@hutson/parse-repository-url": "^3.0.0",
- "hosted-git-info": "^4.0.0",
- "through2": "^2.0.0",
- "yargs": "^16.2.0"
- },
- "dependencies": {
- "cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
- "dev": true,
- "requires": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^7.0.0"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
- "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "safe-buffer": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
- "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
- "dev": true
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "dev": true,
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- },
- "through2": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
- "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
- "dev": true,
- "requires": {
- "readable-stream": "~2.3.6",
- "xtend": "~4.0.1"
- }
- },
- "yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
- "dev": true,
- "requires": {
- "cliui": "^7.0.2",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.0",
- "y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
- }
- },
- "yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true
- }
- }
- },
"get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
@@ -16180,24 +16152,22 @@
"through2": "^4.0.0"
}
},
- "git-remote-origin-url": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz",
- "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==",
- "dev": true,
- "requires": {
- "gitconfiglocal": "^1.0.0",
- "pify": "^2.3.0"
- }
- },
"git-semver-tags": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz",
- "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-7.0.1.tgz",
+ "integrity": "sha512-NY0ZHjJzyyNXHTDZmj+GG7PyuAKtMsyWSwh07CR2hOZFa+/yoTsXci/nF2obzL8UDhakFNkD9gNdt/Ed+cxh2Q==",
"dev": true,
"requires": {
- "meow": "^8.1.2",
- "semver": "^7.0.0"
+ "meow": "^12.0.1",
+ "semver": "^7.5.2"
+ },
+ "dependencies": {
+ "meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true
+ }
}
},
"git-up": {
@@ -16219,15 +16189,6 @@
"git-up": "^7.0.0"
}
},
- "gitconfiglocal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz",
- "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==",
- "dev": true,
- "requires": {
- "ini": "^1.3.2"
- }
- },
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -16332,13 +16293,13 @@
"dev": true
},
"handlebars": {
- "version": "4.7.7",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
- "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5",
- "neo-async": "^2.6.0",
+ "neo-async": "^2.6.2",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4",
"wordwrap": "^1.0.0"
@@ -16721,9 +16682,9 @@
"dev": true
},
"ip": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
- "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz",
+ "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==",
"dev": true
},
"ipaddr.js": {
@@ -17119,9 +17080,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -17645,12 +17606,6 @@
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
"dev": true
},
- "json-parse-better-errors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
- "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
- "dev": true
- },
"json-parse-even-better-errors": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
@@ -17758,42 +17713,6 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
- "load-json-file": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
- "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "parse-json": "^4.0.0",
- "pify": "^3.0.0",
- "strip-bom": "^3.0.0"
- },
- "dependencies": {
- "parse-json": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
- "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
- "dev": true,
- "requires": {
- "error-ex": "^1.3.1",
- "json-parse-better-errors": "^1.0.1"
- }
- },
- "pify": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
- "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
- "dev": true
- },
- "strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true
- }
- }
- },
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -17833,12 +17752,6 @@
"integrity": "sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==",
"dev": true
},
- "lodash.ismatch": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz",
- "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==",
- "dev": true
- },
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
@@ -17954,9 +17867,9 @@
},
"dependencies": {
"semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true
}
}
@@ -18118,12 +18031,6 @@
"kind-of": "^6.0.3"
}
},
- "modify-values": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
- "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==",
- "dev": true
- },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
@@ -18457,13 +18364,12 @@
}
},
"pac-resolver": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
- "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
+ "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
"dev": true,
"requires": {
"degenerator": "^5.0.0",
- "ip": "^1.1.8",
"netmask": "^2.0.2"
}
},
@@ -18572,12 +18478,6 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
- "dev": true
- },
"pirates": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
@@ -18666,12 +18566,6 @@
}
}
},
- "process-nextick-args": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
- "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
- "dev": true
- },
"promise.allsettled": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/promise.allsettled/-/promise.allsettled-1.0.6.tgz",
@@ -18882,9 +18776,9 @@
}
},
"semver": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true
},
"type-fest": {
@@ -19426,9 +19320,9 @@
"dev": true
},
"semver": {
- "version": "7.5.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
- "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+ "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -19586,14 +19480,6 @@
"requires": {
"ip": "^2.0.0",
"smart-buffer": "^4.2.0"
- },
- "dependencies": {
- "ip": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
- "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==",
- "dev": true
- }
}
},
"socks-proxy-agent": {
@@ -19655,15 +19541,6 @@
"integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==",
"dev": true
},
- "split": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
- "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
- "dev": true,
- "requires": {
- "through": "2"
- }
- },
"split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
@@ -19925,17 +19802,6 @@
"make-error": "1.x",
"semver": "^7.5.3",
"yargs-parser": "^21.0.1"
- },
- "dependencies": {
- "semver": {
- "version": "7.5.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
- "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
- "dev": true,
- "requires": {
- "lru-cache": "^6.0.0"
- }
- }
}
},
"ts-node": {
@@ -20420,12 +20286,6 @@
"integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==",
"dev": true
},
- "xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
- "dev": true
- },
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
From 9bcd6e6b5547974c45ade756b623eb385bb76019 Mon Sep 17 00:00:00 2001
From: Ratchanan Srirattanamet
Date: Fri, 23 Feb 2024 16:30:18 +0700
Subject: [PATCH 33/75] fix: --auth when --git-user contains space (#95)
Since --git-user is a user-facing name, it's common to include a space
in it. As such, it's not suitable to use as a username in a Git remote
URL.
GitLab documented that it doesn't (yet?) check for username [1], and
from my testing GitHub doesn't seem to care either. So just use an
arbitrary name as a username.
[1] https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html
---
dist/cli/index.js | 5 +++--
dist/gha/index.js | 5 +++--
src/service/git/git-cli.ts | 5 +++--
test/service/git/git-cli.test.ts | 18 ++++++++++++++++++
4 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 5a84866..2f6ab30 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -493,8 +493,9 @@ class GitCLIService {
* @param remoteURL remote link, e.g., https://github.com/kiegroup/git-backporting-example.git
*/
remoteWithAuth(remoteURL) {
- if (this.auth && this.gitData.user) {
- return remoteURL.replace("://", `://${this.gitData.user}:${this.auth}@`);
+ if (this.auth) {
+ // Anything will work as a username.
+ return remoteURL.replace("://", `://token:${this.auth}@`);
}
// return remote as it is
return remoteURL;
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 9f2c8e4..60b0fea 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -463,8 +463,9 @@ class GitCLIService {
* @param remoteURL remote link, e.g., https://github.com/kiegroup/git-backporting-example.git
*/
remoteWithAuth(remoteURL) {
- if (this.auth && this.gitData.user) {
- return remoteURL.replace("://", `://${this.gitData.user}:${this.auth}@`);
+ if (this.auth) {
+ // Anything will work as a username.
+ return remoteURL.replace("://", `://token:${this.auth}@`);
}
// return remote as it is
return remoteURL;
diff --git a/src/service/git/git-cli.ts b/src/service/git/git-cli.ts
index 76f6fc3..5eb7678 100644
--- a/src/service/git/git-cli.ts
+++ b/src/service/git/git-cli.ts
@@ -35,8 +35,9 @@ export default class GitCLIService {
* @param remoteURL remote link, e.g., https://github.com/kiegroup/git-backporting-example.git
*/
private remoteWithAuth(remoteURL: string): string {
- if (this.auth && this.gitData.user) {
- return remoteURL.replace("://", `://${this.gitData.user}:${this.auth}@`);
+ if (this.auth) {
+ // Anything will work as a username.
+ return remoteURL.replace("://", `://token:${this.auth}@`);
}
// return remote as it is
diff --git a/test/service/git/git-cli.test.ts b/test/service/git/git-cli.test.ts
index 2b9c364..8c71609 100644
--- a/test/service/git/git-cli.test.ts
+++ b/test/service/git/git-cli.test.ts
@@ -123,4 +123,22 @@ describe("git cli service", () => {
const post = spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd }).stdout.toString().trim();
expect(post).toEqual("tbranch");
});
+
+ test("git clone set url with auth correctly for API token", async () => {
+ const git2 = new GitCLIService("api-token", {
+ user: "Backporting bot",
+ email: "bot@example.com",
+ });
+ const cwd2 = `${__dirname}/test-api-token`;
+
+ try {
+ await git2.clone(`file://${cwd}`, cwd2, "main");
+ const remoteURL = spawnSync("git", ["remote", "get-url", "origin"], { cwd: cwd2 }).stdout.toString().trim();
+
+ expect(remoteURL).toContain("api-token");
+ expect(remoteURL).not.toContain("Backporting bot");
+ } finally {
+ fs.rmSync(cwd2, { recursive: true, force: true });
+ }
+ });
});
\ No newline at end of file
From 5afc46426847bdeda68a3694a64c506c5f3d0255 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Fri, 23 Feb 2024 11:44:47 +0100
Subject: [PATCH 34/75] chore: add issue templates and improve pr template
(#99)
---
.github/ISSUE_TEMPLATE/bug.md | 23 +++++++++++++++++++++++
.github/ISSUE_TEMPLATE/chore.md | 8 ++++++++
.github/ISSUE_TEMPLATE/feature.md | 20 ++++++++++++++++++++
.github/pull_request_template.md | 25 +++++++++++++++----------
4 files changed, 66 insertions(+), 10 deletions(-)
create mode 100644 .github/ISSUE_TEMPLATE/bug.md
create mode 100644 .github/ISSUE_TEMPLATE/chore.md
create mode 100644 .github/ISSUE_TEMPLATE/feature.md
diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md
new file mode 100644
index 0000000..e1581e7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug.md
@@ -0,0 +1,23 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: 'bug'
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Do this '...'
+2. Do that '....'
+3. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Additional context**
+Add any other context about the problem here.
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/chore.md b/.github/ISSUE_TEMPLATE/chore.md
new file mode 100644
index 0000000..2af5c99
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/chore.md
@@ -0,0 +1,8 @@
+---
+name: Chore issue
+about: General purpose issues related to chores, project management, etc.
+title: ''
+labels: 'chore'
+assignees: ''
+
+---
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md
new file mode 100644
index 0000000..b3b4ea8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature.md
@@ -0,0 +1,20 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+title: ''
+labels: 'feature'
+assignees: ''
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.
\ No newline at end of file
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 20ad8a1..37f00ed 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,22 +1,27 @@
**Thank you for submitting this pull request**
-fix _(please add the issue ID if it exists)_
+fixes _(please add the issue ID if it exists)_
-### Referenced pull requests
+## Description
+
-
-
+## How Has This Been Tested?
+
+
+
### Checklist
- [ ] Tests added if applicable.
- [ ] Documentation updated if applicable.
+### Merge criteria:
+
+
+
+- [ ] The commits and have meaningful messages; the author will squash them _after approval_ or will ask to merge with squash.
+- [ ] Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
+- [ ] The developer has manually tested the changes and verified that the changes work
+
> **Note:** `dist/cli/index.js` and `dist/gha/index.js` are automatically generated by git hooks and gh workflows.
From 2c5c54654d0af04d17eaf8cae4992a5fca22770c Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Fri, 23 Feb 2024 11:50:56 +0100
Subject: [PATCH 35/75] build: skip ci when not required (#100)
---
.github/workflows/coverage.yml | 27 +++++++++++++++++----------
.github/workflows/pull-request.yml | 10 +++++++++-
2 files changed, 26 insertions(+), 11 deletions(-)
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index d5afeb5..3d12a0e 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -1,15 +1,22 @@
name: 'coverage report'
on:
- pull_request_target:
- branches:
- - main
+ pull_request_target:
+ branches:
+ - main
+ paths-ignore:
+ - 'LICENSE*'
+ - '**.gitignore'
+ - '**.md'
+ - '**.txt'
+ - '.github/ISSUE_TEMPLATE/**'
+ - '.github/dependabot.yml'
jobs:
- coverage:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v3
- - uses: ArtiomTr/jest-coverage-report-action@v2
- with:
- test-script: npm test
\ No newline at end of file
+ coverage:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - uses: ArtiomTr/jest-coverage-report-action@v2
+ with:
+ test-script: npm test
\ No newline at end of file
diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index 947d54a..a72fe6c 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -3,7 +3,15 @@
name: "pull request check"
-on: pull_request
+on:
+ pull_request:
+ paths-ignore:
+ - 'LICENSE*'
+ - '**.gitignore'
+ - '**.md'
+ - '**.txt'
+ - '.github/ISSUE_TEMPLATE/**'
+ - '.github/dependabot.yml'
jobs:
build:
From c57fca6bd6b9c241c11ad1f728cc9bc0acfd7f88 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Fri, 23 Feb 2024 15:13:34 +0100
Subject: [PATCH 36/75] fix(gh-96): fix git token parsing (#98)
---
dist/cli/index.js | 113 ++++++++++--------
dist/gha/index.js | 113 ++++++++++--------
src/service/configs/configs-parser.ts | 41 +------
.../configs/pullrequest/pr-configs-parser.ts | 12 +-
src/service/git/git-util.ts | 39 ++++++
src/service/runner/runner.ts | 27 ++++-
.../github-pr-configs-parser-multiple.test.ts | 5 +-
.../github-pr-configs-parser.test.ts | 85 +------------
.../gitlab-pr-configs-parser-multiple.test.ts | 4 -
.../gitlab-pr-configs-parser.test.ts | 95 +--------------
test/service/runner/cli-github-runner.test.ts | 61 +++++++++-
test/service/runner/cli-gitlab-runner.test.ts | 61 +++++++++-
test/service/runner/gha-github-runner.test.ts | 5 +-
test/service/runner/gha-gitlab-runner.test.ts | 5 +-
14 files changed, 324 insertions(+), 342 deletions(-)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 2f6ab30..df9bcc2 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -251,9 +251,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-const configs_types_1 = __nccwpck_require__(4753);
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
-const git_types_1 = __nccwpck_require__(750);
/**
* Abstract configuration parser class in charge to parse
* Args and produces a common Configs object
@@ -275,42 +273,6 @@ class ConfigsParser {
}
return Promise.resolve(configs);
}
- /**
- * 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.
- * @param gitType
- * @returns tuple where
- * - the first element is the corresponding env value
- * - the second element is true if the value is not undefined nor empty
- */
- getGitTokenFromEnv(gitType) {
- let [token] = this.getEnv(configs_types_1.AuthTokenId.GIT_TOKEN);
- let [specToken, specOk] = [undefined, false];
- if (git_types_1.GitClientType.GITHUB == gitType) {
- [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITHUB_TOKEN);
- }
- else if (git_types_1.GitClientType.GITLAB == gitType) {
- [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITLAB_TOKEN);
- }
- else if (git_types_1.GitClientType.CODEBERG == gitType) {
- [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
- }
- if (specOk) {
- token = specToken;
- }
- return token;
- }
- /**
- * Get process env variable given the input key string
- * @param key
- * @returns tuple where
- * - the first element is the corresponding env value
- * - the second element is true if the value is not undefined nor empty
- */
- getEnv(key) {
- const val = process.env[key];
- return [val, val !== undefined && val !== ""];
- }
}
exports["default"] = ConfigsParser;
@@ -371,18 +333,9 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
}
- // setup the auth token
- let token = args.auth;
- if (token === undefined) {
- this.logger.info("Auth argument not provided, checking available tokens from env..");
- token = this.getGitTokenFromEnv(this.gitClient.getClientType());
- if (!token) {
- this.logger.info("Git token not set in the env");
- }
- }
return {
dryRun: args.dryRun,
- auth: token,
+ auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
@@ -662,8 +615,9 @@ GitClientFactory.logger = logger_service_factory_1.default.getLogger();
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.inferGitApiUrl = exports.inferGitClient = void 0;
+exports.getEnv = exports.getGitTokenFromEnv = exports.inferGitApiUrl = exports.inferGitClient = void 0;
const git_types_1 = __nccwpck_require__(750);
+const configs_types_1 = __nccwpck_require__(4753);
const PUBLIC_GITHUB_URL = "https://github.com";
const PUBLIC_GITHUB_API = "https://api.github.com";
/**
@@ -701,6 +655,44 @@ const inferGitApiUrl = (prUrl, apiVersion = "v4") => {
return `${baseUrl}/api/${apiVersion}`;
};
exports.inferGitApiUrl = inferGitApiUrl;
+/**
+ * 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.
+ * @param gitType
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+const getGitTokenFromEnv = (gitType) => {
+ let [token] = (0, exports.getEnv)(configs_types_1.AuthTokenId.GIT_TOKEN);
+ let [specToken, specOk] = [undefined, false];
+ if (git_types_1.GitClientType.GITHUB == gitType) {
+ [specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.GITHUB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.GITLAB == gitType) {
+ [specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.GITLAB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.CODEBERG == gitType) {
+ [specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
+ }
+ if (specOk) {
+ token = specToken;
+ }
+ return token;
+};
+exports.getGitTokenFromEnv = getGitTokenFromEnv;
+/**
+ * Get process env variable given the input key string
+ * @param key
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+const getEnv = (key) => {
+ const val = process.env[key];
+ return [val, val !== undefined && val !== ""];
+};
+exports.getEnv = getEnv;
/***/ }),
@@ -1354,9 +1346,11 @@ class Runner {
const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
// the api version is ignored in case of github
const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
- const gitApi = git_client_factory_1.default.getOrCreate(gitClientType, args.auth, apiUrl);
+ const token = this.fetchToken(args, gitClientType);
+ const gitApi = git_client_factory_1.default.getOrCreate(gitClientType, token, apiUrl);
// 3. parse configs
this.logger.debug("Parsing configs..");
+ args.auth = token; // override auth
const configs = await new pr_configs_parser_1.default().parseAndValidate(args);
const backportPRs = configs.backportPullRequests;
// start local git operations
@@ -1381,6 +1375,25 @@ class Runner {
throw new Error(`Failure occurred during one of the backports: [${failures.join(" ; ")}]`);
}
}
+ /**
+ * Fetch the GIT token from the provided Args obj, if not empty, otherwise fallback
+ * to the environment variables.
+ * @param args input arguments
+ * @param gitType git client type
+ * @returns the provided or fetched token, or undefined if not set anywhere
+ */
+ fetchToken(args, gitType) {
+ let token = args.auth;
+ if (token === undefined) {
+ // try to fetch the auth from env variable
+ this.logger.info("Auth argument not provided, checking available tokens from env..");
+ token = (0, git_util_1.getGitTokenFromEnv)(gitType);
+ if (!token) {
+ this.logger.info("Git token not found in the environment");
+ }
+ }
+ return token;
+ }
async executeBackport(configs, backportPR, git) {
this.logger.setContext(backportPR.base);
const originalPR = configs.originalPullRequest;
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 60b0fea..529a401 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -221,9 +221,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
-const configs_types_1 = __nccwpck_require__(4753);
const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
-const git_types_1 = __nccwpck_require__(750);
/**
* Abstract configuration parser class in charge to parse
* Args and produces a common Configs object
@@ -245,42 +243,6 @@ class ConfigsParser {
}
return Promise.resolve(configs);
}
- /**
- * 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.
- * @param gitType
- * @returns tuple where
- * - the first element is the corresponding env value
- * - the second element is true if the value is not undefined nor empty
- */
- getGitTokenFromEnv(gitType) {
- let [token] = this.getEnv(configs_types_1.AuthTokenId.GIT_TOKEN);
- let [specToken, specOk] = [undefined, false];
- if (git_types_1.GitClientType.GITHUB == gitType) {
- [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITHUB_TOKEN);
- }
- else if (git_types_1.GitClientType.GITLAB == gitType) {
- [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.GITLAB_TOKEN);
- }
- else if (git_types_1.GitClientType.CODEBERG == gitType) {
- [specToken, specOk] = this.getEnv(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
- }
- if (specOk) {
- token = specToken;
- }
- return token;
- }
- /**
- * Get process env variable given the input key string
- * @param key
- * @returns tuple where
- * - the first element is the corresponding env value
- * - the second element is true if the value is not undefined nor empty
- */
- getEnv(key) {
- const val = process.env[key];
- return [val, val !== undefined && val !== ""];
- }
}
exports["default"] = ConfigsParser;
@@ -341,18 +303,9 @@ class PullRequestConfigsParser extends configs_parser_1.default {
if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
}
- // setup the auth token
- let token = args.auth;
- if (token === undefined) {
- this.logger.info("Auth argument not provided, checking available tokens from env..");
- token = this.getGitTokenFromEnv(this.gitClient.getClientType());
- if (!token) {
- this.logger.info("Git token not set in the env");
- }
- }
return {
dryRun: args.dryRun,
- auth: token,
+ auth: args.auth,
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
@@ -632,8 +585,9 @@ GitClientFactory.logger = logger_service_factory_1.default.getLogger();
"use strict";
Object.defineProperty(exports, "__esModule", ({ value: true }));
-exports.inferGitApiUrl = exports.inferGitClient = void 0;
+exports.getEnv = exports.getGitTokenFromEnv = exports.inferGitApiUrl = exports.inferGitClient = void 0;
const git_types_1 = __nccwpck_require__(750);
+const configs_types_1 = __nccwpck_require__(4753);
const PUBLIC_GITHUB_URL = "https://github.com";
const PUBLIC_GITHUB_API = "https://api.github.com";
/**
@@ -671,6 +625,44 @@ const inferGitApiUrl = (prUrl, apiVersion = "v4") => {
return `${baseUrl}/api/${apiVersion}`;
};
exports.inferGitApiUrl = inferGitApiUrl;
+/**
+ * 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.
+ * @param gitType
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+const getGitTokenFromEnv = (gitType) => {
+ let [token] = (0, exports.getEnv)(configs_types_1.AuthTokenId.GIT_TOKEN);
+ let [specToken, specOk] = [undefined, false];
+ if (git_types_1.GitClientType.GITHUB == gitType) {
+ [specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.GITHUB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.GITLAB == gitType) {
+ [specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.GITLAB_TOKEN);
+ }
+ else if (git_types_1.GitClientType.CODEBERG == gitType) {
+ [specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
+ }
+ if (specOk) {
+ token = specToken;
+ }
+ return token;
+};
+exports.getGitTokenFromEnv = getGitTokenFromEnv;
+/**
+ * Get process env variable given the input key string
+ * @param key
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+const getEnv = (key) => {
+ const val = process.env[key];
+ return [val, val !== undefined && val !== ""];
+};
+exports.getEnv = getEnv;
/***/ }),
@@ -1324,9 +1316,11 @@ class Runner {
const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
// the api version is ignored in case of github
const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
- const gitApi = git_client_factory_1.default.getOrCreate(gitClientType, args.auth, apiUrl);
+ const token = this.fetchToken(args, gitClientType);
+ const gitApi = git_client_factory_1.default.getOrCreate(gitClientType, token, apiUrl);
// 3. parse configs
this.logger.debug("Parsing configs..");
+ args.auth = token; // override auth
const configs = await new pr_configs_parser_1.default().parseAndValidate(args);
const backportPRs = configs.backportPullRequests;
// start local git operations
@@ -1351,6 +1345,25 @@ class Runner {
throw new Error(`Failure occurred during one of the backports: [${failures.join(" ; ")}]`);
}
}
+ /**
+ * Fetch the GIT token from the provided Args obj, if not empty, otherwise fallback
+ * to the environment variables.
+ * @param args input arguments
+ * @param gitType git client type
+ * @returns the provided or fetched token, or undefined if not set anywhere
+ */
+ fetchToken(args, gitType) {
+ let token = args.auth;
+ if (token === undefined) {
+ // try to fetch the auth from env variable
+ this.logger.info("Auth argument not provided, checking available tokens from env..");
+ token = (0, git_util_1.getGitTokenFromEnv)(gitType);
+ if (!token) {
+ this.logger.info("Git token not found in the environment");
+ }
+ }
+ return token;
+ }
async executeBackport(configs, backportPR, git) {
this.logger.setContext(backportPR.base);
const originalPR = configs.originalPullRequest;
diff --git a/src/service/configs/configs-parser.ts b/src/service/configs/configs-parser.ts
index 379e39b..5b901cb 100644
--- a/src/service/configs/configs-parser.ts
+++ b/src/service/configs/configs-parser.ts
@@ -1,8 +1,7 @@
import { Args } from "@bp/service/args/args.types";
-import { AuthTokenId, Configs } from "@bp/service/configs/configs.types";
+import { Configs } from "@bp/service/configs/configs.types";
import LoggerService from "../logger/logger-service";
import LoggerServiceFactory from "../logger/logger-service-factory";
-import { GitClientType } from "../git/git.types";
/**
* Abstract configuration parser class in charge to parse
@@ -35,42 +34,4 @@ import { GitClientType } from "../git/git.types";
return Promise.resolve(configs);
}
-
- /**
- * 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.
- * @param gitType
- * @returns tuple where
- * - the first element is the corresponding env value
- * - the second element is true if the value is not undefined nor empty
- */
- public getGitTokenFromEnv(gitType: GitClientType): string | undefined {
- let [token] = this.getEnv(AuthTokenId.GIT_TOKEN);
- let [specToken, specOk]: [string | undefined, boolean] = [undefined, false];
- if (GitClientType.GITHUB == gitType) {
- [specToken, specOk] = this.getEnv(AuthTokenId.GITHUB_TOKEN);
- } else if (GitClientType.GITLAB == gitType) {
- [specToken, specOk] = this.getEnv(AuthTokenId.GITLAB_TOKEN);
- } else if (GitClientType.CODEBERG == gitType) {
- [specToken, specOk] = this.getEnv(AuthTokenId.CODEBERG_TOKEN);
- }
-
- if (specOk) {
- token = specToken;
- }
-
- return token;
- }
-
- /**
- * Get process env variable given the input key string
- * @param key
- * @returns tuple where
- * - the first element is the corresponding env value
- * - the second element is true if the value is not undefined nor empty
- */
- public getEnv(key: string): [string | undefined, boolean] {
- const val = process.env[key];
- return [val, val !== undefined && val !== ""];
- }
}
\ No newline at end of file
diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts
index 34c3c88..cca2c8d 100644
--- a/src/service/configs/pullrequest/pr-configs-parser.ts
+++ b/src/service/configs/pullrequest/pr-configs-parser.ts
@@ -33,19 +33,9 @@ export default class PullRequestConfigsParser extends ConfigsParser {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
}
- // setup the auth token
- let token = args.auth;
- if (token === undefined) {
- this.logger.info("Auth argument not provided, checking available tokens from env..");
- token = this.getGitTokenFromEnv(this.gitClient.getClientType());
- if (!token) {
- this.logger.info("Git token not set in the env");
- }
- }
-
return {
dryRun: args.dryRun!,
- auth: token,
+ auth: args.auth, // this has been already pre-processed before parsing configs
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
mergeStrategy: args.strategy,
mergeStrategyOption: args.strategyOption,
diff --git a/src/service/git/git-util.ts b/src/service/git/git-util.ts
index 2ac1f2b..67d32ff 100644
--- a/src/service/git/git-util.ts
+++ b/src/service/git/git-util.ts
@@ -1,4 +1,5 @@
import { GitClientType } from "@bp/service/git/git.types";
+import { AuthTokenId } from "@bp/service/configs/configs.types";
const PUBLIC_GITHUB_URL = "https://github.com";
const PUBLIC_GITHUB_API = "https://api.github.com";
@@ -38,4 +39,42 @@ export const inferGitApiUrl = (prUrl: string, apiVersion = "v4"): string => {
}
return `${baseUrl}/api/${apiVersion}`;
+};
+
+/**
+ * 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.
+ * @param gitType
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+export const getGitTokenFromEnv = (gitType: GitClientType): string | undefined => {
+ let [token] = getEnv(AuthTokenId.GIT_TOKEN);
+ let [specToken, specOk]: [string | undefined, boolean] = [undefined, false];
+ if (GitClientType.GITHUB == gitType) {
+ [specToken, specOk] = getEnv(AuthTokenId.GITHUB_TOKEN);
+ } else if (GitClientType.GITLAB == gitType) {
+ [specToken, specOk] = getEnv(AuthTokenId.GITLAB_TOKEN);
+ } else if (GitClientType.CODEBERG == gitType) {
+ [specToken, specOk] = getEnv(AuthTokenId.CODEBERG_TOKEN);
+ }
+
+ if (specOk) {
+ token = specToken;
+ }
+
+ return token;
+};
+
+/**
+ * Get process env variable given the input key string
+ * @param key
+ * @returns tuple where
+ * - the first element is the corresponding env value
+ * - the second element is true if the value is not undefined nor empty
+ */
+export const getEnv = (key: string): [string | undefined, boolean] => {
+ const val = process.env[key];
+ return [val, val !== undefined && val !== ""];
};
\ No newline at end of file
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index ce6d543..1e48193 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -8,7 +8,7 @@ import GitClientFactory from "@bp/service/git/git-client-factory";
import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/git/git.types";
import LoggerService from "@bp/service/logger/logger-service";
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
-import { inferGitClient, inferGitApiUrl } from "@bp/service/git/git-util";
+import { inferGitClient, inferGitApiUrl, getGitTokenFromEnv } from "@bp/service/git/git-util";
interface Git {
gitClientType: GitClientType;
@@ -63,10 +63,12 @@ export default class Runner {
const gitClientType: GitClientType = inferGitClient(args.pullRequest);
// the api version is ignored in case of github
const apiUrl = inferGitApiUrl(args.pullRequest, gitClientType === GitClientType.CODEBERG ? "v1" : undefined);
- const gitApi: GitClient = GitClientFactory.getOrCreate(gitClientType, args.auth, apiUrl);
+ const token = this.fetchToken(args, gitClientType);
+ const gitApi: GitClient = GitClientFactory.getOrCreate(gitClientType, token, apiUrl);
// 3. parse configs
this.logger.debug("Parsing configs..");
+ args.auth = token; // override auth
const configs: Configs = await new PullRequestConfigsParser().parseAndValidate(args);
const backportPRs: BackportPullRequest[] = configs.backportPullRequests;
@@ -94,6 +96,27 @@ export default class Runner {
}
}
+ /**
+ * Fetch the GIT token from the provided Args obj, if not empty, otherwise fallback
+ * to the environment variables.
+ * @param args input arguments
+ * @param gitType git client type
+ * @returns the provided or fetched token, or undefined if not set anywhere
+ */
+ fetchToken(args: Args, gitType: GitClientType): string | undefined {
+ let token = args.auth;
+ if (token === undefined) {
+ // try to fetch the auth from env variable
+ this.logger.info("Auth argument not provided, checking available tokens from env..");
+ token = getGitTokenFromEnv(gitType);
+ if (!token) {
+ this.logger.info("Git token not found in the environment");
+ }
+ }
+
+ return token;
+ }
+
async executeBackport(configs: Configs, backportPR: BackportPullRequest, git: Git): Promise {
this.logger.setContext(backportPR.base);
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 38adb10..eab1bfa 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
@@ -4,7 +4,7 @@ import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
-import { resetEnvTokens, resetProcessArgs } from "../../../support/utils";
+import { resetProcessArgs } from "../../../support/utils";
import { MERGED_PR_FIXTURE, REPO, TARGET_OWNER, MULT_COMMITS_PR_FIXTURE } from "../../../support/mock/github-data";
import GitHubMapper from "@bp/service/git/github/github-mapper";
import GitHubClient from "@bp/service/git/github/github-client";
@@ -27,9 +27,6 @@ describe("github pull request config parser", () => {
beforeEach(() => {
// reset process.env variables
resetProcessArgs();
-
- // reset env tokens
- resetEnvTokens();
// mock octokit
mockGitHubClient("http://localhost/api/v3");
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 a45def3..f392cc7 100644
--- a/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/github-pr-configs-parser.test.ts
@@ -1,10 +1,10 @@
import { Args } from "@bp/service/args/args.types";
-import { AuthTokenId, Configs } from "@bp/service/configs/configs.types";
+import { Configs } from "@bp/service/configs/configs.types";
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
-import { addProcessArgs, createTestFile, removeTestFile, resetEnvTokens, resetProcessArgs } from "../../../support/utils";
+import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../../support/utils";
import { MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, REPO, TARGET_OWNER, MULT_COMMITS_PR_FIXTURE } from "../../../support/mock/github-data";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import GitHubMapper from "@bp/service/git/github/github-mapper";
@@ -66,9 +66,6 @@ describe("github pull request config parser", () => {
// reset process.env variables
resetProcessArgs();
- // reset env tokens
- resetEnvTokens();
-
// mock octokit
mockGitHubClient("http://localhost/api/v3");
@@ -842,82 +839,4 @@ describe("github pull request config parser", () => {
comments: ["First comment", "Second comment"],
});
});
-
- test("override token using auth arg", async () => {
- process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
- const args: Args = {
- dryRun: true,
- auth: "whatever",
- pullRequest: mergedPRUrl,
- targetBranch: "prod",
- folder: "/tmp/test",
- gitUser: "GitHub",
- gitEmail: "noreply@github.com",
- reviewers: [],
- assignees: [],
- inheritReviewers: true,
- };
-
- const configs: Configs = await configParser.parseAndValidate(args);
-
- expect(configs.dryRun).toEqual(true);
- expect(configs.auth).toEqual("whatever");
- expect(configs.folder).toEqual("/tmp/test");
- expect(configs.git).toEqual({
- user: "GitHub",
- email: "noreply@github.com"
- });
- });
-
- test("auth using GITHUB_TOKEN has precedence over GIT_TOKEN env variable", async () => {
- process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
- process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
- const args: Args = {
- dryRun: true,
- pullRequest: mergedPRUrl,
- targetBranch: "prod",
- folder: "/tmp/test",
- gitUser: "GitHub",
- gitEmail: "noreply@github.com",
- reviewers: [],
- assignees: [],
- inheritReviewers: true,
- };
-
- const configs: Configs = await configParser.parseAndValidate(args);
-
- expect(configs.dryRun).toEqual(true);
- expect(configs.auth).toEqual("mygithubtoken");
- expect(configs.folder).toEqual("/tmp/test");
- expect(configs.git).toEqual({
- user: "GitHub",
- email: "noreply@github.com"
- });
- });
-
- test("ignore env variables related to other git platforms", async () => {
- process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
- process.env[AuthTokenId.CODEBERG_TOKEN] = "mycodebergtoken";
- const args: Args = {
- dryRun: true,
- pullRequest: mergedPRUrl,
- targetBranch: "prod",
- folder: "/tmp/test",
- gitUser: "GitHub",
- gitEmail: "noreply@github.com",
- reviewers: [],
- assignees: [],
- inheritReviewers: true,
- };
-
- const configs: Configs = await configParser.parseAndValidate(args);
-
- expect(configs.dryRun).toEqual(true);
- expect(configs.auth).toEqual(undefined);
- expect(configs.folder).toEqual("/tmp/test");
- expect(configs.git).toEqual({
- user: "GitHub",
- email: "noreply@github.com"
- });
- });
});
\ No newline at end of file
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 842a9ca..deff8de 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
@@ -7,7 +7,6 @@ import { getAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { MERGED_SQUASHED_MR } from "../../../support/mock/gitlab-data";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import GitLabMapper from "@bp/service/git/gitlab/gitlab-mapper";
-import { resetEnvTokens } from "../../../support/utils";
jest.spyOn(GitLabMapper.prototype, "mapPullRequest");
jest.spyOn(GitLabClient.prototype, "getPullRequest");
@@ -32,9 +31,6 @@ describe("gitlab merge request config parser", () => {
});
beforeEach(() => {
- // reset env tokens
- resetEnvTokens();
-
configParser = new PullRequestConfigsParser();
});
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 0c9248d..981cb25 100644
--- a/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
+++ b/test/service/configs/pullrequest/gitlab-pr-configs-parser.test.ts
@@ -1,5 +1,5 @@
import { Args } from "@bp/service/args/args.types";
-import { AuthTokenId, Configs } from "@bp/service/configs/configs.types";
+import { Configs } from "@bp/service/configs/configs.types";
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
@@ -798,97 +798,4 @@ describe("gitlab merge request config parser", () => {
comments: ["First comment", "Second comment"],
});
});
-
- test("override token using auth arg", async () => {
- process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
- const args: Args = {
- dryRun: true,
- auth: "whatever",
- pullRequest: mergedPRUrl,
- targetBranch: "prod",
- folder: "/tmp/test",
- gitUser: "Gitlab",
- gitEmail: "noreply@gitlab.com",
- reviewers: [],
- assignees: [],
- inheritReviewers: true,
- };
-
- const configs: Configs = await configParser.parseAndValidate(args);
-
- expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
- expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
- expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
- expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
-
- expect(configs.dryRun).toEqual(true);
- expect(configs.auth).toEqual("whatever");
- expect(configs.folder).toEqual("/tmp/test");
- expect(configs.git).toEqual({
- user: "Gitlab",
- email: "noreply@gitlab.com"
- });
- });
-
- test("auth using GITLAB_TOKEN has precedence over GIT_TOKEN env variable", async () => {
- process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
- process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
- const args: Args = {
- dryRun: true,
- pullRequest: mergedPRUrl,
- targetBranch: "prod",
- folder: "/tmp/test",
- gitUser: "Gitlab",
- gitEmail: "noreply@gitlab.com",
- reviewers: [],
- assignees: [],
- inheritReviewers: true,
- };
-
- const configs: Configs = await configParser.parseAndValidate(args);
-
- expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
- expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
- expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
- expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
-
- expect(configs.dryRun).toEqual(true);
- expect(configs.auth).toEqual("mygitlabtoken");
- expect(configs.folder).toEqual("/tmp/test");
- expect(configs.git).toEqual({
- user: "Gitlab",
- email: "noreply@gitlab.com"
- });
- });
-
- test("ignore env variables related to other git platforms", async () => {
- process.env[AuthTokenId.CODEBERG_TOKEN] = "mycodebergtoken";
- process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
- const args: Args = {
- dryRun: true,
- pullRequest: mergedPRUrl,
- targetBranch: "prod",
- folder: "/tmp/test",
- gitUser: "Gitlab",
- gitEmail: "noreply@gitlab.com",
- reviewers: [],
- assignees: [],
- inheritReviewers: true,
- };
-
- const configs: Configs = await configParser.parseAndValidate(args);
-
- expect(GitLabClient.prototype.getPullRequest).toBeCalledTimes(1);
- expect(GitLabClient.prototype.getPullRequest).toBeCalledWith("superuser", "backporting-example", 1, true);
- expect(GitLabMapper.prototype.mapPullRequest).toBeCalledTimes(1);
- expect(GitLabMapper.prototype.mapPullRequest).toBeCalledWith(expect.anything(), []);
-
- expect(configs.dryRun).toEqual(true);
- expect(configs.auth).toEqual(undefined);
- expect(configs.folder).toEqual("/tmp/test");
- expect(configs.git).toEqual({
- user: "Gitlab",
- email: "noreply@gitlab.com"
- });
- });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-github-runner.test.ts b/test/service/runner/cli-github-runner.test.ts
index bbd31da..7d747b4 100644
--- a/test/service/runner/cli-github-runner.test.ts
+++ b/test/service/runner/cli-github-runner.test.ts
@@ -3,10 +3,11 @@ import Runner from "@bp/service/runner/runner";
import GitCLIService from "@bp/service/git/git-cli";
import GitHubClient from "@bp/service/git/github/github-client";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
-import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../support/utils";
+import { addProcessArgs, createTestFile, removeTestFile, resetEnvTokens, resetProcessArgs } from "../../support/utils";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { BackportPullRequest, GitClientType } from "@bp/service/git/git.types";
+import { AuthTokenId } from "@bp/service/configs/configs.types";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT_PATHNAME = "./cli-github-runner-pr-merged-with-overrides.json";
const GITHUB_MERGED_PR_W_OVERRIDES_CONFIG_FILE_CONTENT = {
@@ -48,6 +49,9 @@ beforeEach(() => {
// reset process.env variables
resetProcessArgs();
+ // reset git env tokens
+ resetEnvTokens();
+
// mock octokit
mockGitHubClient();
@@ -1104,4 +1108,59 @@ describe("cli runner", () => {
});
expect(GitHubClient.prototype.createPullRequest).toThrowError();
});
+
+ test("auth using GITHUB_TOKEN takes precedence over GIT_TOKEN env variable", async () => {
+ process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
+ process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/8632"
+ ]);
+
+ await runner.execute();
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, "mygithubtoken", "https://api.github.com");
+
+ // Not interested in all subsequent calls, already tested in other test cases
+ });
+
+ test("auth arg takes precedence over GITHUB_TOKEN", async () => {
+ process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/8632",
+ "-a",
+ "mytoken"
+ ]);
+
+ await runner.execute();
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, "mytoken", "https://api.github.com");
+
+ // Not interested in all subsequent calls, already tested in other test cases
+ });
+
+ test("ignore env variables related to other git platforms", async () => {
+ process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
+ process.env[AuthTokenId.CODEBERG_TOKEN] = "mycodebergtoken";
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://github.com/owner/reponame/pull/8632"
+ ]);
+
+ await runner.execute();
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITHUB, undefined, "https://api.github.com");
+
+ // Not interested in all subsequent calls, already tested in other test cases
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/cli-gitlab-runner.test.ts b/test/service/runner/cli-gitlab-runner.test.ts
index 92dc4d7..b5e985a 100644
--- a/test/service/runner/cli-gitlab-runner.test.ts
+++ b/test/service/runner/cli-gitlab-runner.test.ts
@@ -3,11 +3,12 @@ import Runner from "@bp/service/runner/runner";
import GitCLIService from "@bp/service/git/git-cli";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
-import { addProcessArgs, createTestFile, removeTestFile, resetProcessArgs } from "../../support/utils";
+import { addProcessArgs, createTestFile, removeTestFile, resetEnvTokens, resetProcessArgs } from "../../support/utils";
import { getAxiosMocked } from "../../support/mock/git-client-mock-support";
import { MERGED_SQUASHED_MR } from "../../support/mock/gitlab-data";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
+import { AuthTokenId } from "@bp/service/configs/configs.types";
const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT_PATHNAME = "./cli-gitlab-runner-pr-merged-with-overrides.json";
const GITLAB_MERGED_PR_COMPLEX_CONFIG_FILE_CONTENT = {
@@ -63,6 +64,9 @@ beforeEach(() => {
// reset process.env variables
resetProcessArgs();
+ // reset git env tokens
+ resetEnvTokens();
+
// create CLI arguments parser
parser = new CLIArgsParser();
@@ -595,4 +599,59 @@ describe("cli runner", () => {
}
);
});
+
+ test("auth using GITLAB_TOKEN takes precedence over GIT_TOKEN env variable", async () => {
+ process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
+ process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"
+ ]);
+
+ await runner.execute();
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, "mygitlabtoken", "https://my.gitlab.host.com/api/v4");
+
+ // Not interested in all subsequent calls, already tested in other test cases
+ });
+
+ test("auth arg takes precedence over GITLAB_TOKEN", async () => {
+ process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
+ "-a",
+ "mytoken"
+ ]);
+
+ await runner.execute();
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, "mytoken", "https://my.gitlab.host.com/api/v4");
+
+ // Not interested in all subsequent calls, already tested in other test cases
+ });
+
+ test("ignore env variables related to other git platforms", async () => {
+ process.env[AuthTokenId.GITHUB_TOKEN] = "mygithubtoken";
+ process.env[AuthTokenId.CODEBERG_TOKEN] = "mycodebergtoken";
+ addProcessArgs([
+ "-tb",
+ "target",
+ "-pr",
+ "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"
+ ]);
+
+ await runner.execute();
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
+
+ // Not interested in all subsequent calls, already tested in other test cases
+ });
});
\ No newline at end of file
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 3e9fd73..7976a9d 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -3,7 +3,7 @@ import Runner from "@bp/service/runner/runner";
import GitCLIService from "@bp/service/git/git-cli";
import GitHubClient from "@bp/service/git/github/github-client";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
-import { createTestFile, removeTestFile, spyGetInput } from "../../support/utils";
+import { createTestFile, removeTestFile, resetEnvTokens, spyGetInput } from "../../support/utils";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
@@ -46,6 +46,9 @@ afterAll(() => {
});
beforeEach(() => {
+ // reset git env tokens
+ resetEnvTokens();
+
mockGitHubClient();
// create GHA arguments parser
diff --git a/test/service/runner/gha-gitlab-runner.test.ts b/test/service/runner/gha-gitlab-runner.test.ts
index 748ca15..5212da8 100644
--- a/test/service/runner/gha-gitlab-runner.test.ts
+++ b/test/service/runner/gha-gitlab-runner.test.ts
@@ -3,7 +3,7 @@ import Runner from "@bp/service/runner/runner";
import GitCLIService from "@bp/service/git/git-cli";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
-import { createTestFile, removeTestFile, spyGetInput } from "../../support/utils";
+import { createTestFile, removeTestFile, resetEnvTokens, spyGetInput } from "../../support/utils";
import { getAxiosMocked } from "../../support/mock/git-client-mock-support";
import { MERGED_SQUASHED_MR } from "../../support/mock/gitlab-data";
import GitClientFactory from "@bp/service/git/git-client-factory";
@@ -59,6 +59,9 @@ afterAll(() => {
});
beforeEach(() => {
+ // reset git env tokens
+ resetEnvTokens();
+
// create GHA arguments parser
parser = new GHAArgsParser();
From bce5dd4f9969d47da9cbb6ed06abbf87216afc98 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 23 Feb 2024 15:29:56 +0100
Subject: [PATCH 37/75] chore: release v4.5.1 (#101)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 9 +++++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 151bcb9..aec168d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog
+## [4.5.1](https://github.com/kiegroup/git-backporting/compare/v4.5.0...v4.5.1) (2024-02-23)
+
+
+### Bug Fixes
+
+* --auth when --git-user contains space ([#95](https://github.com/kiegroup/git-backporting/issues/95)) ([9bcd6e6](https://github.com/kiegroup/git-backporting/commit/9bcd6e6b5547974c45ade756b623eb385bb76019))
+* --no-squash on single-commit GitLab MR ([#93](https://github.com/kiegroup/git-backporting/issues/93)) ([300fa91](https://github.com/kiegroup/git-backporting/commit/300fa91a8ae065b7f6f6370882b10929bbde6309))
+* **gh-96:** fix git token parsing ([#98](https://github.com/kiegroup/git-backporting/issues/98)) ([c57fca6](https://github.com/kiegroup/git-backporting/commit/c57fca6bd6b9c241c11ad1f728cc9bc0acfd7f88))
+
## [4.5.0](https://github.com/kiegroup/git-backporting/compare/v4.4.1...v4.5.0) (2023-12-10)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index df9bcc2..7fa7d77 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23687,7 +23687,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.5.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.5.1","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 5988a6e..962d63b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.5.0",
+ "version": "4.5.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.5.0",
+ "version": "4.5.1",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index 4668492..75dc8ea 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.5.0",
+ "version": "4.5.1",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From c8ede8d4e2428cb3f4dc2d727f24b37e5781cbb1 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Thu, 7 Mar 2024 09:35:08 +0100
Subject: [PATCH 38/75] build: upgrade to node20 for gha (#102)
---
.github/workflows/ci.yml | 4 ++--
.github/workflows/pull-request.yml | 2 +-
action.yml | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 046dd4a..c8afc45 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,9 +13,9 @@ jobs:
name: ${{ matrix.os }} - node ${{ matrix.node-version }}
strategy:
matrix:
- node-version: [16, 18]
+ node-version: [16, 18, 20]
os: [ubuntu-latest]
- fail-fast: true
+ fail-fast: false
runs-on: ${{ matrix.os }}
steps:
diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index a72fe6c..ea2d6e0 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -18,7 +18,7 @@ jobs:
name: ${{ matrix.os }} - node ${{ matrix.node-version }}
strategy:
matrix:
- node-version: [16, 18]
+ node-version: [16, 18, 20]
os: [ubuntu-latest]
fail-fast: false
runs-on: ${{ matrix.os }}
diff --git a/action.yml b/action.yml
index aad7087..04c4626 100644
--- a/action.yml
+++ b/action.yml
@@ -72,7 +72,7 @@ inputs:
required: false
runs:
- using: node16
+ using: node20
main: dist/gha/index.js
branding:
From f4a2683189e62ce0acf2f3285b3b27debf2eacc9 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 8 Mar 2024 12:51:25 +0100
Subject: [PATCH 39/75] chore: release v4.5.2 (#103)
* chore: release v4.5.2
* Update CHANGELOG.md
---------
Co-authored-by: Create or Update Pull Request Action
Co-authored-by: Andrea Lamparelli
---
CHANGELOG.md | 6 ++++++
dist/cli/index.js | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
4 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aec168d..6f9d856 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
# Changelog
+## [4.5.2](https://github.com/kiegroup/git-backporting/compare/v4.5.1...v4.5.2) (2024-03-08)
+
+### Improvements
+
+* upgrade to node20 for gha ([c8ede8d](https://github.com/kiegroup/git-backporting/commit/c8ede8d4e2428cb3f4dc2d727f24b37e5781cbb1))
+
## [4.5.1](https://github.com/kiegroup/git-backporting/compare/v4.5.0...v4.5.1) (2024-02-23)
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 7fa7d77..9d3a9d1 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -23687,7 +23687,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.5.1","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.5.2","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/package-lock.json b/package-lock.json
index 962d63b..408e946 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.5.1",
+ "version": "4.5.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.5.1",
+ "version": "4.5.2",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index 75dc8ea..dd0ed6d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.5.1",
+ "version": "4.5.2",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From a36b740991acf1428a72f1dc587230528275d65a Mon Sep 17 00:00:00 2001
From: Earl Warren <109468362+earl-warren@users.noreply.github.com>
Date: Fri, 22 Mar 2024 16:04:20 +0100
Subject: [PATCH 40/75] docs: fix typos (#105)
Signed-off-by: Earl Warren
---
README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 57734a5..800b67f 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ This tool is released on the [public npm registry](https://www.npmjs.com/), ther
$ npm install -g @kie/git-backporting
```
-Then you just have to choose the pull request (or merge request on *Gitlab*) that you would like to backport and the target branch and the simply run the following command:
+Then you just have to choose the pull request (or merge request on *Gitlab*) that you would like to backport and the target branch and then simply run the following command:
```bash
$ git-backporting -tb -pr -a
@@ -67,7 +67,7 @@ This is the easiest invocation where you let the tool set / compute most of the
### How it works?
-The simply works in this way: given the provided `pull/merge request` it infers the git client to use (either *Github* or *Gitlab* for now) and it retrieve the corresponding pull request object (original pull/merge request to be backported into another branch).
+It works in this way: given the provided `pull/merge request` it infers the server API to use (either *Github* or *Gitlab* for now) and retrieves the corresponding pull request object (original pull/merge request to be backported into another branch).
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).
@@ -141,7 +141,7 @@ This is an example of a configuration file that can be used.
"auth": "*****"
}
```
-Keep in mind that its structue MUST match the [Args](src/service/args/args.types.ts) interface, which is actually a camel-case version of the CLI options.
+Keep in mind that its structure MUST match the [Args](src/service/args/args.types.ts) interface, which is actually a camel-case version of the CLI options.
### Supported git services
From 646d8fe41cc0967fbef52771a80b77805acf4ca2 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 22 Mar 2024 16:06:11 +0100
Subject: [PATCH 41/75] build(deps): bump follow-redirects from 1.15.4 to
1.15.6 (#104)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)
---
updated-dependencies:
- dependency-name: follow-redirects
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 408e946..af22e7c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5642,9 +5642,9 @@
"dev": true
},
"node_modules/follow-redirects": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
- "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
"funding": [
{
"type": "individual",
@@ -15957,9 +15957,9 @@
"dev": true
},
"follow-redirects": {
- "version": "1.15.4",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
- "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
},
"for-each": {
"version": "0.3.3",
From 80a0b554f0c1920a178e28bd678f709581a1b224 Mon Sep 17 00:00:00 2001
From: Earl Warren <109468362+earl-warren@users.noreply.github.com>
Date: Sat, 23 Mar 2024 17:13:14 +0100
Subject: [PATCH 42/75] feat: add --git-client to explicitly set the type of
forge (#106)
codeberg is running Forgejo and it may not be possible to infer that
from the URL alone. The same is true for GitHub Enterprise Server.
---
README.md | 1 +
action.yml | 3 +++
dist/cli/index.js | 11 ++++++++++-
dist/gha/index.js | 10 +++++++++-
src/service/args/args-parser.ts | 1 +
src/service/args/args.types.ts | 1 +
src/service/args/cli/cli-args-parser.ts | 2 ++
src/service/args/gha/gha-args-parser.ts | 1 +
src/service/runner/runner.ts | 7 ++++++-
test/service/args/cli/cli-args-parser.test.ts | 17 +++++++++++++++++
test/service/runner/gha-github-runner.test.ts | 19 +++++++++++++++++++
11 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 800b67f..b820807 100644
--- a/README.md
+++ b/README.md
@@ -99,6 +99,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Configuration File | -cf, --config-file | N | Configuration file, in JSON format, containing all options to be overridded, note that if provided all other CLI options will be ignored | |
| Auth | -a, --auth | N | Git access/authorization token, if provided all token env variables will be ignored. See [auth token](#authorization-token) section for more details | "" |
| Folder | -f, --folder | N | Local folder full name of the repository that will be checked out, e.g., /tmp/folder | {cwd}/bp |
+| Git Client | --git-client | N | Git client type , if not set it is infered from pull-request
| Git User | -gu, --git-user | N | Local git user name | "GitHub" |
| Git Email | -ge, --git-email | N | Local git user email | "noreply@github.com" |
| Title | --title | N | Backporting pull request title | "{original-pr-title}" |
diff --git a/action.yml b/action.yml
index 04c4626..d7b5281 100644
--- a/action.yml
+++ b/action.yml
@@ -18,6 +18,9 @@ inputs:
description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT), if not provided will look for existing env variables like GITHUB_TOKEN"
default: ${{ github.token }}
required: false
+ git-client:
+ description: "Git client type , if not set it is infered from pull-request"
+ required: false
git-user:
description: "Local git user name"
default: "GitHub"
diff --git a/dist/cli/index.js b/dist/cli/index.js
index 9d3a9d1..a3f1819 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -49,6 +49,7 @@ class ArgsParser {
dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder),
+ gitClient: this.getOrDefault(args.gitClient),
gitUser: this.getOrDefault(args.gitUser),
gitEmail: this.getOrDefault(args.gitEmail),
title: this.getOrDefault(args.title),
@@ -183,6 +184,7 @@ class CLIArgsParser extends args_parser_1.default {
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth ", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
+ .option("--git-client ", "git client type, if not set it is infered from --pull-request")
.option("-gu, --git-user ", "local git user name, default is 'GitHub'")
.option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'")
.option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder")
@@ -217,6 +219,7 @@ class CLIArgsParser extends args_parser_1.default {
pullRequest: opts.pullRequest,
targetBranch: opts.targetBranch,
folder: opts.folder,
+ gitClient: opts.gitClient,
gitUser: opts.gitUser,
gitEmail: opts.gitEmail,
title: opts.title,
@@ -1343,7 +1346,13 @@ class Runner {
this.logger.warn("Dry run enabled");
}
// 2. init git service
- const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
+ let gitClientType;
+ if (args.gitClient === undefined) {
+ gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
+ }
+ else {
+ gitClientType = args.gitClient;
+ }
// the api version is ignored in case of github
const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
const token = this.fetchToken(args, gitClientType);
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 529a401..21cc4e7 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -49,6 +49,7 @@ class ArgsParser {
dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder),
+ gitClient: this.getOrDefault(args.gitClient),
gitUser: this.getOrDefault(args.gitUser),
gitEmail: this.getOrDefault(args.gitEmail),
title: this.getOrDefault(args.title),
@@ -187,6 +188,7 @@ class GHAArgsParser extends args_parser_1.default {
pullRequest: (0, core_1.getInput)("pull-request"),
targetBranch: (0, core_1.getInput)("target-branch"),
folder: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("folder")),
+ gitClient: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-client")),
gitUser: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-user")),
gitEmail: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-email")),
title: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("title")),
@@ -1313,7 +1315,13 @@ class Runner {
this.logger.warn("Dry run enabled");
}
// 2. init git service
- const gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
+ let gitClientType;
+ if (args.gitClient === undefined) {
+ gitClientType = (0, git_util_1.inferGitClient)(args.pullRequest);
+ }
+ else {
+ gitClientType = args.gitClient;
+ }
// the api version is ignored in case of github
const apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
const token = this.fetchToken(args, gitClientType);
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index 1c8cb51..bc71810 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -27,6 +27,7 @@ export default abstract class ArgsParser {
dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder),
+ gitClient: this.getOrDefault(args.gitClient),
gitUser: this.getOrDefault(args.gitUser),
gitEmail: this.getOrDefault(args.gitEmail),
title: this.getOrDefault(args.title),
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index 1a38562..2e34064 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -8,6 +8,7 @@ export interface Args {
dryRun?: boolean, // if enabled do not push anything remotely
auth?: string, // git service auth, like github token
folder?: string, // local folder where the repositories should be cloned
+ gitClient?: string, // git client
gitUser?: string, // local git user, default 'GitHub'
gitEmail?: string, // local git email, default 'noreply@github.com'
title?: string, // backport pr title, default original pr title prefixed by target branch
diff --git a/src/service/args/cli/cli-args-parser.ts b/src/service/args/cli/cli-args-parser.ts
index c8ebc92..f96cb55 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -14,6 +14,7 @@ export default class CLIArgsParser extends ArgsParser {
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth ", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
+ .option("--git-client ", "git client type, if not set it is infered from --pull-request")
.option("-gu, --git-user ", "local git user name, default is 'GitHub'")
.option("-ge, --git-email ", "local git user email, default is 'noreply@github.com'")
.option("-f, --folder ", "local folder where the repo will be checked out, e.g., /tmp/folder")
@@ -49,6 +50,7 @@ export default class CLIArgsParser extends ArgsParser {
pullRequest: opts.pullRequest,
targetBranch: opts.targetBranch,
folder: opts.folder,
+ gitClient: opts.gitClient,
gitUser: opts.gitUser,
gitEmail: opts.gitEmail,
title: opts.title,
diff --git a/src/service/args/gha/gha-args-parser.ts b/src/service/args/gha/gha-args-parser.ts
index 29580ab..9d0b04e 100644
--- a/src/service/args/gha/gha-args-parser.ts
+++ b/src/service/args/gha/gha-args-parser.ts
@@ -18,6 +18,7 @@ export default class GHAArgsParser extends ArgsParser {
pullRequest: getInput("pull-request"),
targetBranch: getInput("target-branch"),
folder: getOrUndefined(getInput("folder")),
+ gitClient: getOrUndefined(getInput("git-client")),
gitUser: getOrUndefined(getInput("git-user")),
gitEmail: getOrUndefined(getInput("git-email")),
title: getOrUndefined(getInput("title")),
diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts
index 1e48193..e7db1b9 100644
--- a/src/service/runner/runner.ts
+++ b/src/service/runner/runner.ts
@@ -60,7 +60,12 @@ export default class Runner {
}
// 2. init git service
- const gitClientType: GitClientType = inferGitClient(args.pullRequest);
+ let gitClientType: GitClientType;
+ if (args.gitClient === undefined) {
+ gitClientType = inferGitClient(args.pullRequest);
+ } else {
+ gitClientType = args.gitClient as GitClientType;
+ }
// the api version is ignored in case of github
const apiUrl = inferGitApiUrl(args.pullRequest, gitClientType === GitClientType.CODEBERG ? "v1" : undefined);
const token = this.fetchToken(args, gitClientType);
diff --git a/test/service/args/cli/cli-args-parser.test.ts b/test/service/args/cli/cli-args-parser.test.ts
index bf82586..c8b462d 100644
--- a/test/service/args/cli/cli-args-parser.test.ts
+++ b/test/service/args/cli/cli-args-parser.test.ts
@@ -15,6 +15,7 @@ const RANDOM_CONFIG_FILE_CONTENT = {
"targetBranch": "target-branch-name",
"pullRequest": "https://github.com/user/repo/pull/123",
"folder": "/path/to/local/folder",
+ "gitClient": "codeberg",
"gitUser": "YourGitUser",
"gitEmail": "your-email@example.com",
"title": "Backport: Original PR Title",
@@ -62,6 +63,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -90,6 +92,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -120,6 +123,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -148,6 +152,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -185,6 +190,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("bearer-token");
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual("Me");
expect(args.gitEmail).toEqual("me@email.com");
expect(args.folder).toEqual(undefined);
@@ -213,6 +219,8 @@ describe("cli args parser", () => {
"target",
"--pull-request",
"https://localhost/whatever/pulls/1",
+ "--git-client",
+ "codeberg",
"--git-user",
"Me",
"--git-email",
@@ -238,6 +246,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("bearer-token");
+ expect(args.gitClient).toEqual("codeberg");
expect(args.gitUser).toEqual("Me");
expect(args.gitEmail).toEqual("me@email.com");
expect(args.folder).toEqual(undefined);
@@ -266,6 +275,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("your-git-service-auth-token");
+ expect(args.gitClient).toEqual("codeberg");
expect(args.gitUser).toEqual("YourGitUser");
expect(args.gitEmail).toEqual("your-email@example.com");
expect(args.folder).toEqual("/path/to/local/folder");
@@ -296,6 +306,8 @@ describe("cli args parser", () => {
"target",
"--pull-request",
"https://localhost/whatever/pulls/1",
+ "--git-client",
+ "github",
"--git-user",
"Me",
"--git-email",
@@ -321,6 +333,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("your-git-service-auth-token");
+ expect(args.gitClient).toEqual("codeberg");
expect(args.gitUser).toEqual("YourGitUser");
expect(args.gitEmail).toEqual("your-email@example.com");
expect(args.folder).toEqual("/path/to/local/folder");
@@ -352,6 +365,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -384,6 +398,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -416,6 +431,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
@@ -445,6 +461,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse();
expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined);
+ expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined);
diff --git a/test/service/runner/gha-github-runner.test.ts b/test/service/runner/gha-github-runner.test.ts
index 7976a9d..dfdf902 100644
--- a/test/service/runner/gha-github-runner.test.ts
+++ b/test/service/runner/gha-github-runner.test.ts
@@ -768,4 +768,23 @@ describe("gha runner", () => {
});
expect(GitHubClient.prototype.createPullRequest).toReturnTimes(3);
});
+
+ test("explicitly set git client", async () => {
+ spyGetInput({
+ "target-branch": "target",
+ "pull-request": "https://api.github.com/repos/owner/reponame/pulls/2368",
+ "git-client": "codeberg",
+ });
+
+ await runner.execute();
+
+ const cwd = process.cwd() + "/bp";
+
+ expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
+ expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.CODEBERG, undefined, "https://api.github.com");
+
+ expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
+ expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target");
+ });
+
});
\ No newline at end of file
From ffe625d8b35d0d8e3eb42bbd51aab7ca889c587e Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 25 Mar 2024 09:30:30 +0100
Subject: [PATCH 43/75] chore: release v4.6.0 (#107)
Co-authored-by: Create or Update Pull Request Action
---
CHANGELOG.md | 7 +++++++
dist/cli/index.js | 5 +++--
dist/gha/index.js | 3 ++-
package-lock.json | 4 ++--
package.json | 2 +-
5 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6f9d856..7e12293 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [4.6.0](https://github.com/kiegroup/git-backporting/compare/v4.5.2...v4.6.0) (2024-03-25)
+
+
+### Features
+
+* add --git-client to explicitly set the type of forge ([#106](https://github.com/kiegroup/git-backporting/issues/106)) ([80a0b55](https://github.com/kiegroup/git-backporting/commit/80a0b554f0c1920a178e28bd678f709581a1b224))
+
## [4.5.2](https://github.com/kiegroup/git-backporting/compare/v4.5.1...v4.5.2) (2024-03-08)
### Improvements
diff --git a/dist/cli/index.js b/dist/cli/index.js
index a3f1819..bd91c1f 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -5891,6 +5891,7 @@ var preservedUrlFields = [
"protocol",
"query",
"search",
+ "hash",
];
// Create handlers that pass events from native requests
@@ -6324,7 +6325,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
redirectUrl.protocol !== "https:" ||
redirectUrl.host !== currentHost &&
!isSubdomain(redirectUrl.host, currentHost)) {
- removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
+ removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
@@ -23696,7 +23697,7 @@ module.exports = axios;
/***/ ((module) => {
"use strict";
-module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.5.2","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
+module.exports = JSON.parse('{"name":"@kie/git-backporting","version":"4.6.0","description":"Git backporting is a tool to execute automatic pull request git backporting.","author":"","license":"MIT","private":false,"main":"./dist/gha/index.js","bin":{"git-backporting":"./dist/cli/index.js"},"files":["dist/cli/index.js"],"publishConfig":{"access":"public"},"scripts":{"prepare":"husky install","clean":"rm -rf ./build ./dist","compile":"tsc -p tsconfig.json && tsc-alias -p tsconfig.json","package":"npm run package:cli && npm run package:gha","package:cli":"ncc build ./build/src/bin/cli.js -o dist/cli","package:gha":"ncc build ./build/src/bin/gha.js -o dist/gha","build":"npm run clean && npm run compile && npm run package","test":"jest --silent","test:report":"npm test -- --coverage --testResultsProcessor=jest-sonar-reporter","lint":"eslint . --ext .ts","lint:fix":"npm run lint -- --fix","ts-node":"ts-node","postversion":"npm run build && git add dist && rm -rf build","release":"release-it","release:branch":"git checkout -b release/$(release-it --release-version) main","release:prepare":"release-it --no-npm.publish --no-github.release --no-git.push --no-git.tag --no-git.requireUpstream","release:prepare:all":"npm run release:branch && npm run release:prepare"},"repository":{"type":"git","url":"git+https://github.com/kiegroup/git-backporting.git"},"keywords":["backporting","pull-requests","merge-requests","github-action","cherry-pick"],"bugs":{"url":"https://github.com/kiegroup/git-backporting/issues"},"homepage":"https://github.com/kiegroup/git-backporting#readme","devDependencies":{"@commitlint/cli":"^17.4.0","@commitlint/config-conventional":"^17.4.0","@gitbeaker/rest":"^39.1.0","@kie/mock-github":"^1.1.0","@octokit/webhooks-types":"^6.8.0","@release-it/conventional-changelog":"^7.0.0","@types/fs-extra":"^9.0.13","@types/jest":"^29.2.4","@types/node":"^18.11.17","@typescript-eslint/eslint-plugin":"^5.47.0","@typescript-eslint/parser":"^5.47.0","@vercel/ncc":"^0.36.0","eslint":"^8.30.0","husky":"^8.0.2","jest":"^29.0.0","jest-sonar-reporter":"^2.0.0","release-it":"^16.1.3","semver":"^7.3.8","ts-jest":"^29.0.0","ts-node":"^10.8.1","tsc-alias":"^1.8.2","tsconfig-paths":"^4.1.0","typescript":"^4.9.3"},"dependencies":{"@actions/core":"^1.10.0","@octokit/rest":"^18.12.0","axios":"^1.4.0","commander":"^9.3.0","fs-extra":"^11.1.0","https":"^1.0.0","simple-git":"^3.15.1"}}');
/***/ }),
diff --git a/dist/gha/index.js b/dist/gha/index.js
index 21cc4e7..b50c45c 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -7621,6 +7621,7 @@ var preservedUrlFields = [
"protocol",
"query",
"search",
+ "hash",
];
// Create handlers that pass events from native requests
@@ -8054,7 +8055,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
redirectUrl.protocol !== "https:" ||
redirectUrl.host !== currentHost &&
!isSubdomain(redirectUrl.host, currentHost)) {
- removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
+ removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
diff --git a/package-lock.json b/package-lock.json
index af22e7c..5f5a00b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@kie/git-backporting",
- "version": "4.5.2",
+ "version": "4.6.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@kie/git-backporting",
- "version": "4.5.2",
+ "version": "4.6.0",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
diff --git a/package.json b/package.json
index dd0ed6d..0400a4a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
- "version": "4.5.2",
+ "version": "4.6.0",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
From b30ba6021a4385fe7b802c2e3925d72efba21337 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 28 Mar 2024 19:51:30 +0100
Subject: [PATCH 44/75] build(deps-dev): bump express from 4.18.2 to 4.19.2
(#108)
Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2)
---
updated-dependencies:
- dependency-name: express
dependency-type: indirect
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
package-lock.json | 76 +++++++++++++++++++++++------------------------
1 file changed, 38 insertions(+), 38 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 5f5a00b..0960be2 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2915,13 +2915,13 @@
}
},
"node_modules/body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
+ "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"dev": true,
"dependencies": {
"bytes": "3.1.2",
- "content-type": "~1.0.4",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@@ -2929,7 +2929,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
- "raw-body": "2.5.1",
+ "raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@@ -3632,9 +3632,9 @@
}
},
"node_modules/content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"dev": true,
"engines": {
"node": ">= 0.6"
@@ -4321,9 +4321,9 @@
"dev": true
},
"node_modules/cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"dev": true,
"engines": {
"node": ">= 0.6"
@@ -5364,17 +5364,17 @@
}
},
"node_modules/express": {
- "version": "4.18.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
- "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+ "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dev": true,
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.1",
+ "body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.5.0",
+ "cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -9501,9 +9501,9 @@
}
},
"node_modules/raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dev": true,
"dependencies": {
"bytes": "3.1.2",
@@ -14018,13 +14018,13 @@
}
},
"body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
+ "version": "1.20.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz",
+ "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==",
"dev": true,
"requires": {
"bytes": "3.1.2",
- "content-type": "~1.0.4",
+ "content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
@@ -14032,7 +14032,7 @@
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.11.0",
- "raw-body": "2.5.1",
+ "raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
@@ -14517,9 +14517,9 @@
}
},
"content-type": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"dev": true
},
"conventional-changelog": {
@@ -14985,9 +14985,9 @@
"dev": true
},
"cookie": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz",
- "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
"dev": true
},
"cookie-signature": {
@@ -15726,17 +15726,17 @@
}
},
"express": {
- "version": "4.18.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz",
- "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz",
+ "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==",
"dev": true,
"requires": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
- "body-parser": "1.20.1",
+ "body-parser": "1.20.2",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
- "cookie": "0.5.0",
+ "cookie": "0.6.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
@@ -18708,9 +18708,9 @@
"dev": true
},
"raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"dev": true,
"requires": {
"bytes": "3.1.2",
From ee7a87f26f0ce6863c078a2cefed1f78c68f8d57 Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Fri, 29 Mar 2024 09:39:39 +0100
Subject: [PATCH 45/75] docs: remove migrating section (#109)
---
README.md | 20 +-------------------
1 file changed, 1 insertion(+), 19 deletions(-)
diff --git a/README.md b/README.md
index b820807..44e220e 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,6 @@ Table of content
* **[CLI tool](#cli-tool)**
* **[GitHub action](#github-action)**
* **[Future works](#future-works)**
-* **[Migrating to v4](#migrating-to-v4)**
* **[Development](#development)**
* **[Contributing](#contributing)**
* **[License](#license)**
@@ -39,7 +38,7 @@ Therefore this tools is for anybody who is working on projects where they have t
## CLI tool
-> All instructions provided below pertain to version `v4` of the tool. If you wish to use an earlier version, we strongly encourage you to consider migrating to version `v4` as there are no valid reason to keep using older versions. Please refer to [Migrating to v4](#migrating-to-v4) section for comprehensive details on how to properly migrate to version `v4`.
+> All instructions provided below pertain to version `v4` of the tool. If you wish to use an earlier version, please refer to the documentation from the corresponding tag/release.
This tool is released on the [public npm registry](https://www.npmjs.com/), therefore it can be easily installed using `npm`:
@@ -244,23 +243,6 @@ For a complete description of all inputs see [Inputs section](#inputs).
- Integrate it into other CI/CD services like gitlab CI.
- Provide some reusable *GitHub* workflows.
-## Migrating to v4
-
-From version `v4` the project has been moved under [@kiegroup](https://github.com/kiegroup) organization. During this migration we changed some things that you should be aware of. I'll try to summarize them in the following table:
-
-> **NOTE**: these changes did not affect the tool features.
-
-| | **v4 (after migration)** | v3 or older (before migration) |
-|-------------|--------------------------|--------------------------------|
-| Owner | kiegroup | lampajr |
-| Repository | git-backporting | backporting |
-| NPM package | @kie/git-backporting | @lampajr/bper |
-| CLI tool | git-backporting | bper |
-
-So everytime you would use older version keep in mind that these changes are madnatory to make the tool working.
-
-> **NOTE**: Versions `v3.1.1` and `v4.0.0` offer identical features; the only distinction lies in the project's renaming and organization movement.
-
## Development
### Package release
From b2e2e271b9f2ae6ff9d9aa98ea14ce6da5411625 Mon Sep 17 00:00:00 2001
From: Earl Warren <109468362+earl-warren@users.noreply.github.com>
Date: Sat, 30 Mar 2024 11:04:32 +0100
Subject: [PATCH 46/75] docs: explain the strategy equivalent to the
cherry-pick defaults (#110)
---
README.md | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index 44e220e..e999d8a 100644
--- a/README.md
+++ b/README.md
@@ -74,14 +74,24 @@ By default the tool will try to cherry-pick the single squashed/merged commit in
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.
-#### Default cherry-pick strategy
+#### cherry-pick strategy
The default cherry-pick strategy is `recursive` with `theirs` option for automatic conflicts resolution. Therefore, by default, all commits are cherry-picked using the following git-equivalent command:
```bash
$ git cherry-pick -m 1 --strategy=recursive --strategy-option=theirs
```
-From version `v4.2.0` we made both `strategy` and `strategy-option` fully configurable from CLI or GitHub action, so if users need a specific strategy which differs from the default one please consider using either `--strategy` or `--strategy-option`, or their equivalent GitHub action inputs, more details in [inputs](#inputs) section.
+From version `v4.2.0` both can be configured via the `strategy` or `strategy-option` inputs if using the action and the `--strategy` or `--strategy-option` arguments if using the CLI.
+
+The [default strategy](https://git-scm.com/docs/git-merge#Documentation/git-merge.txt--sltstrategygt) of the `git-cherry-pick` command is different from the defaults of `git-backporting`.
+```bash
+$ git cherry-pick -m 1
+```
+is the same as:
+```bash
+$ git cherry-pick -m 1 --strategy=ort --strategy-option=find-renames
+```
+If there is a conflict the backport will fail and require manual intervention.
> **NOTE**: If there are any conflicts, the tool will block the process and exit signalling the failure as there are still no ways to interactively resolve them. In these cases a manual cherry-pick is needed, or alternatively users could manually resume the process in the cloned repository (here the user will have to resolve the conflicts, push the branch and create the pull request - all manually).
@@ -304,4 +314,4 @@ Every change must be submitted through a *GitHub* pull request (PR). Backporting
## License
-Git backporting open source project is licensed under the [MIT](./LICENSE) license.
\ No newline at end of file
+Git backporting open source project is licensed under the [MIT](./LICENSE) license.
From 53cc505f17630fb30daa70f75895323325cc0c7d Mon Sep 17 00:00:00 2001
From: Andrea Lamparelli
Date: Sat, 30 Mar 2024 19:19:17 +0100
Subject: [PATCH 47/75] feat(gh75): extract target branched from pr labels
(#112)
---
README.md | 3 +-
action.yml | 72 +++++++---
dist/cli/index.js | 48 ++++++-
dist/gha/index.js | 49 ++++++-
src/service/args/args-parser.ts | 8 +-
src/service/args/args.types.ts | 3 +-
src/service/args/cli/cli-args-parser.ts | 2 +
src/service/args/gha/gha-args-parser.ts | 3 +-
.../configs/pullrequest/pr-configs-parser.ts | 39 +++++-
test/service/args/cli/cli-args-parser.test.ts | 8 +-
test/service/args/gha/gha-args-parser.test.ts | 6 +-
.../github-pr-configs-parser-multiple.test.ts | 73 +++++++++-
.../github-pr-configs-parser.test.ts | 125 ++++++++++++++++--
.../gitlab-pr-configs-parser.test.ts | 96 ++++++++++++--
test/service/runner/cli-github-runner.test.ts | 25 +++-
test/service/runner/cli-gitlab-runner.test.ts | 4 +-
test/service/runner/gha-github-runner.test.ts | 4 +-
test/service/runner/gha-gitlab-runner.test.ts | 4 +-
test/support/mock/github-data.ts | 32 ++++-
test/support/mock/gitlab-data.ts | 2 +-
20 files changed, 523 insertions(+), 83 deletions(-)
diff --git a/README.md b/README.md
index e999d8a..6bf646e 100644
--- a/README.md
+++ b/README.md
@@ -104,6 +104,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Version | -V, --version | - | Current version of the tool | |
| Help | -h, --help | - | Display the help message | |
| Target Branches | -tb, --target-branch | N | Comma separated list of branches where the changes must be backported to | |
+| Target Branches Pattern | -tbp, --target-branch-pattern | N | Regular expression pattern to extract target branch(es) from pr labels. The branches will be extracted from the pattern's required `target` named capturing group, e.g., `^backport (?([^ ]+))$` | |
| Pull Request | -pr, --pull-request | N | Original pull request url, the one that must be backported, e.g., https://github.com/kiegroup/git-backporting/pull/1 | |
| Configuration File | -cf, --config-file | N | Configuration file, in JSON format, containing all options to be overridded, note that if provided all other CLI options will be ignored | |
| Auth | -a, --auth | N | Git access/authorization token, if provided all token env variables will be ignored. See [auth token](#authorization-token) section for more details | "" |
@@ -126,7 +127,7 @@ This tool comes with some inputs that allow users to override the default behavi
| Additional comments | --comments | N | Semicolon separated list of additional comments to be posted to the backported pull request | [] |
| Dry Run | -d, --dry-run | N | If enabled the tool does not push nor create anything remotely, use this to skip PR creation | false |
-> **NOTE**: `pull request` and `target branch` are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
+> **NOTE**: `pull request` and (`target branch` or `target branch pattern`) are *mandatory*, they must be provided as CLI options or as part of the configuration file (if used).
#### Authorization token
diff --git a/action.yml b/action.yml
index d7b5281..33e04ee 100644
--- a/action.yml
+++ b/action.yml
@@ -1,77 +1,105 @@
name: "Backporting GitHub Action"
-description: "GitHub action providing an automated way to backport pull requests from one branch to another"
+description: GitHub action providing an automated way to backport pull requests from one branch to another
inputs:
pull-request:
- description: "URL of the pull request to backport, e.g., https://github.com/kiegroup/git-backporting/pull/1"
+ description: >
+ URL of the pull request to backport, e.g., "https://github.com/kiegroup/git-backporting/pull/1"
required: false
target-branch:
- description: "Comma separated list of branches where the pull request must be backported to"
+ description: >
+ Comma separated list of branches where the pull request must be backported to
+ required: false
+ target-branch-pattern:
+ description: >
+ Regular expression pattern to extract target branch(es) from pr labels.
+ The branches will be extracted from the pattern's required `target` named capturing group,
+ for instance "^backport (?([^ ]+))$"
required: false
config-file:
- description: "Path to a file containing the json configuration for this tool, the object must match the Args interface"
+ description: >
+ Path to a file containing the json configuration for this tool,
+ the object must match the Args interface
required: false
dry-run:
- description: "If enabled the tool does not create any pull request nor push anything remotely"
+ description: >
+ If enabled the tool does not create any pull request nor push anything remotely
required: false
default: "false"
auth:
- description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT), if not provided will look for existing env variables like GITHUB_TOKEN"
+ description: >
+ GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT),
+ if not provided will look for existing env variables like GITHUB_TOKEN
default: ${{ github.token }}
required: false
git-client:
- description: "Git client type , if not set it is infered from pull-request"
+ description: >
+ Git client type , if not set it is infered from pull-request
required: false
git-user:
- description: "Local git user name"
+ description: Local git user name
default: "GitHub"
required: false
git-email:
- description: "Local git user email"
+ description: Local git user email
default: "noreply@github.com"
required: false
title:
- description: "Backporting PR title. Default is the original PR title prefixed by the target branch"
+ description: >
+ Backporting PR title. Default is the original PR title prefixed by the target branch
required: false
body-prefix:
- description: "Backporting PR body prefix. Default is `Backport: `"
+ description: >
+ Backporting PR body prefix. Default is `Backport: `
required: false
body:
- description: "Backporting PR body. Default is the original PR body"
+ description: >
+ Backporting PR body. Default is the original PR body
required: false
bp-branch-name:
- description: "Comma separated list of backporting PR branch names. Default is auto-generated from commit and target branches"
+ description: >
+ Comma separated list of backporting PR branch names.
+ Default is auto-generated from commit and target branches
required: false
reviewers:
- description: "Comma separated list of reviewers for the backporting pull request"
+ description: >
+ Comma separated list of reviewers for the backporting pull request
required: false
assignees:
- description: "Comma separated list of reviewers for the backporting pull request"
+ description: >
+ Comma separated list of reviewers for the backporting pull request
required: false
no-inherit-reviewers:
- description: "Considered only if reviewers is empty, if true keep reviewers as empty list, otherwise inherit from original pull request"
+ description: >
+ Considered only if reviewers is empty, if true keep reviewers as empty list,
+ otherwise inherit from original pull request
required: false
default: "false"
labels:
- description: "Comma separated list of labels to be assigned to the backported pull request"
+ description: >
+ Comma separated list of labels to be assigned to the backported pull request
required: false
inherit-labels:
- description: "If true the backported pull request will inherit labels from the original one"
+ description: >
+ If true the backported pull request will inherit labels from the original one
required: false
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"
+ description: >
+ If set to true the tool will backport all commits as part of the pull request
+ instead of the suqashed one
required: false
default: "false"
strategy:
- description: "Cherry-pick merge strategy"
+ description: Cherry-pick merge strategy
required: false
default: "recursive"
strategy-option:
- description: "Cherry-pick merge strategy option"
+ description: Cherry-pick merge strategy option
required: false
default: "theirs"
comments:
- description: "Semicolon separated list of additional comments to be posted to the backported pull request"
+ description: >
+ Semicolon separated list of additional comments to be posted to the backported pull request
required: false
runs:
diff --git a/dist/cli/index.js b/dist/cli/index.js
index bd91c1f..447d098 100755
--- a/dist/cli/index.js
+++ b/dist/cli/index.js
@@ -39,13 +39,17 @@ class ArgsParser {
}
parse() {
const args = this.readArgs();
+ if (!args.pullRequest) {
+ throw new Error("Missing option: pull request must be provided");
+ }
// validate and fill with defaults
- if (!args.pullRequest || !args.targetBranch || args.targetBranch.trim().length == 0) {
- throw new Error("Missing option: pull request and target branches must be provided");
+ if ((!args.targetBranch || args.targetBranch.trim().length == 0) && !args.targetBranchPattern) {
+ throw new Error("Missing option: target branch(es) or target regular expression must be provided");
}
return {
pullRequest: args.pullRequest,
targetBranch: args.targetBranch,
+ targetBranchPattern: args.targetBranchPattern,
dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder),
@@ -181,6 +185,7 @@ class CLIArgsParser extends args_parser_1.default {
.version(package_json_1.version)
.description(package_json_1.description)
.option("-tb, --target-branch ", "comma separated list of branches where changes must be backported to")
+ .option("-tbp, --target-branch-pattern ", "regular expression pattern to extract target branch(es) from pr labels, the branches will be extracted from the pattern's required `target` named capturing group")
.option("-pr, --pull-request ", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1")
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth ", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
@@ -218,6 +223,7 @@ class CLIArgsParser extends args_parser_1.default {
auth: opts.auth,
pullRequest: opts.pullRequest,
targetBranch: opts.targetBranch,
+ targetBranchPattern: opts.targetBranchPattern,
folder: opts.folder,
gitClient: opts.gitClient,
gitUser: opts.gitUser,
@@ -331,7 +337,18 @@ class PullRequestConfigsParser extends configs_parser_1.default {
throw error;
}
const folder = args.folder ?? this.getDefaultFolder();
- const targetBranches = [...new Set((0, args_utils_1.getAsCommaSeparatedList)(args.targetBranch))];
+ let targetBranches = [];
+ if (args.targetBranchPattern) {
+ // parse labels to extract target branch(es)
+ targetBranches = this.getTargetBranchesFromLabels(args.targetBranchPattern, pr.labels);
+ if (targetBranches.length === 0) {
+ throw new Error(`Unable to extract target branches with regular expression "${args.targetBranchPattern}"`);
+ }
+ }
+ else {
+ // target branch must be provided if targetRegExp is missing
+ targetBranches = [...new Set((0, args_utils_1.getAsCommaSeparatedList)(args.targetBranch))];
+ }
const bpBranchNames = [...new Set(args.bpBranchName ? ((0, args_utils_1.getAsCleanedCommaSeparatedList)(args.bpBranchName) ?? []) : [])];
if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
@@ -353,6 +370,28 @@ class PullRequestConfigsParser extends configs_parser_1.default {
getDefaultFolder() {
return "bp";
}
+ /**
+ * Parse the provided labels and return a list of target branches
+ * obtained by applying the provided pattern as regular expression extractor
+ * @param pattern reg exp pattern to extract target branch from label name
+ * @param labels list of labels to check
+ * @returns list of target branches
+ */
+ getTargetBranchesFromLabels(pattern, labels) {
+ this.logger.debug(`Extracting branches from [${labels}] using ${pattern}`);
+ const regExp = new RegExp(pattern);
+ const branches = [];
+ for (const l of labels) {
+ const result = regExp.exec(l);
+ if (result?.groups) {
+ const { target } = result.groups;
+ if (target) {
+ branches.push(target);
+ }
+ }
+ }
+ return [...new Set(branches)];
+ }
/**
* Create a backport pull request starting from the target branch and
* the original pr to be backported
@@ -5891,7 +5930,6 @@ var preservedUrlFields = [
"protocol",
"query",
"search",
- "hash",
];
// Create handlers that pass events from native requests
@@ -6325,7 +6363,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
redirectUrl.protocol !== "https:" ||
redirectUrl.host !== currentHost &&
!isSubdomain(redirectUrl.host, currentHost)) {
- removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
+ removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
diff --git a/dist/gha/index.js b/dist/gha/index.js
index b50c45c..11e617b 100755
--- a/dist/gha/index.js
+++ b/dist/gha/index.js
@@ -39,13 +39,17 @@ class ArgsParser {
}
parse() {
const args = this.readArgs();
+ if (!args.pullRequest) {
+ throw new Error("Missing option: pull request must be provided");
+ }
// validate and fill with defaults
- if (!args.pullRequest || !args.targetBranch || args.targetBranch.trim().length == 0) {
- throw new Error("Missing option: pull request and target branches must be provided");
+ if ((!args.targetBranch || args.targetBranch.trim().length == 0) && !args.targetBranchPattern) {
+ throw new Error("Missing option: target branch(es) or target regular expression must be provided");
}
return {
pullRequest: args.pullRequest,
targetBranch: args.targetBranch,
+ targetBranchPattern: args.targetBranchPattern,
dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder),
@@ -186,7 +190,8 @@ class GHAArgsParser extends args_parser_1.default {
dryRun: (0, args_utils_1.getAsBooleanOrDefault)((0, core_1.getInput)("dry-run")),
auth: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("auth")),
pullRequest: (0, core_1.getInput)("pull-request"),
- targetBranch: (0, core_1.getInput)("target-branch"),
+ targetBranch: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("target-branch")),
+ targetBranchPattern: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("target-reg-exp")),
folder: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("folder")),
gitClient: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-client")),
gitUser: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-user")),
@@ -300,7 +305,18 @@ class PullRequestConfigsParser extends configs_parser_1.default {
throw error;
}
const folder = args.folder ?? this.getDefaultFolder();
- const targetBranches = [...new Set((0, args_utils_1.getAsCommaSeparatedList)(args.targetBranch))];
+ let targetBranches = [];
+ if (args.targetBranchPattern) {
+ // parse labels to extract target branch(es)
+ targetBranches = this.getTargetBranchesFromLabels(args.targetBranchPattern, pr.labels);
+ if (targetBranches.length === 0) {
+ throw new Error(`Unable to extract target branches with regular expression "${args.targetBranchPattern}"`);
+ }
+ }
+ else {
+ // target branch must be provided if targetRegExp is missing
+ targetBranches = [...new Set((0, args_utils_1.getAsCommaSeparatedList)(args.targetBranch))];
+ }
const bpBranchNames = [...new Set(args.bpBranchName ? ((0, args_utils_1.getAsCleanedCommaSeparatedList)(args.bpBranchName) ?? []) : [])];
if (bpBranchNames.length > 1 && bpBranchNames.length != targetBranches.length) {
throw new Error(`The number of backport branch names, if provided, must match the number of target branches or just one, provided ${bpBranchNames.length} branch names instead`);
@@ -322,6 +338,28 @@ class PullRequestConfigsParser extends configs_parser_1.default {
getDefaultFolder() {
return "bp";
}
+ /**
+ * Parse the provided labels and return a list of target branches
+ * obtained by applying the provided pattern as regular expression extractor
+ * @param pattern reg exp pattern to extract target branch from label name
+ * @param labels list of labels to check
+ * @returns list of target branches
+ */
+ getTargetBranchesFromLabels(pattern, labels) {
+ this.logger.debug(`Extracting branches from [${labels}] using ${pattern}`);
+ const regExp = new RegExp(pattern);
+ const branches = [];
+ for (const l of labels) {
+ const result = regExp.exec(l);
+ if (result?.groups) {
+ const { target } = result.groups;
+ if (target) {
+ branches.push(target);
+ }
+ }
+ }
+ return [...new Set(branches)];
+ }
/**
* Create a backport pull request starting from the target branch and
* the original pr to be backported
@@ -7621,7 +7659,6 @@ var preservedUrlFields = [
"protocol",
"query",
"search",
- "hash",
];
// Create handlers that pass events from native requests
@@ -8055,7 +8092,7 @@ RedirectableRequest.prototype._processResponse = function (response) {
redirectUrl.protocol !== "https:" ||
redirectUrl.host !== currentHost &&
!isSubdomain(redirectUrl.host, currentHost)) {
- removeMatchingHeaders(/^(?:(?:proxy-)?authorization|cookie)$/i, this._options.headers);
+ removeMatchingHeaders(/^(?:authorization|cookie)$/i, this._options.headers);
}
// Evaluate the beforeRedirect callback
diff --git a/src/service/args/args-parser.ts b/src/service/args/args-parser.ts
index bc71810..2c83a72 100644
--- a/src/service/args/args-parser.ts
+++ b/src/service/args/args-parser.ts
@@ -16,14 +16,18 @@ export default abstract class ArgsParser {
public parse(): Args {
const args = this.readArgs();
+ if (!args.pullRequest) {
+ throw new Error("Missing option: pull request must be provided");
+ }
// validate and fill with defaults
- if (!args.pullRequest || !args.targetBranch || args.targetBranch.trim().length == 0) {
- throw new Error("Missing option: pull request and target branches must be provided");
+ if ((!args.targetBranch || args.targetBranch.trim().length == 0) && !args.targetBranchPattern) {
+ throw new Error("Missing option: target branch(es) or target regular expression must be provided");
}
return {
pullRequest: args.pullRequest,
targetBranch: args.targetBranch,
+ targetBranchPattern: args.targetBranchPattern,
dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder),
diff --git a/src/service/args/args.types.ts b/src/service/args/args.types.ts
index 2e34064..95ad4ea 100644
--- a/src/service/args/args.types.ts
+++ b/src/service/args/args.types.ts
@@ -3,7 +3,8 @@
*/
export interface Args {
// NOTE: keep targetBranch as singular and of type string for backward compatibilities
- targetBranch: string, // comma separated list of branches on the target repo where the change should be backported to
+ targetBranch?: string, // comma separated list of branches on the target repo where the change should be backported to
+ targetBranchPattern?: string, // regular expression to extract target branch(es) from pull request labels
pullRequest: string, // url of the pull request to backport
dryRun?: boolean, // if enabled do not push anything remotely
auth?: string, // git service auth, like github token
diff --git a/src/service/args/cli/cli-args-parser.ts b/src/service/args/cli/cli-args-parser.ts
index f96cb55..568ee68 100644
--- a/src/service/args/cli/cli-args-parser.ts
+++ b/src/service/args/cli/cli-args-parser.ts
@@ -11,6 +11,7 @@ export default class CLIArgsParser extends ArgsParser {
.version(version)
.description(description)
.option("-tb, --target-branch