mirror of
https://github.com/Noratrieb/does-it-build.git
synced 2026-01-14 10:25:01 +01:00
Surface broken nightly errors
This commit is contained in:
parent
cfef23bc31
commit
5ec24bbfaf
5 changed files with 103 additions and 37 deletions
4
migrations/20250703200547_broken-error.sql
Normal file
4
migrations/20250703200547_broken-error.sql
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
-- Add migration script here
|
||||||
|
|
||||||
|
ALTER TABLE finished_nightly
|
||||||
|
ADD COLUMN broken_error BOOLEAN DEFAULT NULL;
|
||||||
|
|
@ -62,7 +62,7 @@ async fn background_builder_inner(db: &Db, nightly_cache: &mut NightlyCache) ->
|
||||||
.wrap_err_with(|| format!("building targets for toolchain {nightly}"));
|
.wrap_err_with(|| format!("building targets for toolchain {nightly}"));
|
||||||
if let Err(err) = result {
|
if let Err(err) = result {
|
||||||
error!(%nightly, %mode, ?err, "Failed to build nightly");
|
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
|
.await
|
||||||
.wrap_err("marking nightly as broken")?;
|
.wrap_err("marking nightly as broken")?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
28
src/db.rs
28
src/db.rs
|
|
@ -73,6 +73,14 @@ pub struct FinishedNightly {
|
||||||
pub mode: BuildMode,
|
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 {
|
impl Db {
|
||||||
pub async fn open(path: &str) -> Result<Self> {
|
pub async fn open(path: &str) -> Result<Self> {
|
||||||
let db_opts = SqliteConnectOptions::from_str(path)
|
let db_opts = SqliteConnectOptions::from_str(path)
|
||||||
|
|
@ -120,6 +128,16 @@ impl Db {
|
||||||
.wrap_err("getting history for single nightly")
|
.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>> {
|
pub async fn target_list(&self) -> Result<Vec<String>> {
|
||||||
#[derive(sqlx::FromRow)]
|
#[derive(sqlx::FromRow)]
|
||||||
struct TargetName {
|
struct TargetName {
|
||||||
|
|
@ -204,10 +222,16 @@ impl Db {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn finish_nightly_as_broken(&self, nightly: &str, mode: BuildMode) -> Result<()> {
|
pub async fn finish_nightly_as_broken(
|
||||||
sqlx::query("INSERT INTO finished_nightly (nightly, mode, is_broken) VALUES (?, ?, TRUE)")
|
&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(nightly)
|
||||||
.bind(mode)
|
.bind(mode)
|
||||||
|
.bind(error)
|
||||||
.execute(&self.conn)
|
.execute(&self.conn)
|
||||||
.await
|
.await
|
||||||
.wrap_err("inserting finished broken nightly")?;
|
.wrap_err("inserting finished broken nightly")?;
|
||||||
|
|
|
||||||
87
src/web.rs
87
src/web.rs
|
|
@ -156,47 +156,66 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
|
||||||
builds: Vec<(String, Option<BuildInfo>, Option<BuildInfo>)>,
|
builds: Vec<(String, Option<BuildInfo>, Option<BuildInfo>)>,
|
||||||
core_failures: usize,
|
core_failures: usize,
|
||||||
std_failures: usize,
|
std_failures: usize,
|
||||||
|
core_broken: Option<String>,
|
||||||
|
std_broken: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
match state.db.history_for_nightly(&query.nightly).await {
|
match state.db.history_for_nightly(&query.nightly).await {
|
||||||
Ok(builds) => {
|
Ok(builds) => match state.db.nightly_info(&query.nightly).await {
|
||||||
let mut builds_grouped =
|
Ok(info) => {
|
||||||
HashMap::<String, (Option<BuildInfo>, Option<BuildInfo>)>::new();
|
let mut builds_grouped =
|
||||||
for build in &builds {
|
HashMap::<String, (Option<BuildInfo>, Option<BuildInfo>)>::new();
|
||||||
let v = builds_grouped.entry(build.target.clone()).or_default();
|
for build in &builds {
|
||||||
match build.mode {
|
let v = builds_grouped.entry(build.target.clone()).or_default();
|
||||||
BuildMode::Core => v.0 = Some(build.clone()),
|
|
||||||
BuildMode::MiriStd => v.1 = Some(build.clone()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut std_failures = 0;
|
|
||||||
let mut core_failures = 0;
|
|
||||||
for build in builds {
|
|
||||||
if build.status == Status::Error {
|
|
||||||
match build.mode {
|
match build.mode {
|
||||||
BuildMode::Core => core_failures += 1,
|
BuildMode::Core => v.0 = Some(build.clone()),
|
||||||
BuildMode::MiriStd => std_failures += 1,
|
BuildMode::MiriStd => v.1 = Some(build.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut std_failures = 0;
|
||||||
|
let mut core_failures = 0;
|
||||||
|
for build in builds {
|
||||||
|
if build.status == Status::Error {
|
||||||
|
match build.mode {
|
||||||
|
BuildMode::Core => core_failures += 1,
|
||||||
|
BuildMode::MiriStd => std_failures += 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut builds = builds_grouped
|
||||||
|
.into_iter()
|
||||||
|
.map(|(k, (v1, v2))| (k, v1, v2))
|
||||||
|
.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()
|
||||||
}
|
}
|
||||||
|
Err(err) => {
|
||||||
let mut builds = builds_grouped
|
error!(?err, "Error loading target state");
|
||||||
.into_iter()
|
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||||
.map(|(k, (v1, v2))| (k, v1, v2))
|
}
|
||||||
.collect::<Vec<_>>();
|
},
|
||||||
builds.sort_by_cached_key(|build| build.0.clone());
|
|
||||||
|
|
||||||
let page = NightlyPage {
|
|
||||||
nightly: query.nightly,
|
|
||||||
version: crate::VERSION,
|
|
||||||
builds,
|
|
||||||
std_failures,
|
|
||||||
core_failures,
|
|
||||||
};
|
|
||||||
|
|
||||||
Html(page.render().unwrap()).into_response()
|
|
||||||
}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!(?err, "Error loading target state");
|
error!(?err, "Error loading target state");
|
||||||
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
StatusCode::INTERNAL_SERVER_ERROR.into_response()
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,25 @@
|
||||||
std builds (on targets that have it) but does not check whether
|
std builds (on targets that have it) but does not check whether
|
||||||
codegen/linking works.
|
codegen/linking works.
|
||||||
</p>
|
</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>
|
<p>
|
||||||
<dl>
|
<dl>
|
||||||
<dt>core failures</dt>
|
<dt>core failures</dt>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue