Surface broken nightly errors

This commit is contained in:
nora 2025-07-03 22:20:00 +02:00
parent cfef23bc31
commit 5ec24bbfaf
5 changed files with 103 additions and 37 deletions

View file

@ -0,0 +1,4 @@
-- Add migration script here
ALTER TABLE finished_nightly
ADD COLUMN broken_error BOOLEAN DEFAULT NULL;

View file

@ -62,7 +62,7 @@ async fn background_builder_inner(db: &Db, nightly_cache: &mut NightlyCache) ->
.wrap_err_with(|| format!("building targets for toolchain {nightly}"));
if let Err(err) = result {
error!(%nightly, %mode, ?err, "Failed to build nightly");
db.finish_nightly_as_broken(&nightly, mode)
db.finish_nightly_as_broken(&nightly, mode, &format!("{err:?}"))
.await
.wrap_err("marking nightly as broken")?;
}

View file

@ -73,6 +73,14 @@ pub struct FinishedNightly {
pub mode: BuildMode,
}
#[derive(sqlx::FromRow, Debug, PartialEq, Eq, Hash)]
pub struct FinishedNightlyWithBroken {
pub nightly: String,
pub mode: BuildMode,
pub is_broken: bool,
pub broken_error: Option<String>,
}
impl Db {
pub async fn open(path: &str) -> Result<Self> {
let db_opts = SqliteConnectOptions::from_str(path)
@ -120,6 +128,16 @@ impl Db {
.wrap_err("getting history for single nightly")
}
pub async fn nightly_info(&self, nightly: &str) -> Result<Vec<FinishedNightlyWithBroken>> {
sqlx::query_as::<_, FinishedNightlyWithBroken>(
"SELECT nightly, mode, is_broken, broken_error FROM finished_nightly WHERE nightly = ?",
)
.bind(nightly)
.fetch_all(&self.conn)
.await
.wrap_err("getting finished_nightly for single nightly")
}
pub async fn target_list(&self) -> Result<Vec<String>> {
#[derive(sqlx::FromRow)]
struct TargetName {
@ -204,10 +222,16 @@ impl Db {
Ok(())
}
pub async fn finish_nightly_as_broken(&self, nightly: &str, mode: BuildMode) -> Result<()> {
sqlx::query("INSERT INTO finished_nightly (nightly, mode, is_broken) VALUES (?, ?, TRUE)")
pub async fn finish_nightly_as_broken(
&self,
nightly: &str,
mode: BuildMode,
error: &str,
) -> Result<()> {
sqlx::query("INSERT INTO finished_nightly (nightly, mode, is_broken, broken_error) VALUES (?, ?, TRUE, ?)")
.bind(nightly)
.bind(mode)
.bind(error)
.execute(&self.conn)
.await
.wrap_err("inserting finished broken nightly")?;

View file

@ -156,10 +156,13 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
builds: Vec<(String, Option<BuildInfo>, Option<BuildInfo>)>,
core_failures: usize,
std_failures: usize,
core_broken: Option<String>,
std_broken: Option<String>,
}
match state.db.history_for_nightly(&query.nightly).await {
Ok(builds) => {
Ok(builds) => match state.db.nightly_info(&query.nightly).await {
Ok(info) => {
let mut builds_grouped =
HashMap::<String, (Option<BuildInfo>, Option<BuildInfo>)>::new();
for build in &builds {
@ -187,12 +190,23 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
.collect::<Vec<_>>();
builds.sort_by_cached_key(|build| build.0.clone());
let core_broken = info
.iter()
.find(|info| info.mode == BuildMode::Core && info.is_broken)
.and_then(|info| info.broken_error.clone());
let std_broken = info
.iter()
.find(|info| info.mode == BuildMode::MiriStd && info.is_broken)
.and_then(|info| info.broken_error.clone());
let page = NightlyPage {
nightly: query.nightly,
version: crate::VERSION,
builds,
std_failures,
core_failures,
core_broken,
std_broken,
};
Html(page.render().unwrap()).into_response()
@ -201,6 +215,11 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
error!(?err, "Error loading target state");
StatusCode::INTERNAL_SERVER_ERROR.into_response()
}
},
Err(err) => {
error!(?err, "Error loading target state");
StatusCode::INTERNAL_SERVER_ERROR.into_response()
}
}
}

View file

@ -20,6 +20,25 @@
std builds (on targets that have it) but does not check whether
codegen/linking works.
</p>
{% if let Some(core_broken) = core_broken %}
<p>
⚠️ The core build is broken in general for this nightly, so no data is available ⚠️
</p>
<pre>
{{core_broken}}
</pre>
{% endif %}
{% if let Some(std_broken) = std_broken %}
<p>
⚠️ The std build is broken for this nightly, so no data is available ⚠️
</p>
<pre>
{{std_broken}}
</pre>
{% endif %}
<p>
<dl>
<dt>core failures</dt>