Documentación/Proceso de Release
Proceso de Release
DBFlux usa desarrollo trunk-based con release branches de corta duración. Un
branch de larga duración (main) es el objetivo de integración; un branch
release/vX.Y se crea por cada minor durante la estabilización y se descarta
después de su EOL.
Este documento es la referencia orientada a humanos. El skill automatizado
dbflux-release (skills/dbflux-release/SKILL.md) sigue estas mismas reglas.
Canales
| Canal | Branch de origen | Patrón de tag | Tipo de GitHub release | Construido por |
|---|---|---|---|---|
| nightly | main HEAD | nightly (rolling) | prerelease | Cron — diario |
| rc | release/vX.Y | vX.Y.Z-rc.N | prerelease | Push del tag |
| stable | release/vX.Y | vX.Y.Z | published | Push del tag |
El canal -dev.N está retirado. Nightly lo reemplaza. Los tags -dev.N
antiguos permanecen en GitHub pero no se crean nuevos.
Los íconos de aplicación por canal se rastrean en el issue #183. No los implementes aquí.
Modelo de Changelog (git-cliff, Modelo B)
El changelog se deriva del historial de git mediante
git-cliff. No edites [Unreleased] a mano.
cliff.tomlen la raíz del repositorio configura el generador.[Unreleased]significa “cada commit convencional visible para el usuario desde el último tag stable.” Los tags rc y nightly son transparentes: no cierran la ventana[Unreleased](skip_tagsencliff.toml).- Los mensajes de commit son fundamentales para el proceso. Un commit
feat,fixoperfaparece en el changelog; un commitchore,ci,docs,test,refactorostylese descarta. Los cambios relevantes de seguridad usanfix(security):o un footerSecurity:. - El bloque
[Unreleased]se cierra solo en stable. Cuando se hace push de un tag stable, git-cliff renderiza el conjunto completo de commits visibles para el usuario desde el stable anterior como las release notes de ese tag. - No renombres
[Unreleased]a mano al cortar un RC o un nightly. El procedimiento de corte de RC es más simple bajo este modelo — ver abajo.
CHANGELOG.md se mantiene en el repositorio y se actualiza en el momento del
release anteponiendo (prepending) la sección de la nueva versión con
git-cliff --prepend. Nunca se edita a mano ni se regenera por completo — una
regeneración completa (git-cliff -o CHANGELOG.md) colapsaría todas las
secciones históricas en un único rango desde el último tag stable, destruyendo
las entradas ## [0.6.0] y ## [0.6.0-dev.N].
Transición a v0.7.0: la generación de changelog con git-cliff aplica desde v0.7.0 en adelante. Las secciones
## [0.6.0]y## [0.6.0-dev.N]son baselines escritas a mano, comiteadas enCHANGELOG.md. Nunca deben regenerarse — hacerlo las duplicaría o colapsaría. El flujo de prepend comienza con el primer RC de v0.7.0.
Branches
| Branch | Duración | Acepta | Tags producidos |
|---|---|---|---|
main | permanente | cada commit nuevo (features, fixes, refactors) | (ninguno — nightly rolling) |
release/vX.Y | hasta EOL | solo fixes cherry-picked (sin features nuevas) | vX.Y.Z-rc.N, vX.Y.Z, vX.Y.(Z+1) |
Reglas inviolables
- Un commit nunca se autoriza directamente en un release branch. Siempre
aterriza primero en
main, y luego se hacegit cherry-pick -x <sha>hacia el release branch. - Un release branch nunca se hace merge de vuelta a
main. - Sin features nuevas en un release branch una vez creado. Solo bugfixes y los propios bumps de version-artifact del release.
mainsiempre está abierto para desarrollo. No se requiere una entrada manual de CHANGELOG enmain— los mensajes de commit llevan la información.
Tags
Los tags deben ser anotados:
git tag -a vX.Y.Z[-suffix.N] -m "vX.Y.Z[-suffix.N]"
git push origin vX.Y.Z[-suffix.N]
El workflow de release (.github/workflows/release.yml) clasifica los tags
automáticamente:
| Patrón de tag | Branch de origen permitido | Tipo de GitHub release |
|---|---|---|
vX.Y.Z-rc.N | release/vX.Y | prerelease |
vX.Y.Z | release/vX.Y | stable (published) |
| cualquier otro | (red de seguridad) | draft |
Reglas de Versionado
La versión del workspace (Cargo.toml [workspace.package].version) es la
fuente de verdad. Todos los demás manifiestos deben mantenerse sincronizados.
En main:
La versión del manifiesto es X.(Y+1).0-dev.0, donde X.Y es el minor que se
está estabilizando actualmente en release/vX.Y. Este marcador se fija cuando
se crea release/vX.Y y permanece en main durante toda la ventana de
estabilización y más allá, hasta el siguiente corte. Es solo un marcador de
desarrollo — nunca se publican releases -dev.N. El workflow de nightly deriva
X.(Y+1).0-nightly+<sha> a partir de él, quitando el sufijo de pre-release y
agregando -nightly+<short-sha>.
En release/vX.Y:
- Próximo RC: si el último tag es
vX.Y.Z-rc.N→-rc.(N+1). Si no hay ninguno →-rc.0. - Promover a stable: quitar el sufijo RC →
vX.Y.0. - Patch: incrementar
Z→vX.Y.(Z+1). Nunca subir el minor en un release branch.
Ejemplo de Ciclo: 0.7.0
- Las features aterrizan en
main. No se requieren entradas manuales de changelog. - Cuando está listo para estabilizar, se crea
release/v0.7desdemainHEAD.- En
release/v0.7: subir cada artefacto versionado a0.7.0-rc.0. Commit y push. - En
main: subir cada artefacto versionado a0.8.0-dev.0. Commit y push.mainahora apunta al siguiente minor. - Tag
v0.7.0-rc.0en el release branch. git-cliff renderiza el rango unreleased como el cuerpo del RC automáticamente.
- En
- Se encuentra un bug durante el RC:
- Commitear el fix en
main. git cherry-pick -x <sha>haciarelease/v0.7.- Subir a
v0.7.0-rc.1y taggear.
- Commitear el fix en
- Cuando está limpio, subir el release branch de
v0.7.0-rc.Nav0.7.0. Tagv0.7.0. git-cliff renderiza el rango unreleased completo (desdev0.6.0) como las release notes de stable. mainya está en0.8.0-dev.0— no se necesita más bump después de stable.- Los patches (
v0.7.1,v0.7.2, …) vienen del mismo release branch vía cherry-picks desdemain.
Procedimiento de Corte: main → release/vX.Y
-
Verifica que estás en
main, árbol limpio, actualizado conorigin/main. -
Verifica que
.github/workflows/release.ymlenmaincontiene el jobClassify release. Si falta, arréglalo enmainprimero — de lo contrario los tags stable se publicarán como drafts. -
Crea el branch (usa un worktree dedicado si usas el layout de bare-repo para que
mainsiga checked out):git worktree add ../release-vX.Y -b release/vX.Y main # o en un repo de checkout único: git checkout -b release/vX.Y -
En
release/vX.Y:-
Sube cada artefacto versionado a
X.Y.0-rc.0(ver Archivos a Actualizar). -
Antepón la nueva sección de RC a
CHANGELOG.md:git-cliff --tag vX.Y.0-rc.0 --unreleased --prepend CHANGELOG.md git add CHANGELOG.md # incorpóralo al mismo commit chore(release) que el bump de versiónAdvertencia: NO uses
git-cliff -o CHANGELOG.md. Eso regenera el archivo por completo y colapsa todas las secciones históricas desde el último tag stable en un único bloque. -
Commit:
chore(release): cut release/vX.Y at vX.Y.0-rc.0. -
Push:
git push -u origin release/vX.Y.
-
-
De vuelta en
main:- Sube cada artefacto versionado a
X.(Y+1).0-dev.0(main ahora apunta al siguiente minor). - Commit:
chore(version): move main to X.(Y+1).0-dev.0 marker. - Push.
- Sube cada artefacto versionado a
-
Tag
vX.Y.0-rc.0en el release branch.
No hay paso de renombre de CHANGELOG bajo el modelo de git-cliff. El cuerpo del release RC se genera automáticamente a partir de commits convencionales.
Promoción a Stable: release/vX.Y → vX.Y.0
Ejecuta esto en release/vX.Y cuando el RC está limpio:
-
Sube cada artefacto versionado de
X.Y.0-rc.NaX.Y.0. -
Antepón la sección stable a
CHANGELOG.md:git-cliff --tag vX.Y.0 --unreleased --prepend CHANGELOG.md git add CHANGELOG.md # incorpóralo al mismo commit chore(release) que el bump de versiónAdvertencia: NO uses
git-cliff -o CHANGELOG.md. Eso regenera el archivo por completo y colapsa todas las secciones históricas desde el último tag stable en un único bloque. -
Commit:
chore(release): promote release/vX.Y to vX.Y.0. -
Tag
vX.Y.0en el release branch y push del branch + tag.
git-cliff genera las release notes curadas a partir de todos los commits visibles para el usuario desde el tag stable anterior. No hay paso manual de curación de CHANGELOG.
Curación opcional: si quieres agregar una introducción escrita a mano o una nota editorial al cuerpo del release stable, puedes hacerlo directamente en la UI de edición de GitHub Release después de que el workflow lo publique. Esto no toca CHANGELOG.md.
Próximo Ciclo de Desarrollo
main se sube a X.(Y+1).0-dev.0 cuando se crea release/vX.Y (ver
Procedimiento de Corte, paso 5). No se requiere más bump a main después del
tag stable. Los builds de nightly continúan desde main HEAD automáticamente,
produciendo X.(Y+1).0-nightly+<sha> durante toda la ventana de estabilización.
Archivos a Actualizar
Por cada release, actualiza todos los siguientes a exactamente la misma versión:
Cargo.toml—[workspace.package].version. Los crates del workspace heredan víaversion.workspace = true.flake.nixresources/windows/installer.iss- Revisión manual (no hereda):
examples/custom_driver/Cargo.toml.
Después de que se publican los artefactos del GitHub Release para el tag, actualiza también:
nix/release-info.nix—version+ ambosurls yhashes del tarball prebuilt (ver Nix abajo). Este es un puntero de canal por branch. Requiere los artefactos publicados, así que aterriza como un commit de seguimiento una vez que el workflow de release termina.
El PKGBUILD de AUR vive en un repositorio AUR externo, no en este repo.
Solo se sube para tags stable.
Cómo Funciona Nightly
.github/workflows/nightly.yml corre diariamente a las 03:17 UTC:
- Lee la versión del workspace desde
Cargo.toml, quita cualquier sufijo de pre-release existente, y agrega-nightly+<short-sha>(p. ej.0.8.0-nightly+abc1234cuandomainlleva0.8.0-dev.0). No se requiere commit deCargo.toml. Comomainrastrea el siguiente minor desde el momento en que se crearelease/vX.Y, la versión nightly siempre está claramente por delante de la línea en estabilización. - Llama a
build.ymlconchannel: nightly. - Calcula el hash SRI SHA256 de cada tarball de Linux y regenera
nix/nightly-info.nixcon los hashes reales y las URLs de release rolling. - Commitea el
nix/nightly-info.nixactualizado encima delmainHEAD actual. Este commit no se hace push amain— se convierte en el único destino del tagnightly. - Fuerza el movimiento del tag
nightlyal commit de pin y hace push del tag. Hacer push del tag es suficiente para que el commit sea alcanzable en el remoto; no se requiere push de branch. - Publica o actualiza el GitHub prerelease rolling
nightlycon los nuevos artefactos y un cuerpo generado por git-cliff cubriendo los commits desde el último tag stable. El tag del release apunta al commit de pin, así quenix/nightly-info.nixen la refnightlysiempre coincide con los artefactos publicados.
El tag nightly se fuerza (force-push) y el release se reemplaza en cada corrida.
Solo el repositorio canónico (0xErwin1/dbflux) ejecuta el schedule.
Se salta cuando main no ha avanzado. Una corrida programada primero
compara el main HEAD actual contra el commit desde el que se construyó el
último nightly (git rev-parse nightly^, el primer padre del commit de pin). Si
coinciden, la corrida se salta por completo: sin rebuild, sin mover el tag, sin
churn de release. Esto evita republicar un build idéntico bajo un hash fresco no
reproducible que rompería innecesariamente los pins de Nix. Una corrida manual
workflow_dispatch siempre construye, incluso sin commits nuevos.
Paquete Nix de Nightly
El workflow fija nix/nightly-info.nix en la ref nightly en cada corrida. Los
usuarios downstream obtienen el binario nightly prebuilt sin compilar desde el
código fuente:
# Ejecutar nightly directamente
nix run github:0xErwin1/dbflux/nightly#dbflux-nightly
# Instalar en un perfil
nix profile install github:0xErwin1/dbflux/nightly#dbflux-nightly
Un nightly desde el código fuente (sin fijación de hash requerida) también funciona:
nix run github:0xErwin1/dbflux/nightly#dbflux-source
No consumas #dbflux-nightly desde main. En main,
nix/nightly-info.nix contiene hashes de placeholder que no van a fetch. Usa
siempre la ref nightly como se muestra arriba.
Disciplina de Cherry-Pick
Un release branch nunca debería contener commits ausentes en main, excepto
commits exclusivos del release (chore(release): ..., chore(version): ...).
# En main: aterriza el fix.
git checkout main
# ...commit, push...
# En el release branch: cherry-pick con -x para registrar el SHA de origen.
git checkout release/vX.Y
git cherry-pick -x <sha>
Auditoría: cada commit que no sea de release en release/vX.Y desde el
branch-off debería mencionar (cherry picked from commit ...) en su mensaje.
git log --grep='cherry picked from' release/vX.Y
Canales Downstream
| Tipo de tag | GitHub Release | AUR | Nix flake (este repo) | nixpkgs (futuro) |
|---|---|---|---|---|
| nightly | prerelease | se omite | auto-fijado — #dbflux-nightly en la ref nightly | se omite |
-rc.N | prerelease | se omite | actualiza el release-info de la release branch y de main | se omite |
Stable vX.Y.Z | published | bump + push | actualiza el release-info de la release branch y de main | bump + PR |
AUR
pkgver de AUR no permite - (reservado para pkgrel). Para releases stable
la traducción es un no-op (pkgver=X.Y.Z). Para hipotéticos prereleases de AUR:
vX.Y.Z-rc.N→pkgver=X.Y.Z.rc.N
Nix (el flake de este repo)
El flake expone varios paquetes en Linux (x86_64 y aarch64):
| Paquete | Qué provee |
|---|---|
dbflux (default) | Binario stable/rc prebuilt cuando está disponible, source en caso contrario |
dbflux-bin | Prebuilt explícito desde nix/release-info.nix |
dbflux-source | Build desde source vía crane (todas las plataformas) |
dbflux-nightly | Nightly rolling prebuilt desde nix/nightly-info.nix (usa la ref nightly) |
Stable / RC (nix/release-info.nix): puntero de canal por branch. main
rastrea el tag publicado más reciente de cualquier tipo; cada release/vX.Y
rastrea el más reciente de su propia línea. Después de que se publican los
artefactos de un tag, refresca release-info.nix en cada branch cuyo canal ese
tag hace avanzar.
ver=X.Y.Z
for arch in amd64 arm64; do
hex=$(curl -fsSL "https://github.com/0xErwin1/dbflux/releases/download/v$ver/dbflux-linux-$arch.tar.gz.sha256" | awk '{print $1}')
nix-hash --to-sri --type sha256 "$hex"
done
Actualiza version, ambos urls, y ambos hashes en nix/release-info.nix.
Verifica localmente:
nix build .#dbflux-bin --no-link --print-out-paths
Nightly (nix/nightly-info.nix): auto-actualizado por el workflow de
nightly en la ref nightly. No actualices este archivo manualmente. Consúmelo
vía:
nix run github:0xErwin1/dbflux/nightly#dbflux-nightly
nixpkgs (futuro)
Aún no está en upstream. Cuando lo esté, solo los tags stable recibirán un PR a
NixOS/nixpkgs. Convención de título de PR: dbflux: A -> B.
Anti-Patrones (evita esto)
- Taggear
vX.Y.ZovX.Y.Z-rc.Nmientras HEAD está enmain. - Taggear un RC mientras HEAD está en
main. - Hacer merge de
release/vX.Yde vuelta amain. - Crear features nuevas (commits que no sean fix) en un branch
release/*. - Subir el minor o major dentro de un branch
release/*. - Hacer push de un tag sin un árbol de trabajo limpio.
- Hacer push del bump de AUR con
pkgverconteniendo un guion. - Cortar
release/vX.Ydesde unmainHEAD que no contiene el jobClassify releaseenrelease.yml. - Crear tags
-dev.Nnuevos (el canal está retirado; usa nightly en su lugar).
Validación Local Antes de Etiquetar
cargo check --workspace
cargo fmt --all -- --check
cargo clippy --workspace -- -D warnings
cargo test --workspace
Relacionado
.github/workflows/release.yml— lógica de clasificación y publicación de artefactos.github/workflows/nightly.yml— build nightly diario.github/workflows/build.yml— jobs de build reutilizables (llamados por release y nightly).github/release-template.md— sección de instalación agregada a cada cuerpo de releasecliff.toml— configuración de git-cliff para la generación de changelogskills/dbflux-release/SKILL.md— skill orientado a agentes que automatiza este proceso