Implements steps 1 + 2 of #115: turn recorded build failures into triaged patch suggestions instead of hand-scraping Crow logs. ## What this adds A **read-only** reporting pipeline over the `single_builds` metadata table. It never writes to the DB or the registry. - `local/failing-builds-classify.R` — pure, DB-free helpers: - `normalise_error()` strips temp paths, version numbers, hex addresses, and the package name so the same root cause collapses to one fingerprint. - `fingerprint_error()` extracts the salient error line and normalises it. - `classify_error()` matches against a seed signature set; unmatched errors are never guessed at. - `propose_registry_entry()` renders a schema-valid `registry.json` entry. - `local/failing-builds-report.R` — entrypoint: queries `single_builds WHERE error_occurred = TRUE AND removed = FALSE`, groups by root cause (signature when classified, fingerprint otherwise), classifies each group, and prints a triaged report. Flags: `--platform`, `--arch`, `--min`, `--json`; `PLATFORM`/`ARCH` env fallbacks. - `local/tests/test-failing-builds-classify.R` — unit tests for the helpers. - `local/patches/README.md` — documents the workflow. ## Seed signatures Each rule carries a fix tier, confidence, and an auto/human-only flag: | Signature | Fix | Disposition | | --- | --- | --- | | `tbb/tbb_stddef.h: No such file` | makevars `-DTBB_INTERFACE_NEW` | auto-proposable | | RcppParallel bundled TBB (musl / new g++) | curated `disable-tbb.patch` | auto-proposable | | system `libuv.so` link leak | force vendored/static lib | **human triage** (novel source diff) | | unmatched | none | **human triage** | ## Guardrails honored - No autonomous novel source diffs: only known env/makevars levers and already-curated package patches are auto-proposable; anything needing a brand-new diff, and any unknown signature, is routed to human triage. - No DB or registry writes; no change to the public `src/contrib` index. - Reuses `single_builds.error_text`; no new failure-capture pipeline. ## Verification - All helper unit tests pass under the Dockerized R 4.5.3 build env. - Pre-commit hooks pass (`air-format`, `validate-patches`, prettier, etc.). - Smoke-tested the full report path with a stubbed DB; generated proposals pass the real `local/validate-patches.R`. Steps 3 (auto-open PRs) and 4 (feedback loop) are intentionally deferred, per the issue's suggestion to validate the signature set first. Closes #115 Reviewed-on: #116
5.7 KiB
Patch Registry
This directory contains the curated registry of per-package build-time patches consumed by bincraft's patches argument.
Schema
The registry is defined in registry.json as an array of patch entries. Each entry specifies lightweight build-time overrides (environment variables, configure arguments, Makevars) and optionally a source diff to apply before building.
Field semantics
| Field | Type | Required | Description |
|---|---|---|---|
package |
string | yes | CRAN package name. |
versions |
string | yes | "*" for any, a constraint such as ">=5.1.0", or an exact version "5.1.11-2". Env-tier fixes are typically "*"; source diffs are normally exact or lower-bounded because a diff is pinned to the source it was generated against. |
platforms |
array of strings | yes | Matched against the running build's platform tokens — distro family (alpine, ubuntu, redhat), codename (ubuntu-2604, alpine-324), and arch (amd64, arm64). An entry matches if any listed token matches any build token. ["*"] matches all platforms. |
env |
object | no | Environment variables exported only for this package's isolated build. |
configure_args |
array | no | Arguments passed as --configure-args to the isolated build. |
makevars |
object | no | Key/value pairs written into a package-local Makevars for the isolated build. |
patch |
string or null | no | Path (relative to local/patches/) to a unified diff applied to the unpacked CRAN source before building. |
reason |
string | yes | Human explanation, surfaced in logs and metadata. |
Adding an entry
To add a new patch entry:
-
Add an object to the array in
registry.jsonwith the fields documented above. Start with lightweight overrides (environment variables, configure arguments, Makevars) before resorting to source diffs. -
If a source diff is needed, place it in
local/patches/<package>/<file>.patchand reference its path in thepatchfield. For example, a diff forRcppParallelwould go inlocal/patches/RcppParallel/fix.patchand be referenced as"patch": "RcppParallel/fix.patch". -
The
reasonfield should clearly explain why the patch is needed and what problem it solves.
Validation
The registry is validated and applied by bincraft during the build process. For manual validation, run the validator from the repo root:
Rscript local/validate-patches.R
This validates the schema, referenced patch-file existence, and checks for duplicate entries across platforms and versions.
Triaging failures into entries
local/failing-builds-report.R turns recorded build failures into triaged patch suggestions instead of hand-scraping Crow logs (issue #115, steps 1 + 2).
It is read-only: it queries single_builds WHERE error_occurred, groups failures by a normalised error fingerprint, classifies each group against the known signature set in local/failing-builds-classify.R, and prints a report.
# All platforms/arches; needs the DB password.
PGPASS=... Rscript local/failing-builds-report.R
# Restrict scope and also emit a machine-readable report.
PGPASS=... Rscript local/failing-builds-report.R --platform alpine-321 --arch amd64 --json report.json
Each group is tagged AUTO-PROPOSABLE (a known env/makevars lever, or an already-curated package patch, safe to pre-fill as a registry.json entry) or HUMAN TRIAGE (unknown signature, or a fix that needs a novel source diff).
For auto-proposable groups it prints a ready-to-review registry entry; still run validate-patches.R and an isolated trial build before merging.
Novel source diffs and unknown signatures stay human-reviewed by design.
Add a new signature by appending a rule to build_signatures() in local/failing-builds-classify.R; the pure helpers are covered by local/tests/test-failing-builds-classify.R.