diff --git a/dist/index.js b/dist/index.js index faf637755..080286d0d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -293,24 +293,41 @@ class GitHubHelper { }; } getActorPermission(repo, actor) { + var _a; return __awaiter(this, void 0, void 0, function* () { - // https://docs.github.com/en/graphql/reference/enums#repositorypermission - // https://docs.github.com/en/graphql/reference/objects#repositorycollaboratoredge - // Returns 'READ', 'TRIAGE', 'WRITE', 'MAINTAIN', 'ADMIN' - const query = `query CollaboratorPermission($owner: String!, $repo: String!, $collaborator: String) { - repository(owner:$owner, name:$repo) { - collaborators(login: $collaborator) { - edges { - permission - } - } - } - }`; - const collaboratorPermission = yield this.octokit.graphql(query, Object.assign(Object.assign({}, repo), { collaborator: actor })); - core.debug(`CollaboratorPermission: ${(0, util_1.inspect)(collaboratorPermission.repository.collaborators.edges)}`); - return collaboratorPermission.repository.collaborators.edges.length > 0 - ? collaboratorPermission.repository.collaborators.edges[0].permission.toLowerCase() - : 'none'; + // Use the REST API approach which can detect both direct and team-based permissions + // This is more reliable than the GraphQL approach for team permissions and works better with default GITHUB_TOKEN + try { + const { data: collaboratorPermission } = yield this.octokit.rest.repos.getCollaboratorPermissionLevel(Object.assign(Object.assign({}, repo), { username: actor })); + const permissions = (_a = collaboratorPermission.user) === null || _a === void 0 ? void 0 : _a.permissions; + core.debug(`REST API collaborator permission: ${(0, util_1.inspect)(permissions)}`); + // Use the detailed permissions object to get the highest permission level + if (permissions) { + // Check permissions in order of highest to lowest + if (permissions.admin) { + return 'admin'; + } + else if (permissions.maintain) { + return 'maintain'; + } + else if (permissions.push) { + return 'write'; + } + else if (permissions.triage) { + core.debug(`User ${actor} has triage permission via REST API`); + return 'triage'; + } + else if (permissions.pull) { + core.debug(`User ${actor} has read permission via REST API`); + return 'read'; + } + } + return 'none'; + } + catch (error) { + core.debug(`REST API permission check failed: ${utils.getErrorMessage(error)}`); + return 'none'; + } }); } tryAddReaction(repo, commentId, reaction) { diff --git a/src/command-helper.ts b/src/command-helper.ts index 6c2f31bac..353a92417 100644 --- a/src/command-helper.ts +++ b/src/command-helper.ts @@ -175,7 +175,7 @@ export function configIsValid(config: Command[]): string | null { } export function actorHasPermission( - actorPermission: string, + actorPermission: utils.RepoPermission, commandPermission: string ): boolean { const permissionLevels = Object.freeze({ diff --git a/src/github-helper.ts b/src/github-helper.ts index 31b96237f..8df006dab 100644 --- a/src/github-helper.ts +++ b/src/github-helper.ts @@ -55,32 +55,47 @@ export class GitHubHelper { } } - async getActorPermission(repo: Repository, actor: string): Promise { - // https://docs.github.com/en/graphql/reference/enums#repositorypermission - // https://docs.github.com/en/graphql/reference/objects#repositorycollaboratoredge - // Returns 'READ', 'TRIAGE', 'WRITE', 'MAINTAIN', 'ADMIN' - const query = `query CollaboratorPermission($owner: String!, $repo: String!, $collaborator: String) { - repository(owner:$owner, name:$repo) { - collaborators(login: $collaborator) { - edges { - permission - } + async getActorPermission( + repo: Repository, + actor: string + ): Promise { + // Use the REST API approach which can detect both direct and team-based permissions + // This is more reliable than the GraphQL approach for team permissions and works better with default GITHUB_TOKEN + try { + const {data: collaboratorPermission} = + await this.octokit.rest.repos.getCollaboratorPermissionLevel({ + ...repo, + username: actor + }) + + const permissions = collaboratorPermission.user?.permissions + core.debug(`REST API collaborator permission: ${inspect(permissions)}`) + + // Use the detailed permissions object to get the highest permission level + if (permissions) { + // Check permissions in order of highest to lowest + if (permissions.admin) { + return 'admin' + } else if (permissions.maintain) { + return 'maintain' + } else if (permissions.push) { + return 'write' + } else if (permissions.triage) { + core.debug(`User ${actor} has triage permission via REST API`) + return 'triage' + } else if (permissions.pull) { + core.debug(`User ${actor} has read permission via REST API`) + return 'read' } } - }` - const collaboratorPermission = - await this.octokit.graphql(query, { - ...repo, - collaborator: actor - }) - core.debug( - `CollaboratorPermission: ${inspect( - collaboratorPermission.repository.collaborators.edges - )}` - ) - return collaboratorPermission.repository.collaborators.edges.length > 0 - ? collaboratorPermission.repository.collaborators.edges[0].permission.toLowerCase() - : 'none' + + return 'none' + } catch (error) { + core.debug( + `REST API permission check failed: ${utils.getErrorMessage(error)}` + ) + return 'none' + } } async tryAddReaction( diff --git a/src/utils.ts b/src/utils.ts index 52dc89799..52fb0266d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,13 @@ import * as core from '@actions/core' +export type RepoPermission = + | 'admin' + | 'maintain' + | 'write' + | 'triage' + | 'read' + | 'none' + export function getInputAsArray( name: string, options?: core.InputOptions