diff --git a/src/github.rs b/src/github.rs index c3a8aa57..aebb3ce6 100644 --- a/src/github.rs +++ b/src/github.rs @@ -554,6 +554,11 @@ pub enum Selection<'a, T: ?Sized> { Except(&'a T), } +#[derive(Debug, serde::Deserialize)] +pub struct CollaboratorPermission { + pub permission: String, +} + #[derive(Debug, Clone, PartialEq, Eq)] pub struct IssueRepository { pub organization: String, @@ -594,6 +599,16 @@ impl IssueRepository { } } } + + pub(crate) async fn collaborator_permission( + &self, + client: &GithubClient, + username: &str, + ) -> anyhow::Result { + let url = format!("{}/collaborators/{username}/permission", self.url(client)); + let permission = client.json(client.get(&url)).await?; + Ok(permission) + } } impl Issue { diff --git a/src/handlers/review_submitted.rs b/src/handlers/review_submitted.rs index 0c2b8363..c07623b2 100644 --- a/src/handlers/review_submitted.rs +++ b/src/handlers/review_submitted.rs @@ -1,3 +1,5 @@ +use anyhow::Context as _; + use crate::github::{Issue, IssueCommentAction, IssueCommentEvent, Label, PullRequestReviewState}; use crate::{config::ReviewSubmittedConfig, github::Event, handlers::Context}; @@ -21,7 +23,19 @@ pub(crate) async fn handle( return Ok(()); } - if event.issue.assignees.contains(&event.comment.user) { + // Let's switch the review labels if the user who issued the changes requested: + // - is one of the assignees + // - or has write/admin permission on the repository + if event.issue.assignees.contains(&event.comment.user) || { + let perm = event + .issue + .repository() + .collaborator_permission(&ctx.github, &event.comment.user.login) + .await + .context("failed to get the user repository permission")?; + + perm.permission == "write" || perm.permission == "admin" + } { // Remove review labels event .issue