All checks were successful
ci/crow/cron/process-updates/9 Pipeline was successful
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
61 lines
5.7 KiB
Markdown
61 lines
5.7 KiB
Markdown
# 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:
|
|
|
|
1. Add an object to the array in `registry.json` with the fields documented above.
|
|
Start with lightweight overrides (environment variables, configure arguments, Makevars) before resorting to source diffs.
|
|
|
|
2. If a source diff is needed, place it in `local/patches/<package>/<file>.patch` and reference its path in the `patch` field.
|
|
For example, a diff for `RcppParallel` would go in `local/patches/RcppParallel/fix.patch` and be referenced as `"patch": "RcppParallel/fix.patch"`.
|
|
|
|
3. The `reason` field 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:
|
|
|
|
```bash
|
|
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.
|
|
|
|
```bash
|
|
# 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`.
|