From 7e01f481c085dbc3729e49374f7bba2c19b5094c Mon Sep 17 00:00:00 2001 From: pat-s Date: Sun, 14 Jun 2026 14:50:40 +0200 Subject: [PATCH] perf(local): skip per-minor passes for non-r-minor-sensitive packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A package's ABI sensitivity is the same across R minors, so for a non-sensitive package the per-minor loop only ran `ensure_bincraft` (a ~14s bincraft/cranlike install per minor) before build-one.R classified and skipped it. The primary pass now writes a .r_minor_sensitive sentinel when it builds a sensitive package, and the wrapper gates the whole per-minor loop (installs included) on that file — non-sensitive rebuilds no longer touch other minors' libraries. --- docker/build-one.Dockerfile | 27 ++++++++++++++++----------- local/build-one.R | 7 +++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/docker/build-one.Dockerfile b/docker/build-one.Dockerfile index 1884a44..2cd4d51 100644 --- a/docker/build-one.Dockerfile +++ b/docker/build-one.Dockerfile @@ -41,20 +41,25 @@ RUN --mount=type=secret,id=b2_access,required=true \ PRIMARY_MINOR=$(echo "$R_VERSION" | cut -d. -f1-2); \ seen=" $PRIMARY_MINOR "; \ prc=0; failed=""; \ + rm -f .r_minor_sensitive; \ echo "=== primary pass under R $R_VERSION ==="; \ ensure_bincraft /opt/R/${R_VERSION}/bin/R; \ run_build /opt/R/${R_VERSION}/bin/Rscript /work/build-one.R "${PACKAGE}" ${VERSIONS} || prc=$?; \ - for RBIN in /opt/R/*/bin/Rscript; do \ - [ -x "$RBIN" ] || continue; \ - RV=$(basename "$(dirname "$(dirname "$RBIN")")"); \ - case "$RV" in [0-9]*) ;; *) continue ;; esac; \ - RMINOR=$(echo "$RV" | cut -d. -f1-2); \ - case "$seen" in *" $RMINOR "*) continue ;; esac; \ - seen="$seen$RMINOR "; \ - echo "=== sensitive-only pass under R $RV ==="; \ - ensure_bincraft "$(dirname "$RBIN")/R"; \ - run_build "$RBIN" /work/build-one.R --sensitive-only "${PACKAGE}" ${VERSIONS} || failed="$failed $RV"; \ - done; \ + if [ -f .r_minor_sensitive ]; then \ + for RBIN in /opt/R/*/bin/Rscript; do \ + [ -x "$RBIN" ] || continue; \ + RV=$(basename "$(dirname "$(dirname "$RBIN")")"); \ + case "$RV" in [0-9]*) ;; *) continue ;; esac; \ + RMINOR=$(echo "$RV" | cut -d. -f1-2); \ + case "$seen" in *" $RMINOR "*) continue ;; esac; \ + seen="$seen$RMINOR "; \ + echo "=== sensitive-only pass under R $RV ==="; \ + ensure_bincraft "$(dirname "$RBIN")/R"; \ + run_build "$RBIN" /work/build-one.R --sensitive-only "${PACKAGE}" ${VERSIONS} || failed="$failed $RV"; \ + done; \ + else \ + echo "Package not r-minor-sensitive; skipping per-minor passes."; \ + fi; \ if [ -n "$failed" ]; then echo "WARNING: extra-minor build(s) failed (non-fatal; e.g. a version too old to compile on a newer R):$failed" >&2; fi; \ if [ "$prc" != 0 ]; then echo "primary pass under R $R_VERSION failed (exit $prc)" >&2; fi; \ exit "$prc" diff --git a/local/build-one.R b/local/build-one.R index 5531124..f2d6ebd 100644 --- a/local/build-one.R +++ b/local/build-one.R @@ -120,6 +120,13 @@ for (ver in versions) { if (sensitive) touched_minor <- TRUE else touched_generic <- TRUE } +# Signal the container wrapper whether per-minor passes are warranted (a single +# package's sensitivity is the same across R minors, so a non-sensitive package +# need not touch any other minor's library). +if (touched_minor) { + file.create(".r_minor_sensitive") +} + # Refresh the PACKAGES index for each slot we wrote to, so the (re)built binary # is immediately resolvable by clients. codename <- bincraft::set_codename(NULL)