molt
CLI de releases para monorepos de Python — entran changesets, salen bumps de versión coordinados, changelogs y publicaciones en PyPI.
- python
- cli
- monorepo
- release
- pep-440
- uv
molt trae el flujo de changesets a Python. Registras la intención de un cambio mientras lo escribes; un paso aparte convierte toda esa intención acumulada en releases — bumps de versión, changelogs, propagación de dependencias y publicación en PyPI.
JavaScript tiene changesets desde hace años. Python tiene el mismo problema y ningún equivalente: un workspace de paquetes que dependen entre sí, donde subir uno significa buscar cada dependiente, decidir cuánto tiene que moverse cada uno y reescribir sus pins a mano. Ese es el hueco que llena molt.
El ciclo de release
molt init # una vez: crea .changeset/ y un bloque [tool.molt]
# ... haces un cambio ...
molt add # registra qué paquetes cambiaron, y cuánto
molt version # sube versiones, escribe changelogs, actualiza el lockfile
molt publish # construye, sube a PyPI, taggeamolt add escribe un archivo Markdown chico que commiteas junto a tu código:
---
'acme-core': minor
---
Agrega un flag --stream a la API de export para datasets grandes.molt version consume todos los changesets pendientes en una sola pasada, toma el bump más alto por paquete, integra los resúmenes en cada CHANGELOG.md y borra los archivos que consumió.
Por qué funciona así
- La propagación se calcula, no se adivina. Si
acme-clirequiereacme-core>=1.2.0,<2.0.0, un bump mayor deacme-coreobliga a un release patch deacme-cliy a reescribir el pin. Un bump menor a1.3.0no libera nada extra, porque1.3.0sigue cumpliendo el rango. La matemática es PEP 440 y PEP 508 víapackaging, la implementación de referencia de PyPA — no un parser propio. - Las escrituras se acumulan y se aplican juntas. Una falla a mitad de camino nunca deja el repositorio a medio versionar.
- Prerelease es un flag, no un modo.
molt version --pre rc. No hay archivo de estado que abrir, commitear ni cerrar. uv.lockse actualiza en cada bump, así una instalación--frozenen CI sigue resolviendo contra el commit del release. Los workspaces de uv son ciudadanos de primera; los demás backends viven detrás de una capa de ecosistema.- Un release malo se yankea, no se despublica. Las versiones en PyPI son permanentes, así que
molt yankverifica la versión e imprime los pasos exactos (PEP 592). - stdout lleva solo datos legibles por máquina.
molt status --output json | jq '.releases[].name'no necesita filtros, y--dry-runimprime el plan de cualquier comando que muta.
Una GitHub Action complementaria, molt-action, corre el ciclo completo: mantiene un pull request de “Version Packages” sincronizado con los changesets pendientes y, cuando ese pull request se mergea, construye, publica y taggea.
Las guías y la referencia completa del CLI están en molt.gio-labs.com.