Wiedii — Políticas de Versionado
- Formato:
MAJOR.MINOR.PATCH— sin prefijov(única excepción: paquetes Go distribuidos porgo install— ver abajo) - Correcto:
1.2.0,1.2.1,2.0.0 - Incorrecto:
v1.2.0,v1.2.1 - Patrón de tag en GitLab CI:
if: $CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+$/ - Subir versión en
package.json→ commitear comochore(release): bump version to 1.2.0
Excepción — paquetes Go (go install / backend go: de mise)
Un paquete Go que se distribuye vía go install <módulo>@version (o el backend go: de mise) debe usar un tag semver con prefijo v (v1.2.0). El sistema de módulos de Go ignora los tags sin v: go list -m -versions no devuelve nada y @version/@latest no resuelven a una versión (caen a una pseudo-versión del último commit). Es un requisito duro de la toolchain de Go, no negociable.
Para estos repos:
- Tag con prefijo
v. Enwietoo.toml→tag_prefix = "v"; en git-flow-next →git config gitflow.branch.release.tagprefix "v". El patrón de tag pasa a ser^v[0-9]+\.[0-9]+\.[0-9]+$. - Entrypoint bajo
cmd/<binario>/. Coloca elpackage mainahí para quego installproduzca un binario llamado<binario>y no el nombre del repo. - Prerequisito del cliente (módulos en el GitLab interno, visibilidad
internal):GOPRIVATE="gitlab.wiedii.co/*"+git config --global url."git@gitlab.wiedii.co:".insteadOf "https://gitlab.wiedii.co/".
Esta es la única excepción autorizada al prefijo v. Referencia viva: wietoo-cli (repo, release v0.1.0) y su repo de ejemplo de consumo vía mise, wietoo-example.
¿Dónde vive el número de versión? — Go vs. otros stacks
En la mayoría de stacks, el manifiesto de dependencias también guarda la versión de la app, y ahí es donde se bumpea. En Go no:
| Stack | Manifiesto de deps | ¿Guarda la versión de la app? |
|---|---|---|
| JS/TS | package.json | Sí ("version") |
| PHP | composer.json | Sí ("version") |
| Python | pyproject.toml | Sí ([project].version) |
| Go | go.mod | NO |
go.mod solo lleva module, la directiva go y las dependencias (ver [[modulos-go#Qué NO va en go.mod]]). Meter la versión propia ahí es antiidiomático: la toolchain la ignora.
La fuente de verdad en Go es el git tag
- Tag semver
vX.Y.Z(con prefijov, la excepción de arriba). Única fuente de verdad:go install <módulo>@versiony el proxy de módulos resuelven desde el tag. - Versión en runtime: se inyecta al compilar con
-ldflags "-X main.version=$(git describe --tags)", con fallback aruntime/debug.ReadBuildInfo()(que expone la versión del módulo cuando se instaló víago install pkg@vX.Y.Z).
// main.go — el binario resuelve su versión así:
var version = "dev" // sobrescrita por -ldflags "-X main.version=..."
func resolveVersion() string {
if version != "dev" {
return version
}
if info, ok := debug.ReadBuildInfo(); ok {
if v := info.Main.Version; v != "" && v != "(devel)" {
return v
}
}
return version
}
Archivo VERSION — opcional
Un archivo VERSION (texto plano con X.Y.Z) es un espejo opcional del tag:
- Librerías (consumidas por otros): no usar archivo, solo tag — cero riesgo de desincronización.
- Apps / CLIs / servicios: el tag sigue siendo la verdad; añadir
VERSIONsolo si alguna herramienta o humano necesita leer la versión de un archivo. Si se mantiene, el flujo de release debe bumpear el archivo junto con el tag, o derivan.
Referencia viva: el repo wietoo-cli inyecta la versión por ldflags + ReadBuildInfo (idiomático) y mantiene un VERSION solo porque su propio wietoo version/release leen un manifiesto-archivo. Mejora pendiente: derivar la versión Go desde git describe --tags y eliminar el archivo (tag-only).
Ejemplo de job de release en GitLab CI
release:
stage: deploy
rules:
- if: $CI_COMMIT_TAG =~ /^[0-9]+\.[0-9]+\.[0-9]+$/
script:
- echo "Releasing version $CI_COMMIT_TAG"
- bun run build
- # ... pasos de release
Ver git-flow para el flujo completo de release con tags.
Token para crear releases — Project Access Token + SOPS
Crear un release en GitLab (página de release + subir binarios al Package Registry) requiere un token con scope api. Estándar Wiedii: un Project Access Token por proyecto (no un token personal, no el token de glab):
-
Crear: en el proyecto → Settings → Access Tokens → scope
api, rolDeveloper(o superior), con expiración. -
Guardar cifrado con SOPS+age (ver gestion-secretos-sops-age) en
secrets.sops.yaml, nunca en claro. Un.sops.yamlen la raíz define el recipient age del equipo;mise run secretsabre el round-trip de edición. -
Cortar el release en local con mise+sops — mise descifra el token al vuelo y lo expone solo al comando de release (
sops exec-env), no al resto del entorno. Es el mismo patrón que usa renovate-runner:# mise.toml[env]SOPS_AGE_KEY_FILE = "{{env.HOME}}/.config/sops/age/keys.txt"[tasks."release:minor"]run = "sops exec-env secrets.sops.yaml 'wietoo release --minor'"Cortar con
mise run release:minor(orelease:patch/release:major). wietoo (repo: wietoo-cli) lee el token deGITLAB_TOKEN. -
En CI, en su lugar, el
CI_JOB_TOKENautomático puede crear la release y escribir el Package Registry del mismo proyecto — sin secreto almacenado (wietoo lo soporta comoJOB-TOKEN).
⚠️ No usar el token que guarda glab (
glab config get token): es un blob OAuth con bytes no imprimibles, inservible como headerPRIVATE-TOKEN. wietoo lo rechaza con un error claro; usar un Project Access Token limpio (glpat-…).