From 1b972a994b70368166f9051b6a2347a01d5fe09b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:26:09 +0200 Subject: [PATCH 01/16] ci: bump crate-ci/typos from 1.45.1 to 1.48.0 (#5) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index ff752fd..8f3ccb2 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Spell check repo - uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1 + uses: crate-ci/typos@bee27e3a4fd1ea2111cf90ab89cd076c870fce14 # v1.48.0 with: config: .config/typos.toml From 43fe903b692e884d81498e5bd64c69a45fd614bf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:26:14 +0200 Subject: [PATCH 02/16] ci: bump astral-sh/setup-uv from 8.1.0 to 8.3.2 (#4) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9eebcdf..a98941e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -58,7 +58,7 @@ jobs: # Install uv to use git-cliff and rumdl - name: Set up uv - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 with: enable-cache: true From 0f909ae2a68d8f726f176b710b870c44dcda7b8e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:26:18 +0200 Subject: [PATCH 03/16] ci: bump step-security/harden-runner from 2.14.0 to 2.20.0 (#3) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/add-to-project.yml | 2 +- .github/workflows/build-website.yml | 2 +- .github/workflows/checks.yml | 6 +++--- .github/workflows/release.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/add-to-project.yml b/.github/workflows/add-to-project.yml index b7f29fc..d743b3f 100644 --- a/.github/workflows/add-to-project.yml +++ b/.github/workflows/add-to-project.yml @@ -26,7 +26,7 @@ jobs: # This is a useful security step to check for unexpected outbound calls from the runner, # which could indicate a compromised token or runner. - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit diff --git a/.github/workflows/build-website.yml b/.github/workflows/build-website.yml index 81509e9..6ba426c 100644 --- a/.github/workflows/build-website.yml +++ b/.github/workflows/build-website.yml @@ -20,7 +20,7 @@ jobs: # This is a useful security step to check for unexpected outbound calls from the runner, # which could indicate a compromised token or runner. - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 8f3ccb2..71c29a2 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -11,7 +11,7 @@ jobs: # This is a useful security step to check for unexpected outbound calls from the runner, # which could indicate a compromised token or runner. - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit @@ -29,7 +29,7 @@ jobs: # This is a useful security step to check for unexpected outbound calls from the runner, # which could indicate a compromised token or runner. - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a98941e..01f2c8b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: # This is a useful security step to check for unexpected outbound calls from the runner, # which could indicate a compromised token or runner. - name: Harden the runner (Audit all outbound calls) - uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0 + uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0 with: egress-policy: audit From a1387d6265eddea48930a5fc1c86e8c2c49c4d57 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:26:23 +0200 Subject: [PATCH 04/16] ci: bump actions/checkout from 6.0.2 to 7.0.0 (#2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-website.yml | 2 +- .github/workflows/checks.yml | 6 +++--- .github/workflows/release.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-website.yml b/.github/workflows/build-website.yml index 6ba426c..1fa0574 100644 --- a/.github/workflows/build-website.yml +++ b/.github/workflows/build-website.yml @@ -25,7 +25,7 @@ jobs: egress-policy: audit - name: Check out repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Quarto uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0 diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 71c29a2..5f6ac2b 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -16,7 +16,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Spell check repo uses: crate-ci/typos@bee27e3a4fd1ea2111cf90ab89cd076c870fce14 # v1.48.0 @@ -34,7 +34,7 @@ jobs: egress-policy: audit - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Set up Quarto uses: quarto-dev/quarto-actions/setup@8a96df13519ee81fd526f2dfca5962811136661b # v2.2.0 @@ -60,7 +60,7 @@ jobs: egress-policy: audit - name: "Checkout Repository" - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: "Dependency Review" uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 01f2c8b..959211e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,7 +38,7 @@ jobs: private-key: ${{ secrets.UPDATE_VERSION_TOKEN }} - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: # Only need the last commit from the repo. fetch-depth: 0 From 2b70f21b645685ec3bf019845ac17fb7dcaca6ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:26:28 +0200 Subject: [PATCH 05/16] ci: bump cocogitto/cocogitto-action from 4.1.0 to 4.2.0 (#1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 959211e..3a0c4bd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,7 +52,7 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - name: Install Cocogitto - uses: cocogitto/cocogitto-action@9a9fe03b31c47444290c0d7f9b1ee1b44ee13f20 # v4.1.0 + uses: cocogitto/cocogitto-action@52d0023b4396897f1815648e553db2ab8d782f3a # v4.2.0 with: command: check From 089c776792f2b3287063855796df4c1b49948038 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Sat, 11 Jul 2026 16:48:10 +0200 Subject: [PATCH 06/16] =?UTF-8?q?chore:=20=F0=9F=99=88=20don't=20track=20Q?= =?UTF-8?q?uarto-generated=20`=5Ffiles/`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8e7c3e8..76c7668 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ _temp/ /.quarto/ docs/.quarto/ **/*.quarto_ipynb +*_files/ # Website generation _site From d5b5a66e4fe1996fc54de36bfa85fec228e5c160 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Sat, 11 Jul 2026 16:48:19 +0200 Subject: [PATCH 07/16] =?UTF-8?q?style:=20=F0=9F=8E=A8=20reformat=20Markdo?= =?UTF-8?q?wn?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 404.qmd | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/404.qmd b/404.qmd index 87ccc8c..f759668 100644 --- a/404.qmd +++ b/404.qmd @@ -6,6 +6,7 @@ Let's get you back to greener grounds. 👉 Go to [homepage](/index.qmd). -![](/_extensions/seedcase-project/seedcase-theme/images/404.svg){fig-alt="An illustration of the number 404 surrounded by trees and mountains"} +![](/_extensions/seedcase-project/seedcase-theme/images/404.svg){fig-alt="An +illustration of the number 404 surrounded by trees and mountains"} ## Illustration by [Storyset](https://storyset.com/online) {.appendix} From 511051d75b75f8e9d244aa08ef5504ec5571efa8 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Sat, 11 Jul 2026 16:48:38 +0200 Subject: [PATCH 08/16] =?UTF-8?q?build:=20=F0=9F=94=A8=20don't=20check=20`?= =?UTF-8?q?pre-commit.ci`=20URLs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- justfile | 1 + 1 file changed, 1 insertion(+) diff --git a/justfile b/justfile index 381b671..3fa6289 100644 --- a/justfile +++ b/justfile @@ -39,6 +39,7 @@ check-urls: --verbose \ --extensions md,qmd \ --exclude "github\.com" \ + --exclude "pre-commit\.ci" \ --exclude-path "_badges.qmd" # Format Markdown files From 79043c7bf57cabc1e219552727a63bd0af36002d Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Sat, 11 Jul 2026 16:50:46 +0200 Subject: [PATCH 09/16] =?UTF-8?q?chore:=20=F0=9F=93=9D=20add=20`#sec-`=20l?= =?UTF-8?q?inks=20to=20empty=20pages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/config.qmd | 2 +- docs/devex.qmd | 2 +- docs/docs.qmd | 2 +- docs/index.qmd | 2 +- docs/license.qmd | 2 +- docs/setup.qmd | 2 +- docs/testing.qmd | 2 +- docs/workflow.qmd | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/config.qmd b/docs/config.qmd index ef5aa80..659157a 100644 --- a/docs/config.qmd +++ b/docs/config.qmd @@ -1 +1 @@ -# Configurations +# Configurations {#sec-config} diff --git a/docs/devex.qmd b/docs/devex.qmd index 409dd9f..31bb6c0 100644 --- a/docs/devex.qmd +++ b/docs/devex.qmd @@ -1 +1 @@ -# Developer experience +# Developer experience {#sec-devex} diff --git a/docs/docs.qmd b/docs/docs.qmd index 25f8d45..4817893 100644 --- a/docs/docs.qmd +++ b/docs/docs.qmd @@ -1 +1 @@ -# Documentation +# Documentation {#sec-docs} diff --git a/docs/index.qmd b/docs/index.qmd index e10b99d..d66c6b2 100644 --- a/docs/index.qmd +++ b/docs/index.qmd @@ -1 +1 @@ -# Introduction +# Introduction {#sec-intro} diff --git a/docs/license.qmd b/docs/license.qmd index cc3e074..cf1cc4b 100644 --- a/docs/license.qmd +++ b/docs/license.qmd @@ -1 +1 @@ -# License +# License {#sec-license} diff --git a/docs/setup.qmd b/docs/setup.qmd index feae8cb..e975ac2 100644 --- a/docs/setup.qmd +++ b/docs/setup.qmd @@ -1 +1 @@ -# Setup +# Setup {#sec-setup} diff --git a/docs/testing.qmd b/docs/testing.qmd index f00b526..0c939f3 100644 --- a/docs/testing.qmd +++ b/docs/testing.qmd @@ -1 +1 @@ -# Testing +# Testing {#sec-testing} diff --git a/docs/workflow.qmd b/docs/workflow.qmd index 93f5694..8afac9d 100644 --- a/docs/workflow.qmd +++ b/docs/workflow.qmd @@ -1 +1 @@ -# Overall workflow +# Overall workflow {#sec-workflow} From 21931330e9223418dcfb30f2aa2748b82d9e81b5 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Sat, 11 Jul 2026 19:30:22 +0200 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=E2=9C=A8=20add=20release=20proce?= =?UTF-8?q?ss=20chapter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release.qmd | 186 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/docs/release.qmd b/docs/release.qmd index 61f2347..82a454f 100644 --- a/docs/release.qmd +++ b/docs/release.qmd @@ -1 +1,187 @@ # Release process {#sec-release} + +A release is a snapshot of the data package at a specific point in time. It +contains the data and metadata in their final state at that point in time and is +tagged with a specific version number. Releases are how we can track changes +over time and make it easier to share or distribute the data package to +researchers in a structured and predictable way. + +The release process is dependent on the type of data contained in the data +package. For data packages that contain human (in particular health or +sensitive) data, the release process is a bit more complicated than for data +packages that contain data that doesn't fall under legal restrictions (e.g. +GDPR). This is because the data must remain on secure servers and can't +(usually) upload the data to any public repository or archive. + +For nonsensitive data, the release process can fairly simple. It can be done +through a GitHub workflow (e.g. `release.yml`) that runs on a schedule or is +triggered by specific events (e.g. a specific type of commit, described later in +this document). The data and metadata can be attached as release artifacts on +GitHub and/or be uploaded to public archives like [Zenodo](https://zenodo.org/). + +For sensitive data that falls under legal regulations, the release process is +quite different. The data must be on secure servers. Because of that, we can't +use GitHub workflows nor upload any data for public access. That means we can't +use a continuous release process like we could with GitHub workflows. + +Regardless of the type of data, the steps remain mostly the same. The difference +is in *where* the release is done and *what triggers* a release. We'll start +with the triggers. + +## Triggers + +There are a few ways to trigger a release: manually, on a schedule, or based on +specific events whenever a change is merged into `main`. Because we practice +[continuous delivery](https://en.wikipedia.org/wiki/Continuous_delivery), we +won't go into the manual release process here. So that leaves a schedule-based +release or a merge/push event. For data that falls under legal regulations, you +likely will need to use a schedule-based process by running a [cron +job](https://en.wikipedia.org/wiki/Cron) on the server. For non-private data, +you can use the merge/push-based process by using a GitHub workflow. + +In both cases, the underlying trigger is the same: a release is created based on +specific text within the commit messages. Using commit messages to trigger a +release is called [semantic +release](https://decisions.seedcase-project.org/why-semantic-release-with-cocogitto/), +which uses [Semantic +Versioning](https://decisions.seedcase-project.org/why-semver/index.html) and +[Conventional +Commits](https://decisions.seedcase-project.org/why-conventional-commits/) as +its foundation. + +### Commits + +In order to trigger a release, commits must follow [Conventional +Commits](https://decisions.seedcase-project.org/why-conventional-commits/) to +structure the commit messages. The structure of a commit message looks like +this: + +```text +(optional scope): + +[optional body] + +[optional footer(s)] +``` + +The two main components of this structure for triggering releases are the "type" +and the "footer". The "type" is the first part of the commit message and is used +to determine what type of change has been made. The "footer" is the last part of +the commit message and is used to include a `BREAKING CHANGE` note if the change +is a breaking change. These two components determine which version to set for +the release. + +Semantic versions are made up of three numbers: `MAJOR.MINOR.PATCH`. The `MAJOR` +version is incremented when there are breaking changes, the `MINOR` version is +incremented when new features are added, and the `PATCH` version is incremented +when fixes are made. For semantic releases, the commit "type" `feat` increases +the `MINOR` version, while the commit "type" `fix`, `refactor`, or `perf` +increases the `PATCH`. If there is a breaking change, with either +`BREAKING CHANGE` in the footer or `!` in the commit message, then the +`MAJOR` version is increased. + +But how do you know which commit type to use? Unlike software development, +develop data packages is quite different and it is a bit more difficult to +determine what a "feature", "fix", or "breaking change" is. So we use aspects of +[Data Package's semantic +versioning](https://datapackage.org/recipes/data-package-version/). + +Breaking changes with the `!` or `BREAKING CHANGE` in the footer format +*must only* happen after the first stable release of the data package. The first +stable release is defined as when the data package has all expected or planned +resources, the metadata has been filled out, and the participants have completed +the initial, main phases of the study. Before that point, only `MINOR` and +`PATCH` changes are allowed. This means that the version will remain at +`0.MINOR.PATCH` until the stable release. Once a stable release has been made, a +breaking change would be when you: + +- Change the data package, resource, or column name or identifier. +- Remove a resource or column from the data package. +- Move a column into another resource. +- Change a column type (e.g. from integer to string). +- Change a column's constraints to be more restrictive (e.g. reduce the distance + between the minimum and maximum values). +- Remove a participant's data (e.g. they request their data be deleted). +- Substantially change the meaning of the text in the metadata (e.g. a column's + description or a resource's title). + +A good guideline to use for `MINOR` (`feat`) commits would be if something *new* +has been added or expanded on (e.g. text in the metadata). Minor changes with +the `feat` format would be: + +- Add a new resource. +- Add data, either as rows or columns to an existing resource. +- Change a column's constraints to be less restrictive (e.g. increase the + distance between the minimum and maximum values). +- Add new text to the metadata, for example, when no metadata existed before. + +A good guideline to use for `PATCH` (`fix`, `refactor`, or `perf`) commits would +be if something has been *corrected* or *refined*. Before the stable release, +many of the breaking change items above would be considered a patch change, as +they generally don't add any new content. Patch changes with the `fix`, +`refactor`, or `perf` commit type would be: + +- Correct errors in existing data, like a typo or data entry error. Depending on + the severity of the error, this could also be a breaking change. +- Change the text of the metadata without changing the meaning, for example + fixing typos, grammatical errors, or clarifying the text without changing its + meaning. +- Changes to how the data is processed so that it results in better compression + or other performance improvements. + +## Steps + +How that we've covered the triggers, let's go over the actual steps involved in +the release process, whether it is schedule-based or merge/push-based. +[Cocogitto](https://decisions.seedcase-project.org/why-semantic-release-with-cocogitto/) +manages all these steps via the `cog.toml` file. + +1. Check the commit history since the last release for any releasable changes. + If no releasable changes are found, then no release is created. Otherwise, + the process continues. + +2. Update the version based on the commit message and update the version in the + `pyproject.toml` file using + [`uv version`](https://docs.astral.sh/uv/reference/cli/#uv-version). If the + metadata format is `datapackage.json`, the version field uses the version in + `pyproject.toml` and will be updated automatically when the + `datapackage.json` file is (re)generated. + +3. Run the build process from start to end. This is described above in the build + process in @sec-build. + +4. Generate the changelog based on the commit messages since the last release. + [git-cliff](https://decisions.seedcase-project.org/why-changelog-with-git-cliff/) + is used to generate the changelog. + +5. Commit the changes that were made in the `CHANGELOG.md` file, the `raw/` data + files, and the `datapackage.json` file, then create a tag for the new version + on that commit. Push the commit and the tag to GitHub. + +6. Create a new GitHub release on GitHub from the new tag and changelog. Attach + the build artifacts to the release. For non-sensitive data, the `.tar` file + is attached to the release. For sensitive data, the`.zip` file is added. + Either way, the file is renamed to simply `feasibility_data.zip` (or `.tar`), + as the tag itself contains the version number. + +7. For non-sensitive data, upload the `.tar` file to Zenodo. For sensitive data, + upload the `.zip` file to the secure server. + +## Practical considerations + +As you develop a data package, there are a few things to keep in mind in order +to make the release process easier. + +- We consider the first release to happen once there is code that takes the + first resource and its metadata from raw into its final state. The code must + also be integrated into the `build.py` file, so that the build pipeline can + run automatically. + +- Whenever you make a change, either directly to main or through a pull request, + you *always* need to make sure commits and pull requests are + [atomic](https://decisions.seedcase-project.org/why-atomic-commits-and-prs/). + This means that each commit or pull request contains only one *conceptual* + change. That's because the commit message (and consequently the changed files + in the commit) determine what type of release will be triggered. The commit + message will also be added to the changelog, so be aware of the message you + use. From 06f06b0f5e7d2d57fe7450b3dbb51501bcf3eff0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 13:09:18 +0000 Subject: [PATCH 11/16] =?UTF-8?q?chore:=20=E2=9C=8F=EF=B8=8F=20automatic?= =?UTF-8?q?=20pre-commit=20hook=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.qmd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/index.qmd b/index.qmd index 49bb6b8..45d88a4 100644 --- a/index.qmd +++ b/index.qmd @@ -28,9 +28,9 @@ the software package development cycle so that the final "data package" (or This guide mostly follows the [diátaxis](https://diataxis.fr/how-to-guides/) "how-to guide" style, though not strictly. It is a living and constantly evolving guide that is regularly updated as we learn and refine how we work and -develop data packages. We intend to continually update and release it with -every update to Zenodo and as GitHub releases. We don't expect this guide to -ever be considered "done". +develop data packages. We intend to continually update and release it with every +update to Zenodo and as GitHub releases. We don't expect this guide to ever be +considered "done". ::: ## Who you are @@ -67,8 +67,8 @@ the GitHub repository. ::: content-hidden -The PDF version of the guide is available in the releases page, as well as -the Zenodo archive. +The PDF version of the guide is available in the releases page, as well as the +Zenodo archive. ::: ## How the website is made From c39471b79b059faed3749ae4531ef8be9ff87557 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Thu, 16 Jul 2026 14:39:02 +0200 Subject: [PATCH 12/16] refactor: :pencil2: edits from review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Signe Kirk Brødbæk <40836345+signekb@users.noreply.github.com> --- docs/release.qmd | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/docs/release.qmd b/docs/release.qmd index 82a454f..1b98b32 100644 --- a/docs/release.qmd +++ b/docs/release.qmd @@ -2,8 +2,8 @@ A release is a snapshot of the data package at a specific point in time. It contains the data and metadata in their final state at that point in time and is -tagged with a specific version number. Releases are how we can track changes -over time and make it easier to share or distribute the data package to +tagged with a specific version number. Releases are how we track changes +over time and make it easier to share or distribute data packages to researchers in a structured and predictable way. The release process is dependent on the type of data contained in the data @@ -11,18 +11,18 @@ package. For data packages that contain human (in particular health or sensitive) data, the release process is a bit more complicated than for data packages that contain data that doesn't fall under legal restrictions (e.g. GDPR). This is because the data must remain on secure servers and can't -(usually) upload the data to any public repository or archive. +(usually) be uploaded to any public repository or archive. -For nonsensitive data, the release process can fairly simple. It can be done +For nonsensitive data, the release process is fairly simple. It can be done through a GitHub workflow (e.g. `release.yml`) that runs on a schedule or is triggered by specific events (e.g. a specific type of commit, described later in this document). The data and metadata can be attached as release artifacts on GitHub and/or be uploaded to public archives like [Zenodo](https://zenodo.org/). For sensitive data that falls under legal regulations, the release process is -quite different. The data must be on secure servers. Because of that, we can't +a bit different. Since the data must be on secure servers, we can't use GitHub workflows nor upload any data for public access. That means we can't -use a continuous release process like we could with GitHub workflows. +use a continuous release process like a GitHub workflow. Regardless of the type of data, the steps remain mostly the same. The difference is in *where* the release is done and *what triggers* a release. We'll start @@ -33,7 +33,7 @@ with the triggers. There are a few ways to trigger a release: manually, on a schedule, or based on specific events whenever a change is merged into `main`. Because we practice [continuous delivery](https://en.wikipedia.org/wiki/Continuous_delivery), we -won't go into the manual release process here. So that leaves a schedule-based +won't go into the manual release process here. That leaves a schedule-based release or a merge/push event. For data that falls under legal regulations, you likely will need to use a schedule-based process by running a [cron job](https://en.wikipedia.org/wiki/Cron) on the server. For non-private data, @@ -68,10 +68,10 @@ The two main components of this structure for triggering releases are the "type" and the "footer". The "type" is the first part of the commit message and is used to determine what type of change has been made. The "footer" is the last part of the commit message and is used to include a `BREAKING CHANGE` note if the change -is a breaking change. These two components determine which version to set for +is a breaking change, i.e., a change that disrupt the compatibility of existing code with newer versions. A breaking change can also be triggered by appending a "!" to the commit "type". These two components determine which version to set for the release. -Semantic versions are made up of three numbers: `MAJOR.MINOR.PATCH`. The `MAJOR` +Semantic versions are made up of three numbers: `MAJOR.MINOR.PATCH`, e.g., `0.1.2`. The `MAJOR` version is incremented when there are breaking changes, the `MINOR` version is incremented when new features are added, and the `PATCH` version is incremented when fixes are made. For semantic releases, the commit "type" `feat` increases @@ -81,8 +81,9 @@ increases the `PATCH`. If there is a breaking change, with either `MAJOR` version is increased. But how do you know which commit type to use? Unlike software development, -develop data packages is quite different and it is a bit more difficult to -determine what a "feature", "fix", or "breaking change" is. So we use aspects of +developing data packages is quite different and it can be a bit more difficult to +determine what a "feature", "fix", or "breaking change" is. To help determine the commit "type", we use aspects of + [Data Package's semantic versioning](https://datapackage.org/recipes/data-package-version/). @@ -90,10 +91,11 @@ Breaking changes with the `!` or `BREAKING CHANGE` in the footer format *must only* happen after the first stable release of the data package. The first stable release is defined as when the data package has all expected or planned resources, the metadata has been filled out, and the participants have completed +resources, the metadata has been filled out, and data has been collected for the initial, main phases of the study. Before that point, only `MINOR` and `PATCH` changes are allowed. This means that the version will remain at `0.MINOR.PATCH` until the stable release. Once a stable release has been made, a -breaking change would be when you: +breaking change would occur if you: - Change the data package, resource, or column name or identifier. - Remove a resource or column from the data package. @@ -101,25 +103,25 @@ breaking change would be when you: - Change a column type (e.g. from integer to string). - Change a column's constraints to be more restrictive (e.g. reduce the distance between the minimum and maximum values). -- Remove a participant's data (e.g. they request their data be deleted). +- Remove a participant's data (e.g. after they request their data be deleted). - Substantially change the meaning of the text in the metadata (e.g. a column's description or a resource's title). A good guideline to use for `MINOR` (`feat`) commits would be if something *new* -has been added or expanded on (e.g. text in the metadata). Minor changes with -the `feat` format would be: +has been added or expanded on. Minor changes with +the `feat` format would be if you: - Add a new resource. -- Add data, either as rows or columns to an existing resource. +- Add data, either new rows or columns to an existing resource. - Change a column's constraints to be less restrictive (e.g. increase the distance between the minimum and maximum values). -- Add new text to the metadata, for example, when no metadata existed before. +- Add new text to the metadata, for example, when no metadata existed before, but not correcting existing metadata (see `PATCH` below). A good guideline to use for `PATCH` (`fix`, `refactor`, or `perf`) commits would be if something has been *corrected* or *refined*. Before the stable release, many of the breaking change items above would be considered a patch change, as they generally don't add any new content. Patch changes with the `fix`, -`refactor`, or `perf` commit type would be: +`refactor`, or `perf` commit type would be if you: - Correct errors in existing data, like a typo or data entry error. Depending on the severity of the error, this could also be a breaking change. @@ -131,11 +133,13 @@ they generally don't add any new content. Patch changes with the `fix`, ## Steps -How that we've covered the triggers, let's go over the actual steps involved in +Now that we've covered the triggers, let's go over the actual steps involved in the release process, whether it is schedule-based or merge/push-based. [Cocogitto](https://decisions.seedcase-project.org/why-semantic-release-with-cocogitto/) manages all these steps via the `cog.toml` file. +The release process runs the following steps to check and potentially update the release number: + 1. Check the commit history since the last release for any releasable changes. If no releasable changes are found, then no release is created. Otherwise, the process continues. From 4d777408866b13d45cbc0f8bd1c46f7bd720cdc0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 16 Jul 2026 12:39:08 +0000 Subject: [PATCH 13/16] =?UTF-8?q?chore:=20=E2=9C=8F=EF=B8=8F=20automatic?= =?UTF-8?q?=20pre-commit=20hook=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release.qmd | 63 ++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/docs/release.qmd b/docs/release.qmd index 1b98b32..b24832f 100644 --- a/docs/release.qmd +++ b/docs/release.qmd @@ -2,9 +2,9 @@ A release is a snapshot of the data package at a specific point in time. It contains the data and metadata in their final state at that point in time and is -tagged with a specific version number. Releases are how we track changes -over time and make it easier to share or distribute data packages to -researchers in a structured and predictable way. +tagged with a specific version number. Releases are how we track changes over +time and make it easier to share or distribute data packages to researchers in a +structured and predictable way. The release process is dependent on the type of data contained in the data package. For data packages that contain human (in particular health or @@ -19,10 +19,10 @@ triggered by specific events (e.g. a specific type of commit, described later in this document). The data and metadata can be attached as release artifacts on GitHub and/or be uploaded to public archives like [Zenodo](https://zenodo.org/). -For sensitive data that falls under legal regulations, the release process is -a bit different. Since the data must be on secure servers, we can't -use GitHub workflows nor upload any data for public access. That means we can't -use a continuous release process like a GitHub workflow. +For sensitive data that falls under legal regulations, the release process is a +bit different. Since the data must be on secure servers, we can't use GitHub +workflows nor upload any data for public access. That means we can't use a +continuous release process like a GitHub workflow. Regardless of the type of data, the steps remain mostly the same. The difference is in *where* the release is done and *what triggers* a release. We'll start @@ -68,21 +68,24 @@ The two main components of this structure for triggering releases are the "type" and the "footer". The "type" is the first part of the commit message and is used to determine what type of change has been made. The "footer" is the last part of the commit message and is used to include a `BREAKING CHANGE` note if the change -is a breaking change, i.e., a change that disrupt the compatibility of existing code with newer versions. A breaking change can also be triggered by appending a "!" to the commit "type". These two components determine which version to set for -the release. - -Semantic versions are made up of three numbers: `MAJOR.MINOR.PATCH`, e.g., `0.1.2`. The `MAJOR` -version is incremented when there are breaking changes, the `MINOR` version is -incremented when new features are added, and the `PATCH` version is incremented -when fixes are made. For semantic releases, the commit "type" `feat` increases -the `MINOR` version, while the commit "type" `fix`, `refactor`, or `perf` -increases the `PATCH`. If there is a breaking change, with either -`BREAKING CHANGE` in the footer or `!` in the commit message, then the -`MAJOR` version is increased. +is a breaking change, i.e., a change that disrupt the compatibility of existing +code with newer versions. A breaking change can also be triggered by appending a +"!" to the commit "type". These two components determine which version to set +for the release. + +Semantic versions are made up of three numbers: `MAJOR.MINOR.PATCH`, e.g., +`0.1.2`. The `MAJOR` version is incremented when there are breaking changes, the +`MINOR` version is incremented when new features are added, and the `PATCH` +version is incremented when fixes are made. For semantic releases, the commit +"type" `feat` increases the `MINOR` version, while the commit "type" `fix`, +`refactor`, or `perf` increases the `PATCH`. If there is a breaking change, with +either `BREAKING CHANGE` in the footer or `!` in the commit message, then +the `MAJOR` version is increased. But how do you know which commit type to use? Unlike software development, -developing data packages is quite different and it can be a bit more difficult to -determine what a "feature", "fix", or "breaking change" is. To help determine the commit "type", we use aspects of +developing data packages is quite different and it can be a bit more difficult +to determine what a "feature", "fix", or "breaking change" is. To help determine +the commit "type", we use aspects of [Data Package's semantic versioning](https://datapackage.org/recipes/data-package-version/). @@ -91,11 +94,11 @@ Breaking changes with the `!` or `BREAKING CHANGE` in the footer format *must only* happen after the first stable release of the data package. The first stable release is defined as when the data package has all expected or planned resources, the metadata has been filled out, and the participants have completed -resources, the metadata has been filled out, and data has been collected for -the initial, main phases of the study. Before that point, only `MINOR` and -`PATCH` changes are allowed. This means that the version will remain at -`0.MINOR.PATCH` until the stable release. Once a stable release has been made, a -breaking change would occur if you: +resources, the metadata has been filled out, and data has been collected for the +initial, main phases of the study. Before that point, only `MINOR` and `PATCH` +changes are allowed. This means that the version will remain at `0.MINOR.PATCH` +until the stable release. Once a stable release has been made, a breaking change +would occur if you: - Change the data package, resource, or column name or identifier. - Remove a resource or column from the data package. @@ -108,14 +111,15 @@ breaking change would occur if you: description or a resource's title). A good guideline to use for `MINOR` (`feat`) commits would be if something *new* -has been added or expanded on. Minor changes with -the `feat` format would be if you: +has been added or expanded on. Minor changes with the `feat` format would be if +you: - Add a new resource. - Add data, either new rows or columns to an existing resource. - Change a column's constraints to be less restrictive (e.g. increase the distance between the minimum and maximum values). -- Add new text to the metadata, for example, when no metadata existed before, but not correcting existing metadata (see `PATCH` below). +- Add new text to the metadata, for example, when no metadata existed before, + but not correcting existing metadata (see `PATCH` below). A good guideline to use for `PATCH` (`fix`, `refactor`, or `perf`) commits would be if something has been *corrected* or *refined*. Before the stable release, @@ -138,7 +142,8 @@ the release process, whether it is schedule-based or merge/push-based. [Cocogitto](https://decisions.seedcase-project.org/why-semantic-release-with-cocogitto/) manages all these steps via the `cog.toml` file. -The release process runs the following steps to check and potentially update the release number: +The release process runs the following steps to check and potentially update the +release number: 1. Check the commit history since the last release for any releasable changes. If no releasable changes are found, then no release is created. Otherwise, From b012d51438cc540d62916debf73b1740fd2d48f7 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Thu, 16 Jul 2026 14:40:07 +0200 Subject: [PATCH 14/16] refactor: :pencil2: edits from review Co-authored-by: Luke W. Johnston --- docs/release.qmd | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/release.qmd b/docs/release.qmd index b24832f..a9a23a1 100644 --- a/docs/release.qmd +++ b/docs/release.qmd @@ -13,6 +13,7 @@ packages that contain data that doesn't fall under legal restrictions (e.g. GDPR). This is because the data must remain on secure servers and can't (usually) be uploaded to any public repository or archive. + For nonsensitive data, the release process is fairly simple. It can be done through a GitHub workflow (e.g. `release.yml`) that runs on a schedule or is triggered by specific events (e.g. a specific type of commit, described later in From 6cfa61e5f81ab63d7832c1816b03e115b7bea604 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Thu, 16 Jul 2026 14:47:19 +0200 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20=E2=99=BB=EF=B8=8F=20revise?= =?UTF-8?q?=20based=20on=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release.qmd | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/docs/release.qmd b/docs/release.qmd index a9a23a1..b4e206b 100644 --- a/docs/release.qmd +++ b/docs/release.qmd @@ -21,13 +21,14 @@ this document). The data and metadata can be attached as release artifacts on GitHub and/or be uploaded to public archives like [Zenodo](https://zenodo.org/). For sensitive data that falls under legal regulations, the release process is a -bit different. Since the data must be on secure servers, we can't use GitHub -workflows nor upload any data for public access. That means we can't use a -continuous release process like a GitHub workflow. +bit different, as will be explained later. Since the data must be on secure +servers, we can't use GitHub workflows nor upload any data for public access. +That means we can't use a continuous release process like a GitHub workflow. -Regardless of the type of data, the steps remain mostly the same. The difference -is in *where* the release is done and *what triggers* a release. We'll start -with the triggers. +Regardless of the type of data, the general steps remain mostly the same with +some notable differences. The difference is in *where* the release is done (the +computing environment where the release process is executed, e.g. GitHub or on a +secure server) and *what triggers* a release. We'll start with the triggers. ## Triggers @@ -157,8 +158,11 @@ release number: `pyproject.toml` and will be updated automatically when the `datapackage.json` file is (re)generated. -3. Run the build process from start to end. This is described above in the build - process in @sec-build. +3. Run the build process from start to end. This is described in the build + process in @sec-build. The main artifacts of the build process are the + `_.tar` file for sensitive and nonsensitive data and + the `_.zip` for an artifact that can be publicly + uploaded when the data is sensitive. 4. Generate the changelog based on the commit messages since the last release. [git-cliff](https://decisions.seedcase-project.org/why-changelog-with-git-cliff/) @@ -169,13 +173,13 @@ release number: on that commit. Push the commit and the tag to GitHub. 6. Create a new GitHub release on GitHub from the new tag and changelog. Attach - the build artifacts to the release. For non-sensitive data, the `.tar` file - is attached to the release. For sensitive data, the`.zip` file is added. - Either way, the file is renamed to simply `feasibility_data.zip` (or `.tar`), - as the tag itself contains the version number. + the build artifacts to the release. For nonsensitive data, the `.tar` file is + attached to the release. For sensitive data, the`.zip` file is added. Either + way, the file is renamed to simply `.zip` (or + `.tar`), as the tag itself contains the version number. -7. For non-sensitive data, upload the `.tar` file to Zenodo. For sensitive data, - upload the `.zip` file to the secure server. +7. For nonsensitive data, upload the `.tar` file to Zenodo. For + sensitive data, upload the `.zip` file to the secure server. ## Practical considerations From cf720d67b0c53be54351def6f31482bb265f4000 Mon Sep 17 00:00:00 2001 From: "Luke W. Johnston" Date: Thu, 16 Jul 2026 14:49:57 +0200 Subject: [PATCH 16/16] =?UTF-8?q?refactor:=20=E2=9C=8F=EF=B8=8F=20fix=20re?= =?UTF-8?q?dundant=20text?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/release.qmd | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/release.qmd b/docs/release.qmd index b4e206b..34c7132 100644 --- a/docs/release.qmd +++ b/docs/release.qmd @@ -8,10 +8,13 @@ structured and predictable way. The release process is dependent on the type of data contained in the data package. For data packages that contain human (in particular health or -sensitive) data, the release process is a bit more complicated than for data -packages that contain data that doesn't fall under legal restrictions (e.g. -GDPR). This is because the data must remain on secure servers and can't -(usually) be uploaded to any public repository or archive. +sensitive) data, the release process is a bit more complicated, as will be +explained later, than for data packages that contain data that doesn't fall +under legal restrictions (e.g. GDPR). This is because the data must remain on +secure servers and can't (usually) be uploaded to any public repository or +archive. That means we can't use services like GitHub workflows nor upload any +data for public access, so we can't use a continuous release process (or at +least it is more difficult to). For nonsensitive data, the release process is fairly simple. It can be done @@ -20,11 +23,6 @@ triggered by specific events (e.g. a specific type of commit, described later in this document). The data and metadata can be attached as release artifacts on GitHub and/or be uploaded to public archives like [Zenodo](https://zenodo.org/). -For sensitive data that falls under legal regulations, the release process is a -bit different, as will be explained later. Since the data must be on secure -servers, we can't use GitHub workflows nor upload any data for public access. -That means we can't use a continuous release process like a GitHub workflow. - Regardless of the type of data, the general steps remain mostly the same with some notable differences. The difference is in *where* the release is done (the computing environment where the release process is executed, e.g. GitHub or on a