build-cran-binaries/.crow
Repository files (latest commit first)
Filename Latest commit message Latest commit date
pat-s 26406a3e86
All checks were successful
ci/crow/manual/rebuild-abi-gap/7 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/9 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/11 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/13 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/17 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/2 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/1 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/15 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/3 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/6 Pipeline was successful
ci/crow/cron/process-updates/11 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/5 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/8 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/10 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/12 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/14 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/16 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/18 Pipeline was successful
ci/crow/cron/process-updates/18 Pipeline was successful
ci/crow/manual/rebuild-abi-gap/4 Pipeline was successful
feat(ci): add a targeted per-R-minor rebuild workflow (#198)
## Why

A user hit this on amd64/resolute under R 4.6.1:

```
base64enc.so: undefined symbol: SETLENGTH
```

R 4.6 no longer exports `SETLENGTH`:

```
R 4.4: missing -> R_ClosureEnv R_ClosureFormals R_MakeMissingBinding R_PromiseEnv R_PromiseValue R_mkClosure
R 4.5: missing -> R_MakeMissingBinding R_PromiseEnv R_PromiseValue
R 4.6: missing -> R_PromiseEnv R_PromiseValue SETLENGTH
```

`base64enc` calls `SETLENGTH` (`base64.c:206`, `253`), its flat binary was built under R 4.4.3, and it has no per-minor copy at all, so the union index hands that binary to a 4.6 client.

The safety net missed it because the risky set is defined circularly:

```r
risky_packages_across_minors <- function(...) {
  # a package is "risky" iff it already has a tarball in some per-minor slot
```

A package counts as ABI-risky only if it has *already* been built per-minor. `base64enc` never was, and having no new CRAN version it never enters the build list to be classified. So the per-minor protection only covers packages that passed through the pipeline after the scheme existed.

## Scope

Scanning all 4,585 compiled binaries in amd64/resolute's flat index for symbols R 4.6 does not export found 10 referencing `SETLENGTH`. Most already have per-minor builds and are served correctly. Two do not:

```
base64enc_0.1-6   flat=200  4.4=404  4.5=404  4.6=404
lobstr_1.2.1      flat=200  4.4=404  4.5=200  4.6=404
```

(`iotools` lacks a 4.5 copy but 4.5 still exports `SETLENGTH`, so it does not break.)

## What this adds

Rebuilding one package into one minor was only possible with `just rebuild` from a workstation holding the S3 and Postgres credentials. This adds the CI path:

```sh
crow pipeline create devxy/build-cran-binaries \
  --var rebuild_abi_gap=ubuntu-2604-amd64 \
  --var ABI_PACKAGES="base64enc@0.1-6 lobstr@1.2.1" \
  --var ABI_R_MINOR=4.6
```

- reuses `reindex.yaml`'s slot matrix verbatim, so the slot-to-image mapping cannot drift
- runs `build-one.R --sensitive-only`, which reclassifies each version and skips anything not ABI-risky rather than writing it to the wrong slot
- mounts no shared cache volume, so it cannot disturb the build pipeline's per-agent caches
- attempts every package, then exits non-zero if any failed

`crow lint` passes.

## Not in this PR

This is the remediation path, not the fix. The circular `risky_packages_across_minors()` definition is still in place, so new instances of this class can still appear. That is the follow-up.

Reviewed-on: #198
2026-09-04 10:24:47 +00:00
..
archive-missed-packages.yaml fix(index): add a slot repair for a broken Built stamp and retire alpine 3.21 (#150) 2026-08-07 09:15:04 +00:00
auto-apply-patches.yaml fix(ci): install RPostgres for audit workflows (#172) 2026-08-30 07:31:28 +00:00
build-all-versions-install-deps.yaml fix(ci): make every manual gate default to a value that matches nothing (#158) 2026-08-09 15:31:14 +00:00
build-all-versions.yaml fix(ci): install RPostgres in build shards (#195) 2026-09-03 20:09:20 +00:00
process-updates.yaml fix(ci): install RPostgres for metadata updates 2026-08-28 08:48:58 +00:00
rebuild-abi-gap.yaml feat(ci): add a targeted per-R-minor rebuild workflow (#198) 2026-09-04 10:24:47 +00:00
reindex.yaml fix(cdn): purge the staging zone too (#181) 2026-08-31 10:31:35 +00:00
repair-built-stamp.yaml fix(ci): make every manual gate default to a value that matches nothing (#158) 2026-08-09 15:31:14 +00:00
trial-build-registry.yaml fix(ci): gate the three ungated pipelines on their own variable (#155) 2026-08-09 10:02:05 +00:00
weekly-audit-missing.yaml fix(ci): install RPostgres for audit workflows (#172) 2026-08-30 07:31:28 +00:00
weekly-patch-proposals.yaml fix(ci): install RPostgres for audit workflows (#172) 2026-08-30 07:31:28 +00:00
weekly-rebuild-missing.yaml Revert "fix(ci): split oversized weekly rebuild matrix" 2026-08-14 07:01:56 +00:00
weekly-rebuild-reindex.yaml fix(cdn): purge the staging zone too (#181) 2026-08-31 10:31:35 +00:00