DaSCH Service Platform Documentation

June 16, 2026 ยท View on GitHub

This repository is the source from which the DSP documentation on docs.dasch.swiss is generated. It includes these components:

File structure

Each software component has its own documentation in its repository. The individual documentations are stored as git submodules in the /dsp folder. Please do not change anything there. They have to be updated in their own repositories. To grab the latest version of them, run make update-submodules.

In addition to those embedded contents, there are contents that live in this repository. They are stored in the /docs folder:

  • main landing page
  • general DSP developers guide, with basics about DSP and how to contribute to the DSP software

Images like screenshots and so on have to be stored in /docs/assets/images.

How to build the documentation from source

In order to build the documentation from source, you need to install the following prerequisites:

Xcode command line tools

Some Terminal commands used for the instructions below are not shipped with macOS by default. They must be installed separately. Install the Xcode command line tools (not to be confused with the entire Xcode application) as follows:

xcode-select --install

You will be asked in a prompt if you want to install the command line developer tools. Click "Install".

Homebrew

Homebrew is a package manager that allows us to install other software. Install it with

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Python

The documentation is built with MkDocs, which requires Python. This repo uses uv as Python bootstrapper and virtual environment manager. Install uv:

curl -LsSf https://astral.sh/uv/install.sh | sh

Graphviz

Install Graphviz (Graph visualization software) to work with .dot files:

brew install graphviz

Clone repository and initialize submodules

Clone this repository from GitHub and initialize the submodules:

git clone https://github.com/dasch-swiss/dsp-docs.git
cd dsp-docs
make init-submodules

Update the submodules

If you have been away for a while, you might want to update the submodules to get the latest version of DSP-API, DSP-APP and DSP-TOOLS documentation:

make update-submodules

Install Python packages in a virtual environment

Install the required python packages (this will automatically create a virtual environment):

make install-requirements

Serving the documentation locally

MkDocs comes with a built-in dev-server that lets you preview your documentation as you work on it.

Make sure that the submodules are up-to-date (run make init-submodules and/or make update-submodules).

Then start the server with:

make serve

Open up http://127.0.0.1:8000/ in your browser, and you'll see the documentation landing page.

Deploying GitHub page

Publication of the documentation to docs.dasch.swiss is fully automated. A dsp-tools release publish triggers bump-release.yml, which opens a deploy:-prefixed PR against main; once pr-checks.yml is green, bump-release.yml merges it directly as the DaSCH Bot App (a review-bypass actor on main, so no human approval is needed) and deploy.yml publishes via mike to gh-pages. Once GitHub Pages serves the new version, deploy.yml's send-chat-notification job posts the public release announcement.

Repo-level preconditions

Run-time settings the maintainer must keep enabled (see ยง5 for secrets / vars):

  • Branch protection on main requires the pr-checks / Build documentation status check.
  • The DaSCH Bot App is listed under "Allow specified actors to bypass required pull requests" in main's branch protection. The bump PR is authored by the App, which cannot approve its own PR, and GitHub auto-merge does not honour bypass allowances โ€” so bump-release.yml instead waits for the required checks to pass and then merges the PR directly as the App (gh pr merge --admin), which the bypass authorizes. Without this entry the merge is rejected and the PR sits BLOCKED on the required review.
  • "Automatically delete head branches" enabled at the same settings page. The bump workflow force-pushes defensively so a previously merged-and-not-deleted bump branch doesn't block a re-dispatch, but auto-delete is the canonical fix.
  • The four submodule repos (dsp-api, dsp-app, dsp-tools, dsp-meta) remain publicly readable โ€” make update-submodules runs git fetch inside each submodule worktree without authentication. If any of those go private, bump-release.yml will need a credential helper inside the submodule fetches.

1. Automated path (Wednesday)

What fires:

  1. dsp-tools publishes a release to PyPI.
  2. The dispatch-dsp-docs-bump job in dsp-tools mints a DaSCH Bot App token and calls gh workflow run bump-release.yml against dsp-docs, passing DSP / API / APP parsed from dsp-tools's src/dsp_tools/resources/start-stack/versions.env plus TOOLS from the triggering release tag.
  3. bump-release.yml renders release.mk from .github/release.mk.tmpl, runs make update-submodules, and opens a PR titled deploy: bump docs to <DSP>.
  4. bump-release.yml waits for the required checks to pass, then squash-merges the PR directly as the App (gh pr merge --admin, authorized by the bypass allowance). The merge commit subject preserves the deploy: prefix so deploy.yml's gate fires.
  5. deploy.yml publishes to gh-pages via mike. GitHub Pages then builds and serves the new version (the "pages build and deployment" run, ~10 min behind the merge).
  6. deploy.yml's send-chat-notification job polls the github-pages deployment until it reaches success, then posts ๐Ÿ“š *DSP-DOCS* <DSP> released and deployed to the public release-announcements room โ€” so the announcement fires only once the site is live. (Polling, not a deployment_status trigger: that event is emitted by github-pages[bot] via GITHUB_TOKEN, which GitHub suppresses from triggering workflows.)

Where to verify:

2. Manual override (workflow_dispatch)

Use when the dispatcher did not fire (e.g. dsp-tools released out-of-band) or to publish a specific combination of upstream tags:

gh workflow run bump-release.yml \
  --repo dasch-swiss/dsp-docs \
  -f dsp=2026.05.13 \
  -f api=v35.8.1 \
  -f app=v13.3.0 \
  -f tools=v18.14.0 \
  # -f meta=dsp-meta-v2.4.16   # optional; defaults to latest dsp-meta release

The equivalent Run workflow โ–พ form is at https://github.com/dasch-swiss/dsp-docs/actions/workflows/bump-release.yml โ€” same inputs.

bump-release.yml re-runs idempotently โ€” if release.mk + submodule pointers already match the inputs, the run exits 0 without opening a PR. If a peer run already opened the PR it is a no-op too.

3. Kill switch

The bump workflow respects a per-repo vars.BUMP_RELEASE_ENABLED flag. To pause auto-bumps (e.g. during incident recovery):

# Pause
gh variable set BUMP_RELEASE_ENABLED --body false --repo dasch-swiss/dsp-docs

# Re-enable
gh variable set BUMP_RELEASE_ENABLED --body true --repo dasch-swiss/dsp-docs

The equivalent UI is at https://github.com/dasch-swiss/dsp-docs/settings/variables/actions. The change takes effect on the next workflow run.

The symmetric switch on the dispatcher side is vars.DSP_DOCS_DISPATCH_ENABLED in the dsp-tools repo โ€” set it the same way via gh variable set or https://github.com/dasch-swiss/dsp-tools/settings/variables/actions.

4. Failure modes

SymptomDetectionRecovery
bump-release.yml itself failsL1 internal Chat alert + GitHub Actions failureRe-dispatch manually after fixing inputs / tags
Bump PR opens but pr-checks.yml fails (mkdocs --strict regression)PR stays open until pushed-fix or closePush a fix to the bump branch or fix pr-checks.yml and re-run
Bump never opens (dispatcher silently failed)Wednesday checklist + absence of public success pingManually gh workflow run bump-release.yml
Bump PR opens but never mergesbump-release.yml blocks/fails at the merge stepConfirm the DaSCH Bot App is a bypass actor on main (see preconditions)
deploy.yml fails (mike publish)internal Chat alert + Actions failureRe-run deploy.yml, or re-dispatch bump-release.yml
Docs go live but no announcementabsence of public ping; deploy.yml's send-chat-notification job failed/timed out + internal alertRe-run deploy.yml, or post the announcement manually

5. Credentials

Auth uses the DaSCH Bot App installed at org level on dsp-docs, dsp-tools, dsp-api, dsp-app, dsp-meta. Workflows mint short-lived (1h) installation tokens; nothing is persisted.

Secret / varLocationPurpose
secrets.DASCH_BOT_APP_IDorg dasch-swissApp identifier
secrets.DASCH_BOT_APP_PRIVATE_KEYorg dasch-swissPEM, raw newlines, no base64 wrapping
secrets.GOOGLE_CHAT_DSP_RELEASES_WEBHOOK_URLorg dasch-swissPublic room โ€” DSP Release Announcements
secrets.GOOGLE_CHAT_DSP_RELEASE_INTERNAL_WEBHOOK_URLdsp-docs and dsp-tools (repo-level, same URL in both)Internal engineering โ€” failure / health alerts. Rotate in both.
secrets.DASCHBOT_PATdsp-docs repoLegacy PAT used by deploy.yml (gh-pages mike publish) and pr-checks.yml (submodule fetches via .git-credentials). Flagged for follow-up migration to the DaSCH Bot App.
vars.BUMP_RELEASE_ENABLEDdsp-docs repoKill switch (true/false, case-insensitive)
vars.DSP_DOCS_DISPATCH_ENABLEDdsp-tools repoSymmetric kill switch on the dispatcher

Upstream of this chain, bump-stack-versions.yml in dsp-tools runs scripts/bump_stack_versions.py to write versions.env; it uses the workflow's auto-issued secrets.GITHUB_TOKEN (no manual setup needed).

Private-key rotation: add the new key in the App settings, update the org secret, smoke-test (manual workflow_dispatch on bump-release.yml), then delete the old key. GitHub Apps support up to 25 active keys.

6. Rollback

If a bump publishes broken docs:

  1. Confirm the regression at https://docs.dasch.swiss.
  2. Open a manual PR titled exactly deploy: revert bump to <DSP> โ€” do not use GitHub's auto-generated Revert "deploy: โ€ฆ" title; it lacks the deploy: prefix and deploy.yml's commit-message gate will not fire.
  3. The PR body should revert release.mk to the previous DSP / API / APP / TOOLS / META values and revert the four submodule pointers.
  4. Merge with gh pr merge --squash <PR>. deploy.yml fires; mike redeploys the prior version.
  5. Verify https://docs.dasch.swiss/versions.json advertises the prior DSP under latest.
  6. Post a manual notice to the public release-announcements room explaining the revert.

Help for the make commands

To get help for the make commands, run:

make help