On this page

Release checks

The GitHub workflow runs on master pushes, pull requests and manual dispatch. It does not publish packages.

  • Contract/regression tests and end-to-end acceptance run in separate steps, without running the same test in both steps. The release acceptance runner rejects skipped cases and missing reference workflows. The acceptance marker and workflow ownership are documented in acceptance. Tests use the pinned dependencies in requirements-ci.txt.
  • API documentation must match the generated reference. Guide examples are executed by the tests, and MkDocs builds with strict navigation/link checks using requirements-docs.txt.
  • Thirteen complete fixtures are compared against reviewed SVG/PDF baselines.
  • Complete v2 and v2.5 figures enforce cold-build budgets and cached compilation.
  • Wheels are built and installed in isolated environments on Linux with Python 3.11, 3.12 and 3.13, and on Windows/macOS with Python 3.12. The smoke test verifies both the public API and CLI with only core dependencies and rejects accidental imports from the source checkout.
  • The twenty-panel stress test checks dense mixed content, live edits, provenance, cached compilation and physical resizing.
  • The preset comparison renders the same plots, workflow, table and native 3D object in all ten presets, preserving SVG/PDF files and both previews. Preset tests cover inherited styles, explicit overrides, switching, caching, data provenance and physical formats. Three complete destination examples exercise journal limits, 16:9 slides and A4 worksheets, including PDF page sizes.

V3 adds cross-format paint/compositing tests and direct PNG size checks. Separate Blender CPU jobs install checksum-pinned 4.2.23 and 4.5.13 LTS builds and require successful discovery before running scene, pass, projection, annotation, template and render-job tests. Both jobs also generate and render all three templates from an installed wheel. The ordinary figure job still skips optional Blender integrations. GPU rendering is checked locally, not on hosted runners. See the support matrix and release acceptance criteria.

Run scene integrations locally with python -m pytest tests/test_blend_scene.py tests/test_scene_templates.py, then build tools/v3_showcase.py. Select an installation with INKLET_BLENDER; legacy Grease Pencil vector baking requires 4.2 LTS even when complete scenes use 4.5.

The figure job uses Ubuntu 24.04, Python 3.12, Chrome Stable 145.0.7632.45, Poppler 24.02.0, DejaVu and Noto fonts. The visual checker verifies the renderer versions and DejaVu file hashes before comparisons; mismatches fail with an environment error. Review artifacts and test reports are retained for seven days, including on failed runs. The static documentation site is included in the artifact. Hosting is configured separately through Read the Docs.

The workflow uses the official uv setup action. Action references are pinned to commits. Python test dependencies are locked; the visual browser archive is pinned by version and SHA-256. System fonts and Poppler still come from Ubuntu packages, so this is not a fully hermetic rendering environment.

Local equivalents:

uv venv
uv pip install -r requirements-ci.txt -e .
.venv/bin/python -m pytest -q -m "not acceptance"
.venv/bin/python tools/acceptance.py --output out/acceptance.xml
.venv/bin/python tools/benchmark_project.py --output out/project-benchmark.json
.venv/bin/python tools/benchmark_reports.py --output out/report-benchmark
.venv/bin/python tools/gen_api.py --check
uv pip install -r requirements-docs.txt
.venv/bin/python -m mkdocs build --strict
.venv/bin/python tools/visual_check.py
.venv/bin/python tools/benchmark_v2.py
.venv/bin/python tools/stress20.py
.venv/bin/python tools/preset_gallery.py
uv build --wheel --out-dir out/dist
.venv/bin/python tools/check_wheel.py out/dist/inklet-*.whl

Both wheel checks use uv when available, otherwise Python's venv/pip support. Add tools/check_render_wheel.py out/dist/inklet-*.whl --templates to exercise installed template creation with Blender. The --scene option accepts the laboratory .blend generated by tools/v3_showcase.py for a broader scene check. Neither visual checker updates baselines during normal runs. Changes to the baseline require explicit visual review and tools/visual_check.py --update.

Read the Docs

.readthedocs.yaml configures a strict MkDocs build on Ubuntu 24.04 with Python 3.12 and the pinned documentation requirements. The site includes the existing gallery images and search index; building it does not require Chrome, Blender or regeneration of the figures.

Hosting is active at stable for the newest activated release tag and latest for master. The GitHub integration rebuilds the site on pushes. MkDocs uses the canonical URL supplied by Read the Docs; links to source files use the commit checked out for that documentation build.

After tagging a release, check the project's build dashboard and confirm that stable successfully builds a new stable tag. For a development prerelease, keep stable on the latest stable release and use latest or the explicitly activated preview tag. The old v2.5.0 tag predates the hosting configuration and is intentionally unchanged.

One-command release

tools/release.py runs a whole release from a clean, up-to-date master whose pyproject.toml, inklet.__version__ and CHANGELOG.md already name the new version:

python tools/release.py 4.9.0 --dry-run   # local checks and build only
python tools/release.py 4.9.0             # publish, asking before each outward step

It runs the API reference, compatibility, strict docs and test-suite checks, builds the wheel and source archive into out/release-<version> (rejecting a source archive over 25 MB), and writes SHA256SUMS and release notes from the changelog. It then pushes master and waits for this workflow, creates and pushes the tag, creates the GitHub release (as a prerelease for development and RC versions), runs the publishing workflow as a dry run and then for real, and checks that PyPI serves files with the same hashes. It asks before every step that reaches GitHub or PyPI unless given --yes. Finished steps are detected and skipped, so a stopped release continues with the same command; --from <step> starts later and --fast leaves the local test suite to CI.

Publishing to PyPI

The separate publishing workflow uploads the wheel and source archive from an existing, published GitHub release. It verifies the release's SHA256SUMS and runs Twine's strict metadata checks. It does not rebuild the packages, so GitHub and PyPI receive identical files. The workflow accepts stable tags such as v3.1.0 and developmental tags such as v4.0.0.dev1, and release candidates such as v4.0.0rc1, and runs from master. Development and RC tags must be marked as GitHub prereleases; stable tags must not. Both archives' package name/version metadata must match the tag.

The project already has an active trusted publisher with these settings:

Field Value
PyPI project name inklet
GitHub owner Mapika
Repository name inklet
Workflow filename publish.yml
Environment name pypi

The workflow filename is just publish.yml, without .github/workflows/. The matching GitHub environment is named pypi. Authentication uses Trusted Publishing; no PyPI API token or GitHub repository secret is needed. Publisher configuration is managed in the PyPI project settings.

In GitHub Actions, select Publish to PyPI, then Run workflow on master. Enter the published release tag. Leave Validate release files without uploading to PyPI checked for a dry run; uncheck it to publish. The workflow runs only when manually dispatched. Creating a tag or GitHub release does not upload to PyPI automatically.

The same operations are available through the GitHub CLI:

# Validate the existing release without uploading.
gh workflow run publish.yml --ref master -f tag=v4.9.0 -F dry_run=true

# Publish the verified release assets.
gh workflow run publish.yml --ref master -f tag=v4.9.0 -F dry_run=false

For subsequent versions, run release checks, create the tag and GitHub release, and attach the wheel, source archive and SHA256SUMS before dispatching the publishing workflow. PyPI does not permit replacing an uploaded distribution; package changes require a new version.

For a development snapshot or release candidate, mark the GitHub release as a prerelease and keep it out of GitHub's latest stable release slot (gh release create --prerelease --latest=false). Use an exact PEP 440 version, for example 4.0.0.dev1 or 4.0.0rc1, in both pyproject.toml and inklet.__version__. The same checksum, metadata and isolated-package checks apply; run the workflow first with dry_run=true, then publish the same attached files with dry_run=false. Users opt in with an exact pin such as python -m pip install "inklet==4.0.0.dev1".

Search documentation

Type to search guides, examples and the API.