Before you start
Open an issue at https://github.com/GidonFrischkorn/jatosr/issues for anything larger than a typo. There is a form for each of the three kinds: a bug, which asks for the JATOS version and the function that fails; a feature, which asks for the workflow it serves; and a sibling package for another hosting platform, which asks for the platform’s name and a link to its API documentation. The package follows one workflow, JATOS with Prolific, so an issue first saves work on both sides.
A bug report must not contain an API token. A token can appear in an error message, in an httr2 verbose log and in the output of Sys.getenv(); replace it with <token> before pasting. If one has already been posted, revoke it in the JATOS user interface.
Branches and pull requests
main is protected. Nothing is pushed to it directly: every change, the maintainer’s included, arrives through a pull request from a branch.
git switch -c fix-metadata-columns # one branch per issue
# work, commit
git push -u origin fix-metadata-columns
gh pr create --fillA pull request is merged when
- the five required
R-CMD-checkjobs pass (macOS, Windows, and Ubuntu on R devel, release and oldrel-1); the sixth job, Ubuntu on R 4.1, andtest-coverageandpkgdownare not required, - one approving review is on it, and every review thread is resolved,
- the checklist in the pull request template is ticked or the unticked boxes are explained.
A review is required for every pull request, so a contributor’s branch waits for the maintainer. GitHub does not let anyone approve their own pull request; the maintainer merges his own branches through the repository admin bypass, once the checks are green. Merged branches are deleted automatically.
Development cycle
devtools::load_all() # never library(jatosr) while developing
devtools::document() # before every check; NAMESPACE and man/ are generated
devtools::test()
devtools::check()NAMESPACE and man/ are generated by roxygen2; edit the roxygen comments, not the generated files. Every user-facing change gets a bullet in NEWS.md.
Rules
- Tokens live in the operating system’s credential store, reached through
keyringunder the service namejatosr; the host lives inprofiles.jsonundertools::R_user_dir().JATOS_HOSTandJATOS_TOKENare read, and take precedence, but nothing in the package writes them, and nothing writes a token to a file. - No token literal anywhere in the repository: not in vignettes, not in fixtures, not in test bodies. The fake tokens the tests need are defined once, in the
fake_tokensvector oftests/testthat/helper-credentials.R;expect_no_token()asserts that none of them appears in a print, message or error path, andtests/testthat/test-canary.Rgreps the sources and the documentation for a token-shaped literal. - The connection object carries no token. If you add a field to it, or a file the package writes, the canary test must still pass — it scans every artefact byte by byte.
- No test touches a real credential store.
local_no_credentials()andlocal_fake_credentials()forcekeyring’senvbackend,setup.Rpoints the configuration attempdir(), andkeyring_guard()aborts on any other backend. Before a release, rundata-raw/check-keyring.Rby hand on each platform: it is the only thing that exercises the real store. -
httr2::request()is called in exactly one place,jatos_req()inR/request.R. Every endpoint goes through it. - No live network in tests. HTTP is mocked with
local_jatos_mock()(tests/testthat/helper-mock.R). Fixtures live intests/testthat/fixtures/; the zip fixtures are regenerated withdata-raw/make-fixtures.R, never edited by hand. - Style: native pipe, explicit
pkg::fun(), typedpurrr::map_*(), roxygen2 on every export,cli::cli_abort()for errors, no dplyr, stringr or tidyr inImports. - Metadata is a plain tibble with a column-name contract, one row per component result; functions check it with
check_metadata()at entry.
Sibling packages
A package that does for another platform what jatosr does for JATOS is welcome, and this repository is meant to be its template. The section “Using jatosr as a template” of vignette("developer-notes") lists what to copy unchanged, what to replace, and in which order to build.
