Skip to contents

Branching and Release Model

pizzarr uses three branch types tied to its two distribution tiers (CRAN and r-universe).

  • develop — active development. All pull requests should target develop, not main. DESCRIPTION carries a .9000 suffix (e.g., 0.2.0.9000) and Cargo.toml uses a -dev pre-release tag (0.2.0-dev).
  • release/X.Y.Z — release candidate. Cut from develop when ready to ship. The .9000 / -dev suffixes are dropped, NEWS.md is finalized, and the CRAN tarball is built with bash tools/cran-build.sh. This branch is PR’d to main.
  • main — release-only and the GitHub default branch. Always matches the latest version accepted by CRAN. r-universe auto-builds from main, so the r-universe binary (which includes the compiled zarrs Rust backend) tracks the same release version as CRAN. pkgdown deploys from main.

The release sequence:

  1. Development proceeds on develop (version X.Y.Z.9000).
  2. Pre-release (r-universe only): merge develop to main and tag X.Y.Z-pre. r-universe builds binaries from main for testing before CRAN submission. The DESCRIPTION version is X.Y.Z (R does not support pre-release suffixes). NEWS.md carries the -pre label.
  3. Cut a release/X.Y.Z branch from develop. Drop the .9000 / -dev suffixes, finalize NEWS.md, and submit to CRAN via bash tools/cran-build.sh.
  4. Open a PR from release/X.Y.Z to main. Do not merge until CRAN has accepted the package.
  5. After CRAN acceptance, merge the PR to main. r-universe picks up the new commit and builds binaries with the zarrs backend. pkgdown rebuilds.
  6. Merge main back into develop and bump the version to the next X.Y.Z.9000.

Both CRAN and r-universe serve the same version number. The difference is the build: CRAN gets pure R (no Rust), r-universe gets the zarrs backend. Users can check which tier they have with pizzarr_compiled_features().

Development Setup

# make sure you are on the develop branch
setwd("path/to/pizzarr")
install.packages("devtools")
devtools::install()
devtools::load_all()

Build and Test Cycles

pizzarr has two build tiers that affect how you develop and test locally.

CRAN tier (pure R)

If you are working on R-side logic (indexers, stores, codecs, R6 classes) and do not need the zarrs backend, this is the faster cycle:

devtools::load_all()
devtools::test()
devtools::check()

Tests run single-threaded (Config/testthat/parallel: false in DESCRIPTION). All zarrs-specific tests skip automatically when the Rust library is absent — they guard on .pizzarr_env$zarrs_available.

To produce a CRAN-ready source tarball that strips src/, configure, and SystemRequirements:

bash tools/cran-build.sh

The resulting .tar.gz passes R CMD check without a Rust toolchain.

r-universe tier (zarrs backend)

The r-universe build compiles the zarrs Rust crate via extendr. You need rustc >= 1.91 with the GNU target on Windows:

rustup target add x86_64-pc-windows-gnu

After modifying any #[extendr] function in src/rust/src/lib.rs, regenerate the R wrappers:

rextendr::document()

This rebuilds the Rust library and regenerates R/extendr-wrappers.R. Never edit that file by hand. Then run the standard cycle:

devtools::load_all()
devtools::test()
devtools::check()

devtools::check() will emit a NOTE about downloading Rust crates — that is expected and is not a problem for r-universe builds. See RUST-STYLE.md for Rust conventions, module layout, and build pipeline details.

Building Documentation

devtools::document()
pkgdown::build_site()

Coding Conventions

  • Style: snake_case everywhere (functions, methods, variables). 2-space indent.
  • Errors: stop("ErrorName(details)") — mimics Python Zarr error names. No rlang.
  • Warnings/info: warning() and message() from base R.
  • Assertions: direct if (...) stop() — no assertion library.
  • R6 docs: roxygen2 with @title, @docType class, @format [R6::R6Class]. See r6-roxygen-convention.md for the full style guide.
  • Tests: testthat 3e with test_that("description", { ... }).

Resources