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