Skip to content
This repository was archived by the owner on Oct 11, 2023. It is now read-only.

Commit

Permalink
improve error handling so that the bot is able to communicate errors …
Browse files Browse the repository at this point in the history
…better in comments
  • Loading branch information
joao-paulo-parity committed Oct 9, 2021
1 parent 8e9ea6e commit 6f6624d
Show file tree
Hide file tree
Showing 7 changed files with 886 additions and 660 deletions.
2 changes: 1 addition & 1 deletion src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ fn handle_cmd_result<'a>(
err_output.replace(secret, "${SECRET}");
}
}
log::error!(
log::info!(
"handle_cmd_result: {} failed with error: {}",
cmd_display,
err_output
Expand Down
95 changes: 90 additions & 5 deletions src/companion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ use crate::{
error::*,
github::*,
github_bot::GithubBot,
webhook::{merge, ready_to_merge, wait_to_merge},
Result, COMPANION_LONG_REGEX, COMPANION_PREFIX_REGEX,
webhook::{
get_latest_checks_state, get_latest_statuses_state, merge,
ready_to_merge, wait_to_merge,
},
Result, Status, COMPANION_LONG_REGEX, COMPANION_PREFIX_REGEX,
COMPANION_SHORT_REGEX, PR_HTML_URL_REGEX,
};

Expand Down Expand Up @@ -340,8 +343,9 @@ pub async fn check_all_companions_are_mergeable(
for (html_url, owner, repo, number) in parse_all_companions(body) {
let companion =
github_bot.pull_request(&owner, &repo, number).await?;
let head_sha = companion.head_sha()?;

let is_owner_a_user = companion
let has_user_owner = companion
.user
.as_ref()
.map(|user| {
Expand All @@ -351,7 +355,7 @@ pub async fn check_all_companions_are_mergeable(
.unwrap_or(false)
})
.unwrap_or(false);
if !is_owner_a_user {
if !has_user_owner {
return Err(Error::Message {
msg: format!(
"Companion {} is not owned by a user, therefore processbot would not be able to push the lockfile update to their branch due to a Github limitation (https://github.com/isaacs/github/issues/1681)",
Expand All @@ -372,6 +376,86 @@ pub async fn check_all_companions_are_mergeable(
),
});
}

let target_branch = github_bot
.branch(
&companion.base.repo.owner.login,
&companion.base.repo.name,
&companion.base.ref_field,
)
.await?;

let statuses = get_latest_statuses_state(
github_bot,
&owner,
&repo,
head_sha,
&pr.html_url,
Some(
&target_branch
.protection
.required_status_checks
.contexts,
),
)
.await?;
match statuses {
Status::Success => (),
Status::Pending => {
return Err(Error::InvalidCompanionStatus {
status: Status::Pending,
msg: format!(
"Companion {} has pending required statuses",
html_url
),
});
}
Status::Failure => {
return Err(Error::InvalidCompanionStatus {
status: Status::Failure,
msg: format!(
"Companion {} has failed required statuses",
html_url
),
});
}
};

let checks = get_latest_checks_state(
github_bot,
&owner,
&repo,
&head_sha,
&pr.html_url,
Some(
&target_branch
.protection
.required_status_checks
.contexts,
),
)
.await?;
match checks {
Status::Success => (),
Status::Pending => {
return Err(Error::InvalidCompanionStatus {
status: checks,
msg: format!(
"Companion {} has pending required checks",
html_url
),
});
}
Status::Failure => {
return Err(Error::InvalidCompanionStatus {
status: checks,
msg: format!(
"Companion {} has failed required checks",
html_url
),
});
}
};
}
}
}
Expand Down Expand Up @@ -447,12 +531,13 @@ async fn update_then_merge_companion(
&format!("parity-processbot[bot]"),
&updated_sha,
db,
None,
)
.await?;
}
} else {
return Err(Error::Message {
msg: "Companion PR is missing some API data.".to_string(),
msg: format!("Companion {} is missing some API data", html_url),
});
}

Expand Down
21 changes: 16 additions & 5 deletions src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::Status;
use snafu::Snafu;

// TODO this really should be struct { repository, owner, number }
Expand Down Expand Up @@ -50,11 +51,6 @@ pub enum Error {
actual: String,
},

#[snafu(display("Error getting process info: {}", source))]
ProcessFile {
source: Box<Error>,
},

#[snafu(display("Missing process info."))]
ProcessInfo {
errors: Option<Vec<String>>,
Expand Down Expand Up @@ -195,6 +191,12 @@ pub enum Error {
MergeFailureWillBeSolvedLater {
msg: String,
},

#[snafu(display("{}", msg))]
InvalidCompanionStatus {
status: Status,
msg: String,
},
}

impl Error {
Expand All @@ -207,6 +209,15 @@ impl Error {
},
}
}
pub fn stops_merge_attempt(&self) -> bool {
match self {
Self::WithIssue { source, .. } | Self::Merge { source, .. } => {
source.stops_merge_attempt()
}
Self::MergeFailureWillBeSolvedLater { .. } => false,
_ => true,
}
}
}

impl From<curl::Error> for Error {
Expand Down
35 changes: 25 additions & 10 deletions src/github.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
error::*, utils::parse_bot_comment_from_text, Result, PR_HTML_URL_REGEX,
error::*, utils::parse_bot_comment_from_text,
PlaceholderDeserializationItem, Result, PR_HTML_URL_REGEX,
};
use regex::Regex;
use serde::{Deserialize, Serialize};
Expand All @@ -9,6 +10,19 @@ pub trait HasIssueDetails {
fn get_issue_details(&self) -> Option<IssueDetails>;
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BranchProtectionRequiredStatusChecks {
pub contexts: Vec<String>,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BranchProtection {
pub required_status_checks: BranchProtectionRequiredStatusChecks,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Branch {
pub protection: BranchProtection,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PullRequest {
pub url: String,
Expand Down Expand Up @@ -73,7 +87,7 @@ pub struct Issue {
// User might be missing when it has been deleted
pub user: Option<User>,
pub body: Option<String>,
pub pull_request: Option<IssuePullRequest>,
pub pull_request: Option<PlaceholderDeserializationItem>,
pub repository: Option<Repository>,
pub repository_url: Option<String>,
}
Expand Down Expand Up @@ -172,9 +186,6 @@ pub struct Team {
pub id: i64,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct IssuePullRequest {}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Head {
pub label: Option<String>,
Expand All @@ -188,10 +199,8 @@ pub struct Head {
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Base {
#[serde(rename = "ref")]
pub ref_field: Option<String>,
pub sha: Option<String>,
// Repository might be missing when it has been deleted
pub repo: Option<HeadRepo>,
pub ref_field: String,
pub repo: BaseRepo,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -324,6 +333,12 @@ pub struct HeadRepo {
pub owner: Option<User>,
}

#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct BaseRepo {
pub name: String,
pub owner: User,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CheckRunConclusion {
Expand Down Expand Up @@ -354,7 +369,7 @@ pub struct WebhookIssueComment {
pub number: i64,
pub html_url: String,
pub repository_url: Option<String>,
pub pull_request: Option<IssuePullRequest>,
pub pull_request: Option<PlaceholderDeserializationItem>,
}

impl HasIssueDetails for WebhookIssueComment {
Expand Down
17 changes: 16 additions & 1 deletion src/github_bot/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::{github, Result};
use super::GithubBot;

impl GithubBot {
/// Returns a repository with the given name.
pub async fn repository<A>(
&self,
owner: &str,
Expand All @@ -20,6 +19,22 @@ impl GithubBot {
);
self.client.get(url).await
}

pub async fn branch(
&self,
owner: &str,
repo: &str,
branch: &str,
) -> Result<github::Branch> {
let url = format!(
"{}/repos/{}/{}/branches/{}",
Self::BASE_URL,
owner,
repo,
branch
);
self.client.get(url).await
}
}

/*
Expand Down
12 changes: 12 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use serde::{Deserialize, Serialize};

mod auth;
pub mod bamboo;
pub mod cmd;
Expand All @@ -24,6 +26,7 @@ pub mod webhook;

pub type Result<T, E = error::Error> = std::result::Result<T, E>;

#[derive(Debug)]
pub enum Status {
Success,
Pending,
Expand All @@ -43,3 +46,12 @@ pub enum CommentCommand {
BurninRequest,
CompareReleaseRequest,
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PlaceholderDeserializationItem {}

pub enum MergeCancelOutcome {
ShaDidNotExist,
WasCancelled,
WasNotCancelled,
}
Loading

0 comments on commit 6f6624d

Please sign in to comment.