fix(local): make the trial-build gate detect non-throwing build failures (#130)
Some checks failed
ci/crow/cron/process-updates/2 Pipeline was successful
ci/crow/cron/process-updates/7 Pipeline was successful
ci/crow/cron/process-updates/8 Pipeline was successful
ci/crow/cron/process-updates/9 Pipeline was successful
ci/crow/cron/process-updates/3 Pipeline was successful
ci/crow/cron/process-updates/4 Pipeline was successful
ci/crow/cron/process-updates/10 Pipeline was successful
ci/crow/cron/process-updates/13 Pipeline was successful
ci/crow/manual/build-all-versions-install-deps/2 Pipeline was successful
ci/crow/cron/process-updates/14 Pipeline was successful
ci/crow/cron/process-updates/15 Pipeline was successful
ci/crow/cron/process-updates/16 Pipeline was successful
ci/crow/cron/process-updates/11 Pipeline was successful
ci/crow/cron/process-updates/18 Pipeline was successful
ci/crow/cron/process-updates/17 Pipeline was successful
ci/crow/cron/process-updates/5 Pipeline was successful
ci/crow/cron/process-updates/12 Pipeline was successful
ci/crow/manual/auto-apply-patches Pipeline was successful
ci/crow/cron/process-updates/6 Pipeline was successful
ci/crow/cron/process-updates/1 Pipeline was successful
ci/crow/manual/build-all-versions/7 Pipeline failed
ci/crow/manual/build-all-versions/8 Pipeline failed
ci/crow/manual/build-all-versions/5 Pipeline failed
ci/crow/manual/build-all-versions/6 Pipeline failed

## Critical: the gate was false-green

The latest run printed **`3/3 passed on alpine-324`** while all three builds actually **failed** (their `rstan` dependency won't compile). A false-green gate would let broken registry entries merge — worse than no gate.

Root cause: `bincraft::build_binary_package()` catches build failures internally and **returns `"error"`** for the failed tag rather than throwing. The gate's `tryCatch` only treated a *thrown* exception as failure, so every non-throwing failure looked like a pass.

Fix: inspect the return value. A tag passes only if the flattened result is non-empty and contains no `"error"` sentinel; a thrown error still counts as failure. Verified the verdict against `error`/`skipped`/`TRUE`/`list(success=TRUE)`/`NULL`/mixed inputs.

With this, the current rstan-blocked entries will correctly show **0/3 (red)** — which is the right answer until rstan builds.

Reviewed-on: #130
This commit is contained in:
Patrick Schratz 2026-07-16 08:24:03 +00:00 committed by Patrick Schratz
commit 118a92889f

View file

@ -117,23 +117,34 @@ results <- vapply(
pkgs,
function(pkg) {
cat(sprintf("\n=== trial build: %s ===\n", pkg))
tryCatch(
{
bincraft::build_binary_package(
pkg,
tag_limit = 1L,
patches = patches_dir,
archive = FALSE,
upload = FALSE,
store_build_metadata = FALSE
)
TRUE
},
# bincraft::build_binary_package() catches build failures internally and
# RETURNS "error" for the failed tag rather than throwing, so a green gate
# must inspect the return value -- checking only for a thrown exception
# reports a broken build as passing.
res <- tryCatch(
bincraft::build_binary_package(
pkg,
tag_limit = 1L,
patches = patches_dir,
archive = FALSE,
upload = FALSE,
store_build_metadata = FALSE
),
error = function(e) {
cat(sprintf("FAILED %s: %s\n", pkg, conditionMessage(e)))
FALSE
cat(sprintf("FAILED %s (threw): %s\n", pkg, conditionMessage(e)))
"error"
}
)
flat <- as.character(unlist(res))
ok <- length(flat) > 0L && !("error" %in% flat)
if (!ok) {
cat(sprintf(
"FAILED %s: build did not succeed (result: %s)\n",
pkg,
if (length(flat) > 0L) toString(flat) else "<empty>"
))
}
ok
},
logical(1L)
)