Skip to content

Repository practices

BetaRulesetv1 (2026-07-18)RefreshWeekly
Repository practices is in Beta while the ruleset settles. Corrections and requests go through the r-observatory/feedback front door.

Overview

When a package points to a public source repository, we look inside it for the everyday tooling a maintainer sets up and leaves in the open, and we list what we find. Continuous integration, a linter config, a container or environment file, citation metadata, a code of conduct: each is a file we can either see or not see.

The section on a package page

Repository practices

Upstream repositoryBeta

6 development-tooling and community-health practices detected across 5 families in the upstream repository

Checks run against github.com/example/textutils on 2026-07-20.

Continuous integration (1)
GitHub Actions
Reproducibility and dev environment (1)
renv
CRAN release process (1)
cran-comments.md
Research and citation (1)
CITATION.cff
Show all practices
Lint, format, editor (2)
lintrEditorConfig
How this is detected·Detection ruleset v1 (2026-07-18)

Every item is something present in the repository. The order carries no ranking, and the list is never turned into a score.

Why the repository, not the tarball

None of this survives the trip to CRAN. When a package is built for release, R CMD build reads .Rbuildignore and drops the development scaffolding along the way: the .github/ directory, .lintr, renv/, the Dockerfile, cran-comments.md, a README.qmd, and more.

Someone reading only the source tarball never sees any of it. The upstream repository is the one place these files are still visible, which is why the signal reads from there.

Practices we detect

The files fall into a handful of families, and most packages touch only some of them.

  • Continuous integration
    • Build and check workflows, whether that is GitHub Actions, GitLab CI, Travis, AppVeyor, or one of the others.
  • Reproducibility and environment
    • An renv lockfile, a Dockerfile or dev container, a Makefile, a Nix or Binder setup.
  • CRAN release process
    • cran-comments.md, a revdep/ directory, a CRAN-SUBMISSION record.
  • Documentation source
    • A Quarto or R Markdown README that the plain README is rendered from.
  • Research and citation
    • A CITATION.cff, codemeta.json, a JOSS paper, a Zenodo record.
  • Automation and maintenance
    • Dependabot, Renovate, pre-commit hooks.
  • Lint, format, and editor
    • A .lintr, an Air or EditorConfig file, VS Code settings.

Reading an absence

A blank spot is not a bad mark, so the page keeps a few situations apart rather than collapsing them into one empty result.

No repositoryThe package is not assessed. No section is shown at all.
Linked, not scannedA pending note names the repository awaiting a scan.
Scanned, emptyA single line reads none detected.

The scan covers GitHub for now. A package hosted somewhere else is left unassessed instead of shown as empty. Each one is checked again once a week, and the section always reflects the most recent pass, with the date it ran shown alongside it.

The limits

Each item is a check that a file exists. It tells you a maintainer set the tool up, not that it is configured well or run on every commit.

An empty result is just as limited. Many maintainers lint, test, and pin their dependencies with tools that live outside the repository, or under a personal account, where this scan never sees them.

So read the list as a place to start looking, not a grade.