Development¶
This page is for maintainers of pkdb_data. It describes the checks that run on study folders, the pins that fix their result, the workflows and the settings they need. Curators find the workflow of a study in the curation guide. Everything about study format 2 runs on format 2 folders only; format 1 folders are skipped.
Pre-commit¶
Set up the hooks once per checkout:
Install uv first, because the hooks need uvx on the PATH. The first run needs network access, since uv fetches Python 3.14 and the pinned pkdb. Run all hooks on the repository with uvx pre-commit run --all-files. The hook pkdb-check then runs pkdb check --staged, which checks only the staged studies. To check every study with the pinned pkdb, for example after a change of a pin, run env PKDB_NO_UPDATE=1 uvx --python 3.14 --with-requirements requirements/pkdb.txt pkdb check --format human.
| Hook | What it does |
|---|---|
| Generic hooks (YAML, TOML and JSON syntax, large files, merge conflicts, symlinks, whitespace, end of file, private keys, case conflicts, line endings) | Check the files outside studies/. Each of them excludes studies/, so nobody reformats the curated data in bulk. |
pkdb-check |
Runs env PKDB_NO_UPDATE=1 uvx --python 3.14 --with-requirements requirements/pkdb.txt pkdb check --staged --format human when files below studies/ are staged. It checks the format 2 studies of the staged files with the pinned pkdb and vocabulary.lock.json. PKDB_NO_UPDATE=1 stops the update check of pkdb. |
actionlint |
Checks the workflow files of .github/workflows/. |
Other repository settings that matter to curators: .gitignore ignores the state files .*.pkdb-base of the workbook sync, and .gitattributes sets LF line ends for TSV and JSON files and marks PDF, PNG, JPG and XLSX files as binary. The line studies/**/*.xlsx is added to .gitignore only in the cutover pull request. Until then pkdb check refuses a tracked format 2 workbook.
Pins¶
Two files fix what the checks answer, so a result changes only when the data or a reviewed pin changes. Pre-commit and the workflows read the same files.
requirements/pkdb.txtholdspkdb==0.12.15, the release whose vocabulary has the effect summariesACE inhibition maximum,ACE inhibition tmaxandACE inhibition AUECand those ofrenin activity (change absolute), and thefiltration fraction, whose vocabulary has the substancechlorthalidoneand the methodambulatory blood pressure monitoring, whosepkdb migraterefuses unmapped numbers of the rows that it converts, whose vocabulary hasradioactivity excretion rate, whose paper tables can have their raw table as the source when no image exists, whosepkdb migratekeeps the WebPlotDigitizer projects of a format 1 folder and whose vocabulary has the terms of the remaining format 1 studies, that does not check the rows of dismissed review items, whose scatters hold several points of one subject (each row ofscatters_<source>.tsvis a point, andpkdb migratepairs the points of a format 1 dataset by its shared fields,rowamong them), whose curation app shows the tables of a study first, the notes of each table at the table and the PDF of the study beside its tables, numbers the lines of a table from its header as line 0, whosepkdb migratewrites the counts of the format 1 tables and single-row array outputs as outputs and refuses a study whose format 1 rows hold numbers in any column thatstudy.jsondoes not map (unmapped_value), and whose bundled vocabulary has the terms of the format 1 studies, among themdisease duration,csf/plasma ratio,renal plasma flowand negative inhibition values; it keeps the substance labels of the study issues, which releases before 0.12.3 remove again. Dependabot cannot update it, because it runs out of disk space cloning this repository (Dependabot::OutOfDisk). To update it, change the version, run the command that checks every study (see Pre-commit) and open a pull request. Curators and agents install the pinned release withuv tool install --python 3.14 --force pkdb --with-requirements requirements/pkdb.txt, run it again after a pin change and setPKDB_NO_UPDATE=1; the hook and the CI decide, so nobody curates with a newer release. A change of this file makes thestudiesworkflow check every study.vocabulary.lock.jsonis the vocabulary snapshot of the server. It is written bypkdb vocabulary sync --output vocabulary.lock.jsonwithPKDB_ENDPOINTset to the server. Thevocabularyworkflow refreshes it every week. A change of this file makes thestudiesworkflow check every study.
Workflows¶
| Workflow | File | Triggers | What it does |
|---|---|---|---|
documentation (job docs) |
.github/workflows/docs.yml |
Pull requests and pushes to develop and main |
Builds the documentation and deploys it from develop. Its job docs is a required check. |
studies |
.github/workflows/studies.yml |
Pull requests, pushes to develop, manual run |
Runs pkdb check. Required check. |
issues |
.github/workflows/issues.yml |
Pushes to develop that touch studies/, every night, manual run |
Runs pkdb issues sync. |
vocabulary |
.github/workflows/vocabulary.yml |
Every week, manual run | Refreshes the vocabulary lock. |
studies. A pull request checks the changed study folders with pkdb check --changed <merge base>. A push to develop checks the studies changed since the previous head. A change of requirements/pkdb.txt or vocabulary.lock.json, and a manual run, check every study. The workflow clones the repository without blobs and with a sparse checkout, and fetches whole study folders: the changed ones, or the study format 2 folders when it checks every study. .github/scripts/sparse-studies.sh selects them, and the vocabulary workflow uses it too. Whole folders keep the result the same as in the hook, which sees every file of a study. It never contacts the server.
issues. Keeps one GitHub issue per study aligned with its title, labels, assignees and state (see GitHub issues of studies). One run at a time. A manual run has the input dry_run, which shows the plan and changes nothing; start the workflow once with it after the first merge. The step pkdb issues sync --adopt, which gives existing studies an issue, is a manual step of the cutover and is not part of the workflow.
vocabulary. Runs pkdb vocabulary sync. When the lock changed, it checks every study with the new lock and opens or updates the pull request vocabulary/refresh with the new lock and the check summary. It closes that pull request again when the vocabulary of the server returns to the version in develop. A pull request opened with the workflow token starts no other workflows. A maintainer closes and reopens the pull request to run the required studies check, and merges when it passes.
Settings the workflows need¶
| Setting | Kind | Used by |
|---|---|---|
PKDB_API_KEY |
Repository secret | issues: the API key of a PK-DB account that may read the curator roster. The vocabulary is public and needs no key. |
PKDB_ENDPOINT |
Repository variable | issues and vocabulary: the PK-DB server whose curator roster and vocabulary are used. Until it is set, both workflows are skipped without starting a runner. |
| Allow GitHub Actions to create and approve pull requests | Repository setting (Settings, Actions, General) | vocabulary: it opens the refresh pull request. |
Rulesets¶
The rulesets in .github/rulesets/ require the checks docs and studies on develop. A maintainer with admin permission applies them after the merge, and again after every change of the JSON files:
The script is idempotent. A ruleset removed from the directory stays on GitHub and has to be deleted there.
Releases¶
A release names a state of develop, which main then tracks, and its notes list the changes since the release before. To make one:
- On a branch of
develop, setversionanddate-releasedinCITATION.cff, writerelease-notes/<version>.md, and merge the branch through a pull request. - Move
mainto the merge commit:git push origin <commit>:main. The ruleset ofmainallows only this fast-forward. - Create the release, which creates its tag:
gh release create <version> --target <commit> --title <version> --notes-file release-notes/<version>.md.
The major version changes with the study format or the layout of the repository.
Documentation¶
The site builds independently of pkdb. From the repository root:
uvx --from "$(cat docs/requirements.txt)" zensical build --clean --strict
python3 scripts/llms_txt.py
zensical serve with the same --from argument previews the site. Update zensical.toml when you add or remove a page. Do not commit the generated site/.