diff --git a/Cargo.lock b/Cargo.lock index d3e473d0..7e9a7dc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -268,6 +268,7 @@ dependencies = [ "console", "git2", "gql_client", + "humantime", "indicatif", "insta", "itertools", @@ -721,6 +722,12 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "humantime" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" + [[package]] name = "hyper" version = "0.14.32" diff --git a/Cargo.toml b/Cargo.toml index c1d026ec..1b38281d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ sysinfo = { version = "0.33.1", features = ["serde"] } indicatif = "0.17.8" console = "0.15.8" async-trait = "0.1.82" +humantime = "2.2.0" [dev-dependencies] temp-env = { version = "0.3.6", features = ["async_closure"] } diff --git a/src/api_client.rs b/src/api_client.rs index 55e0bf10..611798c9 100644 --- a/src/api_client.rs +++ b/src/api_client.rs @@ -108,11 +108,14 @@ impl Display for ReportConclusion { #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub struct FetchLocalRunReportHeadReport { +pub struct FetchLocalRunReportRun { pub id: String, - pub impact: Option, - pub conclusion: ReportConclusion, + pub status: RunStatus, + pub url: String, + pub head_reports: Vec, + pub results: Vec, } + #[derive(Deserialize, Serialize, Debug, Clone, PartialEq)] #[serde(rename_all = "SCREAMING_SNAKE_CASE")] pub enum RunStatus { @@ -121,14 +124,26 @@ pub enum RunStatus { Pending, Processing, } + #[derive(Debug, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] -pub struct FetchLocalRunReportRun { +pub struct FetchLocalRunReportHeadReport { pub id: String, - pub status: RunStatus, - pub url: String, - pub head_reports: Vec, + pub impact: Option, + pub conclusion: ReportConclusion, +} + +#[derive(Debug, Deserialize, Serialize)] +pub struct FetchLocalRunBenchmarkResult { + pub time: f64, + pub benchmark: FetchLocalRunBenchmark, } + +#[derive(Debug, Deserialize, Serialize)] +pub struct FetchLocalRunBenchmark { + pub name: String, +} + nest! { #[derive(Debug, Deserialize, Serialize)]* #[serde(rename_all = "camelCase")]* @@ -137,7 +152,7 @@ nest! { settings: struct FetchLocalRunReportSettings { allowed_regression: f64, }, - runs: Vec, + run: FetchLocalRunReportRun, } } } @@ -190,22 +205,10 @@ impl CodSpeedAPIClient { ) .await; match response { - Ok(response) => { - let allowed_regression = response.repository.settings.allowed_regression; - - match response.repository.runs.into_iter().next() { - Some(run) => Ok(FetchLocalRunReportResponse { - allowed_regression, - run, - }), - None => bail!( - "No runs found for owner: {}, name: {}, run_id: {}", - vars.owner, - vars.name, - vars.run_id - ), - } - } + Ok(response) => Ok(FetchLocalRunReportResponse { + allowed_regression: response.repository.settings.allowed_regression, + run: response.repository.run, + }), Err(err) if err.contains_error_code("UNAUTHENTICATED") => { bail!("Your session has expired, please login again using `codspeed auth login`") } diff --git a/src/queries/FetchLocalRunReport.gql b/src/queries/FetchLocalRunReport.gql index 20e8f61a..73e950c0 100644 --- a/src/queries/FetchLocalRunReport.gql +++ b/src/queries/FetchLocalRunReport.gql @@ -3,8 +3,8 @@ query FetchLocalRunReport($owner: String!, $name: String!, $runId: String!) { settings { allowedRegression } - runs(where: { id: { equals: $runId } }) { - id + run(id: $runId) { + id status url headReports { @@ -12,6 +12,12 @@ query FetchLocalRunReport($owner: String!, $name: String!, $runId: String!) { impact conclusion } + results { + time + benchmark { + name + } + } } } } diff --git a/src/run/mod.rs b/src/run/mod.rs index 6b9e1073..4a250ce1 100644 --- a/src/run/mod.rs +++ b/src/run/mod.rs @@ -206,17 +206,8 @@ pub async fn run( end_group!(); if provider.get_run_environment() == RunEnvironment::Local { - start_group!("Fetching the results"); - let run_id = upload_result.run_id.clone(); - poll_results::poll_results(api_client, &provider, upload_result.run_id).await?; - if output_json { - // TODO: Refactor `log_json` to avoid having to format the json manually - // We could make use of structured logging for this https://docs.rs/log/latest/log/#structured-logging - log_json!(format!( - "{{\"event\": \"run_finished\", \"run_id\": \"{}\"}}", - run_id - )); - } + poll_results::poll_results(api_client, &provider, upload_result.run_id, output_json) + .await?; end_group!(); } } diff --git a/src/run/poll_results.rs b/src/run/poll_results.rs index 73be7936..acd8198d 100644 --- a/src/run/poll_results.rs +++ b/src/run/poll_results.rs @@ -18,6 +18,7 @@ pub async fn poll_results( api_client: &CodSpeedAPIClient, provider: &Box, run_id: String, + output_json: bool, ) -> Result<()> { let start = Instant::now(); let run_environment_metadata = provider.get_run_environment_metadata()?; @@ -29,6 +30,7 @@ pub async fn poll_results( run_id: run_id.clone(), }; + start_group!("Fetching the results"); let response; loop { if start.elapsed() > RUN_PROCESSING_MAX_DURATION { @@ -84,5 +86,34 @@ pub async fn poll_results( style(response.run.url).blue().bold().underlined() ); + if output_json { + // TODO: Refactor `log_json` to avoid having to format the json manually + // We could make use of structured logging for this https://docs.rs/log/latest/log/#structured-logging + log_json!(format!( + "{{\"event\": \"run_finished\", \"run_id\": \"{}\"}}", + run_id + )); + } + + end_group!(); + + if !response.run.results.is_empty() { + start_group!("Benchmarks"); + for result in response.run.results { + let benchmark_name = result.benchmark.name; + let time: humantime::Duration = Duration::from_secs_f64(result.time).into(); + let time_text = style(format!("{}", time)).bold(); + + if output_json { + log_json!(format!( + "{{\"event\": \"benchmark_ran\", \"name\": \"{}\", \"time\": \"{}\"}}", + benchmark_name, result.time, + )); + } + info!("{} - Time: {}", benchmark_name, time_text); + } + end_group!(); + } + Ok(()) }