Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions site/src/github.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod client;
pub mod comparison_summary;
pub mod triage;

use crate::job_queue::build_queue;
use crate::load::{SiteCtxt, TryCommit};
Expand Down
14 changes: 10 additions & 4 deletions site/src/github/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const GRAPHQL_API_BASE: &str = "https://api.github.com/graphql";
/// A client for interacting with the GraphQL GitHub API.
pub struct GraphQLClient {
inner: reqwest::Client,
repo: &'static str,
}

impl GraphQLClient {
Expand All @@ -100,9 +101,12 @@ impl GraphQLClient {
.config
.keys
.github_api_token
.clone()
.as_ref()
.expect("needs github API token");
Self::from_token(token, "rust")
}

fn from_token(token: &str, repo: &'static str) -> Self {
let mut headers = header::HeaderMap::new();
headers.insert(USER_AGENT, header::HeaderValue::from_static(BOT_USER_AGENT));
headers.insert(
Expand All @@ -114,7 +118,10 @@ impl GraphQLClient {
.default_headers(headers)
.build()
.unwrap();
Self { inner: client }
Self {
inner: client,
repo,
}
}

pub async fn get_comments(&self, pull_request: u32) -> anyhow::Result<Vec<ResponseComment>> {
Expand Down Expand Up @@ -157,7 +164,6 @@ impl GraphQLClient {
}

let owner = "rust-lang";
let repo = "rust";

let mut comments = Vec::new();
let mut cursor = None;
Expand All @@ -167,7 +173,7 @@ impl GraphQLClient {
QUERY,
serde_json::json!({
"owner": owner,
"repo": repo,
"repo": self.repo,
"pr": pull_request,
"cursor": cursor,
}),
Expand Down
25 changes: 22 additions & 3 deletions site/src/github/comparison_summary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::load::SiteCtxt;

use database::{metric::Metric, QueuedCommit};

use crate::github::triage::{is_triage_run, TriageBuild};
use crate::github::{COMMENT_MARK_TEMPORARY, RUST_REPO_GITHUB_API_URL};
use humansize::BINARY;
use std::fmt::Write;
Expand All @@ -18,11 +19,11 @@ pub async fn post_comparison_comment(
commit: QueuedCommit,
is_master_commit: bool,
) -> anyhow::Result<()> {
let client = super::client::Client::from_ctxt(ctxt, RUST_REPO_GITHUB_API_URL.to_owned());
let mut client = super::client::Client::from_ctxt(ctxt, RUST_REPO_GITHUB_API_URL.to_owned());
let pr = commit.pr;

// Scan comments to hide outdated ones and gather context
let graph_client = super::client::GraphQLClient::from_ctxt(ctxt);
let mut graph_client = super::client::GraphQLClient::from_ctxt(ctxt);
for comment in graph_client.get_comments(pr).await? {
// If this bot is the author of the comment, the comment is not yet minimized and it is
// a temporary comment, minimize it.
Expand All @@ -37,6 +38,8 @@ pub async fn post_comparison_comment(

let source = if is_master_commit {
PerfRunSource::MasterCommit
} else if let Some(triage_run) = is_triage_run(&commit, &mut client, &mut graph_client).await? {
PerfRunSource::TriageBuild(triage_run)
} else {
PerfRunSource::TryBuild
};
Expand Down Expand Up @@ -88,6 +91,8 @@ enum PerfRunSource {
MasterCommit,
// Manual try build on a PR
TryBuild,
// A try build on a PR as part of a `@rust-timer triage` command
TriageBuild(TriageBuild),
}

// Should the metric be shown by default in the summary?
Expand Down Expand Up @@ -158,9 +163,10 @@ async fn summarize_run(
)
.unwrap();

let next_steps = match source {
let next_steps = match &source {
PerfRunSource::TryBuild => try_run_body(is_regression, deserves_attention),
PerfRunSource::MasterCommit => master_run_body(is_regression),
PerfRunSource::TriageBuild(triage_build) => triage_run_body(triage_build, is_regression),
};
writeln!(&mut message, "{next_steps}\n").unwrap();

Expand Down Expand Up @@ -366,3 +372,16 @@ Benchmarking means the PR may be perf-sensitive. \
@rustbot label: -S-waiting-on-perf {sign}perf-regression",
)
}

fn triage_run_body(build: &TriageBuild, is_regression: bool) -> String {
// The triage url deliberately not prefixed with "https://github.com/" as to not trigger the
// "mentioned this pull request" github entry on the rollup
Comment thread
Kobzol marked this conversation as resolved.
format!(
"This PR was benchmarked as part of triage of its containing rollup: [triage URL](/rust-lang/rust/pull/{}#issuecomment-{}).\
\n\n\
{}",
build.rollup_pr_number,
build.triage_comment.id,
master_run_body(is_regression)
)
}
40 changes: 40 additions & 0 deletions site/src/github/triage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use crate::github::client::{Client, GraphQLClient, ResponseComment};
use crate::request_handlers::parse_unrolled_build_message;
use database::QueuedCommit;

pub struct TriageBuild {
pub rollup_pr_number: u32,
pub triage_comment: ResponseComment,
}

pub const TRIAGE_MARKER: &str = "<!-- rust-timer: triage -->";

/// Returns `Some` if this commit is part of a triage run.
pub async fn is_triage_run(
commit: &QueuedCommit,
client: &mut Client,
graph_qlclient: &mut GraphQLClient,
) -> anyhow::Result<Option<TriageBuild>> {
// Find the rollup PR
let commit_title = client.get_commit(&commit.sha).await?;
let Ok(unrolled_build) = parse_unrolled_build_message(&commit_title.commit.message) else {
// The commit title parsed successfully during the `@rust-timer triage` command, so if it does not parse here it's not a triage run
return Ok(None);
};

// Find the triage run on the rollup PR
let rollup_comments = graph_qlclient
.get_comments(unrolled_build.rollup_pr_number)
.await?;
let Some(triage_comment) = rollup_comments.into_iter().rev().find(|c| {
c.viewer_did_author && c.body.contains(TRIAGE_MARKER) && c.body.contains(&commit.sha)
}) else {
// This was a try job on the unrolled build that did not originate from a triage command
return Ok(None);
};

Ok(Some(TriageBuild {
rollup_pr_number: unrolled_build.rollup_pr_number,
triage_comment,
}))
}
2 changes: 1 addition & 1 deletion site/src/request_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod status_page;
mod toolchain;

pub use dashboard::handle_dashboard;
pub use github::handle_github_webhook;
pub use github::{handle_github_webhook, parse_unrolled_build_message};
pub use graph::{
handle_compile_detail_graphs, handle_compile_detail_sections, handle_graphs,
handle_runtime_detail_graphs,
Expand Down
12 changes: 7 additions & 5 deletions site/src/request_handlers/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::load::SiteCtxt;
use std::fmt::Write;

use crate::github::client::Client;
use crate::github::triage::TRIAGE_MARKER;
use database::{
parse_backends, parse_profiles, parse_targets, BenchmarkRequest, BenchmarkRequestInsertResult,
CodegenBackend, Profile, Target,
Expand Down Expand Up @@ -274,6 +275,8 @@ async fn handle_rust_timer(
.await;
writeln!(&mut result, "{msg}\n").unwrap();
}
// Add a marker to the comment which should help to find it again later
writeln!(&mut result, "{}", TRIAGE_MARKER).unwrap();
main_client.post_comment(issue.number, result).await;
}
Err(e) => {
Expand All @@ -285,13 +288,12 @@ async fn handle_rust_timer(
}

#[derive(Debug)]
struct UnrolledBuildMessage {
member_pr_number: u32,
#[expect(unused, reason = "Will be used in follow-up PR")]
rollup_pr_number: u32,
pub struct UnrolledBuildMessage {
pub member_pr_number: u32,
pub rollup_pr_number: u32,
}

fn parse_unrolled_build_message(commit_message: &str) -> Result<UnrolledBuildMessage, String> {
pub fn parse_unrolled_build_message(commit_message: &str) -> Result<UnrolledBuildMessage, String> {
let first_line = commit_message.lines().next().unwrap_or("");

// The first line of the commit message will look like
Expand Down
Loading