From 9c35752e60aead142dfd46a733d0c4da34f65c94 Mon Sep 17 00:00:00 2001
From: jiriks74 <jiri@stefka.eu>
Date: Sun, 15 Dec 2024 19:23:00 +0100
Subject: [PATCH] feat: Handle API URLs for Forgejo, Gitea, GitLab and GitHub

---
 dist/index.js | 43 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/dist/index.js b/dist/index.js
index 8cbfb72..6c8616f 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1277,17 +1277,48 @@ const ERROR_PR_ALREADY_EXISTS = 'A pull request already exists for';
 const ERROR_PR_REVIEW_TOKEN_SCOPE = 'Validation Failed: "Could not resolve to a node with the global id of';
 const ERROR_PR_FORK_COLLAB = `Fork collab can't be granted by someone without permission`;
 const blobCreationLimit = (0, p_limit_1.default)(8);
+async function determineApiBaseUrl(hostname) {
+    if ( hostname == 'github.com' ){
+      core.info(`Valid API path detected: https://api.github.com`);
+      return "https://api.github.com";
+    }
+
+    const baseUrl = 'https://${hostname}';
+    const possiblePaths = ['/api/v4/version', '/api/forgejo/v1/version', '/api/v1/version' ];
+
+    for (const path of possiblePaths) {
+      try {
+            const url = `${baseUrl}${path}`;
+            const response = await fetch(url, { method: 'GET', redirect: 'manual' }); // GitLab redirects `/api/forgejo/v1/version to
+                                                                                      // login prompt so we get response 200
+                                                                                      // if we allow the redirect. Now we get 302.
+
+            const contentType = response.headers.get('Content-Type') || '';
+            if (
+                (response.ok || [401, 403].includes(response.status)) && // Check for valid API status codes
+                contentType.includes('application/json') // Ensure it's returning JSON
+            ) {
+                core.info(`Valid API path detected: ${path.includes('/version') ? url.replace('/version', '') : url}`);
+                return path.includes('/version') ? url.replace('/version', '') : url;
+            }
+        } catch (error) {
+          core.warning(`URL ${baseURL}${path} failed with ${error}`);
+        }
+    }
+
+    throw new Error(`Unable to determine API base URL for hostname: ${hostname}`);
+}
 class GitHubHelper {
     constructor(githubServerHostname, token) {
         const options = {};
         if (token) {
             options.auth = `${token}`;
         }
-        if (githubServerHostname !== 'github.com') {
-            options.baseUrl = `https://${githubServerHostname}/api/v1`;
-        }
-        else {
-            options.baseUrl = 'https://api.github.com';
+        try {
+            options.baseUrl = determineApiBaseUrl(githubServerHostname);
+        } catch (error) {
+            console.error(error.message);
+            process.exit(1); // Exit with an error code if no API path is found
         }
         options.throttle = octokit_client_1.throttleOptions;
         this.octokit = new octokit_client_1.Octokit(options);
@@ -36020,4 +36051,4 @@ function validateConcurrency(concurrency) {
 /******/ 	module.exports = __webpack_exports__;
 /******/ 	
 /******/ })()
-;
\ No newline at end of file
+;