Skip to content

feat(regression): R2 write backend for native baselines#732

Open
lewisjared wants to merge 3 commits into
feat/regression-coupling-gatefrom
feat/regression-r2-backend
Open

feat(regression): R2 write backend for native baselines#732
lewisjared wants to merge 3 commits into
feat/regression-coupling-gatefrom
feat/regression-r2-backend

Conversation

@lewisjared

@lewisjared lewisjared commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Description

Implements the Cloudflare R2 (S3-compatible) write backend for the regression native-baseline store (RFC-005, so ref test-cases mint can upload native blobs to the shared object store instead of only a local path.

Stacked on:

What's included

  • R2WriteStore — content-addressed, flat digest-keyed uploads (served at {url}/{digest}), idempotent put, hash-verified fetch. boto3 is an optional aws extra, lazily imported, so the read/replay/CI paths never need it.
  • Credentials never live in config — the S3 endpoint and bucket are non-secret config (defaulting to the production R2 bucket); the access-key id / secret are resolved at upload time from REF_NATIVE_STORE_ACCESS_KEY_ID / REF_NATIVE_STORE_SECRET_ACCESS_KEY, else a named REF_NATIVE_STORE_PROFILE, else boto3's default credential chain.
  • Minting DX hardening
    • mint now preflights the store (credentials + bucket reachability) and fails fast with an actionable message before running any diagnostics.
    • new ref test-cases check-store verifies connectivity without minting; mint --dry-run previews scope after the preflight.
    • ref test-cases fetch regenerates the gitignored catalog.paths.yaml when it is missing even if the committed catalog is unchanged — a plain fetch now works on a fresh checkout (no --force required).
  • Example migration — minted the example provider's native baselines to R2, removed the committed annual_mean_global_mean_timeseries.nc (now served from the store) and the retired .catalog_hash sidecars.

Checklist

Please confirm that this pull request has done the following:

  • Tests added
  • Documentation added (where applicable)
  • Changelog item added to changelog/

Implement the Cloudflare R2 (S3-compatible) write backend so `ref test-cases mint`
can upload native baseline blobs to the shared object store, not just a local path.
Blobs are content-addressed with a flat, digest-keyed layout,
so each is served publicly at `{url}/{digest}` and reused across cases and re-mints.

The S3 endpoint and bucket are non-secret config (defaulting to the production R2 bucket);
write credentials are resolved at upload time only —
explicit `REF_NATIVE_STORE_ACCESS_KEY_ID` / `REF_NATIVE_STORE_SECRET_ACCESS_KEY`,
else a named `REF_NATIVE_STORE_PROFILE`,
else boto3's default credential chain — so secrets never land in the persisted config.
boto3 is an optional `aws` extra; the read and replay paths never need it.

Harden the minting developer experience:

- `mint` preflights the store (credentials and bucket reachability)
  and fails fast with an actionable message before running any diagnostics.
- add `ref test-cases check-store` to verify connectivity without minting,
  and `mint --dry-run` to preview scope after the preflight.
- `ref test-cases fetch` now regenerates the gitignored `catalog.paths.yaml`
  when it is missing even if the committed catalog is unchanged,
  so a plain fetch works on a fresh checkout (no `--force` needed).
Mint the example provider's native baselines to the production R2 bucket and author the
`native` block in each test case's `manifest.json`.
Remove the committed `annual_mean_global_mean_timeseries.nc` (now fetched from the store)
and the retired `.catalog_hash` sidecars.
@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.25974% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...-ref-core/src/climate_ref_core/regression/store.py 85.29% 11 Missing and 4 partials ⚠️
Flag Coverage Δ
core 92.51% <90.25%> (-0.07%) ⬇️
providers 91.80% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...f-core/src/climate_ref_core/regression/__init__.py 100.00% <ø> (ø)
...s/climate-ref-core/src/climate_ref_core/testing.py 90.15% <100.00%> (+0.32%) ⬆️
...ckages/climate-ref/src/climate_ref/cli/__init__.py 96.96% <ø> (ø)
...ages/climate-ref/src/climate_ref/cli/test_cases.py 83.30% <100.00%> (+0.71%) ⬆️
packages/climate-ref/src/climate_ref/config.py 98.13% <100.00%> (+0.01%) ⬆️
...-ref-core/src/climate_ref_core/regression/store.py 90.60% <85.29%> (-6.96%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant