Skip to content
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

Add config options to change labels for draft/closed/reopened PRs #1768

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ pub(crate) struct Config {
pub(crate) github_releases: Option<GitHubReleasesConfig>,
pub(crate) review_submitted: Option<ReviewSubmittedConfig>,
pub(crate) review_requested: Option<ReviewRequestedConfig>,
pub(crate) converted_to_draft: Option<ConvertedToDraftConfig>,
pub(crate) ready_for_review: Option<ReadyForReviewConfig>,
pub(crate) closed_pr: Option<ClosedPrConfig>,
pub(crate) shortcut: Option<ShortcutConfig>,
pub(crate) note: Option<NoteConfig>,
pub(crate) mentions: Option<MentionsConfig>,
Expand Down Expand Up @@ -209,6 +212,12 @@ pub(crate) struct AutolabelLabelConfig {
#[serde(default)]
pub(crate) new_pr: bool,
#[serde(default)]
pub(crate) new_draft_pr: bool,
#[serde(default)]
pub(crate) reopened_pr: bool,
#[serde(default)]
pub(crate) reopened_draft_pr: bool,
#[serde(default)]
pub(crate) new_issue: bool,
}

Expand Down Expand Up @@ -289,6 +298,27 @@ pub(crate) struct ReviewRequestedConfig {
pub(crate) add_labels: Vec<String>,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ConvertedToDraftConfig {
pub(crate) remove_labels: Vec<String>,
pub(crate) add_labels: Vec<String>,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ReadyForReviewConfig {
pub(crate) remove_labels: Vec<String>,
pub(crate) add_labels: Vec<String>,
}

#[derive(PartialEq, Eq, Debug, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub(crate) struct ClosedPrConfig {
pub(crate) remove_labels: Vec<String>,
pub(crate) add_labels: Vec<String>,
}

pub(crate) async fn get(
gh: &GithubClient,
repo: &Repository,
Expand Down
6 changes: 6 additions & 0 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ impl fmt::Display for HandlerError {
mod assign;
mod autolabel;
mod close;
mod closed_pr;
mod converted_to_draft;
pub mod docs_update;
mod github_releases;
mod glacier;
Expand All @@ -39,6 +41,7 @@ mod notification;
mod notify_zulip;
mod ping;
mod prioritize;
mod ready_for_review;
mod relabel;
mod review_requested;
mod review_submitted;
Expand Down Expand Up @@ -167,6 +170,9 @@ issue_handlers! {
no_merges,
notify_zulip,
review_requested,
converted_to_draft,
ready_for_review,
closed_pr,
validate_config,
}

Expand Down
32 changes: 23 additions & 9 deletions src/handlers/autolabel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ pub(super) async fn parse_input(
// FIXME: This will re-apply labels after a push that the user had tried to
// remove. Not much can be done about that currently; the before/after on
// synchronize may be straddling a rebase, which will break diff generation.
if event.action == IssuesAction::Opened || event.action == IssuesAction::Synchronize {
if matches!(
&event.action,
IssuesAction::Opened | IssuesAction::Reopened | IssuesAction::Synchronize
) {
let files = event
.issue
.diff(&ctx.github)
Expand Down Expand Up @@ -69,21 +72,32 @@ pub(super) async fn parse_input(
name: label.to_owned(),
});
}
if cfg.new_pr && event.action == IssuesAction::Opened {
autolabels.push(Label {
name: label.to_owned(),
});
}
}

if event.issue.pull_request.is_none()
&& cfg.new_issue
&& event.action == IssuesAction::Opened
if event.issue.is_pr()
&& matches!(event.action, IssuesAction::Opened)
&& ((cfg.new_pr && !event.issue.draft) || (cfg.new_draft_pr && event.issue.draft))
{
autolabels.push(Label {
name: label.to_owned(),
});
}

if event.issue.is_pr()
&& matches!(event.action, IssuesAction::Reopened)
&& ((cfg.reopened_pr && !event.issue.draft)
|| (cfg.reopened_draft_pr && event.issue.draft))
{
autolabels.push(Label {
name: label.to_owned(),
});
}

if !event.issue.is_pr() && cfg.new_issue && event.action == IssuesAction::Opened {
autolabels.push(Label {
name: label.to_owned(),
});
}
}

if !autolabels.is_empty() {
Expand Down
44 changes: 44 additions & 0 deletions src/handlers/closed_pr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::config::ClosedPrConfig;
use crate::github::{IssuesAction, IssuesEvent, Label};
use crate::handlers::Context;

pub(crate) struct ClosedPrInput {}

pub(crate) async fn parse_input(
_ctx: &Context,
event: &IssuesEvent,
_config: Option<&ClosedPrConfig>,
) -> Result<Option<ClosedPrInput>, String> {
// PR author requests a review from one of the assignees

match &event.action {
IssuesAction::Closed if event.issue.is_pr() => Ok(Some(ClosedPrInput {})),
_ => Ok(None),
}
}

pub(crate) async fn handle_input(
ctx: &Context,
config: &ClosedPrConfig,
event: &IssuesEvent,
ClosedPrInput {}: ClosedPrInput,
) -> anyhow::Result<()> {
event
.issue
.add_labels(
&ctx.github,
config
.add_labels
.iter()
.cloned()
.map(|name| Label { name })
.collect(),
)
.await?;

for label in &config.remove_labels {
event.issue.remove_label(&ctx.github, label).await?;
}

Ok(())
}
44 changes: 44 additions & 0 deletions src/handlers/converted_to_draft.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::config::ConvertedToDraftConfig;
use crate::github::{IssuesAction, IssuesEvent, Label};
use crate::handlers::Context;

pub(crate) struct ConvertedToDraftInput {}

pub(crate) async fn parse_input(
_ctx: &Context,
event: &IssuesEvent,
_config: Option<&ConvertedToDraftConfig>,
) -> Result<Option<ConvertedToDraftInput>, String> {
// PR author requests a review from one of the assignees

match &event.action {
IssuesAction::ConvertedToDraft => Ok(Some(ConvertedToDraftInput {})),
_ => Ok(None),
}
}

pub(crate) async fn handle_input(
ctx: &Context,
config: &ConvertedToDraftConfig,
event: &IssuesEvent,
ConvertedToDraftInput {}: ConvertedToDraftInput,
) -> anyhow::Result<()> {
event
.issue
.add_labels(
&ctx.github,
config
.add_labels
.iter()
.cloned()
.map(|name| Label { name })
.collect(),
)
.await?;

for label in &config.remove_labels {
event.issue.remove_label(&ctx.github, label).await?;
}

Ok(())
}
44 changes: 44 additions & 0 deletions src/handlers/ready_for_review.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use crate::config::ReadyForReviewConfig;
use crate::github::{IssuesAction, IssuesEvent, Label};
use crate::handlers::Context;

pub(crate) struct ReadyForReviewInput {}

pub(crate) async fn parse_input(
_ctx: &Context,
event: &IssuesEvent,
_config: Option<&ReadyForReviewConfig>,
) -> Result<Option<ReadyForReviewInput>, String> {
// PR author requests a review from one of the assignees

match &event.action {
IssuesAction::ReadyForReview => Ok(Some(ReadyForReviewInput {})),
_ => Ok(None),
}
}

pub(crate) async fn handle_input(
ctx: &Context,
config: &ReadyForReviewConfig,
event: &IssuesEvent,
ReadyForReviewInput {}: ReadyForReviewInput,
) -> anyhow::Result<()> {
event
.issue
.add_labels(
&ctx.github,
config
.add_labels
.iter()
.cloned()
.map(|name| Label { name })
.collect(),
)
.await?;

for label in &config.remove_labels {
event.issue.remove_label(&ctx.github, label).await?;
}

Ok(())
}
Loading