-
-
Notifications
You must be signed in to change notification settings - Fork 438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug](solved?): Forgejo/Gitea failing due to bad API URL #3569
Comments
We can possibly figure out the host by looking at the |
Ok a better way is to check {"version":"1.23.0+dev-789-g18061af490"} |
If we want to check specifically for Forgejo we can use {"version":"9.0.2+gitea-1.22.0"} |
I made a simple proof of concept. Keep in mind that I don't know JavaScript so it probably needs some revision: Codeasync function determineApiBaseUrl(hostname) {
if ( hostname == 'github.com' ){
console.log(`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
) {
console.log(`Valid API path detected: ${path.includes('/version') ? url.replace('/version', '') : url}`);
return path.includes('/version') ? url.replace('/version', '') : url;
}
} catch (error) {
}
}
throw new Error(`Unable to determine API base URL for hostname: ${hostname}`);
}
(async () => {
try {
const hostname = "github.com";
const apiBaseUrl = await determineApiBaseUrl(hostname);
} catch (error) {
console.error(error.message);
process.exit(1); // Exit with an error code if no API path is found
}
})();
(async () => {
try {
const hostname = "codeberg.org";
const apiBaseUrl = await determineApiBaseUrl(hostname);
} catch (error) {
console.error(error.message);
process.exit(1); // Exit with an error code if no API path is found
}
})();
(async () => {
try {
const hostname = "demo.gitea.com";
const apiBaseUrl = await determineApiBaseUrl(hostname);
} catch (error) {
console.error(error.message);
process.exit(1); // Exit with an error code if no API path is found
}
})();
(async () => {
try {
const hostname = "gitlab.com";
const apiBaseUrl = await determineApiBaseUrl(hostname);
} catch (error) {
console.error(error.message);
process.exit(1); // Exit with an error code if no API path is found
}
})(); I get the following output when running this code:
and I get the following when the API URL isn't recognized:
so the end user knows that the Action failed because of a bad API URL. Maybe we could evern let the user define a custom API URL in the Action inputs if we aren't able to detect it. |
With what I found online I was able to create a working patch. I'm happy to open a PR if you find it good enough. Patchdiff --git a/src/create-pull-request.ts b/src/create-pull-request.ts
index 9076b7d..a8971a7 100644
--- a/src/create-pull-request.ts
+++ b/src/create-pull-request.ts
@@ -51,8 +51,10 @@ export async function createPullRequest(inputs: Inputs): Promise<void> {
core.startGroup('Determining the base and head repositories')
const baseRemote = gitConfigHelper.getGitRemote()
// Init the GitHub clients
- const ghBranch = new GitHubHelper(baseRemote.hostname, inputs.branchToken)
- const ghPull = new GitHubHelper(baseRemote.hostname, inputs.token)
+ const apiUrl = await GitHubHelper.determineApiUrl(baseRemote.hostname);
+ core.info(`Using API base URL: ${apiUrl}`);
+ const ghBranch = new GitHubHelper(apiUrl, inputs.branchToken)
+ const ghPull = new GitHubHelper(apiUrl, inputs.token)
// Determine the head repository; the target for the pull request branch
const branchRemoteName = inputs.pushToFork ? 'fork' : 'origin'
const branchRepository = inputs.pushToFork
diff --git a/src/github-helper.ts b/src/github-helper.ts
index 82a9296..15efc16 100644
--- a/src/github-helper.ts
+++ b/src/github-helper.ts
@@ -41,20 +41,49 @@ type TreeObject = {
export class GitHubHelper {
private octokit: InstanceType<typeof Octokit>
- constructor(githubServerHostname: string, token: string) {
+ constructor(apiUrl: string, token: string) {
const options: OctokitOptions = {}
if (token) {
options.auth = `${token}`
}
- if (githubServerHostname !== 'github.com') {
- options.baseUrl = `https://${githubServerHostname}/api/v3`
- } else {
- options.baseUrl = 'https://api.github.com'
- }
+ options.baseUrl = apiUrl;
options.throttle = throttleOptions
this.octokit = new Octokit(options)
}
+ static async determineApiUrl(hostname: string): Promise<string> {
+ if (hostname === '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
+ // invalid API paths
+ // to login prompt
+ // which returns 200
+
+ const contentType = response.headers.get('Content-Type') || '';
+ if (
+ (response.ok || [401, 403].includes(response.status)) && // We might get 401, 403
+ // as we're unauthorised
+ contentType.includes('application/json')
+ ) {
+ return path.includes('/version') ? url.replace('/version', '') : url;
+ }
+
+ } catch (error) {
+ // Ignore errors and try the next path
+ }
+ }
+
+ throw new Error(`Unable to determine API base URL for hostname: ${hostname}`);
+ }
+
private parseRepository(repository: string): Repository {
const [owner, repo] = repository.split('/')
return { I've tested the function locally with the following code determineApiUrl("github.com")
.then(url => console.log(url))
.catch(error => console.error(error));
determineApiUrl("gitlab.com")
.then(url => console.log(url))
.catch(error => console.error(error));
determineApiUrl("codeberg.org")
.then(url => console.log(url))
.catch(error => console.error(error));
determineApiUrl("demo.gitea.com")
.then(url => console.log(url))
.catch(error => console.error(error)); producing this output
|
Hi @jiriks74 Thank you for raising this and your effort to solve it! Very interesting. This action supports many use cases, and I would be very surprised if they all work outside of GitHub's ecosystem. I'm not sure that I'm prepared to try and make this action work elsewhere and keep up with its maintenance. You are welcome to fork this action and try and make a working version that covers the test cases. If you achieve it I would consider if it makes sense to merge it in. |
Subject of the issue
Running this action on Forgejo/Gitea results in the following error:
Debugging this lead me to the following URL definition:
https://github.com/peter-evans/create-pull-request/blob/16e0059bfd236716f0191bfcfa63d9ded4cf325f/dist/index.js#L1287
Changing this
resolves the issue and results in a working Action:
Steps to reproduce
::error::Not found.%0A
errorThe text was updated successfully, but these errors were encountered: