Commit graph build-cran-binaries/.crow/rebuild-abi-gap.yaml
Author SHA1 Message Date
8140702b5f
chore(alpine): drop the deprecated Alpine 3.22 slot
Alpine 3.22 is deprecated and is no longer a published slot.
It was never routed: `local.rpkgs_slots` in `cdn.tf` lists eight distros and
alpine322 is not among them, so `UNION_SLOTS` never gated per-minor rewriting
for it and every request fell through to the flat index.

The fleet-wide routing verification made that concrete.
Across all 16 published slots, both architectures, three R minors and both
contractual URL forms, 1056 of 1056 install-and-load checks passed.
Every failure in the run was alpine322, identical on amd64 and arm64, and
identical across `arch`, `generic` and `flat`.
That last part is the signature of an unrouted slot: on a routed slot the
contractual forms diverge from `flat`, because the divergence is the routing.
Its flat objects are R 4.5 builds, so R 4.4 and R 4.6 clients got
`LOAD_FAILED` while R 4.5 clients were fine.

This change will:

- Remove the alpine-322 matrix rows and dropdown options from every pipeline
  that carried them, so `=all` no longer fans out to a slot nobody can reach.
- Remove `3.22` from the `OS_VERSION` dropdowns in `build-all-versions.yaml`
  and `repair-built-stamp.yaml`, and move the latter's default to `3.23`.
- Update the stale `3.22` examples in `local/packages-to-build.R`.

The six alpine-322 cron jobs are deleted from the Crow server as well, since a
cron whose matrix row is gone would keep firing against nothing:

    5   process-cran-updates-alpine-322-amd64     0 5/8 * * *
    6   process-cran-updates-alpine-322-arm64     30 5/8 * * *
    68  weekly-audit-missing-alpine-322-amd64     20 0 * * 0
    69  weekly-audit-missing-alpine-322-arm64     30 0 * * 0
    82  weekly-rebuild-missing-alpine-322-amd64   0 4 * * 0
    83  weekly-rebuild-missing-alpine-322-arm64   10 4 * * 0

The published objects and indexes under `amd64/alpine322` and `arm64/alpine322`
are left in place; removing them from the bucket is a separate decision.
2026-09-11 07:25:21 +00:00
cceda03935 fix(ci): do not gate the targeted repair on the source classifier (#205)
All checks were successful
ci/crow/cron/process-updates/12 Pipeline was successful
ci/crow/cron/process-updates/17 Pipeline was successful
ci/crow/cron/process-updates/6 Pipeline was successful
ci/crow/cron/process-updates/5 Pipeline was successful
ci/crow/cron/process-updates/1 Pipeline was successful
ci/crow/cron/process-updates/2 Pipeline was successful
ci/crow/cron/process-updates/7 Pipeline was successful
ci/crow/cron/process-updates/8 Pipeline was successful
ci/crow/cron/process-updates/9 Pipeline was successful
ci/crow/cron/process-updates/3 Pipeline was successful
ci/crow/cron/process-updates/10 Pipeline was successful
ci/crow/cron/process-updates/4 Pipeline was successful
ci/crow/cron/process-updates/13 Pipeline was successful
ci/crow/cron/process-updates/14 Pipeline was successful
ci/crow/cron/process-updates/15 Pipeline was successful
ci/crow/cron/process-updates/16 Pipeline was successful
ci/crow/cron/process-updates/11 Pipeline was successful
ci/crow/cron/process-updates/18 Pipeline was successful
ci/crow/manual/reindex/4 Pipeline was successful
## Why

The repair workflow ran `build-one.R --sensitive-only`. That flag skips any version the **source** classifier does not call r-minor-sensitive — and it misses `Rcpp`.

So the repair skipped `Rcpp` on every slot, leaving its 4.5-built flat binary as the only copy:

```
flat   200  built under R 4.5.3
4.4/   404
4.5/   404
4.6/   404
```

Every R 4.4 client on those slots then failed at `dyn.load()`. A real install check across 8 slots x 3 minors x 3 repository forms found **44 such failures**, `Rcpp`, `Matrix` and `RJSONIO` among them.

## What changed

Drops `--sensitive-only`.

Since bincraft v5.3.0 the destination is decided by the built binary's symbols in `upload_single_binary()`, so building unconditionally is safe and correct: a package that needs a per-minor slot lands there, one that does not lands in the flat slot. Skipping before the build is exactly what removed that decision from the path.

`crow lint` passes.

## Companion

bincraft #129 is the other half: the index build could not compensate either, because it only considered dropping records whose *package* was flagged risky, and `Rcpp` is not — even though the backfill had recorded that object as unable to load under 4.4.

Reviewed-on: #205
2026-09-07 06:20:04 +00:00
26406a3e86 feat(ci): add a targeted per-R-minor rebuild workflow (#198)
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
## 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