Skip to content

Commit b57e62b

Browse files
authored
Merge pull request #364 from Kobzol/strip-try-build-pr-message
Strip PR description from merge message in try builds
2 parents f978428 + 4f80282 commit b57e62b

File tree

5 files changed

+187
-27
lines changed

5 files changed

+187
-27
lines changed

src/bors/handlers/trybuild.rs

Lines changed: 133 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::github::{CommitSha, GithubUser, LabelTrigger, MergeError, PullRequest
1919
use crate::permissions::PermissionType;
2020
use crate::utils::text::suppress_github_mentions;
2121
use anyhow::{Context, anyhow};
22+
use itertools::Itertools;
2223
use octocrab::params::checks::CheckRunConclusion;
2324
use octocrab::params::checks::CheckRunOutput;
2425
use octocrab::params::checks::CheckRunStatus;
@@ -87,7 +88,11 @@ pub(super) async fn command_try_build(
8788
&repo.client,
8889
&pr.github.head.sha,
8990
&base_sha,
90-
&auto_merge_commit_message(pr, repo.client.repository(), "<try>", jobs),
91+
&create_merge_commit_message(
92+
pr,
93+
repo.client.repository(),
94+
MergeType::Try { try_jobs: jobs },
95+
),
9196
)
9297
.await?
9398
{
@@ -339,28 +344,61 @@ fn get_pending_build(pr: &PullRequestModel) -> Option<&BuildModel> {
339344
.and_then(|b| (b.status == BuildStatus::Pending).then_some(b))
340345
}
341346

342-
fn auto_merge_commit_message(
347+
/// Prefix used to specify custom try jobs in PR descriptions.
348+
const CUSTOM_TRY_JOB_PREFIX: &str = "try-job:";
349+
350+
enum MergeType {
351+
Try { try_jobs: Vec<String> },
352+
}
353+
354+
fn create_merge_commit_message(
343355
pr: &PullRequestData,
344356
name: &GithubRepoName,
345-
reviewer: &str,
346-
jobs: Vec<String>,
357+
merge_type: MergeType,
347358
) -> String {
348359
let pr_number = pr.number();
360+
361+
let reviewer = match &merge_type {
362+
MergeType::Try { .. } => "<try>",
363+
};
364+
365+
let mut pr_description = suppress_github_mentions(&pr.github.message);
366+
match &merge_type {
367+
// Strip all PR text for try builds, to avoid useless issue pings on the repository.
368+
// Only keep any lines starting with `CUSTOM_TRY_JOB_PREFIX`.
369+
MergeType::Try { try_jobs } => {
370+
// If we do not have any custom try jobs, keep the ones that might be in the PR
371+
// description.
372+
pr_description = if try_jobs.is_empty() {
373+
pr_description
374+
.lines()
375+
.map(|l| l.trim())
376+
.filter(|l| l.starts_with(CUSTOM_TRY_JOB_PREFIX))
377+
.join("\n")
378+
} else {
379+
// If we do have custom jobs, ignore the original description completely
380+
String::new()
381+
};
382+
}
383+
};
384+
349385
let mut message = format!(
350386
r#"Auto merge of {repo_owner}/{repo_name}#{pr_number} - {pr_label}, r={reviewer}
351387
{pr_title}
352388
353-
{pr_message}"#,
389+
{pr_description}"#,
354390
pr_label = pr.github.head_label,
355391
pr_title = pr.github.title,
356-
pr_message = suppress_github_mentions(&pr.github.message),
357392
repo_owner = name.owner(),
358393
repo_name = name.name()
359394
);
360395

361-
// if jobs is empty, try-job won't be added to the message
362-
for job in jobs {
363-
message.push_str(&format!("\ntry-job: {}", job));
396+
match merge_type {
397+
MergeType::Try { try_jobs } => {
398+
for job in try_jobs {
399+
message.push_str(&format!("\n{CUSTOM_TRY_JOB_PREFIX} {}", job));
400+
}
401+
}
364402
}
365403
message
366404
}
@@ -469,6 +507,92 @@ mod tests {
469507
.await;
470508
}
471509

510+
#[sqlx::test]
511+
async fn try_commit_message_strip_description(pool: sqlx::PgPool) {
512+
run_test(pool, async |tester: &mut BorsTester| {
513+
tester
514+
.edit_pr(default_repo_name(), default_pr_number(), |pr| {
515+
pr.description = r"This is a very good PR.
516+
517+
It fixes so many issues, sir."
518+
.to_string();
519+
})
520+
.await?;
521+
522+
tester.post_comment("@bors try").await?;
523+
tester.expect_comments(1).await;
524+
525+
insta::assert_snapshot!(tester.get_branch_commit_message(&tester.try_branch()), @r"
526+
Auto merge of rust-lang/borstest#1 - pr-1, r=<try>
527+
PR #1
528+
");
529+
Ok(())
530+
})
531+
.await;
532+
}
533+
534+
#[sqlx::test]
535+
async fn try_commit_message_strip_description_keep_try_jobs(pool: sqlx::PgPool) {
536+
run_test(pool, async |tester: &mut BorsTester| {
537+
tester
538+
.edit_pr(default_repo_name(), default_pr_number(), |pr| {
539+
pr.description = r"This is a very good PR.
540+
541+
try-job: Foo
542+
543+
It fixes so many issues, sir.
544+
545+
try-job: Bar
546+
"
547+
.to_string();
548+
})
549+
.await?;
550+
551+
tester.post_comment("@bors try").await?;
552+
tester.expect_comments(1).await;
553+
554+
insta::assert_snapshot!(tester.get_branch_commit_message(&tester.try_branch()), @r"
555+
Auto merge of rust-lang/borstest#1 - pr-1, r=<try>
556+
PR #1
557+
558+
try-job: Foo
559+
try-job: Bar
560+
");
561+
Ok(())
562+
})
563+
.await;
564+
}
565+
566+
#[sqlx::test]
567+
async fn try_commit_message_overwrite_try_jobs(pool: sqlx::PgPool) {
568+
run_test(pool, async |tester: &mut BorsTester| {
569+
tester
570+
.edit_pr(default_repo_name(), default_pr_number(), |pr| {
571+
pr.description = r"This is a very good PR.
572+
573+
try-job: Foo
574+
try-job: Bar
575+
"
576+
.to_string();
577+
})
578+
.await?;
579+
580+
tester.post_comment("@bors try jobs=Baz,Baz2").await?;
581+
tester.expect_comments(1).await;
582+
583+
insta::assert_snapshot!(tester.get_branch_commit_message(&tester.try_branch()), @r"
584+
Auto merge of rust-lang/borstest#1 - pr-1, r=<try>
585+
PR #1
586+
587+
588+
try-job: Baz
589+
try-job: Baz2
590+
");
591+
Ok(())
592+
})
593+
.await;
594+
}
595+
472596
#[sqlx::test]
473597
async fn try_merge_branch_history(pool: sqlx::PgPool) {
474598
let gh = run_test(pool, async |tester| {

src/github/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl From<octocrab::models::Author> for GithubUser {
8383
}
8484
}
8585

86-
#[derive(Clone, Debug, PartialEq)]
86+
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
8787
pub struct CommitSha(pub String);
8888

8989
impl From<String> for CommitSha {

src/tests/mocks/bors.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use crate::{
4747

4848
/// How long should we wait before we timeout a test.
4949
/// You can increase this if you want to do interactive debugging.
50-
const TEST_TIMEOUT: Duration = Duration::from_secs(10);
50+
const TEST_TIMEOUT: Duration = Duration::from_secs(100);
5151

5252
pub fn default_cmd_prefix() -> CommandPrefix {
5353
"@bors".to_string().into()
@@ -277,6 +277,13 @@ impl BorsTester {
277277
.clone()
278278
}
279279

280+
pub fn get_branch_commit_message(&self, branch: &Branch) -> String {
281+
self.github
282+
.default_repo()
283+
.lock()
284+
.get_commit_message(branch.get_sha())
285+
}
286+
280287
pub async fn push_to_branch(&mut self, branch: &str) -> anyhow::Result<()> {
281288
self.send_webhook("push", GitHubPushEventPayload::new(branch))
282289
.await

src/tests/mocks/pull_request.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -199,28 +199,43 @@ pub struct GitHubPullRequest {
199199

200200
impl From<PullRequest> for GitHubPullRequest {
201201
fn from(pr: PullRequest) -> Self {
202-
let number = pr.number.0;
202+
let PullRequest {
203+
number,
204+
repo: _,
205+
added_labels: _,
206+
removed_labels: _,
207+
comment_counter: _,
208+
head_sha,
209+
author,
210+
base_branch,
211+
mergeable_state,
212+
status,
213+
merged_at,
214+
closed_at,
215+
assignees,
216+
description,
217+
} = pr;
203218
GitHubPullRequest {
204-
user: pr.author.clone().into(),
219+
user: author.clone().into(),
205220
url: "https://test.com".to_string(),
206-
id: number + 1000,
221+
id: number.0 + 1000,
207222
title: format!("PR #{number}"),
208-
body: format!("Description of PR #{number}"),
209-
mergeable_state: pr.mergeable_state,
210-
draft: pr.status == PullRequestStatus::Draft,
211-
number,
223+
body: description,
224+
mergeable_state,
225+
draft: status == PullRequestStatus::Draft,
226+
number: number.0,
212227
head: Box::new(GitHubHead {
213228
label: format!("pr-{number}"),
214229
ref_field: format!("pr-{number}"),
215-
sha: pr.head_sha,
230+
sha: head_sha,
216231
}),
217232
base: Box::new(GitHubBase {
218-
ref_field: pr.base_branch.get_name().to_string(),
219-
sha: pr.base_branch.get_sha().to_string(),
233+
ref_field: base_branch.get_name().to_string(),
234+
sha: base_branch.get_sha().to_string(),
220235
}),
221-
merged_at: pr.merged_at,
222-
closed_at: pr.closed_at,
223-
assignees: pr.assignees.into_iter().map(Into::into).collect(),
236+
merged_at,
237+
closed_at,
238+
assignees: assignees.into_iter().map(Into::into).collect(),
224239
}
225240
}
226241
}

src/tests/mocks/repository.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub struct PullRequest {
5454
pub merged_at: Option<DateTime<Utc>>,
5555
pub closed_at: Option<DateTime<Utc>>,
5656
pub assignees: Vec<User>,
57+
pub description: String,
5758
}
5859

5960
impl PullRequest {
@@ -76,6 +77,7 @@ impl PullRequest {
7677
merged_at: None,
7778
closed_at: None,
7879
assignees: Vec::new(),
80+
description: format!("Description of PR {number}"),
7981
}
8082
}
8183
}
@@ -153,6 +155,7 @@ pub struct Repo {
153155
pub permissions: Permissions,
154156
pub config: String,
155157
pub branches: Vec<Branch>,
158+
pub commit_messages: HashMap<String, String>,
156159
pub workflows_cancelled_by_bors: Vec<u64>,
157160
pub workflow_cancel_error: bool,
158161
/// All workflows that we know about from the side of the test.
@@ -172,6 +175,7 @@ impl Repo {
172175
config,
173176
pull_requests: Default::default(),
174177
branches: vec![Branch::default()],
178+
commit_messages: Default::default(),
175179
workflows_cancelled_by_bors: vec![],
176180
workflow_cancel_error: false,
177181
workflow_runs: vec![],
@@ -243,6 +247,18 @@ impl Repo {
243247
self.pr_push_counter += 1;
244248
self.pr_push_counter
245249
}
250+
251+
pub fn get_commit_message(&self, sha: &str) -> String {
252+
self.commit_messages
253+
.get(sha)
254+
.expect("Commit message not found")
255+
.clone()
256+
}
257+
258+
pub fn set_commit_message(&mut self, sha: &str, message: &str) {
259+
self.commit_messages
260+
.insert(sha.to_string(), message.to_string());
261+
}
246262
}
247263

248264
/// Represents the default repository for tests.
@@ -285,7 +301,6 @@ pub fn default_repo_name() -> GithubRepoName {
285301
pub struct Branch {
286302
name: String,
287303
sha: String,
288-
commit_message: String,
289304
sha_history: Vec<String>,
290305
merge_counter: u64,
291306
pub merge_conflict: bool,
@@ -296,7 +311,6 @@ impl Branch {
296311
Self {
297312
name: name.to_string(),
298313
sha: sha.to_string(),
299-
commit_message: format!("Commit {sha}"),
300314
sha_history: vec![],
301315
merge_counter: 0,
302316
merge_conflict: false,
@@ -549,7 +563,7 @@ async fn mock_merge_branch(repo: Arc<Mutex<Repo>>, mock_server: &MockServer) {
549563
);
550564
base_branch.merge_counter += 1;
551565
base_branch.set_to_sha(&merge_sha);
552-
base_branch.commit_message = data.commit_message;
566+
repo.set_commit_message(&merge_sha, &data.commit_message);
553567

554568
#[derive(serde::Serialize)]
555569
struct MergeResponse {

0 commit comments

Comments
 (0)