Skip to content

Commit 2579367

Browse files
authored
Merge pull request #1968 from Kobzol/autolabel-draft
Do not apply labels in autolabel when opening a draft PR
2 parents f83b29d + 2eb3d58 commit 2579367

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

src/handlers/autolabel.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::db::issue_data::IssueData;
12
use crate::{
23
config::AutolabelConfig,
34
github::{IssuesAction, IssuesEvent, Label},
@@ -6,6 +7,16 @@ use crate::{
67
use anyhow::Context as _;
78
use tracing as log;
89

10+
/// Key for the state in the database
11+
const AUTOLABEL_KEY: &str = "autolabel";
12+
13+
/// State stored in the database
14+
#[derive(Debug, Default, PartialEq, Clone, serde::Deserialize, serde::Serialize)]
15+
struct AutolabelState {
16+
/// If true, then `autolabel.new_pr` labels have already been applied to this PR.
17+
new_pr_labels_applied: bool,
18+
}
19+
920
pub(super) struct AutolabelInput {
1021
add: Vec<Label>,
1122
remove: Vec<Label>,
@@ -26,7 +37,16 @@ pub(super) async fn parse_input(
2637
// FIXME: This will re-apply labels after a push that the user had tried to
2738
// remove. Not much can be done about that currently; the before/after on
2839
// synchronize may be straddling a rebase, which will break diff generation.
29-
if event.action == IssuesAction::Opened || event.action == IssuesAction::Synchronize {
40+
if matches!(
41+
event.action,
42+
IssuesAction::Opened | IssuesAction::Synchronize | IssuesAction::ReadyForReview
43+
) {
44+
let mut db = ctx.db.get().await;
45+
let mut state: IssueData<'_, AutolabelState> =
46+
IssueData::load(&mut db, &event.issue, AUTOLABEL_KEY)
47+
.await
48+
.map_err(|e| e.to_string())?;
49+
3050
let files = event
3151
.issue
3252
.diff(&ctx.github)
@@ -69,11 +89,19 @@ pub(super) async fn parse_input(
6989
name: label.to_owned(),
7090
});
7191
}
72-
if cfg.new_pr && event.action == IssuesAction::Opened {
73-
autolabels.push(Label {
74-
name: label.to_owned(),
75-
});
76-
}
92+
}
93+
94+
// Treat the following situations as a "new PR":
95+
// 1) New PRs opened as non-draft
96+
// 2) PRs opened as draft that are marked as "ready for review" for the first time.
97+
let is_new_non_draft_pr = event.action == IssuesAction::Opened && !event.issue.draft;
98+
let is_first_time_ready_for_review =
99+
event.action == IssuesAction::ReadyForReview && !state.data.new_pr_labels_applied;
100+
if cfg.new_pr && (is_new_non_draft_pr || is_first_time_ready_for_review) {
101+
autolabels.push(Label {
102+
name: label.to_owned(),
103+
});
104+
state.data.new_pr_labels_applied = true;
77105
}
78106

79107
if event.issue.pull_request.is_none()
@@ -86,6 +114,8 @@ pub(super) async fn parse_input(
86114
}
87115
}
88116

117+
state.save().await.map_err(|e| e.to_string())?;
118+
89119
if !autolabels.is_empty() {
90120
return Ok(Some(AutolabelInput {
91121
add: autolabels,

0 commit comments

Comments
 (0)