Saltar al contenido principal

Wiedii — Políticas de Versionado

  • Formato: MAJOR.MINOR.PATCHsin prefijo v (única excepción: paquetes Go distribuidos por go 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 como chore(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. En wietoo.tomltag_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 el package main ahí para que go install produzca 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:

StackManifiesto de deps¿Guarda la versión de la app?
JS/TSpackage.json ("version")
PHPcomposer.json ("version")
Pythonpyproject.toml ([project].version)
Gogo.modNO

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 prefijo v, la excepción de arriba). Única fuente de verdad: go install <módulo>@version y 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 a runtime/debug.ReadBuildInfo() (que expone la versión del módulo cuando se instaló vía go 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 VERSION solo 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, rol Developer (o superior), con expiración.

  • Guardar cifrado con SOPS+age (ver gestion-secretos-sops-age) en secrets.sops.yaml, nunca en claro. Un .sops.yaml en la raíz define el recipient age del equipo; mise run secrets abre el round-trip de edición.

  • Cortar el release en local con mise+sopsmise 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 (o release:patch / release:major). wietoo (repo: wietoo-cli) lee el token de GITLAB_TOKEN.

  • En CI, en su lugar, el CI_JOB_TOKEN automático puede crear la release y escribir el Package Registry del mismo proyecto — sin secreto almacenado (wietoo lo soporta como JOB-TOKEN).

⚠️ No usar el token que guarda glab (glab config get token): es un blob OAuth con bytes no imprimibles, inservible como header PRIVATE-TOKEN. wietoo lo rechaza con un error claro; usar un Project Access Token limpio (glpat-…).