Skip to content

Commit 071effd

Browse files
authored
feat: introduce forgejo (#240)
Codeberg is running on Forgejo, however it would be better to advertise compatibility with the underlying software than with this specific deployment.
1 parent 6f4ec81 commit 071effd

9 files changed

Lines changed: 73 additions & 32 deletions

File tree

‎README.md‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ This tool comes with some inputs that allow users to override the default behavi
115115
| 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 | |
116116
| 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 | "" |
117117
| Folder | -f, --folder | N | Local folder full name of the repository that will be checked out, e.g., /tmp/folder | {cwd}/bp |
118-
| Git Client | --git-client | N | Git client type <github|gitlab|codeberg>, if not set it is infered from pull-request
118+
| Git Client | --git-client | N | Git client type <github|gitlab|codeberg|forgejo>, if not set it is infered from pull-request / env variables
119119
| Git User | -gu, --git-user | N | Local git user name | "GitHub" |
120120
| Git Email | -ge, --git-email | N | Local git user email | "noreply@github.com" |
121121
| Title | --title | N | Backporting pull request title | "{original-pr-title}" |
@@ -147,7 +147,8 @@ Since version `4.5.0` we introduced a new feature that allows user to provide th
147147
Here the supported list of env variables:
148148
- `GITHUB_TOKEN`: this is checked only if backporting on Github platform.
149149
- `GITLAB_TOKEN`: this is checked only if backporting on Gitlab platform.
150-
- `CODEBERG_TOKEN`: this is checked only if backporting on Codeberg platform.
150+
- `CODEBERG_TOKEN`: this is checked only if backporting on Codeberg.org.
151+
- `FORGEJO_TOKEN`: this is checked only if backporting on Forgejo.
151152
- `GIT_TOKEN`: this is considered if none of the previous envs are set.
152153

153154
> **NOTE**: if `--auth` argument is provided, all env variables will be ignored even if not empty.
@@ -211,7 +212,7 @@ Right now **Git Backporting** supports the following git management services:
211212

212213
* ***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.
213214

214-
* ***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.
215+
* ***CODEBERG/FORGEJO***: Introduced since version `4.4.0`, it works for public [codeberg.org](https://codeberg.org/) and self-hosted 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.
215216

216217
> **NOTE**: by default, all gitlab requests are performed setting `rejectUnauthorized=false`, planning to make this configurable too.
217218

‎dist/cli/index.js‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,8 @@ var AuthTokenId;
324324
AuthTokenId["GITLAB_TOKEN"] = "GITLAB_TOKEN";
325325
// codeberg specific token
326326
AuthTokenId["CODEBERG_TOKEN"] = "CODEBERG_TOKEN";
327+
// forgejo specific token
328+
AuthTokenId["FORGEJO_TOKEN"] = "FORGEJO_TOKEN";
327329
// generic git token
328330
AuthTokenId["GIT_TOKEN"] = "GIT_TOKEN";
329331
})(AuthTokenId = exports.AuthTokenId || (exports.AuthTokenId = {}));
@@ -765,7 +767,8 @@ class GitClientFactory {
765767
GitClientFactory.instance = new gitlab_client_1.default(authToken, apiUrl);
766768
break;
767769
case git_types_1.GitClientType.CODEBERG:
768-
GitClientFactory.instance = new github_client_1.default(authToken, apiUrl, true);
770+
case git_types_1.GitClientType.FORGEJO:
771+
GitClientFactory.instance = new github_client_1.default(authToken, apiUrl, type);
769772
break;
770773
default:
771774
throw new Error(`Invalid git service type received: ${type}`);
@@ -800,7 +803,7 @@ const PUBLIC_GITHUB_URL = "https://github.com";
800803
const PUBLIC_GITHUB_API = "https://api.github.com";
801804
/**
802805
* Infer the remote GIT service to interact with based on the provided
803-
* pull request URL
806+
* pull request URL and environment variables
804807
* @param prUrl provided pull request URL
805808
* @returns {GitClientType}
806809
*/
@@ -815,6 +818,12 @@ const inferGitClient = (prUrl) => {
815818
else if (stdPrUrl.includes(git_types_1.GitClientType.CODEBERG.toString())) {
816819
return git_types_1.GitClientType.CODEBERG;
817820
}
821+
// When running as Forgejo action, some env variables are set
822+
// https://forgejo.org/docs/latest/user/actions/reference/#env-1
823+
let [_, isForgejoRunner] = (0, exports.getEnv)("FORGEJO_SERVER_URL");
824+
if (isForgejoRunner) {
825+
return git_types_1.GitClientType.FORGEJO;
826+
}
818827
throw new Error(`Remote git service not recognized from pr url: ${prUrl}`);
819828
};
820829
exports.inferGitClient = inferGitClient;
@@ -877,6 +886,9 @@ const getGitTokenFromEnv = (gitType) => {
877886
else if (git_types_1.GitClientType.CODEBERG == gitType) {
878887
[specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
879888
}
889+
else if (git_types_1.GitClientType.FORGEJO == gitType) {
890+
[specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.FORGEJO_TOKEN);
891+
}
880892
if (specOk) {
881893
token = specToken;
882894
}
@@ -911,6 +923,7 @@ var GitClientType;
911923
GitClientType["GITHUB"] = "github";
912924
GitClientType["GITLAB"] = "gitlab";
913925
GitClientType["CODEBERG"] = "codeberg";
926+
GitClientType["FORGEJO"] = "forgejo";
914927
})(GitClientType = exports.GitClientType || (exports.GitClientType = {}));
915928
var GitRepoState;
916929
(function (GitRepoState) {
@@ -940,18 +953,18 @@ const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
940953
class GitHubClient {
941954
logger;
942955
apiUrl;
943-
isForCodeberg;
956+
compatibleForge; // undefined for github
944957
octokit;
945958
mapper;
946-
constructor(token, apiUrl, isForCodeberg = false) {
959+
constructor(token, apiUrl, compatibleForge) {
947960
this.apiUrl = apiUrl;
948-
this.isForCodeberg = isForCodeberg;
961+
this.compatibleForge = compatibleForge;
949962
this.logger = logger_service_factory_1.default.getLogger();
950963
this.octokit = octokit_factory_1.default.getOctokit(token, this.apiUrl);
951964
this.mapper = new github_mapper_1.default();
952965
}
953966
getClientType() {
954-
return this.isForCodeberg ? git_types_1.GitClientType.CODEBERG : git_types_1.GitClientType.GITHUB;
967+
return this.compatibleForge ?? git_types_1.GitClientType.GITHUB;
955968
}
956969
// READ
957970
getDefaultGitUser() {
@@ -1078,8 +1091,8 @@ class GitHubClient {
10781091
pull_number: prNumber,
10791092
});
10801093
const commits = data.map(c => ({ sha: c.sha, message: c.commit.message }));
1081-
if (this.isForCodeberg) {
1082-
// For some reason, even though Codeberg advertises API compatibility
1094+
if (this.compatibleForge) {
1095+
// For some reason, even though Codeberg/Forgejo advertises API compatibility
10831096
// with GitHub, it returns commits in reversed order.
10841097
commits.reverse();
10851098
}

‎dist/gha/index.js‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ var AuthTokenId;
286286
AuthTokenId["GITLAB_TOKEN"] = "GITLAB_TOKEN";
287287
// codeberg specific token
288288
AuthTokenId["CODEBERG_TOKEN"] = "CODEBERG_TOKEN";
289+
// forgejo specific token
290+
AuthTokenId["FORGEJO_TOKEN"] = "FORGEJO_TOKEN";
289291
// generic git token
290292
AuthTokenId["GIT_TOKEN"] = "GIT_TOKEN";
291293
})(AuthTokenId = exports.AuthTokenId || (exports.AuthTokenId = {}));
@@ -727,7 +729,8 @@ class GitClientFactory {
727729
GitClientFactory.instance = new gitlab_client_1.default(authToken, apiUrl);
728730
break;
729731
case git_types_1.GitClientType.CODEBERG:
730-
GitClientFactory.instance = new github_client_1.default(authToken, apiUrl, true);
732+
case git_types_1.GitClientType.FORGEJO:
733+
GitClientFactory.instance = new github_client_1.default(authToken, apiUrl, type);
731734
break;
732735
default:
733736
throw new Error(`Invalid git service type received: ${type}`);
@@ -762,7 +765,7 @@ const PUBLIC_GITHUB_URL = "https://github.com";
762765
const PUBLIC_GITHUB_API = "https://api.github.com";
763766
/**
764767
* Infer the remote GIT service to interact with based on the provided
765-
* pull request URL
768+
* pull request URL and environment variables
766769
* @param prUrl provided pull request URL
767770
* @returns {GitClientType}
768771
*/
@@ -777,6 +780,12 @@ const inferGitClient = (prUrl) => {
777780
else if (stdPrUrl.includes(git_types_1.GitClientType.CODEBERG.toString())) {
778781
return git_types_1.GitClientType.CODEBERG;
779782
}
783+
// When running as Forgejo action, some env variables are set
784+
// https://forgejo.org/docs/latest/user/actions/reference/#env-1
785+
let [_, isForgejoRunner] = (0, exports.getEnv)("FORGEJO_SERVER_URL");
786+
if (isForgejoRunner) {
787+
return git_types_1.GitClientType.FORGEJO;
788+
}
780789
throw new Error(`Remote git service not recognized from pr url: ${prUrl}`);
781790
};
782791
exports.inferGitClient = inferGitClient;
@@ -839,6 +848,9 @@ const getGitTokenFromEnv = (gitType) => {
839848
else if (git_types_1.GitClientType.CODEBERG == gitType) {
840849
[specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.CODEBERG_TOKEN);
841850
}
851+
else if (git_types_1.GitClientType.FORGEJO == gitType) {
852+
[specToken, specOk] = (0, exports.getEnv)(configs_types_1.AuthTokenId.FORGEJO_TOKEN);
853+
}
842854
if (specOk) {
843855
token = specToken;
844856
}
@@ -873,6 +885,7 @@ var GitClientType;
873885
GitClientType["GITHUB"] = "github";
874886
GitClientType["GITLAB"] = "gitlab";
875887
GitClientType["CODEBERG"] = "codeberg";
888+
GitClientType["FORGEJO"] = "forgejo";
876889
})(GitClientType = exports.GitClientType || (exports.GitClientType = {}));
877890
var GitRepoState;
878891
(function (GitRepoState) {
@@ -902,18 +915,18 @@ const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936));
902915
class GitHubClient {
903916
logger;
904917
apiUrl;
905-
isForCodeberg;
918+
compatibleForge; // undefined for github
906919
octokit;
907920
mapper;
908-
constructor(token, apiUrl, isForCodeberg = false) {
921+
constructor(token, apiUrl, compatibleForge) {
909922
this.apiUrl = apiUrl;
910-
this.isForCodeberg = isForCodeberg;
923+
this.compatibleForge = compatibleForge;
911924
this.logger = logger_service_factory_1.default.getLogger();
912925
this.octokit = octokit_factory_1.default.getOctokit(token, this.apiUrl);
913926
this.mapper = new github_mapper_1.default();
914927
}
915928
getClientType() {
916-
return this.isForCodeberg ? git_types_1.GitClientType.CODEBERG : git_types_1.GitClientType.GITHUB;
929+
return this.compatibleForge ?? git_types_1.GitClientType.GITHUB;
917930
}
918931
// READ
919932
getDefaultGitUser() {
@@ -1040,8 +1053,8 @@ class GitHubClient {
10401053
pull_number: prNumber,
10411054
});
10421055
const commits = data.map(c => ({ sha: c.sha, message: c.commit.message }));
1043-
if (this.isForCodeberg) {
1044-
// For some reason, even though Codeberg advertises API compatibility
1056+
if (this.compatibleForge) {
1057+
// For some reason, even though Codeberg/Forgejo advertises API compatibility
10451058
// with GitHub, it returns commits in reversed order.
10461059
commits.reverse();
10471060
}

‎src/service/configs/configs.types.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export enum AuthTokenId {
3939
GITLAB_TOKEN = "GITLAB_TOKEN",
4040
// codeberg specific token
4141
CODEBERG_TOKEN = "CODEBERG_TOKEN",
42+
// forgejo specific token
43+
FORGEJO_TOKEN = "FORGEJO_TOKEN",
4244
// generic git token
4345
GIT_TOKEN = "GIT_TOKEN",
44-
}
46+
}

‎src/service/git/git-client-factory.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ export default class GitClientFactory {
4444
GitClientFactory.instance = new GitLabClient(authToken, apiUrl);
4545
break;
4646
case GitClientType.CODEBERG:
47-
GitClientFactory.instance = new GitHubService(authToken, apiUrl, true);
47+
case GitClientType.FORGEJO:
48+
GitClientFactory.instance = new GitHubService(authToken, apiUrl, type);
4849
break;
4950
default:
5051
throw new Error(`Invalid git service type received: ${type}`);
@@ -58,4 +59,4 @@ export default class GitClientFactory {
5859
GitClientFactory.logger.warn("Resetting git service");
5960
GitClientFactory.instance = undefined;
6061
}
61-
}
62+
}

‎src/service/git/git-util.ts‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const PUBLIC_GITHUB_API = "https://api.github.com";
77

88
/**
99
* Infer the remote GIT service to interact with based on the provided
10-
* pull request URL
10+
* pull request URL and environment variables
1111
* @param prUrl provided pull request URL
1212
* @returns {GitClientType}
1313
*/
@@ -22,6 +22,13 @@ export const inferGitClient = (prUrl: string): GitClientType => {
2222
return GitClientType.CODEBERG;
2323
}
2424

25+
// When running as Forgejo action, some env variables are set
26+
// https://forgejo.org/docs/latest/user/actions/reference/#env-1
27+
let [_, isForgejoRunner] = getEnv("FORGEJO_SERVER_URL");
28+
if (isForgejoRunner) {
29+
return GitClientType.FORGEJO;
30+
}
31+
2532
throw new Error(`Remote git service not recognized from pr url: ${prUrl}`);
2633
};
2734

@@ -82,6 +89,8 @@ export const getGitTokenFromEnv = (gitType: GitClientType): string | undefined =
8289
[specToken, specOk] = getEnv(AuthTokenId.GITLAB_TOKEN);
8390
} else if (GitClientType.CODEBERG == gitType) {
8491
[specToken, specOk] = getEnv(AuthTokenId.CODEBERG_TOKEN);
92+
} else if (GitClientType.FORGEJO == gitType) {
93+
[specToken, specOk] = getEnv(AuthTokenId.FORGEJO_TOKEN);
8594
}
8695

8796
if (specOk) {
@@ -101,4 +110,4 @@ export const getGitTokenFromEnv = (gitType: GitClientType): string | undefined =
101110
export const getEnv = (key: string): [string | undefined, boolean] => {
102111
const val = process.env[key];
103112
return [val, val !== undefined && val !== ""];
104-
};
113+
};

‎src/service/git/git.types.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,13 @@ export interface BackportPullRequest {
4343
export enum GitClientType {
4444
GITHUB = "github",
4545
GITLAB = "gitlab",
46-
CODEBERG = "codeberg",
46+
CODEBERG = "codeberg", // codeberg runs Forgejo, kept for historic reasons
47+
FORGEJO = "forgejo",
4748
}
4849

4950
export enum GitRepoState {
5051
OPEN = "open",
5152
CLOSED = "closed",
5253
LOCKED = "locked", // just on gitlab
5354
MERGED = "merged", // just on gitlab
54-
}
55+
}

‎src/service/git/github/github-client.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ export default class GitHubClient implements GitClient {
1212

1313
private logger: LoggerService;
1414
private apiUrl: string;
15-
private isForCodeberg: boolean;
15+
private compatibleForge: GitClientType | undefined; // undefined for github
1616
private octokit: Octokit;
1717
private mapper: GitHubMapper;
1818

19-
constructor(token: string | undefined, apiUrl: string, isForCodeberg = false) {
19+
constructor(token: string | undefined, apiUrl: string, compatibleForge?: GitClientType) {
2020
this.apiUrl = apiUrl;
21-
this.isForCodeberg = isForCodeberg;
21+
this.compatibleForge = compatibleForge;
2222
this.logger = LoggerServiceFactory.getLogger();
2323
this.octokit = OctokitFactory.getOctokit(token, this.apiUrl);
2424
this.mapper = new GitHubMapper();
2525
}
2626

2727
getClientType(): GitClientType {
28-
return this.isForCodeberg ? GitClientType.CODEBERG : GitClientType.GITHUB;
28+
return this.compatibleForge ?? GitClientType.GITHUB;
2929
}
3030

3131
// READ
@@ -175,8 +175,8 @@ export default class GitHubClient implements GitClient {
175175
});
176176

177177
const commits = data.map(c => ({ sha: c.sha, message: c.commit.message }));
178-
if (this.isForCodeberg) {
179-
// For some reason, even though Codeberg advertises API compatibility
178+
if (this.compatibleForge) {
179+
// For some reason, even though Codeberg/Forgejo advertises API compatibility
180180
// with GitHub, it returns commits in reversed order.
181181
commits.reverse();
182182
}

‎test/support/utils.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const resetEnvTokens = () => {
1414
delete process.env[AuthTokenId.GITHUB_TOKEN];
1515
delete process.env[AuthTokenId.GITLAB_TOKEN];
1616
delete process.env[AuthTokenId.CODEBERG_TOKEN];
17+
delete process.env[AuthTokenId.FORGEJO_TOKEN];
1718
delete process.env[AuthTokenId.GIT_TOKEN];
1819
};
1920

0 commit comments

Comments
 (0)