Skip to content

Commit 3acfb84

Browse files
authored
Merge pull request #907 from rylev/untriaged
Fetch untriaged perf-regression PRs
2 parents c9f6d39 + ba3fe3f commit 3acfb84

File tree

2 files changed

+112
-40
lines changed

2 files changed

+112
-40
lines changed

site/src/comparison.rs

Lines changed: 25 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
use crate::api;
66
use crate::db::{ArtifactId, Cache, Crate, Profile};
7+
use crate::github;
78
use crate::load::SiteCtxt;
89
use crate::selector::{self, Tag};
910

@@ -80,7 +81,7 @@ pub async fn handle_triage(
8081
}
8182
let end = end.unwrap_or(after);
8283

83-
let report = generate_report(&start, &end, report);
84+
let report = generate_report(&start, &end, report).await;
8485
Ok(api::triage::Response(report))
8586
}
8687

@@ -191,7 +192,7 @@ impl ComparisonSummary<'_> {
191192
use std::fmt::Write;
192193

193194
let mut result = if let Some(pr) = comparison.b.pr {
194-
let title = gh_pr_title(pr).await;
195+
let title = github::pr_title(pr).await;
195196
format!(
196197
"{} [#{}](https://github.com/rust-lang/rust/issues/{})\n",
197198
title, pr, pr
@@ -725,7 +726,7 @@ impl std::fmt::Display for Direction {
725726
}
726727
}
727728

728-
fn generate_report(
729+
async fn generate_report(
729730
start: &Bound,
730731
end: &Bound,
731732
mut report: HashMap<Direction, Vec<String>>,
@@ -742,6 +743,22 @@ fn generate_report(
742743
let regressions = report.remove(&Direction::Regression).unwrap_or_default();
743744
let improvements = report.remove(&Direction::Improvement).unwrap_or_default();
744745
let mixed = report.remove(&Direction::Mixed).unwrap_or_default();
746+
let untriaged = match github::untriaged_perf_regressions().await {
747+
Ok(u) => u
748+
.iter()
749+
.map(|github::PullRequest { title, number }| {
750+
format!(
751+
"- [#{} {}](https://github.com/rust-lang/rust/pull/{})",
752+
number, title, number
753+
)
754+
})
755+
.collect::<Vec<_>>()
756+
.join("\n"),
757+
Err(e) => format!(
758+
"An **error** occurred when finding the untriaged PRs: {}",
759+
e
760+
),
761+
};
745762
format!(
746763
r#####"# {date} Triage Log
747764
@@ -764,6 +781,10 @@ Revision range: [{first_commit}..{last_commit}](https://perf.rust-lang.org/?star
764781
765782
{mixed}
766783
784+
#### Untriaged Pull Requests
785+
786+
{untriaged}
787+
767788
#### Nags requiring follow up
768789
769790
TODO: Nags
@@ -778,6 +799,7 @@ TODO: Nags
778799
regressions = regressions.join("\n\n"),
779800
improvements = improvements.join("\n\n"),
780801
mixed = mixed.join("\n\n"),
802+
untriaged = untriaged
781803
)
782804
}
783805

@@ -795,37 +817,3 @@ fn compare_link(start: &ArtifactId, end: &ArtifactId) -> String {
795817
start, end
796818
)
797819
}
798-
799-
async fn gh_pr_title(pr: u32) -> String {
800-
let url = format!("https://api.github.com/repos/rust-lang/rust/pulls/{}", pr);
801-
let client = reqwest::Client::new();
802-
let mut request = client
803-
.get(&url)
804-
.header("Content-Type", "application/json")
805-
.header("User-Agent", "rustc-perf");
806-
807-
if let Some(token) = std::env::var("GITHUB_TOKEN").ok() {
808-
request = request.header("Authorization", format!("token {}", token));
809-
}
810-
811-
async fn send(request: reqwest::RequestBuilder) -> Result<String, BoxedError> {
812-
Ok(request
813-
.send()
814-
.await?
815-
.error_for_status()?
816-
.json::<serde_json::Value>()
817-
.await?
818-
.get("title")
819-
.ok_or_else(|| "JSON was malformed".to_owned())?
820-
.as_str()
821-
.ok_or_else(|| "JSON was malformed".to_owned())?
822-
.to_owned())
823-
}
824-
match send(request).await {
825-
Ok(t) => t,
826-
Err(e) => {
827-
eprintln!("Error fetching url: {}", e);
828-
String::from("<UNKNOWN>")
829-
}
830-
}
831-
}

site/src/github.rs

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
use crate::api::{github, ServerResult};
22
use crate::comparison::{ComparisonSummary, Direction};
33
use crate::load::{Config, SiteCtxt, TryCommit};
4-
use anyhow::Context as _;
5-
use hashbrown::HashSet;
6-
use serde::Deserialize;
74

5+
use anyhow::Context as _;
86
use database::ArtifactId;
7+
use hashbrown::HashSet;
98
use regex::Regex;
109
use reqwest::header::USER_AGENT;
10+
use serde::Deserialize;
11+
1112
use std::{fmt::Write, sync::Arc, time::Duration};
1213

14+
type BoxedError = Box<dyn std::error::Error + Send + Sync>;
15+
1316
lazy_static::lazy_static! {
1417
static ref BODY_TRY_COMMIT: Regex =
1518
Regex::new(r#"(?:\W|^)@rust-timer\s+build\s+(\w+)(?:\W|$)(?:include=(\S+))?\s*(?:exclude=(\S+))?\s*(?:runs=(\d+))?"#).unwrap();
@@ -732,3 +735,84 @@ async fn categorize_benchmark(
732735
write!(result, "\n{}", DISAGREEMENT).unwrap();
733736
(result, Some(direction))
734737
}
738+
739+
pub(crate) struct PullRequest {
740+
pub number: u64,
741+
pub title: String,
742+
}
743+
744+
/// Fetch all merged PRs that are labeled with `perf-regression` and not `perf-regression-triaged`
745+
pub(crate) async fn untriaged_perf_regressions() -> Result<Vec<PullRequest>, BoxedError> {
746+
let url = "https://api.github.com/search/issues?q=repo:rust-lang/rust+label:perf-regression+-label:perf-regression-triaged+is:merged".to_owned();
747+
let request = github_request(&url);
748+
let body = send_request(request).await?;
749+
Ok(body
750+
.get("items")
751+
.ok_or_else(malformed_json_error)?
752+
.as_array()
753+
.ok_or_else(malformed_json_error)?
754+
.iter()
755+
.map(|v| {
756+
let title = v
757+
.get("title")
758+
.ok_or_else(malformed_json_error)?
759+
.as_str()
760+
.ok_or_else(malformed_json_error)?
761+
.to_owned();
762+
let number = v
763+
.get("number")
764+
.ok_or_else(malformed_json_error)?
765+
.as_u64()
766+
.ok_or_else(malformed_json_error)?;
767+
Ok(PullRequest { title, number })
768+
})
769+
.collect::<Result<_, BoxedError>>()?)
770+
}
771+
772+
/// Get the title of a PR with the given number
773+
pub(crate) async fn pr_title(pr: u32) -> String {
774+
let url = format!("https://api.github.com/repos/rust-lang/rust/pulls/{}", pr);
775+
let request = github_request(&url);
776+
777+
async fn send(request: reqwest::RequestBuilder) -> Result<String, BoxedError> {
778+
let body = send_request(request).await?;
779+
Ok(body
780+
.get("title")
781+
.ok_or_else(malformed_json_error)?
782+
.as_str()
783+
.ok_or_else(malformed_json_error)?
784+
.to_owned())
785+
}
786+
match send(request).await {
787+
Ok(t) => t,
788+
Err(e) => {
789+
eprintln!("Error fetching url: {}", e);
790+
String::from("<UNKNOWN>")
791+
}
792+
}
793+
}
794+
795+
fn github_request(url: &str) -> reqwest::RequestBuilder {
796+
let client = reqwest::Client::new();
797+
let mut request = client
798+
.get(url)
799+
.header("Content-Type", "application/json")
800+
.header("User-Agent", "rustc-perf");
801+
if let Some(token) = std::env::var("GITHUB_TOKEN").ok() {
802+
request = request.header("Authorization", format!("token {}", token));
803+
}
804+
request
805+
}
806+
807+
async fn send_request(request: reqwest::RequestBuilder) -> Result<serde_json::Value, BoxedError> {
808+
Ok(request
809+
.send()
810+
.await?
811+
.error_for_status()?
812+
.json::<serde_json::Value>()
813+
.await?)
814+
}
815+
816+
fn malformed_json_error() -> String {
817+
"JSON was malformed".to_owned()
818+
}

0 commit comments

Comments
 (0)