From a650f1d18a2991b72ab63eab5a75b337a40e5cbd Mon Sep 17 00:00:00 2001 From: pat-s Date: Thu, 3 Sep 2026 13:37:04 +0000 Subject: [PATCH] fix(build): scope the errored-package filter to the snapshot's R minor (#194) ## Why After #192 and #193 the builds stopped recompiling what they already had, but every slot still showed a per-minor gap that a successful run did not close: ``` arm64/resolute 3302 amd64/resolute 1783 amd64/alpine324 1163 arm64/alpine324 1104 arm64/rhel8 572 amd64/rhel8 532 amd64/rhel10 453 arm64/rhel10 176 (others <= 13) ``` amd64/alpine324 had just completed successfully, yet 655 ABI-risky packages were still absent from its 4.6 index. Sampling 25 of them against that run's log: ``` attempted: 0 errored: 0 uploaded: 0 never attempted: 25 ``` They were filtered out before the build loop. The candidate list drops every package with an error row for this platform/arch: ```sql SELECT name, tag FROM single_builds WHERE error_occurred = TRUE and platform='%s' and arch='%s' ``` There is no `r_version` in that predicate, and the row is keyed by `(name, tag, platform, arch)` only. So a single failure under one minor cancels the package's builds under every other minor, permanently. The index data matches that shape rather than a build-failure shape: of the 508 ABI-risky packages missing from alpine324's 4.4 index, **505 are also missing from 4.6** - a 99% overlap. Genuine per-minor failures would not correlate that way (only 3 were 4.4-specific). ## What changed Adds the `substring(r_version from '^[0-9]+[.][0-9]+') = ''` scoping already used by `check_package_error()` (#119) and the per-minor error query (#189). Errors specific to another minor are still respected downstream: `filter_packages_with_errors()` runs per pass with that pass's own `r_version`, so a package that genuinely fails under 4.6 is still skipped there. ## Verification Rendered query: ```sql SELECT name, tag FROM single_builds WHERE error_occurred = TRUE and platform='alpine-324' and arch='amd64' and substring(r_version from '^[0-9]+[.][0-9]+') = '4.5' ``` Routing itself is unaffected and remains green: `verify-r-minor-routing.sh` reports 232 passed / 0 failed across all 16 slots, and `--live` reported 328 passed / 0 failed. Reviewed-on: https://git.devxy.io/devxy/build-cran-binaries/pulls/194 --- local/packages-to-build.R | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/local/packages-to-build.R b/local/packages-to-build.R index 0654a43..ead73b8 100644 --- a/local/packages-to-build.R +++ b/local/packages-to-build.R @@ -355,12 +355,30 @@ query_error <- function(pkg, ver) { } # Fetch all relevant columns from the database +# Scoped to the snapshot's own R minor, like `check_package_error()` in +# bincraft (#119) and the per-minor error query (#189). Unscoped, a single +# failure under any one minor removed the package from the candidate list for +# every minor, permanently: the row is keyed by (name, tag, platform, arch) +# only, so an error under 4.6 also cancelled its 4.4 and 4.5 builds. +# +# That is what the residual per-minor gaps were. On amd64/alpine324, 505 of the +# 508 ABI-risky packages missing from 4.4 were also missing from 4.6 -- a 99% +# overlap, which per-minor build failures would not produce. None of them were +# even attempted by the run that had just succeeded. +# +# Errors specific to another minor are still respected downstream: +# `filter_packages_with_errors()` runs per pass with that pass's r_version. errored_pkgs <- DBI::dbGetQuery( con, sprintf( - "SELECT name, tag FROM single_builds WHERE error_occurred = TRUE and platform='%s' and arch='%s'", + paste0( + "SELECT name, tag FROM single_builds WHERE error_occurred = TRUE ", + "and platform='%s' and arch='%s' ", + "and substring(r_version from '^[0-9]+[.][0-9]+') = '%s'" + ), platform, - arch + arch, + snapshot_r_minor ) ) errored_pkgs <- as.data.table(errored_pkgs)