Contributing to idem
This document describes the contribution process for idem. This package follows tidyverse conventions for code style and workflow — see the tidyverse development contributing guide and code review principles for broader context.
Before you start
File an issue before writing any code. This ensures the change is needed and avoids wasted effort. If you have found a bug, include a minimal reprex in the issue — this makes it easier to diagnose and to write a unit test later. The tidyverse guide on how to create a great issue has useful advice.
Prerequisites
The following tools must be available on your PATH before following the contribution workflow. Install them once and they will work across all projects.
uv
uv is a Python package manager used to install the other tools.
Windows (installation guide):
macOS / Linux (installation guide):
pre-commit
pre-commit runs the hook scripts before each commit. Install it via uv (recommended):
Alternatives: pip install pre-commit or brew install pre-commit.
Branching model
This repository uses a release-branch workflow:
- A
release/vX.Y.Zbranch is created by a maintainer for each planned release. - Each piece of work (feature, fix, docs, etc.) gets its own branch cut from the target release branch, named
<issue-number>-brief-description(e.g.7-improve-contributing-guide). - Completed feature branches are merged into the release branch via a pull request. All CI checks must pass before merging.
- When a release is ready, the release branch is merged into
main. The merge commit is tagged with the version number (e.g.v0.2.0).
Maintainers create and manage release branches. If you are an external contributor, check whether an active release branch exists and target your PR there. If none exists, ask in your issue which branch to use.
gitGraph
commit id: "…"
branch release/v0.2.0
checkout release/v0.2.0
branch "5-add-validation"
checkout "5-add-validation"
commit id: "feat: add validation"
commit id: "test: cover validation"
checkout release/v0.2.0
merge "5-add-validation" id: "Merge #5"
branch "6-fix-edge-case"
checkout "6-fix-edge-case"
commit id: "fix: edge case"
checkout release/v0.2.0
merge "6-fix-edge-case" id: "Merge #6"
checkout main
merge release/v0.2.0 id: "v0.2.0" tag: "v0.2.0"
Contribution workflow
1. Fork and clone
Fork the repository and clone it locally. The easiest way is:
usethis::create_from_github("impact-initiatives/idem", fork = TRUE)Or with plain git:
2. Install dependencies and verify the baseline
devtools::install_dev_deps()
devtools::check()R CMD check must pass cleanly before you make any changes. If it does not, open an issue rather than continuing.
Before moving on, install the pre-commit hooks — see Pre-commit hooks below. The hooks must be in place before you make your first commit.
4. Make changes and commit
Follow the commit message format described below. Each commit should be a coherent, self-contained unit of work. The PR as a whole should address just one thing — see the tidyverse guide on focused PRs.
Pre-commit hooks
Pre-commit hooks are tests that run each time you attempt to commit. If the tests pass, the commit will be made, otherwise not.
This repository uses pre-commit to run automated checks before each commit. The hook scripts are not committed to the repository — every contributor must install them locally after cloning. The steps below are required, not optional: without them the hooks will not run.
1. Install the precommit R package and activate the hooks
The precommit R package provides a convenient way to install the pre-commit framework and activate the hooks from R. Run the following in an R session from the root of the cloned repository:
install.packages("precommit")
precommit::use_precommit()precommit::use_precommit() writes the hook scripts into .git/hooks/. The pre-commit framework must already be installed — see Prerequisites if you have not done so yet. You only need to run this once per clone.
[!CAUTION] Do not abort while hooks are running in RStudio git tab. Non-staged changes are stashed to a temp directory and when you abort in RStudio, these changes are not brought back to you repo.
This installs both the pre-commit and commit-msg hooks. The commit-msg hook enforces the Conventional Commits format — see Commit message format below for the rules and allowed types.
Run hooks manually
To run all hooks against every file without making a commit:
To run a single hook by its id:
Hook reference
| Hook | What it checks / does |
|---|---|
roxygenize |
Rebuilds man/ and NAMESPACE from roxygen2 tags |
use-tidy-description |
Sorts and normalises DESCRIPTION fields |
spell-check |
Spell-checks documentation and vignettes |
lintr |
Lints R source for style and potential issues |
readme-rmd-rendered |
Ensures README.md is up-to-date with README.Rmd
|
parsable-R |
Verifies all .R files parse without error |
no-browser-statement |
Blocks accidental browser() calls |
no-print-statement |
Blocks accidental print() calls |
no-debug-statement |
Blocks accidental debug()/debugonce() calls |
deps-in-desc |
Ensures every used package is declared in DESCRIPTION
|
pkgdown |
Validates the pkgdown site configuration |
check-added-large-files |
Blocks files larger than 200 KB |
file-contents-sorter |
Keeps .Rbuildignore entries sorted |
end-of-file-fixer |
Ensures files end with a newline |
air-format |
Auto-formats R code to the tidyverse style via Air |
conventional-pre-commit |
Enforces Conventional Commits format on commit messages |
forbid-to-commit |
Blocks .Rhistory, .RData, .Rds, .rds files |
Commit message format
The conventional-pre-commit hook enforces the Conventional Commits specification. Every commit message must start with a type prefix:
type: short description in the imperative mood
Types used in this repository:
| Type | When to use |
|---|---|
feat |
A new feature or behaviour |
fix |
A bug fix |
docs |
Documentation changes only |
refactor |
Code change that neither fixes a bug nor adds a feature |
test |
Adding or updating tests |
chore |
Maintenance tasks (dependency updates, config changes, etc.) |
Example: feat: add validate_choices() function
Commits that do not follow this format will be rejected by the hook.
Code style
New code must follow the tidyverse style guide. The
air-formathook applies this automatically on commit — do not restyle code that is unrelated to your change.-
To format manually before committing:
Or format a single file:
-
To lint R source files:
lintr::lint_package() -
This package uses roxygen2 with Markdown syntax for all documentation. After editing roxygen2 comments, regenerate the docs:
devtools::document() This package uses testthat (v3) for unit tests. Contributions that include test cases are easier to accept.