Skip to content

Developer Contribution Guidelines

Jan-Philipp Quast edited this page Jan 14, 2026 · 9 revisions

Developer Guidelines (Internal)

This page documents how development of this package works and why certain decisions were made. It is intended for developers and maintainers, not for end users. These guidelines prioritise CRAN compliance and long-term stability over rapid feature iteration.

1. Branching & Pull Requests

  • Each change (bug fix, new feature, refactor, etc.) should be developed in a dedicated branch.
  • Once development is complete:
    1. Run devtools::check() locally with TEST_PROTTI and BUILD_VIGNETTE environment variables set.
    2. Open a Pull Request (PR) into the Developer branch.
    3. All GitHub Actions workflows need to pass (exceptions can be made for tests that fail due to external factors).
    4. At least one reviewer should review the PR before merging.

2. Backward compatibility

  • Avoid breaking changes to exported functions whenever possible
  • If unavoidable:
    • Document clearly in NEWS
    • Consider deprecation warnings before removal

3. Code Style

  • Each file contains one function.
  • Prefer existing naming patterns over introducing new ones.
  • Avoid adding synonyms for existing functionality.
  • Arguments should be named consistently across related functions.
  • Functions that access the internet should fail gracefully (no error) with an informative message if resources are not available.
  • All code should be written using the tidyverse style.
  • All code must follow tidyverse styling using:
    • styler::tidyverse_style()
    • A GitHub Actions workflow automatically applies this style. Still, try to format code locally before committing.

4. Testing

  • Unit tests are required for all new functions.
  • Run tests locally before opening a PR.

CRAN-specific testing behaviour

  • Many functions access external databases or APIs.
  • These tests and other long running tests must not run on CRAN, because:
    • External services may be temporarily unavailable
    • APIs may change
    • Full test execution exceeds CRAN time limits (~45 min)
  • We still want to keep track of problems in all functions therefore we run these tests locally and in GitHub Actions.

Environment variable: TEST_PROTTI

  • Tests that should not run on CRAN must check:
    • Sys.getenv("TEST_PROTTI") == "true"
  • These tests:
    • Run in GitHub Actions
    • Run locally when the variable is set
    • Are skipped on CRAN

5. Documentation

  • Document new features clearly.
  • Mention any user facing changes in NEWS.
    • If there are any major changes to internal behaviours or functions that is relevant for other developers you may briefly mention them.
  • Write roxygen documentation and update README.Rmd and vignettes if necessary.
  • After making changes, always update documentation:
  • Run roxygen to generate documentation:
    • devtools::document()
  • If you modified README.Rmd, rebuild the README:
    • devtools::build_readme()

6. Dependencies

  • CRAN strongly discourages packages with many dependencies.

General rules

  • Keep external dependencies to a minimum.
  • Prefer existing package dependencies when possible.

Imports vs Suggests

  • If a dependency is:
    • Core to package functionality → add to Imports
    • Niche or optional → add to Suggests

Handling suggested packages in functions

  • If a function relies on a suggested package:
    • Do not add it to Imports
    • Add it to Suggests in DESCRIPTION
  • At the start of the function, check if the package is installed:
if (!requireNamespace("PackageName", quietly = TRUE)) {
    message(strwrap("Package \"PackageName\" is needed for this function to work. Please install it.",
      prefix = "\n", initial = ""
    ))
    return(invisible(NULL))
  }

This allows users to install optional dependencies via:

devtools::install_github("jpquast/protti", dependencies = TRUE)

7. GitHub Actions & CI

  • We use several GitHub Actions workflows to ensure quality:
    • Unit testing (Codecov)
    • Code styling
    • R CMD check
    • Documentation site generation (pkgdown – main branch only)
  • These workflows are mostly generated using usethis, with some project-specific environment variables.
  • Keep workflows up to date when:
    • New versions release
    • GitHub Actions deprecate features

R CMD check

  • Tests on Windows, Mac and Linux
  • Tests release, oldrel and devel.
  • The devel test may fail due to dependencies temporarily not being available. If verifiable this is okay and can be ignored if all other tests pass.
    • The failed test should be rerun periodically and monitored.

8. Vignettes & Package Size

  • CRAN enforces strict package size limits.
  • Because this package includes many vignettes, we use conditional builds.

Environment variable: BUILD_VIGNETTE

  • Vignettes are only built when:
    • Sys.getenv("BUILD_VIGNETTE") == "true"

This keeps CRAN submissions within size limits while still allowing full documentation builds locally and in CI.

9. Pre-release Checklist

  • Check NEWS:
    • Are all updates documented?
    • Is the version number correct?
  • Check DESCRIPTION:
    • Is the version number correct?
  • Run devtools::document() and devtools::build_readme()
  • Run Sys.setenv(TEST_PROTTI = "true", BUILD_VIGNETTE = "true")
  • Run devtools::check() to test package locally.
  • Run devtools::check_mac_release() to test package remotely on Mac.
  • Run devtools::check_win_release() to test package remotely on CRAN servers.
    • You may need to fix some links that don't work externally.
  • Update cran-comments.md
  • Commit any leftover changes.
  • Restart R session or set above environment variables to "false".
  • Run devtools::release() to submit package to CRAN.
  • Confirm submission in email.

After CRAN acceptance:

  • Merge Developermain
  • Create a GitHub release for the new version