diff --git a/src/handlers/milestone_prs.rs b/src/handlers/milestone_prs.rs index 35338501..f086d22d 100644 --- a/src/handlers/milestone_prs.rs +++ b/src/handlers/milestone_prs.rs @@ -3,6 +3,7 @@ use crate::{ handlers::Context, }; use anyhow::Context as _; +use reqwest::StatusCode; pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { let e = if let Event::Issue(e) = event { @@ -39,8 +40,65 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { return Ok(()); }; - // Fetch channel.rs from the upstream repository + // Fetch the version from the upstream repository. + let version = if let Some(version) = get_version_standalone(ctx, merge_sha).await? { + version + } else if let Some(version) = get_version_channelrs(ctx, merge_sha).await? { + version + } else { + log::error!("could not find the version of {:?}", merge_sha); + return Ok(()); + }; + + if !version.starts_with("1.") && version.len() < 8 { + log::error!("Weird version {:?} for {:?}", version, merge_sha); + return Ok(()); + } + + // Associate this merged PR with the version it merged into. + // + // Note that this should work for rollup-merged PRs too. It will *not* + // auto-update when merging a beta-backport, for example, but that seems + // fine; we can manually update without too much trouble in that case, and + // eventually automate it separately. + e.issue.set_milestone(&ctx.github, &version).await?; + + Ok(()) +} + +async fn get_version_standalone(ctx: &Context, merge_sha: &str) -> anyhow::Result> { + let resp = ctx + .github + .raw() + .get(&format!( + "https://raw.githubusercontent.com/rust-lang/rust/{}/src/version", + merge_sha + )) + .send() + .await + .with_context(|| format!("retrieving src/version for {}", merge_sha))?; + + match resp.status() { + StatusCode::OK => {} + // Don't treat a 404 as a failure, we'll try another way to retrieve the version. + StatusCode::NOT_FOUND => return Ok(None), + status => anyhow::bail!( + "unexpected status code {} while retrieving src/version for {}", + status, + merge_sha + ), + } + + Ok(Some( + resp.text() + .await + .with_context(|| format!("deserializing src/version for {}", merge_sha))? + .trim() + .to_string(), + )) +} +async fn get_version_channelrs(ctx: &Context, merge_sha: &str) -> anyhow::Result> { let resp = ctx .github .raw() @@ -66,28 +124,15 @@ pub async fn handle(ctx: &Context, event: &Event) -> anyhow::Result<()> { prefix, merge_sha ); - return Ok(()); + return Ok(None); }; let after = &resp[start..]; let end = if let Some(idx) = after.find('"') { idx } else { log::error!("No suffix in contents of channel.rs at {:?}", merge_sha); - return Ok(()); + return Ok(None); }; - let version = &after[..end]; - if !version.starts_with("1.") && version.len() < 8 { - log::error!("Weird version {:?} for {:?}", version, merge_sha); - return Ok(()); - } - // Associate this merged PR with the version it merged into. - // - // Note that this should work for rollup-merged PRs too. It will *not* - // auto-update when merging a beta-backport, for example, but that seems - // fine; we can manually update without too much trouble in that case, and - // eventually automate it separately. - e.issue.set_milestone(&ctx.github, version).await?; - - Ok(()) + Ok(Some(after[..end].to_string())) }