{rix} into your package workflow?This vignette walks through a recommended development loop for package authors:
{rix}.default.nix to the
repository.Start by calling rix() from your package root. List the
R packages and system tools that your package requires for development,
testing, or vignette builds:
rix(
r_ver = "bleeding-edge",
r_pkgs = c(
"devtools", "rcmdcheck", "roxygen2", # package development helpers
"jsonlite", "httr" # package runtime deps
),
system_pkgs = c("pandoc"), # or anything else
ide = "none",
path = "default.nix",
overwrite = TRUE
)A few tips when shaping the environment:
r_ver = "bleeding-edge" (or at least a very
recent date). This aligns your local setup with what users will
experience soon and surfaces compatibility problems early. See
vignette("z-bleeding_edge.Rmd") for more details on using
"bleeding-edge".date current.
Updating it every few weeks lets you track CRAN, nixpkgs, and system
toolchain updates. If the new snapshot fails you can fix issues right
away instead of facing a large backlog later, or you could always revert
to an earlier working date.Place the default.nix file at the root of the package
repository so that contributors can run:
This drops them into a shell with the right environment for contributing.
To simplify onboarding, document in README.md (or a
contributing guide) that contributors should run nix-shell
before working on the package.
Because the environment is pinned, collaborators and CI jobs execute the same versions of your dependencies, eliminating “works on my machine” bugs.
You could setp up a CI action to update the environment frequently, which would then trigger unit tests on CI as well. If the tests fail you can immediately address incompatibilities introduced by recent CRAN changes.
{rix} in GitHub ActionsBecause default.nix captures the entire toolchain, you
should use it as the basis for your CI workflow. Below is a minimal
GitHub Actions configuration thatruns your package’s unit tests:
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
name: devtools-tests-via-r-nix
permissions:
contents: read
jobs:
devtools_test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
env:
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Create this folder to silence warning
run: mkdir -p ~/.nix-defexpr/channels
- name: Create .Renviron
run: |
echo "GITHUB_PAT=${{ secrets.GITHUB_TOKEN }}" >> ~/.Renviron
shell: bash
- uses: cachix/install-nix-action@v31
with:
nix_path: nixpkgs=https://github.com/rstats-on-nix/nixpkgs/archive/refs/heads/r-daily.tar.gz
- uses: cachix/cachix-action@v14
with:
name: rstats-on-nix
- name: devtools::test() via nix-shell
run: nix-shell --run "Rscript -e \"devtools::test(stop_on_failure = TRUE)\""The workflow builds the same shell you use locally and uses our
rstats-on-nix binary cache for fast, reproducible builds.
Any failure signals that newly published CRAN may be incompatible.
Having the tests run on a schedule is a safe way to catch them very
early and avoid the dreaded 2 weeks notice from CRAN to fix your
package!
By defining your package environment with {rix},
committing the default.nix, and reusing it across local
development and CI/CD, you build confidence that your package remains
compatible with the evolving R ecosystem. Regularly updating the
snapshot keeps you close to the latest CRAN state while still benefiting
from the reproducibility that Nix provides.