build-cran-binaries/local/trial-build-patch.R
pat-s 3d3c4c462a
fix(local): make trial-build-patch.R detect non-throwing build failures
local/trial-build-patch.R -- the single-package acceptance gate the proposer
tells humans to run -- reported "Trial build OK" for a build that actually
failed (rstan's rstan.so failing to load with an undefined TBB symbol). Same
root cause as the registry gate before #130: build_binary_package() catches
failures internally and returns "error" rather than throwing, so a tryCatch that
only treats a thrown exception as failure false-greens.

Inspect the return value: a pass requires a non-empty result containing no
"error" sentinel. Mirrors the fix in trial-build-registry.R.
2026-07-17 14:51:20 +00:00

68 lines
2.1 KiB
R

#!/usr/bin/env Rscript
# Acceptance gate for a proposed registry patch (issue #115, step 3): build one
# package in isolation with the current `local/patches` registry applied, and
# report whether it succeeds. Nothing is uploaded, archived, or written to the
# metadata DB -- `patchhash` keeps the trial binary out of the real cache.
#
# Must run inside a build-env image (the same image the failing platform uses),
# because it invokes the real compiler toolchain via bincraft.
#
# Usage:
# Rscript local/trial-build-patch.R <package> [tag]
#
# Exit status: 0 if the patched build succeeds, 1 otherwise -- so it can gate a
# CI step or a manual pre-merge check.
args <- commandArgs(trailingOnly = TRUE)
if (length(args) < 1L) {
stop("usage: Rscript local/trial-build-patch.R <package> [tag]")
}
package <- args[[1L]]
tag <- if (length(args) >= 2L) args[[2L]] else NULL
script_path <- local({
a <- commandArgs(trailingOnly = FALSE)
f <- sub("^--file=", "", a[grepl("^--file=", a)])
if (length(f) == 1L && nzchar(f)) normalizePath(f) else NA_character_
})
patches_dir <- file.path(
if (is.na(script_path)) "local" else dirname(script_path),
"patches"
)
suppressPackageStartupMessages(library(bincraft, quietly = TRUE))
cat(sprintf(
"Trial build: %s%s with registry %s (no upload/archive/metadata)\n",
package,
if (is.null(tag)) "" else sprintf(" @ %s", tag),
patches_dir
))
# build_binary_package() catches build failures internally and RETURNS "error"
# for the failed tag rather than throwing (bincraft >= v4.4.7), so inspect the
# return value -- checking only for a thrown exception reports a broken build as
# passing (false green).
res <- tryCatch(
bincraft::build_binary_package(
package,
tag_limit = 1L,
patches = patches_dir,
archive = FALSE,
upload = FALSE,
store_build_metadata = FALSE
),
error = function(e) {
cat(sprintf("Trial build FAILED (threw): %s\n", conditionMessage(e)))
"error"
}
)
flat <- as.character(unlist(res))
ok <- length(flat) > 0L && !("error" %in% flat)
if (ok) {
cat(sprintf("Trial build OK: %s builds with the proposed patch.\n", package))
q(status = 0)
}
q(status = 1)