From 2861d50446fa5317d1df63bf3b9c8e10b06a23af Mon Sep 17 00:00:00 2001 From: pat-s Date: Sun, 13 Sep 2026 09:34:09 +0000 Subject: [PATCH 01/16] fix(build): build packages requiring newer R on compatible minors --- .crow/build-all-versions.yaml | 2 + .crow/process-updates.yaml | 2 + README.md | 17 +++++++ justfile | 7 +++ local/build-newer-r.R | 72 ++++++++++++++++++++++++++ local/newer-r-helpers.R | 75 +++++++++++++++++++++++++++ local/tests/test-newer-r-helpers.R | 81 ++++++++++++++++++++++++++++++ 7 files changed, 256 insertions(+) create mode 100644 local/build-newer-r.R create mode 100644 local/newer-r-helpers.R create mode 100644 local/tests/test-newer-r-helpers.R diff --git a/.crow/build-all-versions.yaml b/.crow/build-all-versions.yaml index 91b7bcd..7451988 100644 --- a/.crow/build-all-versions.yaml +++ b/.crow/build-all-versions.yaml @@ -167,6 +167,8 @@ steps: R_LIBS_USER="$LIB" "$(dirname "$RBIN")/Rscript" local/install-bincraft.R || true R_LIBS_USER="$LIB" UVR_R_BIN="$RBIN" local/uvr-install.sh RPostgres || true R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -n $SPLIT_INDEX -- "$(dirname "$RBIN")/Rscript" local/build-all.R --sensitive-only $SPLIT_INTO $SPLIT_INDEX $NCPUS 2>&1 || true + # Also build current packages whose required dependency tree needs a newer R. + R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -n $SPLIT_INDEX -- "$(dirname "$RBIN")/Rscript" local/build-newer-r.R "$R_VERSION" $SPLIT_INTO $SPLIT_INDEX done # archive missed packages; first arg is the codename (e.g. "alpine324"), # derived via bincraft like the upload step, not paste(OS, OS_VERSION). diff --git a/.crow/process-updates.yaml b/.crow/process-updates.yaml index 4cd95a7..a1b9698 100644 --- a/.crow/process-updates.yaml +++ b/.crow/process-updates.yaml @@ -207,6 +207,8 @@ steps: R_LIBS_USER="$LIB" "$(dirname "$RBIN")/Rscript" local/install-bincraft.R || true R_LIBS_USER="$LIB" UVR_R_BIN="$RBIN" local/uvr-install.sh RPostgres || true R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -- "$(dirname "$RBIN")/R" -q -e "options(crayon.enabled = TRUE, Ncpus = 4, future.globals.onReference = NULL); bincraft::process_cran_updates(interval = $INTERVAL, platform = '${OS}', process_updated = TRUE, process_new = FALSE, process_removed = FALSE, patches = 'local/patches', r_minor_detection = 'classifier',r_minor_sensitive_only = TRUE, s3_endpoint = 'https://s3.eu-central-003.backblazeb2.com', s3_region = 'eu-central-003', s3_bucket = 'devxy-rpkgs-binaries', s3_access_key_id = Sys.getenv('B2_S3_ACCESS_KEY'), s3_secret_access_key = Sys.getenv('B2_S3_SECRET_KEY'), metadata_db_host = 'r-binaries.devxy.io', metadata_db_name = 'build_metadata', metadata_db_table = 'single_builds', metadata_db_user = 'rpkgs', metadata_db_password = Sys.getenv('PGPASS'), metadata_db_sslmode = 'require', metadata_db_port = 15432, archive = TRUE, upload = TRUE, store_build_metadata = TRUE)" || true + # Also build current packages whose required dependency tree needs a newer R. + R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -- "$(dirname "$RBIN")/Rscript" local/build-newer-r.R "$R_VERSION" done - /opt/R/$R_VERSION/bin/R -q -e 'library(bincraft); upload_package_index(codename = "${OS_ID}", s3_endpoint = "https://s3.eu-central-003.backblazeb2.com", s3_region = "eu-central-003", s3_bucket = "devxy-rpkgs-binaries", s3_access_key_id = Sys.getenv("B2_S3_ACCESS_KEY"), s3_secret_access_key = Sys.getenv("B2_S3_SECRET_KEY"))' - | diff --git a/README.md b/README.md index d137728..99d1143 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,23 @@ This elastic server architecture offers a robust and performant backend while mi ## Technical Details +### Packages requiring a newer R + +The daily update and weekly full-build pipelines run `local/build-newer-r.R` under each non-primary installed R, alongside the ABI-sensitive pass. +It selects current CRAN versions whose `Depends: R` constraints cannot be met by the slot's primary R but can be met by the running R, including incompatibility inherited through `Depends`, `Imports`, and `LinkingTo`. +These builds retain bincraft's ABI classification and storage routing: sensitive binaries use the running minor, while safe binaries can be shared. +No shared S3 existence cache is passed, so bincraft checks the actual objects and distinguishes a source fallback from a binary. +The pass reads unfiltered CRAN metadata independently of the weekly snapshot and its primary-R failure exclusions; existing binaries and failures for the running minor retain bincraft's usual skip behavior. +Weekly workers split this extra work across their existing shards. +This does not select older archive versions for unsupported R minors or change index filtering. + +Preview the selection without building or accessing storage or build metadata: + +```sh +# Run with the target R and supply the slot's full primary R version. +/opt/R/4.6.0/bin/Rscript local/build-newer-r.R 4.4.3 --dry-run +``` + ### Creating/Updating the PACKAGES Index Files Currently, the {cranlike} and {desc} packages only work with files on a local file system. diff --git a/justfile b/justfile index 36ad0e1..524ac9a 100644 --- a/justfile +++ b/justfile @@ -95,3 +95,10 @@ check-slots: # strip a retired slot from .crow/*.yaml (dry run; pass --apply to write) retire-slot codename *flags: Rscript local/retire-slot.R {{ codename }} --config-only {{ flags }} + +# Format or lint selected R files, defaulting to local tooling. +format *files="local": + air format {{ files }} + +fix *files="local": + jarl check --fix {{ files }} diff --git a/local/build-newer-r.R b/local/build-newer-r.R new file mode 100644 index 0000000..3d7794f --- /dev/null +++ b/local/build-newer-r.R @@ -0,0 +1,72 @@ +source(file.path("local", "newer-r-helpers.R")) +source(file.path("local", "rebuild-missing-helpers.R")) + +args <- commandArgs(trailingOnly = TRUE) +pos <- args[!startsWith(args, "--")] +if (!length(pos) %in% c(1L, 3L)) { + stop("Usage: build-newer-r.R PRIMARY_R [SPLIT_INTO SPLIT_INDEX] [--dry-run]") +} +primary_r <- pos[1L] +target_r <- as.character(getRversion()) +pkgs <- newer_r_candidates(tools::CRAN_package_db(), primary_r, target_r) +exclude <- jsonlite::fromJSON("local/excluded-packages.json")[["package"]] +pkgs <- pkgs[!pkgs$Package %in% exclude, , drop = FALSE] +if (length(pos) == 3L) { + pkgs <- pkgs[ + shard_slice(seq_len(nrow(pkgs)), pos[2L], pos[3L]), + , + drop = FALSE + ] +} +message(sprintf( + "R %s: %d package(s) unsupported by primary R %s", + target_r, + nrow(pkgs), + primary_r +)) +if ("--dry-run" %in% args) { + print(pkgs, row.names = FALSE) +} else { + options(crayon.enabled = TRUE, Ncpus = 4, future.globals.onReference = NULL) + for (i in seq_len(nrow(pkgs))) { + message(sprintf( + "[%d/%d] %s %s", + i, + nrow(pkgs), + pkgs$Package[i], + pkgs$Version[i] + )) + bincraft::build_binary_package( + pkgs$Package[i], + tag = pkgs$Version[i], + # Keep bincraft's normal ABI routing: safe binaries can be shared; + # sensitive ones use this interpreter's minor for presence and output. + is_r_minor_sensitive = bincraft::classify_r_minor_sensitive( + pkgs$Package[i], + pkgs$Version[i], + metadata_db_host = "r-binaries.devxy.io", + metadata_db_name = "build_metadata", + metadata_db_user = "rpkgs", + metadata_db_password = Sys.getenv("PGPASS"), + metadata_db_sslmode = "require", + metadata_db_port = 15432 + ), + s3_endpoint = "https://s3.eu-central-003.backblazeb2.com", + s3_region = "eu-central-003", + s3_bucket = "devxy-rpkgs-binaries", + s3_access_key_id = Sys.getenv("B2_S3_ACCESS_KEY"), + s3_secret_access_key = Sys.getenv("B2_S3_SECRET_KEY"), + metadata_db_host = "r-binaries.devxy.io", + metadata_db_name = "build_metadata", + metadata_db_table = "single_builds", + metadata_db_user = "rpkgs", + metadata_db_password = Sys.getenv("PGPASS"), + metadata_db_sslmode = "require", + metadata_db_port = 15432, + archive = TRUE, + patches = "local/patches", + upload = TRUE, + store_build_metadata = TRUE + ) + } +} diff --git a/local/newer-r-helpers.R b/local/newer-r-helpers.R new file mode 100644 index 0000000..4b83204 --- /dev/null +++ b/local/newer-r-helpers.R @@ -0,0 +1,75 @@ +# Evaluate every R constraint, including patch-level and upper bounds. +r_requirement_satisfied <- function(depends, r_version) { + if (is.na(depends) || !nzchar(trimws(depends))) { + return(TRUE) + } + entries <- trimws(strsplit(depends, ",", fixed = TRUE)[[1L]]) + entries <- entries[grepl("^R(\\s|\\(|$)", entries)] + all(vapply( + entries, + function(entry) { + if (entry == "R") { + return(TRUE) + } + match <- regmatches( + entry, + regexec( + "^R\\s*\\(\\s*(>=|<=|==|>|<)\\s*([0-9]+(?:[.-][0-9]+)*)\\s*\\)$", + entry, + perl = TRUE + ) + )[[1L]] + if (length(match) != 3L) { + stop("Cannot parse R dependency: ", entry) + } + comparison <- utils::compareVersion(r_version, match[3L]) + switch( + match[2L], + ">=" = comparison >= 0L, + "<=" = comparison <= 0L, + "==" = comparison == 0L, + ">" = comparison > 0L, + "<" = comparison < 0L + ) + }, + logical(1L) + )) +} + +# Use unfiltered current CRAN metadata: available.packages() would hide exactly +# the packages that cannot run under the primary interpreter. +# Propagate R incompatibility through required dependencies, not Suggests. +newer_r_candidates <- function(db, primary_r, target_r) { + db <- as.data.frame(db, stringsAsFactors = FALSE) + # CRAN also lists R-specific Recommended copies (e.g. Matrix for R-devel). + # Prefer the ordinary contrib record, or a future-R copy can incorrectly + # block every package depending on Matrix on all released interpreters. + if ("Path" %in% names(db)) { + db <- db[order(!is.na(db$Path) & nzchar(db$Path)), , drop = FALSE] + } + db <- db[!duplicated(db$Package), , drop = FALSE] + deps <- tools::package_dependencies( + packages = db$Package, + db = as.matrix(db), + which = c("Depends", "Imports", "LinkingTo"), + recursive = FALSE + ) + supported <- function(version) { + ok <- vapply(db$Depends, r_requirement_satisfied, logical(1L), version) + repeat { + blocked <- db$Package[!ok] + next_ok <- ok & + !vapply(deps, function(x) any(x %in% blocked), logical(1L)) + if (identical(ok, next_ok)) { + return(ok) + } + ok <- next_ok + } + } + selected <- !supported(primary_r) & supported(target_r) + if ("OS_type" %in% names(db)) { + selected <- selected & (is.na(db$OS_type) | db$OS_type != "windows") + } + result <- db[selected, c("Package", "Version"), drop = FALSE] + result[order(result$Package), , drop = FALSE] +} diff --git a/local/tests/test-newer-r-helpers.R b/local/tests/test-newer-r-helpers.R new file mode 100644 index 0000000..c202b7f --- /dev/null +++ b/local/tests/test-newer-r-helpers.R @@ -0,0 +1,81 @@ +source(file.path("..", "newer-r-helpers.R")) + +test_that("R constraints respect patch versions, bounds, and missing fields", { + expect_true(r_requirement_satisfied(NA_character_, "4.4.3")) + expect_true(r_requirement_satisfied( + "Matrix (>= 1.4-0), R (>= 4.5.0)", + "4.5.3" + )) + expect_false(r_requirement_satisfied("R (>= 4.5.0)", "4.4.3")) + expect_false(r_requirement_satisfied("R (>= 4.5.4)", "4.5.3")) + expect_true(r_requirement_satisfied("R (>= 4.5), R (< 4.6)", "4.5.3")) + expect_false(r_requirement_satisfied("R (>= 4.5), R (< 4.6)", "4.6.0")) + expect_true(r_requirement_satisfied("R (== 4.5.3)", "4.5.3")) + expect_true(r_requirement_satisfied("R (> 4.5.2), R (<= 4.5.3)", "4.5.3")) + expect_true(r_requirement_satisfied("R, Rcpp (>= 1.0)", "4.4.3")) + expect_error(r_requirement_satisfied("R (~ 4.5)", "4.5.3"), "Cannot parse") +}) + +fixture <- function() { + data.frame( + Package = c( + "arules", + "arulesSequences", + "indirect", + "optional", + "ordinary", + "future", + "blocked" + ), + Version = rep("1.0", 7L), + Depends = c( + "R (>= 4.5.0)", + "arules", + NA, + NA, + "R (>= 4.0)", + "R (>= 4.7)", + NA + ), + Imports = c(NA, NA, "arulesSequences", NA, NA, NA, "arules, future"), + LinkingTo = NA_character_, + Suggests = c(NA, NA, NA, "arules", NA, NA, NA) + ) +} + +test_that("every compatible newer minor includes required dependents only", { + db <- fixture() + for (target in c("4.5.3", "4.6.0")) { + expect_identical( + newer_r_candidates(db, "4.4.3", target)$Package, + c("arules", "arulesSequences", "indirect") + ) + } + expect_equal(nrow(newer_r_candidates(db, "4.4.3", "4.4.3")), 0L) + expect_equal(nrow(newer_r_candidates(db, "4.5.3", "4.4.3")), 0L) + expect_equal(nrow(newer_r_candidates(db, "4.5.3", "4.6.0")), 0L) +}) + +test_that("LinkingTo, dependency cycles, Windows and empty metadata are handled", { + db <- fixture() + db$LinkingTo[5L] <- "arules" + db$Imports[1L] <- "ordinary" + db$OS_type <- c(NA, "windows", rep(NA_character_, 5L)) + expect_identical( + newer_r_candidates(db, "4.4.3", "4.6.0")$Package, + c("arules", "indirect", "ordinary") + ) + expect_equal(nrow(newer_r_candidates(db[FALSE, ], "4.4.3", "4.6.0")), 0L) +}) + +test_that("R-devel Recommended copies cannot block ordinary CRAN dependencies", { + db <- fixture() + db$Path <- NA_character_ + future_copy <- db[1L, ] + future_copy$Depends <- "R (>= 4.7)" + future_copy$Path <- "4.7.0/Recommended" + expect_identical( + newer_r_candidates(rbind(future_copy, db), "4.4.3", "4.6.1")$Package, + c("arules", "arulesSequences", "indirect") + ) +}) From 6b764d2014cb97e69a7ee7bac135afa85f5fc5c1 Mon Sep 17 00:00:00 2001 From: pat-s Date: Sun, 13 Sep 2026 09:35:50 +0000 Subject: [PATCH 02/16] fix(build): build packages requiring newer R on compatible minors (#216) --- .crow/build-all-versions.yaml | 2 + .crow/process-updates.yaml | 2 + README.md | 17 +++++++ justfile | 7 +++ local/build-newer-r.R | 72 ++++++++++++++++++++++++++ local/newer-r-helpers.R | 75 +++++++++++++++++++++++++++ local/tests/test-newer-r-helpers.R | 81 ++++++++++++++++++++++++++++++ 7 files changed, 256 insertions(+) create mode 100644 local/build-newer-r.R create mode 100644 local/newer-r-helpers.R create mode 100644 local/tests/test-newer-r-helpers.R diff --git a/.crow/build-all-versions.yaml b/.crow/build-all-versions.yaml index 91b7bcd..7451988 100644 --- a/.crow/build-all-versions.yaml +++ b/.crow/build-all-versions.yaml @@ -167,6 +167,8 @@ steps: R_LIBS_USER="$LIB" "$(dirname "$RBIN")/Rscript" local/install-bincraft.R || true R_LIBS_USER="$LIB" UVR_R_BIN="$RBIN" local/uvr-install.sh RPostgres || true R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -n $SPLIT_INDEX -- "$(dirname "$RBIN")/Rscript" local/build-all.R --sensitive-only $SPLIT_INTO $SPLIT_INDEX $NCPUS 2>&1 || true + # Also build current packages whose required dependency tree needs a newer R. + R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -n $SPLIT_INDEX -- "$(dirname "$RBIN")/Rscript" local/build-newer-r.R "$R_VERSION" $SPLIT_INTO $SPLIT_INDEX done # archive missed packages; first arg is the codename (e.g. "alpine324"), # derived via bincraft like the upload step, not paste(OS, OS_VERSION). diff --git a/.crow/process-updates.yaml b/.crow/process-updates.yaml index 4cd95a7..a1b9698 100644 --- a/.crow/process-updates.yaml +++ b/.crow/process-updates.yaml @@ -207,6 +207,8 @@ steps: R_LIBS_USER="$LIB" "$(dirname "$RBIN")/Rscript" local/install-bincraft.R || true R_LIBS_USER="$LIB" UVR_R_BIN="$RBIN" local/uvr-install.sh RPostgres || true R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -- "$(dirname "$RBIN")/R" -q -e "options(crayon.enabled = TRUE, Ncpus = 4, future.globals.onReference = NULL); bincraft::process_cran_updates(interval = $INTERVAL, platform = '${OS}', process_updated = TRUE, process_new = FALSE, process_removed = FALSE, patches = 'local/patches', r_minor_detection = 'classifier',r_minor_sensitive_only = TRUE, s3_endpoint = 'https://s3.eu-central-003.backblazeb2.com', s3_region = 'eu-central-003', s3_bucket = 'devxy-rpkgs-binaries', s3_access_key_id = Sys.getenv('B2_S3_ACCESS_KEY'), s3_secret_access_key = Sys.getenv('B2_S3_SECRET_KEY'), metadata_db_host = 'r-binaries.devxy.io', metadata_db_name = 'build_metadata', metadata_db_table = 'single_builds', metadata_db_user = 'rpkgs', metadata_db_password = Sys.getenv('PGPASS'), metadata_db_sslmode = 'require', metadata_db_port = 15432, archive = TRUE, upload = TRUE, store_build_metadata = TRUE)" || true + # Also build current packages whose required dependency tree needs a newer R. + R_LIBS_USER="$LIB" $XVFB $XVFB_ARGS -- "$(dirname "$RBIN")/Rscript" local/build-newer-r.R "$R_VERSION" done - /opt/R/$R_VERSION/bin/R -q -e 'library(bincraft); upload_package_index(codename = "${OS_ID}", s3_endpoint = "https://s3.eu-central-003.backblazeb2.com", s3_region = "eu-central-003", s3_bucket = "devxy-rpkgs-binaries", s3_access_key_id = Sys.getenv("B2_S3_ACCESS_KEY"), s3_secret_access_key = Sys.getenv("B2_S3_SECRET_KEY"))' - | diff --git a/README.md b/README.md index d137728..99d1143 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,23 @@ This elastic server architecture offers a robust and performant backend while mi ## Technical Details +### Packages requiring a newer R + +The daily update and weekly full-build pipelines run `local/build-newer-r.R` under each non-primary installed R, alongside the ABI-sensitive pass. +It selects current CRAN versions whose `Depends: R` constraints cannot be met by the slot's primary R but can be met by the running R, including incompatibility inherited through `Depends`, `Imports`, and `LinkingTo`. +These builds retain bincraft's ABI classification and storage routing: sensitive binaries use the running minor, while safe binaries can be shared. +No shared S3 existence cache is passed, so bincraft checks the actual objects and distinguishes a source fallback from a binary. +The pass reads unfiltered CRAN metadata independently of the weekly snapshot and its primary-R failure exclusions; existing binaries and failures for the running minor retain bincraft's usual skip behavior. +Weekly workers split this extra work across their existing shards. +This does not select older archive versions for unsupported R minors or change index filtering. + +Preview the selection without building or accessing storage or build metadata: + +```sh +# Run with the target R and supply the slot's full primary R version. +/opt/R/4.6.0/bin/Rscript local/build-newer-r.R 4.4.3 --dry-run +``` + ### Creating/Updating the PACKAGES Index Files Currently, the {cranlike} and {desc} packages only work with files on a local file system. diff --git a/justfile b/justfile index 36ad0e1..524ac9a 100644 --- a/justfile +++ b/justfile @@ -95,3 +95,10 @@ check-slots: # strip a retired slot from .crow/*.yaml (dry run; pass --apply to write) retire-slot codename *flags: Rscript local/retire-slot.R {{ codename }} --config-only {{ flags }} + +# Format or lint selected R files, defaulting to local tooling. +format *files="local": + air format {{ files }} + +fix *files="local": + jarl check --fix {{ files }} diff --git a/local/build-newer-r.R b/local/build-newer-r.R new file mode 100644 index 0000000..3d7794f --- /dev/null +++ b/local/build-newer-r.R @@ -0,0 +1,72 @@ +source(file.path("local", "newer-r-helpers.R")) +source(file.path("local", "rebuild-missing-helpers.R")) + +args <- commandArgs(trailingOnly = TRUE) +pos <- args[!startsWith(args, "--")] +if (!length(pos) %in% c(1L, 3L)) { + stop("Usage: build-newer-r.R PRIMARY_R [SPLIT_INTO SPLIT_INDEX] [--dry-run]") +} +primary_r <- pos[1L] +target_r <- as.character(getRversion()) +pkgs <- newer_r_candidates(tools::CRAN_package_db(), primary_r, target_r) +exclude <- jsonlite::fromJSON("local/excluded-packages.json")[["package"]] +pkgs <- pkgs[!pkgs$Package %in% exclude, , drop = FALSE] +if (length(pos) == 3L) { + pkgs <- pkgs[ + shard_slice(seq_len(nrow(pkgs)), pos[2L], pos[3L]), + , + drop = FALSE + ] +} +message(sprintf( + "R %s: %d package(s) unsupported by primary R %s", + target_r, + nrow(pkgs), + primary_r +)) +if ("--dry-run" %in% args) { + print(pkgs, row.names = FALSE) +} else { + options(crayon.enabled = TRUE, Ncpus = 4, future.globals.onReference = NULL) + for (i in seq_len(nrow(pkgs))) { + message(sprintf( + "[%d/%d] %s %s", + i, + nrow(pkgs), + pkgs$Package[i], + pkgs$Version[i] + )) + bincraft::build_binary_package( + pkgs$Package[i], + tag = pkgs$Version[i], + # Keep bincraft's normal ABI routing: safe binaries can be shared; + # sensitive ones use this interpreter's minor for presence and output. + is_r_minor_sensitive = bincraft::classify_r_minor_sensitive( + pkgs$Package[i], + pkgs$Version[i], + metadata_db_host = "r-binaries.devxy.io", + metadata_db_name = "build_metadata", + metadata_db_user = "rpkgs", + metadata_db_password = Sys.getenv("PGPASS"), + metadata_db_sslmode = "require", + metadata_db_port = 15432 + ), + s3_endpoint = "https://s3.eu-central-003.backblazeb2.com", + s3_region = "eu-central-003", + s3_bucket = "devxy-rpkgs-binaries", + s3_access_key_id = Sys.getenv("B2_S3_ACCESS_KEY"), + s3_secret_access_key = Sys.getenv("B2_S3_SECRET_KEY"), + metadata_db_host = "r-binaries.devxy.io", + metadata_db_name = "build_metadata", + metadata_db_table = "single_builds", + metadata_db_user = "rpkgs", + metadata_db_password = Sys.getenv("PGPASS"), + metadata_db_sslmode = "require", + metadata_db_port = 15432, + archive = TRUE, + patches = "local/patches", + upload = TRUE, + store_build_metadata = TRUE + ) + } +} diff --git a/local/newer-r-helpers.R b/local/newer-r-helpers.R new file mode 100644 index 0000000..4b83204 --- /dev/null +++ b/local/newer-r-helpers.R @@ -0,0 +1,75 @@ +# Evaluate every R constraint, including patch-level and upper bounds. +r_requirement_satisfied <- function(depends, r_version) { + if (is.na(depends) || !nzchar(trimws(depends))) { + return(TRUE) + } + entries <- trimws(strsplit(depends, ",", fixed = TRUE)[[1L]]) + entries <- entries[grepl("^R(\\s|\\(|$)", entries)] + all(vapply( + entries, + function(entry) { + if (entry == "R") { + return(TRUE) + } + match <- regmatches( + entry, + regexec( + "^R\\s*\\(\\s*(>=|<=|==|>|<)\\s*([0-9]+(?:[.-][0-9]+)*)\\s*\\)$", + entry, + perl = TRUE + ) + )[[1L]] + if (length(match) != 3L) { + stop("Cannot parse R dependency: ", entry) + } + comparison <- utils::compareVersion(r_version, match[3L]) + switch( + match[2L], + ">=" = comparison >= 0L, + "<=" = comparison <= 0L, + "==" = comparison == 0L, + ">" = comparison > 0L, + "<" = comparison < 0L + ) + }, + logical(1L) + )) +} + +# Use unfiltered current CRAN metadata: available.packages() would hide exactly +# the packages that cannot run under the primary interpreter. +# Propagate R incompatibility through required dependencies, not Suggests. +newer_r_candidates <- function(db, primary_r, target_r) { + db <- as.data.frame(db, stringsAsFactors = FALSE) + # CRAN also lists R-specific Recommended copies (e.g. Matrix for R-devel). + # Prefer the ordinary contrib record, or a future-R copy can incorrectly + # block every package depending on Matrix on all released interpreters. + if ("Path" %in% names(db)) { + db <- db[order(!is.na(db$Path) & nzchar(db$Path)), , drop = FALSE] + } + db <- db[!duplicated(db$Package), , drop = FALSE] + deps <- tools::package_dependencies( + packages = db$Package, + db = as.matrix(db), + which = c("Depends", "Imports", "LinkingTo"), + recursive = FALSE + ) + supported <- function(version) { + ok <- vapply(db$Depends, r_requirement_satisfied, logical(1L), version) + repeat { + blocked <- db$Package[!ok] + next_ok <- ok & + !vapply(deps, function(x) any(x %in% blocked), logical(1L)) + if (identical(ok, next_ok)) { + return(ok) + } + ok <- next_ok + } + } + selected <- !supported(primary_r) & supported(target_r) + if ("OS_type" %in% names(db)) { + selected <- selected & (is.na(db$OS_type) | db$OS_type != "windows") + } + result <- db[selected, c("Package", "Version"), drop = FALSE] + result[order(result$Package), , drop = FALSE] +} diff --git a/local/tests/test-newer-r-helpers.R b/local/tests/test-newer-r-helpers.R new file mode 100644 index 0000000..c202b7f --- /dev/null +++ b/local/tests/test-newer-r-helpers.R @@ -0,0 +1,81 @@ +source(file.path("..", "newer-r-helpers.R")) + +test_that("R constraints respect patch versions, bounds, and missing fields", { + expect_true(r_requirement_satisfied(NA_character_, "4.4.3")) + expect_true(r_requirement_satisfied( + "Matrix (>= 1.4-0), R (>= 4.5.0)", + "4.5.3" + )) + expect_false(r_requirement_satisfied("R (>= 4.5.0)", "4.4.3")) + expect_false(r_requirement_satisfied("R (>= 4.5.4)", "4.5.3")) + expect_true(r_requirement_satisfied("R (>= 4.5), R (< 4.6)", "4.5.3")) + expect_false(r_requirement_satisfied("R (>= 4.5), R (< 4.6)", "4.6.0")) + expect_true(r_requirement_satisfied("R (== 4.5.3)", "4.5.3")) + expect_true(r_requirement_satisfied("R (> 4.5.2), R (<= 4.5.3)", "4.5.3")) + expect_true(r_requirement_satisfied("R, Rcpp (>= 1.0)", "4.4.3")) + expect_error(r_requirement_satisfied("R (~ 4.5)", "4.5.3"), "Cannot parse") +}) + +fixture <- function() { + data.frame( + Package = c( + "arules", + "arulesSequences", + "indirect", + "optional", + "ordinary", + "future", + "blocked" + ), + Version = rep("1.0", 7L), + Depends = c( + "R (>= 4.5.0)", + "arules", + NA, + NA, + "R (>= 4.0)", + "R (>= 4.7)", + NA + ), + Imports = c(NA, NA, "arulesSequences", NA, NA, NA, "arules, future"), + LinkingTo = NA_character_, + Suggests = c(NA, NA, NA, "arules", NA, NA, NA) + ) +} + +test_that("every compatible newer minor includes required dependents only", { + db <- fixture() + for (target in c("4.5.3", "4.6.0")) { + expect_identical( + newer_r_candidates(db, "4.4.3", target)$Package, + c("arules", "arulesSequences", "indirect") + ) + } + expect_equal(nrow(newer_r_candidates(db, "4.4.3", "4.4.3")), 0L) + expect_equal(nrow(newer_r_candidates(db, "4.5.3", "4.4.3")), 0L) + expect_equal(nrow(newer_r_candidates(db, "4.5.3", "4.6.0")), 0L) +}) + +test_that("LinkingTo, dependency cycles, Windows and empty metadata are handled", { + db <- fixture() + db$LinkingTo[5L] <- "arules" + db$Imports[1L] <- "ordinary" + db$OS_type <- c(NA, "windows", rep(NA_character_, 5L)) + expect_identical( + newer_r_candidates(db, "4.4.3", "4.6.0")$Package, + c("arules", "indirect", "ordinary") + ) + expect_equal(nrow(newer_r_candidates(db[FALSE, ], "4.4.3", "4.6.0")), 0L) +}) + +test_that("R-devel Recommended copies cannot block ordinary CRAN dependencies", { + db <- fixture() + db$Path <- NA_character_ + future_copy <- db[1L, ] + future_copy$Depends <- "R (>= 4.7)" + future_copy$Path <- "4.7.0/Recommended" + expect_identical( + newer_r_candidates(rbind(future_copy, db), "4.4.3", "4.6.1")$Package, + c("arules", "arulesSequences", "indirect") + ) +}) From b0bade879b16e2c4d2a09a4f87fe7b867a71060e Mon Sep 17 00:00:00 2001 From: automation-bot Date: Mon, 14 Sep 2026 00:32:09 +0000 Subject: [PATCH 03/16] chore(deps): lock file maintenance --- .terraform.lock.hcl | 62 ++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 9591b83..5e45f89 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -2,38 +2,38 @@ # Manual edits may be lost in future updates. provider "registry.opentofu.org/hashicorp/http" { - version = "3.6.1" + version = "3.6.2" hashes = [ - "h1:7fra+jbUXbG5wMaz5L6RKMBv6gIuenJcBiIww87GoXo=", - "h1:BzSV3Ie9XMXF7sZHKAS54CzV95v5GBZNhQ4nrprUgfQ=", - "h1:CkrbSKS+pNVgvP3bMe2WoYHaFCIWJUkCtlC5vyTAdLI=", - "h1:FboJEwgVIRmqUJkjEoSRpfavVCJotUTe1zzT+pBzcV0=", - "h1:GlXELDLSZrdV3Svx1jjEBAXiJFkkdF/Hgx1qrmRK5hE=", - "h1:VuXFI2IcnZ6t4sDqtvkuIzbPK1CJQa0CkaM0MBuOlSU=", - "h1:WmL2nFQbSzRiDsDiwUbZbBp/cxGQrXrZnB7A4LGSvJU=", - "h1:Zdj26awWJ+m8kMoAMhItsIDcDFg81PWgKKJrvNi3WOI=", - "h1:lHvYYIumeZ+KJgCrmhCLnRGzrvNMjSHBTdV24coyMEc=", - "h1:pAOYMwA6Zki3ujAbG20b49u1IYXdBz56pW1JHqKdX5U=", - "h1:qi9GUp2+g69C8zY6Z68u4fWPwcZlDTa/CtdhvPgWbMA=", - "h1:w5A3xJ2mowj2wgiE3oNfOI0lFJf5X9IgxOJ6SErMczA=", - "h1:xAO03iJyuNGSOqolIcXcofH8cocgUb6Cnzq6yivbWcI=", - "h1:xXigGPwW8MlrB6Br2ce+Bf35BbdzdPKa97T/q/xrrcA=", - "h1:yDYzQ2ncNE9q1288xAgflIPq98bOOYsAb9tq6vkbFzw=", - "zh:129d7d5944b31f40916b1ca86b31cef65a6b02fd36008809d13c561894bfedb9", - "zh:24631608288b0bcd35c1fc63dc5839572254d881c0589ebba036be52b2fc04d6", - "zh:5a0f100d7eb256463fe5a2aa1a7128391147b2c5fc895ff1b1ef54fc5b8f15ab", - "zh:6a8a1126ab9ca61be3b62ec184f6b2e7cbf01cde810acc548cee27d71277b09b", - "zh:6fffef54fd3aada85c074e34d41386aa09c79a308a4679132da31c7272733c6c", - "zh:899c992d2aa290ebe1304da0289c5104a630bca421cc6a88ce55bf0960aab1b4", - "zh:960fd6c2847859a843dd9dbfc95a0037a470aa744094d155a38a057175cf1502", - "zh:9b032b685a644634158ace5529e260dfc4447a280056f02858d205ea26753f69", - "zh:bba5477c97020c28ed12d4f5b36be2c1bf14d946d7e44b3690e5c23cd7ddf5e6", - "zh:c2ff6c33efef52441fa3485137972792031626dcabca2b1d8b6527d45f185279", - "zh:cd492b3dfd150de6bef8ad505293d3d53c6c907706f36d0e497b4fc027d8edb6", - "zh:d1f832bc33c42781454dc020c6937e7d0133155a5a9f64335309d64a34b36bb7", - "zh:d42e9cbebc77643556853b1ebbec14cefe70c57ee86cd3b8c71fbe7f523f07df", - "zh:d4c0466f578d7f990646bb0847e31ba3797f2100b6380ee1ca736887546c7621", - "zh:d9d81ecebfe6edabdd4c527f3f4debde3e052ff87c5ef4c67497ab3d7539e424", + "h1:7+Ewr07oLewLfoe5K7Fhy4T5JUU4y7I7iRGTG2hrzy4=", + "h1:8AvJ6H30J1tgxwEoVKxe0B0Ac9XFn1gwOzidrIc+F5o=", + "h1:AllxtaK2m88aY+QitHui6kik/qJmBakrH5o5W7vOKI0=", + "h1:OimQGm1/9sIkdDCuUb8D5sxDorhektHeCQ337DHDfGk=", + "h1:T5zxkFXQ9To+ZysjCZu6gFqE8G1aTGh58Ol20bCk1Fc=", + "h1:TZlCCHsmKXSI3FyzmSgCU+TarKOHgiOft0wiYh85Y+E=", + "h1:VgyzPdGw1U/KU8gKhefKlIhy5kQYdpoZkpNcGiTgvVs=", + "h1:aF+Ztfy9m0Ll6nFOtC90NxN6WIEKAmfmVFhXAtFF8CI=", + "h1:bgViIoXF7kMXA7xgNikFYfv1D15rregO8I8Sq95sLGQ=", + "h1:d7tCAc1wr1seWpGMBx7tpRyGKOCicvozaHvn5X8ZFfM=", + "h1:dRCrpHH2UrkKs/lCqewyA00L0VfOCETVM14NBhyxHaM=", + "h1:eIqaNIixQTlhmr2GU1fAFH+eVYLQIfeGw7Ec+JT/bEo=", + "h1:hrK+Jzpgivi4Jo356K3LYDoeWBV1bMqKPBEqrEHwgpA=", + "h1:mrpIAC+TK3rQQz2jllAF8o2WLMKM14/WoclLgYKc4WA=", + "h1:zwE/uNBapBDpkKa5I24moawVPTanbG+eKumHRm/qINw=", + "zh:0cf6173a426f65a85e8baf4f9a7808dc94d0e02a82b34bc903555fda1eb45d7a", + "zh:2b5fa2b0487e692014fa86745a2a98d43f34f7aaea044acd3e2cee139627c9f1", + "zh:2c9c18893ce0f34e077559632c88237d172ac6646853bf00c84a5a4ec3b6c241", + "zh:316c848e892764aa10a890cf2455f52b592c6051a92ac8451955ca1d47ca1d2f", + "zh:4300e32ecaa967ca0ed56ca48f8dcd10796e70203bf6b8311e71dc43cd0d2aa1", + "zh:4a0a555d85a31bd257399253b502ad03816ccdba7b8fbbbd1e07a313d04d83fb", + "zh:6278773c31c1605c6d780fc982eacb83944e2807c8d8afe11534253b225c5aa3", + "zh:81b73da8dbcedf54604f131e0acd7ebd36cf673276174b4b4f10af0b0f10de11", + "zh:887beaa6ef6521d3f5e2b1193d458575fb91855f36bc66dd26a10988127a39fb", + "zh:91b2260424c5f8e5968d9e6d5bdbbdb60d61ccc4ff001aa0d637427629349c54", + "zh:a5d9d7032d00a6dd844e8d0d374b5ae89e25f9a6635a90e01c5f65e9dd14a93e", + "zh:bcf8b2aca448774e4701f221b74d762847be55dc312022b4aad66da3b389bf5d", + "zh:d62a3ad37ee1fb943ad0590978f4e7ee0ac064d19554c1c05ec98e9d2bb658f7", + "zh:e517b8b81fe88bf49868923f076515b9157771d1d3a80849cc8a73b9a19039a1", + "zh:fa9e0e39ef3e5ed2e6cf5886a0b569415ca3b89b9289fd6d01824ff11e470618", ] } From 3325a7bda2542835ba95ae3f6a4b64c41355ec01 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Thu, 17 Sep 2026 00:32:19 +0000 Subject: [PATCH 04/16] chore(deps): update pre-commit hook rbubley/mirrors-prettier to v3.9.7 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4e28c6d..2c8e4b8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: hooks: - id: markdownlint-cli2 - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.9.6 + rev: v3.9.7 hooks: - id: prettier - repo: https://github.com/posit-dev/air-pre-commit From caefd1131f68634354becf541da7e05a9b790a74 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Sat, 19 Sep 2026 00:32:12 +0000 Subject: [PATCH 05/16] chore(deps): update pre-commit hook rbubley/mirrors-prettier to v3.9.8 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2c8e4b8..a64e94b 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: hooks: - id: markdownlint-cli2 - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.9.7 + rev: v3.9.8 hooks: - id: prettier - repo: https://github.com/posit-dev/air-pre-commit From 212065f5a439f8391172d74b4c32016537a87316 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Sun, 20 Sep 2026 00:31:53 +0000 Subject: [PATCH 06/16] chore(deps): update pre-commit hook editorconfig-checker/editorconfig-checker to v4.0.2 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a64e94b..42fa0ab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,7 +36,7 @@ repos: hooks: - id: air-format - repo: https://github.com/editorconfig-checker/editorconfig-checker - rev: v4.0.1 + rev: v4.0.2 hooks: - id: editorconfig-checker exclude: ^local/patches/.*\.patch$ From aa6e5e9dd804948a50be36db2dffad0943cb9fa6 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Mon, 21 Sep 2026 00:31:54 +0000 Subject: [PATCH 07/16] chore(deps): update pre-commit hook davidanson/markdownlint-cli2 to v0.23.3 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42fa0ab..d76cab5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: args: - --markdown-linebreak-ext=md - repo: https://github.com/DavidAnson/markdownlint-cli2 - rev: v0.23.2 + rev: v0.23.3 hooks: - id: markdownlint-cli2 - repo: https://github.com/rbubley/mirrors-prettier From 3962ed6d6129806557c5e68334d1a3f0368fd321 Mon Sep 17 00:00:00 2001 From: pat-s Date: Tue, 22 Sep 2026 12:17:52 +0000 Subject: [PATCH 08/16] fix(installer): install gettext headers on Alpine (#222) --- local/uvr-install.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/local/uvr-install.sh b/local/uvr-install.sh index 3966e85..ed6b1ce 100755 --- a/local/uvr-install.sh +++ b/local/uvr-install.sh @@ -16,8 +16,8 @@ # precisely because such a target may be shared (`/mnt/cache/R-pkgs` holds # bincraft and its dependencies alongside whatever this script installs). # -# System dependencies come from uvr's vendored r-system-requirements rules, so -# `pak::sysreqs_db_update()` and `PKG_SYSREQS_PLATFORM` are no longer needed. +# System dependencies come from uvr's vendored r-system-requirements rules, +# with explicit prerequisites below for gaps in Alpine support. # # Environment: # UVR_R_BIN R interpreter to install for; set by install-bincraft.R so @@ -117,4 +117,11 @@ if command -v apt-get >/dev/null 2>&1; then apt-get update -qq || echo "warning: apt-get update failed; continuing" >&2 fi +# Alpine's build images lack libintl.h, which data.table needs when R enables +# NLS. uvr does not resolve this prerequisite on Alpine, so install it before +# compiling bincraft's dependencies (including when the library cache is cold). +if command -v apk >/dev/null 2>&1; then + apk add --no-cache gettext-dev +fi + "$uvr_bin" sync --library "$target_lib" --install-system-deps From e8b0df0c910fe6ff55d5242170cb1df4f73ca540 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Wed, 23 Sep 2026 00:32:05 +0000 Subject: [PATCH 09/16] chore(deps): update terraform bunnynet to ~> 0.19 --- .terraform.lock.hcl | 72 ++++++++++++++++++++++----------------------- provider.tf | 2 +- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 5e45f89..2b8939f 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -38,43 +38,43 @@ provider "registry.opentofu.org/hashicorp/http" { } provider "registry.terraform.io/bunnyway/bunnynet" { - version = "0.18.2" - constraints = "~> 0.18" + version = "0.19.0" + constraints = "~> 0.19" hashes = [ - "h1:3rZl+Co3WMpwj8SciPaCNXoGA31aSoqp6iweLarr5m4=", - "h1:6d9cKLhz8QOZ4R5yVX1G0TsWL+K1Abtfbm3xngndxto=", - "h1:EBjjkfp5Gx7nXP1DVO+tLhsow6fEUvaIjsCEFRT2fY8=", - "h1:Nu2DoHGOv2YN7ag4kFGpfnPeRDh6bzWqY5anW+ETGpM=", - "h1:OnvZxg28m4/UJeEhHVLU4kM2MZ704sxRzYfLWlLxnhA=", - "h1:PiCse2/UcB7nkPxosveHsJN/jKdBC8AH6tKTxcHSYKw=", - "h1:QAahdtlDBUon7eMwNN0D2V6CxgasOXIi+9/UExik6Sg=", - "h1:Su5z0A7/UaSm/E7FJnFjpDVQaa1Ju5+fZ8Mirf8E+k8=", - "h1:UA3a78FJAPAGqCCvlIg9ekPltpVsrmEhwFLalWCFnew=", - "h1:XAlCTNHRtgUkNjdUItkiak6ajjT7wFJzJN8frXKD5Ms=", - "h1:ZgLBOPebYxH059z1cGHmjYO8CTf+tbWPb3VbO97S2YM=", - "h1:anR91C2F6NDJoQQQIy6KHChodnTaSKnApSWSGM4jSX0=", - "h1:gVmaNmIu4gEiITM+CAb66e+zncAqzNBYkniTZfvxZ5Y=", - "h1:pODlGrkPqHV4yhXiO7LLLu11HtcuxOAB2zUx3B8w1vI=", - "h1:qEYeHEKVRcc78q5xiRGJSY8DGQpLj40KafEXUxFfaQc=", - "h1:qdVz+O0lLHhyf5YX3ujmoVvAGlKqvi+YOPUzVTqpKzY=", - "h1:yTrPkdc9eQkxfPLBYydFf0fpcjarP5w0sdLPzekD9RQ=", - "zh:0fe3987c927d81196c97504470ce4d26c3ad0014f8ee3d0c1be422d08cfcf49c", - "zh:15c36dc69e058876921ac887213e1716217d159b7ee7f0f233e21fb35be85178", - "zh:29d58d7b76dcb142a06d4edd15b8500fe6c1afb7f7c056ada17e2d42bb999fbd", - "zh:33d313836c0e985186b3456c0946e062b27cacfcb08611d0a394f36db9ee1aef", - "zh:47e085e52e9b24ad85fa2988dbb8604256a970a6f53f7fa6aab04d8ae756a738", - "zh:4ba4f87571ca72fbc6c24ab71f2f7b5a086938262e2d8e5c0b39701ed52f8bbc", - "zh:4c6bae97b543c5b328e1ecbcf7c976351b4b381654e9d3e569270dcab3ba816c", + "h1:+QTK+99uKgipcQerdp7XqyDVQr4+j9Rt+J6IlsRTyig=", + "h1:/6HUvLgktHKpi0iUv5Bom5Svx9nssqfBog/Hy2llYsU=", + "h1:0tCQLvrTOsHlYfgv9tbsy8PsoiEjiSMvswfBVfErBFc=", + "h1:1IY3hW9r6wvjsMknmHgByn5qEBMUrYD7ZyW9vzHGQOk=", + "h1:1nmQH1YxIxDZANJhSAkvyJolHO6MJO82zuL94Gitxwk=", + "h1:2ldfuwhEY+KsRqTx6zGSHIom4R2O2oVb06rDKFq2FKo=", + "h1:6KFzTrYT7t2g9cMfyCk5BLu0LgpyzujChK3vlvZZw4A=", + "h1:7CgJOdr7RUdo/O3J0Qhft/sQvgX0E30IKL4WauzBPCg=", + "h1:9mkBzQFtNWbz2niXa5ciskQQZudk/J+Zj1iG6J/Ks/k=", + "h1:FAjraG7Qgv9ETmIVRurqqVCQUjuHAWDMV3hKSFwnoig=", + "h1:QNq/k9igqqg9vVxGvdGNU6y5ySTUcYgETUiFXr/x10E=", + "h1:UpP4dVhp/M7yE0vHLqDslVUgJlvlKuJBrx2uQTbsOVE=", + "h1:VCnb/kkUIMD4HUss8pjQxl3ynqo6e/eAbj6wJfpUjQI=", + "h1:W57YKtRc1V85to2kn2vUjLDKb8BSr0dbEQASA/MBXzo=", + "h1:ZhWq2+5BPm0/allcpEd/MvVvoZX5+YVTukledDhufDQ=", + "h1:Zyf433smZkkoluBh3FMJFt5rvFsv8cD+CUMHMXNJ6Zk=", + "h1:m8evouaTWTHWl/1fIr4/hcTpYCOubyi+DNQJRkxGP0U=", + "zh:0d80b74cc2d1f1782754246333c470be5ab0e003bf88f942a1ceaa248db70ecd", + "zh:1b3871707de0f68d6b4cdab8cb28fe9023765e30138c5e404688014bcfa56feb", + "zh:23029fa78fb8ca799f499577fcf6d7bb3e7eda450ec3a83e22d2bd646f30a021", + "zh:380ca854544eb5a754a333f585b5d0461d9e2959d933f905569c8e074b47ba46", + "zh:3c867179ba968d77b5440297db16ef1f66559c4db07a9623bd8d4b0ac0b79460", + "zh:56a27b4617e9c3589c529a0d2d6abf9858e675d93a2d883fabf0a6d12b5eebbd", + "zh:578cf3aa09278231f63e20736c917a53e67ecce2d7c083218a96d8e536adb3bd", + "zh:5d6d2b3669263e56649b738d1a71228ca08c512e2a16beea8590d0fd2d94ac5c", + "zh:6996d13035e1d2a459962c2b55438cdde9bd96a575e3eb37096209a2ea6f8ddc", + "zh:75789447b0c1708b39369bb000fc2a03a187cfc07e80263475bf5ecd04d9cebd", "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f", - "zh:9ba7ab56537963db2449d217528a751469c9dc4e413dec3e3d63fd7daf3db4ef", - "zh:a3c48eda7e11b03b831f2a639797524bb335f155f0dff0e999cf3496994da8b3", - "zh:aab8f4814d55ef8c6c285d2496ae412437017d0fd1be70106f7b3a4a6e764feb", - "zh:b92b9beacf71ae894717c2036ceb68db52c9c43af4a01b8209eceae9f91a2c8e", - "zh:da389285938e22e1249e6a00cebf12a9f67334743f0b3f66399e6881028bda11", - "zh:dadcc33d06e6f64a17d1965478af5e8bbdc971e92ec9b14e384c5d43861d63f7", - "zh:e090c916e6da685125194af4f0a1fd772494a0c63f3f16ab3741782e17f4a8f9", - "zh:e5881e00fa970c08e66e8079b47d69b76def6e7ff3bdc35b68d7811e5ece55d1", - "zh:eeebb25a066a6287d545c91c0fc264acee5b28174d0979faeebdac3bd14f0fff", - "zh:f368195116c9ce0181aa7527c51ae5e7ab23d42fb966acf4eddca344621ae339", + "zh:8b70254b4a929d49a07b75279c4f7a74e403a21dce0d796af5b2ac39ddd59b87", + "zh:93c03840b56c747933785845e59adca266ee838ed48dc07c57ae4d739d1c76da", + "zh:a1e4a968f0ddfad51c32fd022ccb7e788995b2289e94f4ca74cf773ce319e6d8", + "zh:ab3efbf3bb867caa4133ec3a12ba0dcb03346752a0fafe8d8e7c704804f18580", + "zh:ace4370adaccecf7be48fd4f62f308c1e91961e218ec152f50cdf585b4cba546", + "zh:de074682b8953db39ffbc1337251a25633b796d7b5f68c386c4b039088045068", + "zh:f07ecc5afe3254d36c1a98d843feea5efe39313b5df174c27443e7699f641867", ] } diff --git a/provider.tf b/provider.tf index d4f2564..cb5a87d 100644 --- a/provider.tf +++ b/provider.tf @@ -2,7 +2,7 @@ terraform { required_providers { bunnynet = { source = "registry.terraform.io/BunnyWay/bunnynet" - version = "~> 0.18" + version = "~> 0.19" } } } From b18c21aa8d8dc2585239387cd6ed11792fedf2c7 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Thu, 24 Sep 2026 00:32:00 +0000 Subject: [PATCH 10/16] chore(deps): update pre-commit hook rbubley/mirrors-prettier to v3.9.9 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d76cab5..d57d5eb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: hooks: - id: markdownlint-cli2 - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.9.8 + rev: v3.9.9 hooks: - id: prettier - repo: https://github.com/posit-dev/air-pre-commit From 5231758c00fe612f96e6d40d77c068cdab7c0c45 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Fri, 25 Sep 2026 00:32:19 +0000 Subject: [PATCH 11/16] chore(deps): update terraform bunnynet to v0.19.1 --- .terraform.lock.hcl | 70 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl index 2b8939f..4b118a8 100644 --- a/.terraform.lock.hcl +++ b/.terraform.lock.hcl @@ -38,43 +38,43 @@ provider "registry.opentofu.org/hashicorp/http" { } provider "registry.terraform.io/bunnyway/bunnynet" { - version = "0.19.0" + version = "0.19.1" constraints = "~> 0.19" hashes = [ - "h1:+QTK+99uKgipcQerdp7XqyDVQr4+j9Rt+J6IlsRTyig=", - "h1:/6HUvLgktHKpi0iUv5Bom5Svx9nssqfBog/Hy2llYsU=", - "h1:0tCQLvrTOsHlYfgv9tbsy8PsoiEjiSMvswfBVfErBFc=", - "h1:1IY3hW9r6wvjsMknmHgByn5qEBMUrYD7ZyW9vzHGQOk=", - "h1:1nmQH1YxIxDZANJhSAkvyJolHO6MJO82zuL94Gitxwk=", - "h1:2ldfuwhEY+KsRqTx6zGSHIom4R2O2oVb06rDKFq2FKo=", - "h1:6KFzTrYT7t2g9cMfyCk5BLu0LgpyzujChK3vlvZZw4A=", - "h1:7CgJOdr7RUdo/O3J0Qhft/sQvgX0E30IKL4WauzBPCg=", - "h1:9mkBzQFtNWbz2niXa5ciskQQZudk/J+Zj1iG6J/Ks/k=", - "h1:FAjraG7Qgv9ETmIVRurqqVCQUjuHAWDMV3hKSFwnoig=", - "h1:QNq/k9igqqg9vVxGvdGNU6y5ySTUcYgETUiFXr/x10E=", - "h1:UpP4dVhp/M7yE0vHLqDslVUgJlvlKuJBrx2uQTbsOVE=", - "h1:VCnb/kkUIMD4HUss8pjQxl3ynqo6e/eAbj6wJfpUjQI=", - "h1:W57YKtRc1V85to2kn2vUjLDKb8BSr0dbEQASA/MBXzo=", - "h1:ZhWq2+5BPm0/allcpEd/MvVvoZX5+YVTukledDhufDQ=", - "h1:Zyf433smZkkoluBh3FMJFt5rvFsv8cD+CUMHMXNJ6Zk=", - "h1:m8evouaTWTHWl/1fIr4/hcTpYCOubyi+DNQJRkxGP0U=", - "zh:0d80b74cc2d1f1782754246333c470be5ab0e003bf88f942a1ceaa248db70ecd", - "zh:1b3871707de0f68d6b4cdab8cb28fe9023765e30138c5e404688014bcfa56feb", - "zh:23029fa78fb8ca799f499577fcf6d7bb3e7eda450ec3a83e22d2bd646f30a021", - "zh:380ca854544eb5a754a333f585b5d0461d9e2959d933f905569c8e074b47ba46", - "zh:3c867179ba968d77b5440297db16ef1f66559c4db07a9623bd8d4b0ac0b79460", - "zh:56a27b4617e9c3589c529a0d2d6abf9858e675d93a2d883fabf0a6d12b5eebbd", - "zh:578cf3aa09278231f63e20736c917a53e67ecce2d7c083218a96d8e536adb3bd", - "zh:5d6d2b3669263e56649b738d1a71228ca08c512e2a16beea8590d0fd2d94ac5c", - "zh:6996d13035e1d2a459962c2b55438cdde9bd96a575e3eb37096209a2ea6f8ddc", - "zh:75789447b0c1708b39369bb000fc2a03a187cfc07e80263475bf5ecd04d9cebd", + "h1:02CmekB5A4NtAeptTR7waaECJl66Gf3ww7Wtyg1cy+g=", + "h1:0VWwMHkHQXusR2vdyYWN1pNvfJUPt9OWh6glgZshCck=", + "h1:2NGfMzSWPCcyO2P2T9/lDS5MExYnaOfLuDEMiYvFBg4=", + "h1:2dXsvcYEGXsIf1IHD2Rq9HzgwrNNEA4+qOzBKpbFEpw=", + "h1:8R0H9DumQe0DjXTHRJXNiZUyTBDHT2vjfu/vB+WdRIw=", + "h1:9Gi5M2iKY+Oz8wAYoJh7i0u3mySBk5pretuyzcwgJOw=", + "h1:BZwoP8Ubi1iDueWXhSWb3Tlt/II4bJI0/p6/tqw4i1M=", + "h1:F4yWXkyv55F+97IQi/jYBLhBLyhz4hkokVCyEEQzbM4=", + "h1:MGHXEapStuXemfw3SikP2aLQCT+b7Ee/RrCHevSAAWA=", + "h1:Q10nENYoX8jIsBMz1kP8OBrkMeSNmFI2CfB6/MsWKAc=", + "h1:R9z1oacW8gD9hPTGTO37ngDAhAvlP33/PRhzkgXDStY=", + "h1:UYLBa5/V+giaZ2YYjkbPDKMRO9eQRNcWEnpZqU2I/yU=", + "h1:Wz/QDxt1Kved07fCwqMh+6jtTtwQ/xKi9mXE2StV7vw=", + "h1:Yq0JSIW4Jir3EVO2w7C/iM76yzYKG5eYw51woX6CXJo=", + "h1:e/PEmAJszFbjdfsAMJosDbkxtHwHNnByd/3nKJmE3Sg=", + "h1:lMVwei5IGLQCrPMqAmcpbXs/BjaG7k6HbjhuWtr0kIA=", + "h1:m8dyuq1sXJ9sxjZkU3ZUsjC77BWY87GiraNvxHluSYs=", + "zh:15e84e2fca2bbaec9c9f4d14d1a037d02f4d8cc1d1bdff04709d51085f950774", + "zh:1b9d0cbb7f08e7a554afb8c1e733942a77aa0c8112e8b2b7092c040794f0b113", + "zh:28768988a8ec70e5392ca93375717b83a9aa2eeaa21be2f53c28550273b97065", + "zh:2f357c1d2c013627e4e785c350fc72ccc0bfbebaa6062e536ec7eb9cfecfc913", + "zh:4a41bab7fba5415b8c422f5c03d6fb054ae210e1eb180fab4081d4fa976080b5", + "zh:6c10fad0bd03bbf053b97ad51f0a24e9a0c43a7fc10727033a39eec90ed0a51e", + "zh:795980ac64b0f9bda521f829187eb7b296baa682b7e8d409126f85e6a6f9bcc0", + "zh:841a7e234852ecd516e2dc52c7d31025a704242aeafee15eb36bf392e62f918f", "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f", - "zh:8b70254b4a929d49a07b75279c4f7a74e403a21dce0d796af5b2ac39ddd59b87", - "zh:93c03840b56c747933785845e59adca266ee838ed48dc07c57ae4d739d1c76da", - "zh:a1e4a968f0ddfad51c32fd022ccb7e788995b2289e94f4ca74cf773ce319e6d8", - "zh:ab3efbf3bb867caa4133ec3a12ba0dcb03346752a0fafe8d8e7c704804f18580", - "zh:ace4370adaccecf7be48fd4f62f308c1e91961e218ec152f50cdf585b4cba546", - "zh:de074682b8953db39ffbc1337251a25633b796d7b5f68c386c4b039088045068", - "zh:f07ecc5afe3254d36c1a98d843feea5efe39313b5df174c27443e7699f641867", + "zh:8c876a0a26b249151f0918ee836e24660513c2345c23a06e0f54a28c7c6966b7", + "zh:906a791496cf11dcfdfe43a4167414cb473e548f0bd86d4b8a6a95450b523133", + "zh:9431757bf5b7d055ecc1d3c8465216d5e7a648b75e0e35b136ac8fc25382e97d", + "zh:967fd248df86fc246536727e996a7334711f4c6fe9e3d01ec9f03abe621a9783", + "zh:a6710fbd30f8a4844eb025d616057e78bbb255a7d05cc73876dae55a5d6b0d06", + "zh:b5f260899555430c109da35d2c483999d61b127beda6c2a7b39eb67f27d754c8", + "zh:d24882eb63c6452ed27666e896224b1d866ad00645d6ecc53de84d1687d27fc4", + "zh:e573eb0c99ea7195ec1ed3da728caddacc68a126d82679fb490438c781382f4d", + "zh:fcf0a66c0c0b62af505c5f0f8fe59bca77d6085a0b07763be33420101183702e", ] } From 317990a40f2cd01bda2c2d314afc8efbafff1ff5 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Fri, 2 Oct 2026 00:32:22 +0000 Subject: [PATCH 12/16] chore(deps): update pre-commit hook posit-dev/air-pre-commit to v0.12.0 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d57d5eb..dec6844 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -32,7 +32,7 @@ repos: hooks: - id: prettier - repo: https://github.com/posit-dev/air-pre-commit - rev: 0.11.0 + rev: 0.12.0 hooks: - id: air-format - repo: https://github.com/editorconfig-checker/editorconfig-checker From 40a0a6e02d8c49ea98e0c27068591d44eeb279e0 Mon Sep 17 00:00:00 2001 From: pat-s Date: Sun, 4 Oct 2026 07:35:01 +0000 Subject: [PATCH 13/16] fix(patches): cover every RcppParallel 6.x release with the bundled-TBB patch (#228) --- .../force-bundled-tbb-6.0.0.patch | 152 +++++++++++++++++ .../force-bundled-tbb-6.1.x.patch | 157 ++++++++++++++++++ ...bb.patch => force-bundled-tbb-6.2.x.patch} | 68 ++++---- local/patches/registry.json | 44 ++++- 4 files changed, 381 insertions(+), 40 deletions(-) create mode 100644 local/patches/RcppParallel/force-bundled-tbb-6.0.0.patch create mode 100644 local/patches/RcppParallel/force-bundled-tbb-6.1.x.patch rename local/patches/RcppParallel/{force-bundled-tbb.patch => force-bundled-tbb-6.2.x.patch} (67%) diff --git a/local/patches/RcppParallel/force-bundled-tbb-6.0.0.patch b/local/patches/RcppParallel/force-bundled-tbb-6.0.0.patch new file mode 100644 index 0000000..a7f91dc --- /dev/null +++ b/local/patches/RcppParallel/force-bundled-tbb-6.0.0.patch @@ -0,0 +1,152 @@ +diff --git a/R/aaa.R b/R/aaa.R +index 568a2aa..2744059 100644 +--- a/R/aaa.R ++++ b/R/aaa.R +@@ -5,4 +5,21 @@ TBB_LIB <- "" + TBB_INC <- "" + + TBB_NAME <- "tbb" +-TBB_MALLOC_NAME <- "tbbmalloc" +\ No newline at end of file ++TBB_MALLOC_NAME <- "tbbmalloc" ++ ++# bincraft patch: build images (ours did until build-env-images c51ed09) and ++# plenty of user environments export TBB_ROOT / TBB_LIB / TBB_INC. A binary we ++# publish always carries its own oneTBB in RcppParallel/lib -- see the ++# companion changes in tools/config/configure.R and src/install.libs.R -- so ++# honouring those variables at run time is actively harmful: .onLoad() would ++# dyn.load() a second, unrelated TBB into the process next to the bundled one ++# (two copies of the same symbols in the global scope, which segfaults R on ++# load), and RcppParallelLibs() / CxxFlags() would hand that system TBB to ++# dependents such as rstan, putting NEEDED libtbb.so.12 back into their ++# binaries. Read the variables only when explicitly opted back in. ++bincraftGetenv <- function(name, unset = "") { ++ if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") == "TRUE") ++ Sys.getenv(name, unset = unset) ++ else ++ unset ++} +\ No newline at end of file +diff --git a/R/tbb.R b/R/tbb.R +index 3d8fbb3..9560165 100644 +--- a/R/tbb.R ++++ b/R/tbb.R +@@ -17,7 +17,7 @@ tbbLibraryPath <- function(name = NULL) { + sysname <- Sys.info()[["sysname"]] + + # find root for TBB install +- tbbRoot <- Sys.getenv("TBB_LIB", unset = tbbRoot()) ++ tbbRoot <- bincraftGetenv("TBB_LIB", unset = tbbRoot()) + if (is.null(name)) + return(tbbRoot) + +@@ -60,7 +60,7 @@ tbbCxxFlags <- function() { + flags <- c("-DRCPP_PARALLEL_USE_TBB=1") + + # if TBB_INC is set, apply those library paths +- tbbInc <- Sys.getenv("TBB_INC", unset = TBB_INC) ++ tbbInc <- bincraftGetenv("TBB_INC", unset = TBB_INC) + if (!file.exists(tbbInc)) { + tbbInc <- system.file("include", package = "RcppParallel") + } +@@ -100,7 +100,7 @@ tbbLdFlags <- function() { + } + + # shortcut if TBB_LIB defined +- tbbLib <- Sys.getenv("TBB_LINK_LIB", Sys.getenv("TBB_LIB", unset = TBB_LIB)) ++ tbbLib <- bincraftGetenv("TBB_LINK_LIB", bincraftGetenv("TBB_LIB", unset = TBB_LIB)) + if (nzchar(tbbLib)) { + if (R.version$os == "emscripten") { + fmt <- "-L%1$s -l%2$s" +diff --git a/src/install.libs.R b/src/install.libs.R +index 4dcbac2..57dbc74 100644 +--- a/src/install.libs.R ++++ b/src/install.libs.R +@@ -258,6 +258,18 @@ prependFlags <- function(prependFlags, toFlags) { + tbbLib <- Sys.getenv("TBB_LIB") + tbbInc <- Sys.getenv("TBB_INC") + ++# bincraft patch: the companion change in tools/config/configure.R stops an ++# ambient TBB_LIB / TBB_INC from selecting a system TBB, but this script is ++# also run directly by `R CMD INSTALL` (not only through the `tbb` rule in ++# src/Makevars, which passes the configured values), so at install time it ++# still sees the image's environment and would symlink the system libraries ++# into RcppParallel/lib. Drop them here for the same reason, under the same ++# opt-out. ++if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") != "TRUE") { ++ tbbLib <- "" ++ tbbInc <- "" ++} ++ + args <- commandArgs(trailingOnly = TRUE) + if (identical(args, "build")) { + if (nzchar(tbbLib) && nzchar(tbbInc)) { +diff --git a/tools/config/configure.R b/tools/config/configure.R +index a001e63..bfe8c8e 100644 +--- a/tools/config/configure.R ++++ b/tools/config/configure.R +@@ -144,6 +144,24 @@ tbbRoot <- Sys.getenv("TBB_ROOT", unset = NA) + tbbLib <- Sys.getenv("TBB_LIB", unset = NA) + tbbInc <- Sys.getenv("TBB_INC", unset = NA) + ++# bincraft patch: ignore an ambient TBB_ROOT / TBB_LIB / TBB_INC. Our build ++# images exported these until build-env-images c51ed09 (a leftover from ++# RcppParallel 5.x, whose bundled Intel TBB would not build on musl or with ++# modern g++), and any of them switches the branches below to a system TBB. ++# The published binary then records NEEDED libtbb.so.12 (or libtbb.so.2 for ++# the classic Intel TBB) and gets a RcppParallel/lib full of absolute symlinks ++# into the image's library dir, so it cannot dyn.load on a consumer machine ++# without that exact TBB. 6.x bundles oneTBB 2022 and builds it with cmake on ++# every platform we ship, so the bundled copy is always the right choice here; ++# forcing it in the package rather than relying on the image environment keeps ++# the binary correct whichever image version CI happens to pull. Set ++# BINCRAFT_ALLOW_SYSTEM_TBB=TRUE to restore the upstream behaviour. ++if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") != "TRUE") { ++ tbbRoot <- NA ++ tbbLib <- NA ++ tbbInc <- NA ++} ++ + tbbName <- Sys.getenv("TBB_NAME", unset = "tbb") + tbbMallocName <- Sys.getenv("TBB_MALLOC_NAME", unset = "tbbmalloc") + +@@ -224,10 +242,21 @@ define( + ) + + # set PKG_LIBS ++# ++# bincraft patch: the library directories below are passed as plain '-L', not ++# '-Wl,-L'. gcc expands its own search dirs (/usr/lib64, /usr/lib/) ++# into explicit '-L' options ahead of anything forwarded verbatim with '-Wl,', ++# so with '-Wl,-L' a system libtbb.so wins over the one named here: on a build ++# host with a distro TBB installed, '-ltbb' resolves to that library and ++# RcppParallel.so records its SONAME (libtbb.so.12, or libtbb.so.2 for the ++# classic Intel TBB) instead of the bundled 'libtbb.so'. The binary then loads ++# the system TBB rather than the copy shipped in RcppParallel/lib, and fails ++# outright on a machine that has no system TBB. gcc places a plain '-L' before ++# its built-in dirs, so the intended library is found first. + pkgLibs <- if (!is.na(tbbLib)) { + + c( +- "-Wl,-L\"$(TBB_LIB)\"", ++ "-L\"$(TBB_LIB)\"", + sprintf("-Wl,-rpath,%s", shQuote(tbbLib)), + "-l$(TBB_NAME)", + "-l$(TBB_MALLOC_NAME)" +@@ -240,14 +269,14 @@ pkgLibs <- if (!is.na(tbbLib)) { + } else if (R.version$os == "emscripten") { + + c( +- "-Wl,-Ltbb/build/lib_release", ++ "-Ltbb/build/lib_release", + "-l$(TBB_NAME)" + ) + + } else { + + c( +- "-Wl,-Ltbb/build/lib_release", ++ "-Ltbb/build/lib_release", + "-l$(TBB_NAME)", + "-l$(TBB_MALLOC_NAME)" + ) diff --git a/local/patches/RcppParallel/force-bundled-tbb-6.1.x.patch b/local/patches/RcppParallel/force-bundled-tbb-6.1.x.patch new file mode 100644 index 0000000..948643c --- /dev/null +++ b/local/patches/RcppParallel/force-bundled-tbb-6.1.x.patch @@ -0,0 +1,157 @@ +diff --git a/R/aaa.R b/R/aaa.R +index 568a2aa..2744059 100644 +--- a/R/aaa.R ++++ b/R/aaa.R +@@ -5,4 +5,21 @@ TBB_LIB <- "" + TBB_INC <- "" + + TBB_NAME <- "tbb" +-TBB_MALLOC_NAME <- "tbbmalloc" +\ No newline at end of file ++TBB_MALLOC_NAME <- "tbbmalloc" ++ ++# bincraft patch: build images (ours did until build-env-images c51ed09) and ++# plenty of user environments export TBB_ROOT / TBB_LIB / TBB_INC. A binary we ++# publish always carries its own oneTBB in RcppParallel/lib -- see the ++# companion changes in tools/config/configure.R and src/install.libs.R -- so ++# honouring those variables at run time is actively harmful: .onLoad() would ++# dyn.load() a second, unrelated TBB into the process next to the bundled one ++# (two copies of the same symbols in the global scope, which segfaults R on ++# load), and RcppParallelLibs() / CxxFlags() would hand that system TBB to ++# dependents such as rstan, putting NEEDED libtbb.so.12 back into their ++# binaries. Read the variables only when explicitly opted back in. ++bincraftGetenv <- function(name, unset = "") { ++ if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") == "TRUE") ++ Sys.getenv(name, unset = unset) ++ else ++ unset ++} +\ No newline at end of file +diff --git a/R/tbb.R b/R/tbb.R +index 152fd16..4b06aa5 100644 +--- a/R/tbb.R ++++ b/R/tbb.R +@@ -17,7 +17,7 @@ tbbLibraryPath <- function(name = NULL) { + sysname <- Sys.info()[["sysname"]] + + # find root for TBB install +- tbbRoot <- Sys.getenv("TBB_LIB", unset = tbbRoot()) ++ tbbRoot <- bincraftGetenv("TBB_LIB", unset = tbbRoot()) + if (is.null(name)) + return(tbbRoot) + +@@ -58,7 +58,7 @@ tbbCxxFlags <- function() { + flags <- c("-DRCPP_PARALLEL_USE_TBB=1") + + # if TBB_INC is set, apply those library paths +- tbbInc <- Sys.getenv("TBB_INC", unset = TBB_INC) ++ tbbInc <- bincraftGetenv("TBB_INC", unset = TBB_INC) + if (!file.exists(tbbInc)) { + tbbInc <- system.file("include", package = "RcppParallel") + } +@@ -96,7 +96,7 @@ tbbLdFlags <- function() { + } + + # shortcut if TBB_LIB defined +- tbbLib <- Sys.getenv("TBB_LINK_LIB", Sys.getenv("TBB_LIB", unset = TBB_LIB)) ++ tbbLib <- bincraftGetenv("TBB_LINK_LIB", bincraftGetenv("TBB_LIB", unset = TBB_LIB)) + if (nzchar(tbbLib)) { + if (R.version$os == "emscripten") { + fmt <- "-L%1$s -l%2$s" +diff --git a/src/install.libs.R b/src/install.libs.R +index e770838..1dd2fc7 100644 +--- a/src/install.libs.R ++++ b/src/install.libs.R +@@ -492,6 +492,18 @@ prependFlags <- function(prependFlags, toFlags) { + tbbLib <- Sys.getenv("TBB_LIB") + tbbInc <- Sys.getenv("TBB_INC") + ++# bincraft patch: the companion change in tools/config/configure.R stops an ++# ambient TBB_LIB / TBB_INC from selecting a system TBB, but this script is ++# also run directly by `R CMD INSTALL` (not only through the `tbb` rule in ++# src/Makevars, which passes the configured values), so at install time it ++# still sees the image's environment and would symlink the system libraries ++# into RcppParallel/lib. Drop them here for the same reason, under the same ++# opt-out. ++if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") != "TRUE") { ++ tbbLib <- "" ++ tbbInc <- "" ++} ++ + args <- commandArgs(trailingOnly = TRUE) + if (identical(args, "build")) { + if (nzchar(tbbLib) && nzchar(tbbInc)) { +diff --git a/tools/config/configure.R b/tools/config/configure.R +index c3842f9..adf7876 100644 +--- a/tools/config/configure.R ++++ b/tools/config/configure.R +@@ -66,6 +66,24 @@ tbbRoot <- Sys.getenv("TBB_ROOT", unset = NA) + tbbLib <- Sys.getenv("TBB_LIB", unset = NA) + tbbInc <- Sys.getenv("TBB_INC", unset = NA) + ++# bincraft patch: ignore an ambient TBB_ROOT / TBB_LIB / TBB_INC. Our build ++# images exported these until build-env-images c51ed09 (a leftover from ++# RcppParallel 5.x, whose bundled Intel TBB would not build on musl or with ++# modern g++), and any of them switches the branches below to a system TBB. ++# The published binary then records NEEDED libtbb.so.12 (or libtbb.so.2 for ++# the classic Intel TBB) and gets a RcppParallel/lib full of absolute symlinks ++# into the image's library dir, so it cannot dyn.load on a consumer machine ++# without that exact TBB. 6.x bundles oneTBB 2022 and builds it with cmake on ++# every platform we ship, so the bundled copy is always the right choice here; ++# forcing it in the package rather than relying on the image environment keeps ++# the binary correct whichever image version CI happens to pull. Set ++# BINCRAFT_ALLOW_SYSTEM_TBB=TRUE to restore the upstream behaviour. ++if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") != "TRUE") { ++ tbbRoot <- NA ++ tbbLib <- NA ++ tbbInc <- NA ++} ++ + tbbName <- Sys.getenv("TBB_NAME", unset = "tbb") + tbbMallocName <- Sys.getenv("TBB_MALLOC_NAME", unset = "tbbmalloc") + +@@ -146,6 +164,18 @@ define( + ) + + # set PKG_LIBS ++# ++# bincraft patch: the non-Windows library directories below are passed as ++# plain '-L', not '-Wl,-L'. gcc expands its own search dirs (/usr/lib64, ++# /usr/lib/) into explicit '-L' options ahead of anything forwarded ++# verbatim with '-Wl,', so with '-Wl,-L' a system libtbb.so wins over the one ++# named here: on a build host with a distro TBB installed, '-ltbb' resolves to ++# that library and RcppParallel.so records its SONAME (libtbb.so.12, or ++# libtbb.so.2 for the classic Intel TBB) instead of the bundled 'libtbb.so'. ++# The binary then loads the system TBB rather than the copy shipped in ++# RcppParallel/lib, and fails outright on a machine that has no system TBB. ++# gcc places a plain '-L' before its built-in dirs, so the intended library is ++# found first. + pkgLibs <- if (.Platform$OS.type == "windows") { + + if (!is.na(tbbLib) && file.exists(file.path(tbbInc, "oneapi"))) { +@@ -183,7 +213,7 @@ pkgLibs <- if (.Platform$OS.type == "windows") { + } else if (!is.na(tbbLib)) { + + c( +- "-Wl,-L\"$(TBB_LIB)\"", ++ "-L\"$(TBB_LIB)\"", + sprintf("-Wl,-rpath,%s", shQuote(tbbLib)), + "-l$(TBB_NAME)", + "-l$(TBB_MALLOC_NAME)" +@@ -192,14 +222,14 @@ pkgLibs <- if (.Platform$OS.type == "windows") { + } else if (R.version$os == "emscripten") { + + c( +- "-Wl,-Ltbb/build/lib_release", ++ "-Ltbb/build/lib_release", + "-l$(TBB_NAME)" + ) + + } else { + + c( +- "-Wl,-Ltbb/build/lib_release", ++ "-Ltbb/build/lib_release", + "-l$(TBB_NAME)", + "-l$(TBB_MALLOC_NAME)" + ) diff --git a/local/patches/RcppParallel/force-bundled-tbb.patch b/local/patches/RcppParallel/force-bundled-tbb-6.2.x.patch similarity index 67% rename from local/patches/RcppParallel/force-bundled-tbb.patch rename to local/patches/RcppParallel/force-bundled-tbb-6.2.x.patch index 5c37fa6..d88cfc5 100644 --- a/local/patches/RcppParallel/force-bundled-tbb.patch +++ b/local/patches/RcppParallel/force-bundled-tbb-6.2.x.patch @@ -1,5 +1,5 @@ diff --git a/R/aaa.R b/R/aaa.R -index 568a2aa..bfdab4c 100644 +index 568a2aa..2744059 100644 --- a/R/aaa.R +++ b/R/aaa.R @@ -5,4 +5,21 @@ TBB_LIB <- "" @@ -10,16 +10,16 @@ index 568a2aa..bfdab4c 100644 \ No newline at end of file +TBB_MALLOC_NAME <- "tbbmalloc" + -+# bincraft patch: our build images (and plenty of user environments) export -+# TBB_ROOT / TBB_LIB / TBB_INC. A binary we publish always carries its own -+# oneTBB in RcppParallel/lib -- see the companion changes in -+# tools/config/configure.R and src/install.libs.R -- so honouring those -+# variables at run time is actively harmful: .onLoad() would dyn.load() a -+# second, unrelated TBB into the process next to the bundled one (two copies -+# of the same symbols in the global scope, which segfaults R on load), and -+# RcppParallelLibs() / CxxFlags() would hand that system TBB to dependents -+# such as rstan, putting NEEDED libtbb.so.12 back into their binaries. Read -+# the variables only when explicitly opted back in. ++# bincraft patch: build images (ours did until build-env-images c51ed09) and ++# plenty of user environments export TBB_ROOT / TBB_LIB / TBB_INC. A binary we ++# publish always carries its own oneTBB in RcppParallel/lib -- see the ++# companion changes in tools/config/configure.R and src/install.libs.R -- so ++# honouring those variables at run time is actively harmful: .onLoad() would ++# dyn.load() a second, unrelated TBB into the process next to the bundled one ++# (two copies of the same symbols in the global scope, which segfaults R on ++# load), and RcppParallelLibs() / CxxFlags() would hand that system TBB to ++# dependents such as rstan, putting NEEDED libtbb.so.12 back into their ++# binaries. Read the variables only when explicitly opted back in. +bincraftGetenv <- function(name, unset = "") { + if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") == "TRUE") + Sys.getenv(name, unset = unset) @@ -28,32 +28,24 @@ index 568a2aa..bfdab4c 100644 +} \ No newline at end of file diff --git a/R/tbb.R b/R/tbb.R -index 6f6a745..e407986 100644 +index b071833..e3bf7a5 100644 --- a/R/tbb.R +++ b/R/tbb.R -@@ -17,7 +17,7 @@ tbbLibraryPath <- function(name = NULL) { - sysname <- Sys.info()[["sysname"]] - +@@ -19,3 +19,3 @@ tbbLibraryPath <- function(name = NULL) { # find root for TBB install - tbbRoot <- Sys.getenv("TBB_LIB", unset = tbbRoot()) + tbbRoot <- bincraftGetenv("TBB_LIB", unset = tbbRoot()) if (is.null(name)) - return(tbbRoot) - -@@ -58,3 +58,3 @@ tbbCxxFlags <- function() { +@@ -63,3 +63,3 @@ tbbCxxFlags <- function() { # if TBB_INC is set, apply those library paths - tbbInc <- Sys.getenv("TBB_INC", unset = TBB_INC) + tbbInc <- bincraftGetenv("TBB_INC", unset = TBB_INC) if (!file.exists(tbbInc)) { -@@ -117,7 +117,7 @@ tbbLdFlags <- function() { - } - +@@ -122,3 +122,3 @@ tbbLdFlags <- function() { # shortcut if TBB_LIB defined - tbbLib <- Sys.getenv("TBB_LINK_LIB", Sys.getenv("TBB_LIB", unset = TBB_LIB)) + tbbLib <- bincraftGetenv("TBB_LINK_LIB", bincraftGetenv("TBB_LIB", unset = TBB_LIB)) if (nzchar(tbbLib)) { - if (R.version$os == "emscripten") { - fmt <- "-L%1$s -l%2$s" diff --git a/src/install.libs.R b/src/install.libs.R index 3b3cfda..c0e6f3e 100644 --- a/src/install.libs.R @@ -78,24 +70,24 @@ index 3b3cfda..c0e6f3e 100644 if (identical(args, "build")) { if (nzchar(tbbLib) && nzchar(tbbInc)) { diff --git a/tools/config/configure.R b/tools/config/configure.R -index 6293fe1..eae4aaa 100644 +index c203a1f..0050b5c 100644 --- a/tools/config/configure.R +++ b/tools/config/configure.R -@@ -40,6 +40,24 @@ tbbRoot <- Sys.getenv("TBB_ROOT", unset = NA) +@@ -79,6 +79,24 @@ tbbRoot <- Sys.getenv("TBB_ROOT", unset = NA) tbbLib <- Sys.getenv("TBB_LIB", unset = NA) tbbInc <- Sys.getenv("TBB_INC", unset = NA) -+# bincraft patch: ignore an ambient TBB_ROOT / TBB_LIB / TBB_INC. Several of -+# our build images export these (a leftover from RcppParallel 5.x, whose -+# bundled Intel TBB would not build on musl or with modern g++), and any of -+# them switches the branches below to a system TBB. The published binary then -+# records NEEDED libtbb.so.12 (or libtbb.so.2 for the classic Intel TBB) and -+# gets a RcppParallel/lib full of absolute symlinks into the image's library -+# dir, so it cannot dyn.load on a consumer machine without that exact TBB. -+# 6.x bundles oneTBB 2022 and builds it with cmake on every platform we ship, -+# so the bundled copy is always the right choice here; forcing it in the -+# package rather than relying on the image environment keeps the binary -+# correct whichever image version CI happens to pull. Set ++# bincraft patch: ignore an ambient TBB_ROOT / TBB_LIB / TBB_INC. Our build ++# images exported these until build-env-images c51ed09 (a leftover from ++# RcppParallel 5.x, whose bundled Intel TBB would not build on musl or with ++# modern g++), and any of them switches the branches below to a system TBB. ++# The published binary then records NEEDED libtbb.so.12 (or libtbb.so.2 for ++# the classic Intel TBB) and gets a RcppParallel/lib full of absolute symlinks ++# into the image's library dir, so it cannot dyn.load on a consumer machine ++# without that exact TBB. 6.x bundles oneTBB 2022 and builds it with cmake on ++# every platform we ship, so the bundled copy is always the right choice here; ++# forcing it in the package rather than relying on the image environment keeps ++# the binary correct whichever image version CI happens to pull. Set +# BINCRAFT_ALLOW_SYSTEM_TBB=TRUE to restore the upstream behaviour. +if (Sys.getenv("BINCRAFT_ALLOW_SYSTEM_TBB", unset = "FALSE") != "TRUE") { + tbbRoot <- NA @@ -106,7 +98,7 @@ index 6293fe1..eae4aaa 100644 tbbName <- Sys.getenv("TBB_NAME", unset = "tbb") tbbMallocName <- Sys.getenv("TBB_MALLOC_NAME", unset = "tbbmalloc") -@@ -186,12 +204,23 @@ define( +@@ -225,12 +243,23 @@ define( ) # set PKG_LIBS @@ -131,7 +123,7 @@ index 6293fe1..eae4aaa 100644 if (.Platform$OS.type != "windows") sprintf("-Wl,-rpath,%s", shQuote(tbbLib)), "-l$(TBB_NAME)", -@@ -201,14 +230,14 @@ pkgLibs <- if (!is.na(tbbLib)) { +@@ -240,14 +269,14 @@ pkgLibs <- if (!is.na(tbbLib)) { } else if (R.version$os == "emscripten") { c( diff --git a/local/patches/registry.json b/local/patches/registry.json index 2457304..1f341b7 100644 --- a/local/patches/registry.json +++ b/local/patches/registry.json @@ -6,8 +6,48 @@ "env": {}, "configure_args": [], "makevars": {}, - "patch": "RcppParallel/force-bundled-tbb.patch", - "reason": "RcppParallel 6.x bundles oneTBB 2022 and builds it with cmake on every platform we ship, so the system-TBB workaround needed for 5.x is gone, but two things still steer the build back to a system TBB. (1) Ambient TBB_ROOT/TBB_LIB/TBB_INC: several build images still export these (build-env-images dropped them, but the images are rebuilt only by cron/manual runs, so a stale image keeps them), and R reads ~/.Renviron *after* the process environment, so no pipeline-side env override can undo it. configure.R then takes the system-TBB branch, install.libs.R symlinks the image's libraries into RcppParallel/lib as absolute paths, and the binary records NEEDED libtbb.so.12 (libtbb.so.2 for the classic Intel TBB on el8/el9) -- it cannot dyn.load on a consumer machine without that exact TBB. Both files are patched to ignore those variables (opt out with BINCRAFT_ALLOW_SYSTEM_TBB=TRUE); install.libs.R needs it separately because R CMD INSTALL runs it outside the src/Makevars rule that passes the configured values. (2) Link order: the bundled branch passes its build dir as '-Wl,-Ltbb/build/lib_release', and gcc expands its own search dirs (/usr/lib64, /usr/lib/) into '-L' options ahead of anything forwarded with '-Wl,', so '-ltbb' would still resolve to a distro TBB when one is installed; a plain '-L' puts the bundled dir first. Verified on the current build-env-ubuntu:jammy image (which still exports TBB_INC/TBB_LIB): NEEDED libtbb.so, RUNPATH $ORIGIN/../lib, real libtbb.so.2 in RcppParallel/lib, and the package loads with every system libtbb moved away." + "patch": "RcppParallel/force-bundled-tbb-6.2.x.patch", + "reason": "RcppParallel 6.x builds its bundled oneTBB 2022 with cmake, but tools/config/configure.R passes the library dir as '-Wl,-L...', and gcc places its own search dirs (/usr/lib64, /usr/lib/) ahead of anything forwarded with '-Wl,'. Every build image installs a distro libtbb, so '-ltbb' resolves to it: the binary records NEEDED libtbb.so.12 (libtbb.so.2 on el8/el9) instead of the bundled libtbb.so and cannot load on a machine without that exact system TBB. The patch passes a plain '-L' so the bundled build dir wins. As a safeguard it also makes configure.R, src/install.libs.R and R/tbb.R ignore an ambient TBB_ROOT/TBB_LIB/TBB_INC (opt out with BINCRAFT_ALLOW_SYSTEM_TBB=TRUE): the build images stopped exporting them in build-env-images c51ed09, but a stale image or ~/.Renviron would otherwise switch the build back to the system TBB, and R reads ~/.Renviron after the process environment, so no pipeline env can override it. The read sites move between releases, so each entry pins a patch generated against that version. Upstream still uses '-Wl,-L' in 6.2.1; drop these entries once a release passes a plain '-L'." + }, + { + "package": "RcppParallel", + "versions": "6.2.0", + "platforms": ["*"], + "env": {}, + "configure_args": [], + "makevars": {}, + "patch": "RcppParallel/force-bundled-tbb-6.2.x.patch", + "reason": "RcppParallel 6.x builds its bundled oneTBB 2022 with cmake, but tools/config/configure.R passes the library dir as '-Wl,-L...', and gcc places its own search dirs (/usr/lib64, /usr/lib/) ahead of anything forwarded with '-Wl,'. Every build image installs a distro libtbb, so '-ltbb' resolves to it: the binary records NEEDED libtbb.so.12 (libtbb.so.2 on el8/el9) instead of the bundled libtbb.so and cannot load on a machine without that exact system TBB. The patch passes a plain '-L' so the bundled build dir wins. As a safeguard it also makes configure.R, src/install.libs.R and R/tbb.R ignore an ambient TBB_ROOT/TBB_LIB/TBB_INC (opt out with BINCRAFT_ALLOW_SYSTEM_TBB=TRUE): the build images stopped exporting them in build-env-images c51ed09, but a stale image or ~/.Renviron would otherwise switch the build back to the system TBB, and R reads ~/.Renviron after the process environment, so no pipeline env can override it. The read sites move between releases, so each entry pins a patch generated against that version. Upstream still uses '-Wl,-L' in 6.2.1; drop these entries once a release passes a plain '-L'." + }, + { + "package": "RcppParallel", + "versions": "6.1.1", + "platforms": ["*"], + "env": {}, + "configure_args": [], + "makevars": {}, + "patch": "RcppParallel/force-bundled-tbb-6.1.x.patch", + "reason": "RcppParallel 6.x builds its bundled oneTBB 2022 with cmake, but tools/config/configure.R passes the library dir as '-Wl,-L...', and gcc places its own search dirs (/usr/lib64, /usr/lib/) ahead of anything forwarded with '-Wl,'. Every build image installs a distro libtbb, so '-ltbb' resolves to it: the binary records NEEDED libtbb.so.12 (libtbb.so.2 on el8/el9) instead of the bundled libtbb.so and cannot load on a machine without that exact system TBB. The patch passes a plain '-L' so the bundled build dir wins. As a safeguard it also makes configure.R, src/install.libs.R and R/tbb.R ignore an ambient TBB_ROOT/TBB_LIB/TBB_INC (opt out with BINCRAFT_ALLOW_SYSTEM_TBB=TRUE): the build images stopped exporting them in build-env-images c51ed09, but a stale image or ~/.Renviron would otherwise switch the build back to the system TBB, and R reads ~/.Renviron after the process environment, so no pipeline env can override it. The read sites move between releases, so each entry pins a patch generated against that version. Upstream still uses '-Wl,-L' in 6.2.1; drop these entries once a release passes a plain '-L'." + }, + { + "package": "RcppParallel", + "versions": "6.1.0", + "platforms": ["*"], + "env": {}, + "configure_args": [], + "makevars": {}, + "patch": "RcppParallel/force-bundled-tbb-6.1.x.patch", + "reason": "RcppParallel 6.x builds its bundled oneTBB 2022 with cmake, but tools/config/configure.R passes the library dir as '-Wl,-L...', and gcc places its own search dirs (/usr/lib64, /usr/lib/) ahead of anything forwarded with '-Wl,'. Every build image installs a distro libtbb, so '-ltbb' resolves to it: the binary records NEEDED libtbb.so.12 (libtbb.so.2 on el8/el9) instead of the bundled libtbb.so and cannot load on a machine without that exact system TBB. The patch passes a plain '-L' so the bundled build dir wins. As a safeguard it also makes configure.R, src/install.libs.R and R/tbb.R ignore an ambient TBB_ROOT/TBB_LIB/TBB_INC (opt out with BINCRAFT_ALLOW_SYSTEM_TBB=TRUE): the build images stopped exporting them in build-env-images c51ed09, but a stale image or ~/.Renviron would otherwise switch the build back to the system TBB, and R reads ~/.Renviron after the process environment, so no pipeline env can override it. The read sites move between releases, so each entry pins a patch generated against that version. Upstream still uses '-Wl,-L' in 6.2.1; drop these entries once a release passes a plain '-L'." + }, + { + "package": "RcppParallel", + "versions": "6.0.0", + "platforms": ["*"], + "env": {}, + "configure_args": [], + "makevars": {}, + "patch": "RcppParallel/force-bundled-tbb-6.0.0.patch", + "reason": "RcppParallel 6.x builds its bundled oneTBB 2022 with cmake, but tools/config/configure.R passes the library dir as '-Wl,-L...', and gcc places its own search dirs (/usr/lib64, /usr/lib/) ahead of anything forwarded with '-Wl,'. Every build image installs a distro libtbb, so '-ltbb' resolves to it: the binary records NEEDED libtbb.so.12 (libtbb.so.2 on el8/el9) instead of the bundled libtbb.so and cannot load on a machine without that exact system TBB. The patch passes a plain '-L' so the bundled build dir wins. As a safeguard it also makes configure.R, src/install.libs.R and R/tbb.R ignore an ambient TBB_ROOT/TBB_LIB/TBB_INC (opt out with BINCRAFT_ALLOW_SYSTEM_TBB=TRUE): the build images stopped exporting them in build-env-images c51ed09, but a stale image or ~/.Renviron would otherwise switch the build back to the system TBB, and R reads ~/.Renviron after the process environment, so no pipeline env can override it. The read sites move between releases, so each entry pins a patch generated against that version. Upstream still uses '-Wl,-L' in 6.2.1; drop these entries once a release passes a plain '-L'." }, { "package": "fs", From 3426d5f59f28d1a91ef18115284f0eaa5c4de6e7 Mon Sep 17 00:00:00 2001 From: automation-bot Date: Sun, 11 Oct 2026 00:32:41 +0000 Subject: [PATCH 14/16] chore(deps): update dependency nbafrank/uvr to v0.4.7 --- local/uvr-install.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/local/uvr-install.sh b/local/uvr-install.sh index ed6b1ce..e103e13 100755 --- a/local/uvr-install.sh +++ b/local/uvr-install.sh @@ -30,7 +30,7 @@ set -eu # renovate: datasource=github-releases depName=nbafrank/uvr -UVR_PIN="v0.4.6" +UVR_PIN="v0.4.7" if [ "$#" -eq 0 ]; then echo "usage: $0 ..." >&2 From d992a2b6361439966ffbc70088bacec7b664c78b Mon Sep 17 00:00:00 2001 From: pat-s Date: Sun, 11 Oct 2026 12:12:28 +0000 Subject: [PATCH 15/16] fix(ci): give each xvfb-run its own display (#230) Every `process-cran-updates-ubuntu-2204-arm64` cron run since pipeline 13744 has failed with `xvfb-run: error: Xvfb failed to start` (e.g. 13829). ## Cause The newer-R loop added in #216 runs two `xvfb-run` calls back to back: the R-minor-sensitive `process_cran_updates` pass, then `local/build-newer-r.R`. Without `-a`, `xvfb-run` always uses display `:99`, and on exit it kills its Xvfb without waiting for it. The second call can therefore start while the old server still holds the `:99` lock, so the new Xvfb refuses to start. Only ubuntu-2204-arm64 hits this because it is the only image with a second R minor installed, so the loop body only runs there. ## Change - Default `XVFB_ARGS` to `-a` (`--auto-servernum`) in `process-updates.yaml`, `build-all-versions.yaml` and `weekly-rebuild-missing.yaml`, so each call picks a free display. - The RHEL 10 `xwfb-run` branch still overrides `XVFB_ARGS` with `-c weston`, so it is unchanged. ## Verification `crow lint .crow/` passes. A local repro was not possible (`docker run` hangs on the dev host), so the next ubuntu-2204-arm64 cron run is the real check. Reviewed-on: https://git.devxy.io/devxy/build-cran-binaries/pulls/230 --- .crow/build-all-versions.yaml | 2 +- .crow/process-updates.yaml | 2 +- .crow/weekly-rebuild-missing.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.crow/build-all-versions.yaml b/.crow/build-all-versions.yaml index 7451988..ce3bc09 100644 --- a/.crow/build-all-versions.yaml +++ b/.crow/build-all-versions.yaml @@ -153,7 +153,7 @@ steps: # not visible here. Install the packages needed to recompute the snapshot # and query build metadata in every build job. - UVR_R_BIN=/opt/R/$R_VERSION/bin/R local/uvr-install.sh RPostgres s3fs data.table future jsonlite - - XVFB=$(command -v xwfb-run 2>/dev/null || command -v xvfb-run); XVFB_ARGS=""; if command -v xwfb-run >/dev/null 2>&1; then dnf install -y -q weston 2>/dev/null; XVFB_ARGS="-c weston"; fi + - XVFB=$(command -v xwfb-run 2>/dev/null || command -v xvfb-run); XVFB_ARGS="-a"; if command -v xwfb-run >/dev/null 2>&1; then dnf install -y -q weston 2>/dev/null; XVFB_ARGS="-c weston"; fi - $XVFB $XVFB_ARGS -n $SPLIT_INDEX -- /opt/R/$R_VERSION/bin/Rscript local/build-all.R $SPLIT_INTO $SPLIT_INDEX $NCPUS 2>&1 - | PRIMARY_MINOR=$(echo "$R_VERSION" | cut -d. -f1-2) diff --git a/.crow/process-updates.yaml b/.crow/process-updates.yaml index a1b9698..531a47f 100644 --- a/.crow/process-updates.yaml +++ b/.crow/process-updates.yaml @@ -192,7 +192,7 @@ steps: - UVR_R_BIN=/opt/R/$R_VERSION/bin/R local/uvr-install.sh RPostgres - /opt/R/$R_VERSION/bin/R -q -e 'packageVersion("bincraft")' # rhel-10 ships xwfb-run (Xwayland) instead of xvfb-run; prefer it and start weston, else fall back to xvfb-run - - XVFB=$(command -v xwfb-run 2>/dev/null || command -v xvfb-run); XVFB_ARGS=""; if command -v xwfb-run >/dev/null 2>&1; then dnf install -y -q weston 2>/dev/null; XVFB_ARGS="-c weston"; fi + - XVFB=$(command -v xwfb-run 2>/dev/null || command -v xvfb-run); XVFB_ARGS="-a"; if command -v xwfb-run >/dev/null 2>&1; then dnf install -y -q weston 2>/dev/null; XVFB_ARGS="-c weston"; fi # options(future.globals.onReference = NULL): for some reason s3fs::file_delete() throws 'Error: Detected a non-exportable reference ('externalptr') in one of the globals ('FUN' of class 'function') used in the future expression' otherwise - $XVFB $XVFB_ARGS -- /opt/R/$R_VERSION/bin/R -q -e "options(crayon.enabled = TRUE, Ncpus = 4, future.globals.onReference = 'error', repos = structure(c(getOption('repos'),INLA='https://inla.r-inla-download.org/R/stable'))); progressr::handlers('cli'); progressr::handlers(global = TRUE); options(future.globals.onReference = NULL); bincraft::process_cran_updates(interval = $INTERVAL, platform = '${OS}', process_updated = TRUE, process_new = ${PROCESS_NEW}, process_removed = TRUE, patches = 'local/patches', r_minor_detection = 'classifier',s3_endpoint = 'https://s3.eu-central-003.backblazeb2.com', s3_region = 'eu-central-003', s3_bucket = 'devxy-rpkgs-binaries', s3_access_key_id = Sys.getenv('B2_S3_ACCESS_KEY'), s3_secret_access_key = Sys.getenv('B2_S3_SECRET_KEY'), metadata_db_host = 'r-binaries.devxy.io', metadata_db_name = 'build_metadata', metadata_db_table = 'single_builds', metadata_db_user = 'rpkgs', metadata_db_password = Sys.getenv('PGPASS'), metadata_db_sslmode = 'require', metadata_db_port = 15432, archive = TRUE, upload = TRUE, store_build_metadata = TRUE)" - | diff --git a/.crow/weekly-rebuild-missing.yaml b/.crow/weekly-rebuild-missing.yaml index 955476e..a93a7bd 100644 --- a/.crow/weekly-rebuild-missing.yaml +++ b/.crow/weekly-rebuild-missing.yaml @@ -388,7 +388,7 @@ steps: - rm -rf /mnt/cache/R-pkgs/00LOCK-* - /opt/R/$R_VERSION/bin/Rscript local/install-bincraft.R - /opt/R/$R_VERSION/bin/R -q -e 'packageVersion("bincraft")' - - XVFB=$(command -v xwfb-run 2>/dev/null || command -v xvfb-run); XVFB_ARGS=""; if command -v xwfb-run >/dev/null 2>&1; then dnf install -y -q weston 2>/dev/null; XVFB_ARGS="-c weston"; fi + - XVFB=$(command -v xwfb-run 2>/dev/null || command -v xvfb-run); XVFB_ARGS="-a"; if command -v xwfb-run >/dev/null 2>&1; then dnf install -y -q weston 2>/dev/null; XVFB_ARGS="-c weston"; fi - UVR_R_BIN=/opt/R/$R_VERSION/bin/R local/uvr-install.sh httr2 - /opt/R/$R_VERSION/bin/R -q -e 'source("local/fetch-rebuild-packages-from-issue.R")' - $XVFB $XVFB_ARGS -n $SPLIT_INDEX -- /opt/R/$R_VERSION/bin/Rscript local/rebuild-missing.R $SPLIT_INTO $SPLIT_INDEX $REBUILD_BUDGET_HOURS 2>&1 From 5dad51c76a1136c003853bb6c84fbef9dc798e4d Mon Sep 17 00:00:00 2001 From: automation-bot Date: Mon, 12 Oct 2026 00:32:11 +0000 Subject: [PATCH 16/16] chore(deps): update pre-commit hook rbubley/mirrors-prettier to v3.9.10 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index dec6844..e0ba9a9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -28,7 +28,7 @@ repos: hooks: - id: markdownlint-cli2 - repo: https://github.com/rbubley/mirrors-prettier - rev: v3.9.9 + rev: v3.9.10 hooks: - id: prettier - repo: https://github.com/posit-dev/air-pre-commit