Skip to content

Commit

Permalink
feat: added min duaration checking in RepositorConfig
Browse files Browse the repository at this point in the history
 Changes to be committed:
	modified:   src/bors/event.rs
	modified:   src/bors/handlers/workflow.rs
	modified:   src/config.rs
	modified:   src/github/webhook.rs
  • Loading branch information
sriganeshres committed Dec 10, 2024
1 parent 2deb846 commit 34b52b3
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 14 deletions.
2 changes: 2 additions & 0 deletions src/bors/event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::database::{WorkflowStatus, WorkflowType};
use crate::github::{CommitSha, GithubRepoName, GithubUser, PullRequest, PullRequestNumber};
use chrono::Duration;
use octocrab::models::RunId;

#[derive(Debug)]
Expand Down Expand Up @@ -88,6 +89,7 @@ pub struct WorkflowCompleted {
pub commit_sha: CommitSha,
pub run_id: RunId,
pub status: WorkflowStatus,
pub running_time: Option<Duration>,
}

#[derive(Debug)]
Expand Down
20 changes: 19 additions & 1 deletion src/bors/handlers/workflow.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::sync::Arc;
use std::time::Duration;

use crate::bors::comment::try_build_succeeded_comment;
use crate::bors::event::{CheckSuiteCompleted, WorkflowCompleted, WorkflowStarted};
Expand Down Expand Up @@ -61,12 +62,29 @@ pub(super) async fn handle_workflow_started(
pub(super) async fn handle_workflow_completed(
repo: Arc<RepositoryState>,
db: Arc<PgDbClient>,
payload: WorkflowCompleted,
mut payload: WorkflowCompleted,
) -> anyhow::Result<()> {
if !is_bors_observed_branch(&payload.branch) {
return Ok(());
}

if let Some(running_time) = payload.running_time {
let running_time_as_duration =
chrono::Duration::to_std(&running_time).unwrap_or(Duration::from_secs(0));
if let Some(min_ci_time) = repo.config.load().min_ci_time {
if running_time_as_duration < min_ci_time {
payload.status = WorkflowStatus::Failure;
tracing::warn!(
"Workflow running time is less than the minimum CI duration: {:?} < {:?}",
running_time_as_duration,
min_ci_time
);
}
}
} else {
tracing::warn!("Running time is not available.");
}

tracing::info!("Updating status of workflow to {:?}", payload.status);
db.update_workflow_status(*payload.run_id, payload.status)
.await?;
Expand Down
27 changes: 26 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,23 @@ pub struct RepositoryConfig {
pub timeout: Duration,
#[serde(default, deserialize_with = "deserialize_labels")]
pub labels: HashMap<LabelTrigger, Vec<LabelModification>>,
#[serde(default, deserialize_with = "deserialize_duration_from_secs_opt")]
pub min_ci_time: Option<Duration>,
}

fn default_timeout() -> Duration {
Duration::from_secs(3600)
}

fn deserialize_duration_from_secs_opt<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
where
D: Deserializer<'de>,
{
// Allow null values for the option
let maybe_seconds = Option::<u64>::deserialize(deserializer)?;
Ok(maybe_seconds.map(Duration::from_secs))
}

fn deserialize_duration_from_secs<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
Expand Down Expand Up @@ -124,7 +135,7 @@ where

#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use std::{collections::BTreeMap, time::Duration};

use crate::config::{default_timeout, RepositoryConfig};

Expand All @@ -142,6 +153,20 @@ mod tests {
assert_eq!(config.timeout.as_secs(), 3600);
}

#[test]
fn deserialize_min_ci_time_empty() {
let content = "";
let config = load_config(content);
assert_eq!(config.min_ci_time, None);
}

#[test]
fn deserialize_min_ci_time() {
let content = "min_ci_time = 3600";
let config = load_config(content);
assert_eq!(config.min_ci_time, Some(Duration::from_secs(3600)));
}

#[test]
fn deserialize_labels() {
let content = r#"[labels]
Expand Down
41 changes: 29 additions & 12 deletions src/github/webhook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,18 +273,29 @@ fn parse_workflow_run_events(body: &[u8]) -> anyhow::Result<Option<BorsEvent>> {
url: payload.workflow_run.html_url.into(),
},
))),
"completed" => Some(BorsEvent::Repository(
BorsRepositoryEvent::WorkflowCompleted(WorkflowCompleted {
repository: repository_name,
branch: payload.workflow_run.head_branch,
commit_sha: CommitSha(payload.workflow_run.head_sha),
run_id: RunId(payload.workflow_run.id.0),
status: match payload.workflow_run.conclusion.unwrap_or_default().as_str() {
"success" => WorkflowStatus::Success,
_ => WorkflowStatus::Failure,
},
}),
)),
"completed" => {
let running_time = if let (Some(started_at), Some(completed_at)) = (
Some(payload.workflow_run.created_at),
Some(payload.workflow_run.updated_at),
) {
Some(completed_at - started_at)
} else {
None
};
Some(BorsEvent::Repository(
BorsRepositoryEvent::WorkflowCompleted(WorkflowCompleted {
repository: repository_name,
branch: payload.workflow_run.head_branch,
commit_sha: CommitSha(payload.workflow_run.head_sha),
run_id: RunId(payload.workflow_run.id.0),
running_time,
status: match payload.workflow_run.conclusion.unwrap_or_default().as_str() {
"success" => WorkflowStatus::Success,
_ => WorkflowStatus::Failure,
},
}),
))
}
_ => None,
};
Ok(result)
Expand Down Expand Up @@ -774,6 +785,12 @@ mod tests {
4900979072,
),
status: Failure,
running_time: Some(
TimeDelta {
secs: 13,
nanos: 0,
},
),
},
),
),
Expand Down

0 comments on commit 34b52b3

Please sign in to comment.