|
1 | 1 | use anyhow::anyhow;
|
2 |
| -use octocrab::params::checks::{CheckRunOutput, CheckRunStatus}; |
| 2 | +use octocrab::params::checks::{CheckRunConclusion, CheckRunOutput, CheckRunStatus}; |
3 | 3 | use std::future::Future;
|
4 | 4 | use std::sync::Arc;
|
5 | 5 | use tokio::sync::mpsc;
|
6 | 6 | use tracing::Instrument;
|
7 | 7 |
|
8 | 8 | use crate::BorsContext;
|
9 |
| -use crate::bors::comment::{auto_build_started_comment, auto_build_succeeded_comment}; |
| 9 | +use crate::bors::comment::{ |
| 10 | + auto_build_push_failed_comment, auto_build_started_comment, auto_build_succeeded_comment, |
| 11 | +}; |
10 | 12 | use crate::bors::{PullRequestStatus, RepositoryState};
|
11 | 13 | use crate::database::{BuildStatus, PullRequestModel};
|
12 | 14 | use crate::github::api::client::GithubRepositoryClient;
|
@@ -114,7 +116,36 @@ pub async fn merge_queue_tick(ctx: Arc<BorsContext>) -> anyhow::Result<()> {
|
114 | 116 | )
|
115 | 117 | .await?;
|
116 | 118 | }
|
117 |
| - Err(_) => {} |
| 119 | + Err(error) => { |
| 120 | + tracing::error!( |
| 121 | + "Failed to push PR {pr_num} to base branch: {:?}", |
| 122 | + error |
| 123 | + ); |
| 124 | + |
| 125 | + if let Some(check_run_id) = auto_build.check_run_id { |
| 126 | + if let Err(error) = repo |
| 127 | + .client |
| 128 | + .update_check_run( |
| 129 | + check_run_id as u64, |
| 130 | + CheckRunStatus::Completed, |
| 131 | + Some(CheckRunConclusion::Failure), |
| 132 | + None, |
| 133 | + ) |
| 134 | + .await |
| 135 | + { |
| 136 | + tracing::error!( |
| 137 | + "Could not update check run {check_run_id}: {error:?}" |
| 138 | + ); |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + ctx.db |
| 143 | + .update_build_status(auto_build, BuildStatus::Failure) |
| 144 | + .await?; |
| 145 | + |
| 146 | + let comment = auto_build_push_failed_comment(&error.to_string()); |
| 147 | + repo.client.post_comment(pr.number, comment).await?; |
| 148 | + } |
118 | 149 | };
|
119 | 150 |
|
120 | 151 | // Break to give GitHub time to update the base branch.
|
@@ -315,7 +346,7 @@ pub fn start_merge_queue(ctx: Arc<BorsContext>) -> (MergeQueueSender, impl Futur
|
315 | 346 | #[cfg(test)]
|
316 | 347 | mod tests {
|
317 | 348 |
|
318 |
| - use octocrab::params::checks::CheckRunStatus; |
| 349 | + use octocrab::params::checks::{CheckRunConclusion, CheckRunStatus}; |
319 | 350 |
|
320 | 351 | use crate::{
|
321 | 352 | bors::merge_queue::{AUTO_BRANCH_NAME, AUTO_BUILD_CHECK_RUN_NAME},
|
@@ -383,4 +414,87 @@ mod tests {
|
383 | 414 | })
|
384 | 415 | .await;
|
385 | 416 | }
|
| 417 | + |
| 418 | + #[sqlx::test] |
| 419 | + async fn auto_build_push_fail_comment(pool: sqlx::PgPool) { |
| 420 | + run_test(pool, |mut tester| async { |
| 421 | + tester.create_branch(AUTO_BRANCH_NAME).expect_suites(1); |
| 422 | + |
| 423 | + tester.post_comment("@bors r+").await?; |
| 424 | + tester.expect_comments(1).await; |
| 425 | + |
| 426 | + tester.process_merge_queue().await; |
| 427 | + tester.expect_comments(1).await; |
| 428 | + |
| 429 | + tester.workflow_success(tester.auto_branch()).await?; |
| 430 | + tester.expect_comments(1).await; |
| 431 | + |
| 432 | + tester.default_repo().lock().push_error = true; |
| 433 | + |
| 434 | + tester.process_merge_queue().await; |
| 435 | + insta::assert_snapshot!( |
| 436 | + tester.get_comment().await?, |
| 437 | + @":eyes: Test was successful, but fast-forwarding failed: IO error" |
| 438 | + ); |
| 439 | + |
| 440 | + Ok(tester) |
| 441 | + }) |
| 442 | + .await; |
| 443 | + } |
| 444 | + |
| 445 | + #[sqlx::test] |
| 446 | + async fn auto_build_push_fail_updates_check_run(pool: sqlx::PgPool) { |
| 447 | + run_test(pool, |mut tester| async { |
| 448 | + tester.create_branch(AUTO_BRANCH_NAME).expect_suites(1); |
| 449 | + |
| 450 | + tester.post_comment("@bors r+").await?; |
| 451 | + tester.expect_comments(1).await; |
| 452 | + |
| 453 | + tester.process_merge_queue().await; |
| 454 | + tester.expect_comments(1).await; |
| 455 | + |
| 456 | + tester.workflow_success(tester.auto_branch()).await?; |
| 457 | + tester.expect_comments(1).await; |
| 458 | + |
| 459 | + tester.default_repo().lock().push_error = true; |
| 460 | + |
| 461 | + tester.process_merge_queue().await; |
| 462 | + tester.expect_comments(1).await; |
| 463 | + |
| 464 | + tester.expect_check_run( |
| 465 | + &tester.default_pr().await.get_gh_pr().head_sha, |
| 466 | + AUTO_BUILD_CHECK_RUN_NAME, |
| 467 | + AUTO_BUILD_CHECK_RUN_NAME, |
| 468 | + CheckRunStatus::Completed, |
| 469 | + Some(CheckRunConclusion::Failure), |
| 470 | + ); |
| 471 | + Ok(tester) |
| 472 | + }) |
| 473 | + .await; |
| 474 | + } |
| 475 | + |
| 476 | + #[sqlx::test] |
| 477 | + async fn auto_build_push_fail_in_db(pool: sqlx::PgPool) { |
| 478 | + run_test(pool, |mut tester| async { |
| 479 | + tester.create_branch(AUTO_BRANCH_NAME).expect_suites(1); |
| 480 | + |
| 481 | + tester.post_comment("@bors r+").await?; |
| 482 | + tester.expect_comments(1).await; |
| 483 | + |
| 484 | + tester.process_merge_queue().await; |
| 485 | + tester.expect_comments(1).await; |
| 486 | + |
| 487 | + tester.workflow_success(tester.auto_branch()).await?; |
| 488 | + tester.expect_comments(1).await; |
| 489 | + |
| 490 | + tester.default_repo().lock().push_error = true; |
| 491 | + |
| 492 | + tester.process_merge_queue().await; |
| 493 | + tester.expect_comments(1).await; |
| 494 | + |
| 495 | + tester.default_pr().await.expect_auto_build_failed(); |
| 496 | + Ok(tester) |
| 497 | + }) |
| 498 | + .await; |
| 499 | + } |
386 | 500 | }
|
0 commit comments