Development tools

MAFw ships with a small set of development tools that support maintenance tasks such as building versioned documentation trees and preparing tagged releases.

These tools are not part of the scientific user-facing workflow: a typical MAFw user does not need them, and can safely ignore this section. They exist for the benefit of the development team and for community members who want to contribute to MAFw in a consistent, reproducible way.

Because they automate development activities, they may depend on additional Python packages or external executables that are installed only when MAFw is installed with the optional [dev] feature (or when using the Hatch development environments).

How to invoke the tools

You can invoke each tool in two equivalent ways:

  1. Console entry point (from an activated development environment).

  2. Hatch script (recommended for CI/CD and for reproducible local runs).

The table below provides a quick lookup.

Table 1 Development tools lookup table

Source module

Console entry point

Hatch script (development env)

src/mafw/scripts/doc_versioning.py

multiversion-doc

hatch run dev.py3.14:multidoc

src/mafw/scripts/new_release.py

new_release

hatch run dev.py3.14:release

Note

The Hatch environment name includes the Python version (for example dev.py3.14). On CI, the version is typically driven by the PYTHON_VERSION variable in .gitlab-ci.yml.

doc_versioning.py (multiversion-doc)

Purpose and idea

multiversion-doc builds the MAFw documentation using Sphinx and produces a directory tree that contains:

  • One folder per stable tag (for example v2.1.0).

  • A stable alias pointing to the latest stable tag.

  • Optionally a dev alias for the current branch if it is ahead of stable.

  • A latest folder containing a build of the current working tree.

This makes it possible to publish multiple documentation versions (HTML and optionally PDF) in a single GitLab Pages site, while keeping the workflow reproducible and CI-friendly.

Getting help

To display the full help, use:

multiversion-doc --help

Command structure

The tool is organised into subcommands:

multiversion-doc
├── current      Build only the current working tree documentation (latest/)
├── build        Build a multiversion documentation tree (tags + stable/dev)
├── clean        Remove output directories (all/ or latest/)
├── prune        Remove old versions to respect a size limit
├── redirects    Generate GitLab Pages `_redirects` file
├── landing      Generate a root `index.html` landing page for Pages
├── registry     Interact with the GitLab Generic Package Registry
│   ├── upload
│   ├── download
│   └── delete
└── server       Local HTTP server helper
    ├── start
    ├── status
    ├── stop
    └── restart

Typical usage examples

Build only the current documentation (current)

This is the fastest way to validate documentation changes on your current branch.

multiversion-doc current --help

Typical build (HTML only):

multiversion-doc current -y

Rebuild from scratch (recommended when you changed Sphinx configuration, extensions, or generated files):

multiversion-doc current -y --from-scratch

Logical workflow summary

  1. Optionally delete the docs/build output and Sphinx generated trees (--from-scratch).

  2. Run Sphinx for the current working tree into docs/build/doc/latest.

  3. Write a sphinx-build.log into the output directory for later inspection.

Build a multiversion documentation tree (build)

This builds one documentation folder per stable tag and assembles the published tree under docs/build/doc.

multiversion-doc build --help

Typical build (HTML + PDF, keep only versions >= v1.0.0):

multiversion-doc build --min-vers v1.0.0 --build-pdf

Logical workflow summary

  1. List stable tags and select the version range (--min-vers and other selectors).

  2. For each selected tag, check out the tag (via git worktrees) and run Sphinx.

  3. Create stable (and optionally dev) aliases.

  4. Optionally prune old versions if the output exceeds the configured size limit.

How documentation is built on CI (doc_build_all)

In the GitLab pipeline, the multiversion documentation is generated by the doc_build_all job in .gitlab-ci.yml using a Hatch script:

hatch run dev.py${PYTHON_VERSION}:multidoc build \
  --min-vers $DOC_MIN_VERS \
  --build-pdf \
  --max-size $DOC_MAX_SIZE \
  --zip-filepath /tmp/zips \
  --with-zip-file \
  --with-upload-zip \
  --with-cached-packages

In this workflow:

  • --with-zip-file creates a per-tag zip archive of the generated documentation.

  • --with-upload-zip uploads those zip files to the GitLab Generic Package Registry (package name mafw-docs).

  • --with-cached-packages allows reusing already published zip files instead of rebuilding older tags, making the job faster and more reproducible.

Start a local documentation server (server start)

After building the documentation locally, you can serve the generated tree over HTTP:

multiversion-doc server start -d docs/build -p 8000

Then open your browser at http://127.0.0.1:8000 and navigate to the doc/ folder.

new_release.py (new_release)

Purpose and idea

new_release is a maintainer helper that prepares a new tagged MAFw release by orchestrating a sequence of operations that must stay consistent across releases:

  • bump the project version via Hatch,

  • update NOTICE.txt,

  • regenerate CHANGELOG.md,

  • optionally generate a release-note file,

  • commit the release artifacts,

  • create a git tag,

  • optionally push commits and tags to the remote repository.

The command is intentionally interactive and conservative (it checks the main branch and a clean working tree) to reduce the risk of publishing inconsistent releases.

Getting help

new_release --help

Workflow and flags

The command takes a single positional argument called SEGMENTS. This value is passed to Hatch and supports comma-separated segments such as minor,rc or release.

The behaviour is modified by flags:

  • --dry-run prints the planned operations without applying git changes.

  • --without-push keeps the release local (no remote pushes).

  • --without-release-note skips release note generation.

  • --without-missing-release-check disables the guard that prevents skipping a stable version.

Typical usage examples

Create a minor pre-release (release candidate)

new_release minor,rc --dry-run

Create a second release candidate from an existing RC

If the current version is already an RC (for example 2.1.0rc0), you can increment the RC index:

new_release rc --dry-run

Create a stable release from a pre-release (release segment)

If the current version is a pre-release (for example 2.1.0rc2), you can produce the stable tag:

new_release release --dry-run