fix(prd-1): fix CI test failures and Forgejo permission check

Two issues found during M8 E2E testing on Forgejo:

1. CI test failures (31 tests): Unit tests assume GitHub context but
   Forgejo runner sets GITHUB_SERVER_URL=git.wxs.ro, causing
   detectPlatform() to return "forgejo" and module-level constants in
   config.ts to use Forgejo URLs. Fixed by setting GITHUB_SERVER_URL
   in the test step env. Forgejo-specific tests already override with
   PLATFORM=forgejo in their beforeEach.

2. Permission check 403: Forgejo's getCollaboratorPermissionLevel
   requires admin access. Added checkForgejoPermissions() that uses
   GET /repos/{owner}/{repo} instead — returns a permissions object
   with { admin, push, pull } booleans for the authenticated token.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Vlad MocanuandClaude Opus 4.6 committed 2026-02-25 18:39:18 +02:00
1 parent c61073da42
commit e26d08e666
3 files changed
+195

No files matched your search

+50
View File
@@ -1,6 +1,7 @@
import * as core from "@actions/core";
import type { ParsedGitHubContext } from "../context";
import type { Octokit } from "@octokit/rest";
import { detectPlatform } from "../../platform/detector";
/**
* Check if the actor has write permissions to the repository
@@ -49,6 +50,15 @@ export async function checkWritePermissions(
return true;
}
const platform = detectPlatform();
if (platform === "forgejo") {
// Forgejo's getCollaboratorPermissionLevel requires admin access.
// Use GET /repos/{owner}/{repo} instead — it returns a `permissions`
// object for the authenticated token (push = write access).
return await checkForgejoPermissions(octokit, repository, actor);
}
// Check permissions directly using the permission endpoint
const response = await octokit.repos.getCollaboratorPermissionLevel({
owner: repository.owner,
@@ -71,3 +81,43 @@ export async function checkWritePermissions(
throw new Error(`Failed to check permissions for ${actor}: ${error}`);
}
}
/**
* Forgejo permission check using the repo endpoint.
* GET /repos/{owner}/{repo} returns a `permissions` object for the
* authenticated token with { admin, push, pull } booleans. We check
* that the token has push (write) access.
*/
async function checkForgejoPermissions(
octokit: Octokit,
repository: { owner: string; repo: string },
actor: string,
): Promise<boolean> {
const response = await octokit.repos.get({
owner: repository.owner,
repo: repository.repo,
});
const permissions = (response.data as any).permissions as
| { admin?: boolean; push?: boolean; pull?: boolean }
| undefined;
if (!permissions) {
core.warning(
`Forgejo did not return permissions for repo ${repository.owner}/${repository.repo}`,
);
return false;
}
if (permissions.admin || permissions.push) {
core.info(
`Forgejo token has write access (admin=${permissions.admin}, push=${permissions.push}) for actor: ${actor}`,
);
return true;
}
core.warning(
`Forgejo token has insufficient permissions (admin=${permissions.admin}, push=${permissions.push}) for actor: ${actor}`,
);
return false;
}