Skip to content

feat: skip PNG renders whose source has not changed - #147

Merged
lesnik512 merged 2 commits into
mainfrom
feat/png-skip-unchanged
Oct 29, 2026
Merged

lesnik512 merged 2 commits into
mainfrom
feat/png-skip-unchanged

Conversation

@lesnik512

Copy link
Copy Markdown
Member

brand.build.render now leaves a PNG alone when the SVG it comes from hasn't changed. Before this, every run rewrote all ~110 committed PNGs, because rsvg-convert output differs byte-wise between machines. Each brand PR then had to revert them by hand, and #145 ended up committing them.

export_png hashes the SVG bytes, the requested width and height, and the palette size, and stores the hash in a source-sha256 text chunk inside the PNG. On the next run it reads the chunk back and skips rsvg-convert when the hash matches. A changed SVG, size or palette re-renders as before. Without Pillow there is no chunk, so every PNG renders as it does today.

The second commit re-renders every PNG once to add the chunk. That is the one-time churn: 113 files under brand/ plus the docs/assets copy of the green social card. I compared each of them to main after decoding and all are pixel-identical; only the metadata differs. A second render right after touched no files.

A newer rsvg-convert won't re-render anything on its own. To force it, delete the PNGs and run the renderer.

The Pillow import moved to module level, with the same fallback when Pillow is missing.

Tests: tests/test_raster.py covers the skip on an unchanged source and the re-render on a changed SVG and on a changed size. uv run pytest (184 passed) and uv run mkdocs build --strict pass locally.

@lesnik512
lesnik512 merged commit dca1dbe into main Oct 29, 2026
3 checks passed
@lesnik512
lesnik512 deleted the feat/png-skip-unchanged branch October 29, 2026 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant