1
0
Fork 0
mirror of https://code.forgejo.org/actions/git-backporting synced 2025-03-15 14:44:39 +01:00

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.
This commit is contained in:
Earl Warren 2024-03-23 17:13:14 +01:00 committed by GitHub
parent 646d8fe41c
commit 80a0b554f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 70 additions and 3 deletions

View file

@ -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 | | | 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 | "" | | 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 | | 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 <github|gitlab|codeberg>, if not set it is infered from pull-request
| Git User | -gu, --git-user | N | Local git user name | "GitHub" | | Git User | -gu, --git-user | N | Local git user name | "GitHub" |
| Git Email | -ge, --git-email | N | Local git user email | "noreply@github.com" | | Git Email | -ge, --git-email | N | Local git user email | "noreply@github.com" |
| Title | --title | N | Backporting pull request title | "{original-pr-title}" | | Title | --title | N | Backporting pull request title | "{original-pr-title}" |

View file

@ -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" 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 }} default: ${{ github.token }}
required: false required: false
git-client:
description: "Git client type <github|gitlab|codeberg>, if not set it is infered from pull-request"
required: false
git-user: git-user:
description: "Local git user name" description: "Local git user name"
default: "GitHub" default: "GitHub"

11
dist/cli/index.js vendored
View file

@ -49,6 +49,7 @@ class ArgsParser {
dryRun: this.getOrDefault(args.dryRun, false), dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth), auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder), folder: this.getOrDefault(args.folder),
gitClient: this.getOrDefault(args.gitClient),
gitUser: this.getOrDefault(args.gitUser), gitUser: this.getOrDefault(args.gitUser),
gitEmail: this.getOrDefault(args.gitEmail), gitEmail: this.getOrDefault(args.gitEmail),
title: this.getOrDefault(args.title), title: this.getOrDefault(args.title),
@ -183,6 +184,7 @@ class CLIArgsParser extends args_parser_1.default {
.option("-pr, --pull-request <pr-url>", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1") .option("-pr, --pull-request <pr-url>", "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("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth <auth>", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN") .option("-a, --auth <auth>", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
.option("--git-client <github|gitlab|codeberg>", "git client type, if not set it is infered from --pull-request")
.option("-gu, --git-user <git-user>", "local git user name, default is 'GitHub'") .option("-gu, --git-user <git-user>", "local git user name, default is 'GitHub'")
.option("-ge, --git-email <git-email>", "local git user email, default is 'noreply@github.com'") .option("-ge, --git-email <git-email>", "local git user email, default is 'noreply@github.com'")
.option("-f, --folder <folder>", "local folder where the repo will be checked out, e.g., /tmp/folder") .option("-f, --folder <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, pullRequest: opts.pullRequest,
targetBranch: opts.targetBranch, targetBranch: opts.targetBranch,
folder: opts.folder, folder: opts.folder,
gitClient: opts.gitClient,
gitUser: opts.gitUser, gitUser: opts.gitUser,
gitEmail: opts.gitEmail, gitEmail: opts.gitEmail,
title: opts.title, title: opts.title,
@ -1343,7 +1346,13 @@ class Runner {
this.logger.warn("Dry run enabled"); this.logger.warn("Dry run enabled");
} }
// 2. init git service // 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 // 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 apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
const token = this.fetchToken(args, gitClientType); const token = this.fetchToken(args, gitClientType);

10
dist/gha/index.js vendored
View file

@ -49,6 +49,7 @@ class ArgsParser {
dryRun: this.getOrDefault(args.dryRun, false), dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth), auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder), folder: this.getOrDefault(args.folder),
gitClient: this.getOrDefault(args.gitClient),
gitUser: this.getOrDefault(args.gitUser), gitUser: this.getOrDefault(args.gitUser),
gitEmail: this.getOrDefault(args.gitEmail), gitEmail: this.getOrDefault(args.gitEmail),
title: this.getOrDefault(args.title), title: this.getOrDefault(args.title),
@ -187,6 +188,7 @@ class GHAArgsParser extends args_parser_1.default {
pullRequest: (0, core_1.getInput)("pull-request"), pullRequest: (0, core_1.getInput)("pull-request"),
targetBranch: (0, core_1.getInput)("target-branch"), targetBranch: (0, core_1.getInput)("target-branch"),
folder: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("folder")), 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")), gitUser: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-user")),
gitEmail: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-email")), gitEmail: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("git-email")),
title: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("title")), title: (0, args_utils_1.getOrUndefined)((0, core_1.getInput)("title")),
@ -1313,7 +1315,13 @@ class Runner {
this.logger.warn("Dry run enabled"); this.logger.warn("Dry run enabled");
} }
// 2. init git service // 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 // 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 apiUrl = (0, git_util_1.inferGitApiUrl)(args.pullRequest, gitClientType === git_types_1.GitClientType.CODEBERG ? "v1" : undefined);
const token = this.fetchToken(args, gitClientType); const token = this.fetchToken(args, gitClientType);

View file

@ -27,6 +27,7 @@ export default abstract class ArgsParser {
dryRun: this.getOrDefault(args.dryRun, false), dryRun: this.getOrDefault(args.dryRun, false),
auth: this.getOrDefault(args.auth), auth: this.getOrDefault(args.auth),
folder: this.getOrDefault(args.folder), folder: this.getOrDefault(args.folder),
gitClient: this.getOrDefault(args.gitClient),
gitUser: this.getOrDefault(args.gitUser), gitUser: this.getOrDefault(args.gitUser),
gitEmail: this.getOrDefault(args.gitEmail), gitEmail: this.getOrDefault(args.gitEmail),
title: this.getOrDefault(args.title), title: this.getOrDefault(args.title),

View file

@ -8,6 +8,7 @@ export interface Args {
dryRun?: boolean, // if enabled do not push anything remotely dryRun?: boolean, // if enabled do not push anything remotely
auth?: string, // git service auth, like github token auth?: string, // git service auth, like github token
folder?: string, // local folder where the repositories should be cloned folder?: string, // local folder where the repositories should be cloned
gitClient?: string, // git client
gitUser?: string, // local git user, default 'GitHub' gitUser?: string, // local git user, default 'GitHub'
gitEmail?: string, // local git email, default 'noreply@github.com' gitEmail?: string, // local git email, default 'noreply@github.com'
title?: string, // backport pr title, default original pr title prefixed by target branch title?: string, // backport pr title, default original pr title prefixed by target branch

View file

@ -14,6 +14,7 @@ export default class CLIArgsParser extends ArgsParser {
.option("-pr, --pull-request <pr-url>", "pull request url, e.g., https://github.com/kiegroup/git-backporting/pull/1") .option("-pr, --pull-request <pr-url>", "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("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely")
.option("-a, --auth <auth>", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN") .option("-a, --auth <auth>", "git authentication string, if not provided fallback by looking for existing env variables like GITHUB_TOKEN")
.option("--git-client <github|gitlab|codeberg>", "git client type, if not set it is infered from --pull-request")
.option("-gu, --git-user <git-user>", "local git user name, default is 'GitHub'") .option("-gu, --git-user <git-user>", "local git user name, default is 'GitHub'")
.option("-ge, --git-email <git-email>", "local git user email, default is 'noreply@github.com'") .option("-ge, --git-email <git-email>", "local git user email, default is 'noreply@github.com'")
.option("-f, --folder <folder>", "local folder where the repo will be checked out, e.g., /tmp/folder") .option("-f, --folder <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, pullRequest: opts.pullRequest,
targetBranch: opts.targetBranch, targetBranch: opts.targetBranch,
folder: opts.folder, folder: opts.folder,
gitClient: opts.gitClient,
gitUser: opts.gitUser, gitUser: opts.gitUser,
gitEmail: opts.gitEmail, gitEmail: opts.gitEmail,
title: opts.title, title: opts.title,

View file

@ -18,6 +18,7 @@ export default class GHAArgsParser extends ArgsParser {
pullRequest: getInput("pull-request"), pullRequest: getInput("pull-request"),
targetBranch: getInput("target-branch"), targetBranch: getInput("target-branch"),
folder: getOrUndefined(getInput("folder")), folder: getOrUndefined(getInput("folder")),
gitClient: getOrUndefined(getInput("git-client")),
gitUser: getOrUndefined(getInput("git-user")), gitUser: getOrUndefined(getInput("git-user")),
gitEmail: getOrUndefined(getInput("git-email")), gitEmail: getOrUndefined(getInput("git-email")),
title: getOrUndefined(getInput("title")), title: getOrUndefined(getInput("title")),

View file

@ -60,7 +60,12 @@ export default class Runner {
} }
// 2. init git service // 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 // the api version is ignored in case of github
const apiUrl = inferGitApiUrl(args.pullRequest, gitClientType === GitClientType.CODEBERG ? "v1" : undefined); const apiUrl = inferGitApiUrl(args.pullRequest, gitClientType === GitClientType.CODEBERG ? "v1" : undefined);
const token = this.fetchToken(args, gitClientType); const token = this.fetchToken(args, gitClientType);

View file

@ -15,6 +15,7 @@ const RANDOM_CONFIG_FILE_CONTENT = {
"targetBranch": "target-branch-name", "targetBranch": "target-branch-name",
"pullRequest": "https://github.com/user/repo/pull/123", "pullRequest": "https://github.com/user/repo/pull/123",
"folder": "/path/to/local/folder", "folder": "/path/to/local/folder",
"gitClient": "codeberg",
"gitUser": "YourGitUser", "gitUser": "YourGitUser",
"gitEmail": "your-email@example.com", "gitEmail": "your-email@example.com",
"title": "Backport: Original PR Title", "title": "Backport: Original PR Title",
@ -62,6 +63,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -90,6 +92,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -120,6 +123,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -148,6 +152,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -185,6 +190,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(true); expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("bearer-token"); expect(args.auth).toEqual("bearer-token");
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual("Me"); expect(args.gitUser).toEqual("Me");
expect(args.gitEmail).toEqual("me@email.com"); expect(args.gitEmail).toEqual("me@email.com");
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -213,6 +219,8 @@ describe("cli args parser", () => {
"target", "target",
"--pull-request", "--pull-request",
"https://localhost/whatever/pulls/1", "https://localhost/whatever/pulls/1",
"--git-client",
"codeberg",
"--git-user", "--git-user",
"Me", "Me",
"--git-email", "--git-email",
@ -238,6 +246,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(true); expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("bearer-token"); expect(args.auth).toEqual("bearer-token");
expect(args.gitClient).toEqual("codeberg");
expect(args.gitUser).toEqual("Me"); expect(args.gitUser).toEqual("Me");
expect(args.gitEmail).toEqual("me@email.com"); expect(args.gitEmail).toEqual("me@email.com");
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -266,6 +275,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(true); expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("your-git-service-auth-token"); expect(args.auth).toEqual("your-git-service-auth-token");
expect(args.gitClient).toEqual("codeberg");
expect(args.gitUser).toEqual("YourGitUser"); expect(args.gitUser).toEqual("YourGitUser");
expect(args.gitEmail).toEqual("your-email@example.com"); expect(args.gitEmail).toEqual("your-email@example.com");
expect(args.folder).toEqual("/path/to/local/folder"); expect(args.folder).toEqual("/path/to/local/folder");
@ -296,6 +306,8 @@ describe("cli args parser", () => {
"target", "target",
"--pull-request", "--pull-request",
"https://localhost/whatever/pulls/1", "https://localhost/whatever/pulls/1",
"--git-client",
"github",
"--git-user", "--git-user",
"Me", "Me",
"--git-email", "--git-email",
@ -321,6 +333,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(true); expect(args.dryRun).toEqual(true);
expect(args.auth).toEqual("your-git-service-auth-token"); expect(args.auth).toEqual("your-git-service-auth-token");
expect(args.gitClient).toEqual("codeberg");
expect(args.gitUser).toEqual("YourGitUser"); expect(args.gitUser).toEqual("YourGitUser");
expect(args.gitEmail).toEqual("your-email@example.com"); expect(args.gitEmail).toEqual("your-email@example.com");
expect(args.folder).toEqual("/path/to/local/folder"); expect(args.folder).toEqual("/path/to/local/folder");
@ -352,6 +365,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -384,6 +398,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -416,6 +431,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);
@ -445,6 +461,7 @@ describe("cli args parser", () => {
const args: Args = parser.parse(); const args: Args = parser.parse();
expect(args.dryRun).toEqual(false); expect(args.dryRun).toEqual(false);
expect(args.auth).toEqual(undefined); expect(args.auth).toEqual(undefined);
expect(args.gitClient).toEqual(undefined);
expect(args.gitUser).toEqual(undefined); expect(args.gitUser).toEqual(undefined);
expect(args.gitEmail).toEqual(undefined); expect(args.gitEmail).toEqual(undefined);
expect(args.folder).toEqual(undefined); expect(args.folder).toEqual(undefined);

View file

@ -768,4 +768,23 @@ describe("gha runner", () => {
}); });
expect(GitHubClient.prototype.createPullRequest).toReturnTimes(3); 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");
});
}); });