Two root causes for the 'imaging extension was built for another version
of Pillow' error users hit after install:
1) cleanup_site_packages ran 'find ... -name "*.py" ! -name "__init__.py"
-delete' with a comment claiming 'keep .pyc only' — but no compileall
step exists. Result: the dist shipped __init__.py + .pyd only, missing
every submodule (Image.py, ImageDraw.py, _version.py, ...). Fresh
installs were broken; in-place upgrades produced a half-old/half-new
site-packages. Removed the deletion entirely.
2) NSIS installer extracted over the previous install without cleaning
python/, app/, scripts/. Upgrades left stale files (old PIL/_version.py
next to new PIL/_imaging.pyd) which raised the Pillow ABI mismatch.
Wipe those subtrees before File /r, preserving config.yaml at the
install root.
If a tag or CI ref is not PEP 440 compliant (e.g. 'dev', 'nightly',
'snapshot-2024'), the previous detect_version stamped it raw into
pyproject.toml, which then broke 'pip install' with:
configuration error: project.version must be pep440
Add a regex check after stripping the leading 'v'. If the result
is not PEP 440, substitute '0.0.0.dev0' and warn.
Pattern from ClaudeCodeFacts/gitea-python-ci-cd.md §3.
- Rename GITEA_TOKEN to DEPLOY_TOKEN in release workflow
- Extract shared version detection into build-common.sh
- Use importlib.metadata for runtime version instead of hardcoded string
- Use PEP 440 parsing (packaging lib) for update version comparison
- Add packaging>=23.0 to dependencies
- Fix update banner close button alignment (CSS)
- Update CLAUDE.md with versioning docs and frontend rebuild notes