Skip to content

Composite label fonts resolve to whatever the host has, so README images are only reproducible per-machine #383

Description

@ChuckBuilds

What happens

Re-running plugins/pomodoro-timer/test/render_readme_assets.py on Windows rewrites three of its four images even though the plugin has not changed:

hero.png    identical pixels
options.png 20171 px differ, bbox (24, 26, 744, 564)
phases.png  11814 px differ, bbox (24, 26, 656, 396)
sizes.png    1847 px differ, bbox (24, 26,  88, 542)

hero.png is a bare panel and reproduces exactly. The three that drift are the labelled contact sheets, and the drift is entirely in the caption chrome.

Why

Both renderers pick the caption font from a list of host font paths and fall back if none match.

plugins/pomodoro-timer/test/render_readme_assets.py:

FONT_DIRS = ["/usr/share/fonts/truetype/dejavu", "/Library/Fonts",
             "/usr/share/fonts/TTF"]

There is no Windows path in that list, so _font() falls through to ImageFont.load_default() — a completely different typeface — and every caption re-renders.

scripts/render_docs_assets.py has the same shape with the same consequence, just less visibly: its FONT_CANDIDATES does list Windows paths, so a Windows run silently picks Segoe UI where a Linux run picks DejaVu Sans. The captions still differ; nothing errors.

Why it matters

The pomodoro README states the images can be regenerated rather than edited, and several plugin READMEs I have added state that render_docs_assets.py --check verifies the committed images against a fresh render. Both claims hold on one machine and quietly fail across two. Anyone on a different OS who reruns either script produces a diff on images they did not change.

Nothing is failing today — no workflow in .github/workflows/ runs either renderer — so this is latent rather than breaking. But it does mean --check cannot be moved into CI as it stands: a Linux runner would report drift against every composite rendered on Windows, and vice versa.

Options

  1. Vendor the caption font (DejaVu Sans + Bold, ~1.4 MB) and resolve it from the repo. Fully deterministic; costs repo size.
  2. Use ImageFont.load_default(size=...), which since Pillow 10.1 returns the Aileron face bundled with Pillow. No new files, deterministic for a given Pillow version, but no bold variant, so the caption hierarchy would need another cue.
  3. Leave it and document it — say plainly that the images are regenerated on Linux and that a Windows rerun will differ in the captions only.

Option 1 is the only one that makes --check safe to run in CI, which is the thing that would stop these images drifting from the display for real.

Scope

scripts/render_docs_assets.py, plugins/pomodoro-timer/test/render_readme_assets.py, and every composite currently committed under docs/assets/ and plugins/pomodoro-timer/assets/ (the panels in them are fine; only the captions would change).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions