Compare commits

...
6 Commits
Author SHA1 Message Date
fernandoandClaude Sonnet 5 fb5bed22c2 chore: subir a clusterlog v0.2.0 (plantillas embebidas en el binario)
CI / validate-and-build (push) Successful in 9s
CI / runme (push) Successful in 11s
make templates ya no descarga un tarball aparte: extrae las plantillas
del binario ya descargado con "clusterlog templates extract" (ver
ADR-0006 del motor). fetch-engine.sh se simplifica a un solo modo
(binario); ya no hay asset de plantillas que descargar ni checksum
aparte que verificar para eso.

Probado de extremo a extremo contra el release v0.2.0 real: fetch del
binario, extracción de plantillas, sync, validate --require-zola y
zola build sobre el contenido real de MCPS, todo limpio.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 13:42:30 -06:00
fernandoandClaude Sonnet 5 38c04ca62f fix(ci): runme-ci.sh vuelve a fallar con nombres exactos; usar --dry-run
CI / validate-and-build (push) Successful in 7s
CI / runme (push) Successful in 9s
El intento anterior (correr cada celda por nombre, sin --all) también
aborta en el runner real ("Parsing files..." → "could not execute
command: aborted") — el problema no era --all. --dry-run sí funciona en
ese runner (nunca ejecuta nada él mismo), pero escribe el script
resuelto a stderr, no a stdout: el primer intento de "| bash" no
ejecutaba nada porque el pipe sólo captura stdout, y lo que se veía en
pantalla era stderr yendo directo a la terminal. Corregido con "2>&1
>/dev/null | bash". Probado localmente de extremo a extremo: las 4
celdas ejecutan de verdad (incluye verify-head devolviendo valid:true
real, no sólo el texto del comando).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 01:50:57 -06:00
fernandoandClaude Sonnet 5 064b5d5bb8 fix(ci): correr celdas ci-safe por nombre en vez de runme run --all
CI / validate-and-build (push) Successful in 7s
CI / runme (push) Failing after 7s
El log real del runner confirmó que el crash ("could not execute
command: aborted") ocurre justo al entrar a la UI interactiva
multi-tarea de "runme run --all" (mensajes "Initializing..."/"Parsing
files..."), no en una celda en particular — --log/--log-file ni
siquiera alcanzan a escribir nada. No se pudo reproducir en local pese
a varios intentos (stdin/stdout no interactivos, CI=true, TERM=dumb).

scripts/runme-ci.sh corre cada celda ci-safe por su nombre exacto, sin
--all: --dry-run ya había confirmado que esa forma no dispara la UI
multi-tarea. Makefile y RUNBOOK.md actualizados para reflejarlo.
Probado localmente de extremo a extremo, las 4 celdas en verde.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 01:45:23 -06:00
fernandoandClaude Sonnet 5 f178ecdcc7 fix(ci): forzar entorno no interactivo y agregar diagnóstico a runme-ci
CI / validate-and-build (push) Successful in 7s
CI / runme (push) Failing after 7s
El job runme fallaba en el runner real con "could not execute command:
aborted" justo al iniciar "runme run", algo que no se pudo reproducir
localmente (incluso forzando stdin/stdout no interactivos) — probable
diferencia de cómo act_runner en modo nativo/host expone el proceso
frente a una sesión interactiva. Se agrega CI=true y TERM=dumb al job
(convención estándar que muchas TUIs respetan) y --log/--log-file a
runme-ci para que, si vuelve a fallar, el paso de diagnóstico imprima
el log real en vez de repetir el ciclo de adivinar a ciegas.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 01:40:21 -06:00
fernandoandClaude Sonnet 5 63970a89e1 fix(ci): correr sync antes de validate en el job runme
CI / validate-and-build (push) Successful in 8s
CI / runme (push) Failing after 6s
source_sha256 en data/generated/site_state.json incluye la ruta
absoluta del checkout (sourceDigest hashea path+contenido), así que
difiere entre el checkout donde se commiteó y el checkout de un job de
CI en otra ruta, aunque el contenido sea idéntico. El job
validate-and-build ya corría sync antes de validate en el mismo
checkout; el job runme no, y por eso runme-check fallaba con
generated_state_stale. Reproducido localmente clonando a otra ruta
antes de aplicar el fix, y confirmado limpio después.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 01:30:51 -06:00
fernandoandClaude Sonnet 5 622578b454 fix(content): escapar {{...}} literal en dos memorias (rompía zola check)
CI / validate-and-build (push) Successful in 7s
CI / runme (push) Failing after 5s
Los comandos de ejemplo "podman inspect ... --format '{{range
.Config.Env}}{{println .}}{{end}}'" son sintaxis de Go templates, no de
Tera, pero Zola igual intenta interpretarlos como expresiones Tera al
renderizar la página — zola check fallaba con "Found `}}` but expected
identifier". Encontrado por la propia CI al validar --require-zola tras
la conversión a instancia (antes nunca se había corrido zola check
sobre este contenido en CI con la ruta real). Envueltos en {% raw %}.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-27 01:20:53 -06:00
9 changed files with 100 additions and 51 deletions
+1 -1
View File
@@ -1 +1 @@
v0.1.0
v0.2.0
+9
View File
@@ -66,12 +66,21 @@ jobs:
env:
DO_NOT_TRACK: "true"
SCARF_NO_ANALYTICS: "true"
CI: "true"
TERM: "dumb"
steps:
- uses: actions/checkout@v4
- name: Descargar binario del motor (versión fijada en .clusterlog-version)
run: make build
# source_sha256 de data/generated/site_state.json incluye la ruta
# absoluta del checkout, así que difiere entre máquinas aunque el
# contenido sea idéntico; hay que regenerarlo en este mismo checkout
# antes de validar, igual que ya hace el job validate-and-build.
- name: Regenerar la proyección en este checkout
run: ./bin/clusterlog --root . sync
- name: Instalar Runme fijado (v3.17.4, checksum verificado)
run: make runme-install
+6 -4
View File
@@ -11,13 +11,15 @@ all: build
# verificando su checksum. Se mantiene el nombre "build" para no romper
# RUNBOOK.md ni el hábito de make build/make sync-check de siempre.
build:
./scripts/fetch-engine.sh bin $(BINARY)
./scripts/fetch-engine.sh $(BINARY)
theme:
./scripts/bootstrap-theme.sh
templates:
./scripts/fetch-engine.sh templates templates
# Las plantillas viajan embebidas en el binario del motor desde v0.2.0 (ver
# ADR-0006 del motor): no hay red aparte para esto, sólo se extraen.
templates: build
./$(BINARY) --root . templates extract
sync: build
./$(BINARY) --root . sync
@@ -56,4 +58,4 @@ runme-check: build
./scripts/runme-check.sh
runme-ci: build
runme run --filename RUNBOOK.md --tag ci-safe --all --skip-prompts
./scripts/runme-ci.sh
+22 -7
View File
@@ -59,14 +59,29 @@ ninguna llave privada real.
## Ejecutar
Localmente, fuera de este runner, `runme run --filename RUNBOOK.md --tag
ci-safe --all --skip-prompts` funciona normalmente. En este repositorio,
`make runme-ci` en cambio corre `scripts/runme-ci.sh`, que para cada celda
`ci-safe` extrae su script con `runme run --dry-run <celda>` (nunca ejecuta
nada por sí solo) y lo corre con `bash`, deteniéndose en el primer fallo:
```text
runme run --filename RUNBOOK.md --tag ci-safe --all --skip-prompts
runme run --filename RUNBOOK.md --dry-run clusterlog-runme-preflight | bash
runme run --filename RUNBOOK.md --dry-run clusterlog-sync-check | bash
runme run --filename RUNBOOK.md --dry-run clusterlog-validate-local | bash
runme run --filename RUNBOOK.md --dry-run clusterlog-verify-head | bash
```
es lo que corre `make runme-ci`: exactamente las celdas marcadas `ci-safe`,
en orden, deteniéndose en el primer fallo (verificado con Runme real; ver el
ADR-0004 del motor). Nunca ejecute `runme run --all --skip-prompts` **sin**
`--tag ci-safe` sobre este archivo ni sobre `runbooks/weekly-review.md`: sin
ese filtro, `--all` también incluiría celdas que mutan estado real de esta
instancia. Ésas deben correrse una por una, a mano, después de revisar sus
Tanto `runme run --all` como invocar cada celda por nombre (sin `--all`)
abortan de inmediato en el runner real de esta instancia
("could not execute command: aborted", justo al entrar a "Parsing
files..."), algo que no se pudo reproducir en ninguna terminal local. Sólo
`--dry-run` evita esa ruta de código en ambos lados — ver `scripts/runme-ci.sh`
para el detalle completo, incluida la comprobación real
(`clusterlog-verify-head` corriendo y devolviendo `valid: true` de verdad).
Nunca ejecute `runme run --all --skip-prompts` sobre este archivo ni sobre
`runbooks/weekly-review.md`: sin filtrar por nombre o etiqueta, `--all`
también incluiría celdas que mutan estado real de esta instancia. Ésas
deben correrse una por una, a mano, después de revisar sus
prerrequisitos.
@@ -42,6 +42,7 @@ El usuario pidió configurar correo saliente en mail.mcps-epcm.org (10.8.0.1, mc
## Comandos relevantes (secretos redactados)
{% raw %}
```console
podman exec mailserver setup email list
podman exec mailserver setup email add notificaciones@mcps-epcm.org <password redactado>
@@ -55,6 +56,7 @@ tee /etc/grafana-smtp.env # GF_SMTP_PASSWORD=<redactado>, chmod 600
systemctl daemon-reload && systemctl restart container-grafana.service
podman inspect grafana --format '{{range .Config.Env}}{{println .}}{{end}}'
```
{% endraw %}
## Validación
@@ -41,6 +41,7 @@ El usuario pidió extender el correo saliente ya configurado para Zammad y Grafa
## Comandos relevantes (secretos redactados)
{% raw %}
```console
podman inspect gitea --format '{{range .Config.Env}}{{println .}}{{end}}'
cat /opt/gitea/data/gitea/conf/app.ini
@@ -53,6 +54,7 @@ cat /opt/gitea/data/gitea/conf/app.ini # confirmar seccion [mailer]
podman logs gitea | grep -iE 'mail|error|fatal|panic'
curl -s -o /dev/null -w '%{http_code}' http://10.89.0.60:3000/
```
{% endraw %}
## Validación
+6 -6
View File
@@ -1,7 +1,7 @@
{
"version": 2,
"generated_at": "2026-08-27T06:37:41Z",
"source_sha256": "594001fb9ffeca21d3c081be211f5249968d3f43e857530f45c8d69e25381aec",
"generated_at": "2026-08-27T07:20:28Z",
"source_sha256": "3b845d6aef09eadc3c336ab6c4bb170e461c213ddb59920be6f39ae46b37b0f9",
"stats": {
"active_admins": 1,
"pending_reviews": 7,
@@ -29,7 +29,7 @@
"mcps-vpn-server"
],
"permalink": "/memorias/mem-20260825-eed6f1-extender-el-correo-saliente-de-notificaciones-a-git-mcps-epcm-org-gitea/",
"content_sha256": "08a71d39d9b0fab0f2c1cd6cec76fc087157ec007748be6361e0a90e40095235",
"content_sha256": "69f1610c2d9004fd7a0948af970a12c98178d701231461e2d18c2219c9cb13aa",
"reviewed_by": [],
"missing_reviewers": [
"gen"
@@ -59,7 +59,7 @@
"zammad"
],
"permalink": "/memorias/mem-20260824-254312-configurar-correo-saliente-para-recuperacion-de-contrasena-en-zammad-y-grafana/",
"content_sha256": "7e2cbe7e790e033eda43472177927d0c280dee7967090578e1142faf4ae15e52",
"content_sha256": "afdbe017e912bc7c5926ad5a66b9e79e055099c1eb564f72d6d6258698d5fcc9",
"reviewed_by": [],
"missing_reviewers": [
"gen"
@@ -225,7 +225,7 @@
"slug": "mem-20260825-eed6f1-extender-el-correo-saliente-de-notificaciones-a-git-mcps-epcm-org-gitea",
"permalink": "/memorias/mem-20260825-eed6f1-extender-el-correo-saliente-de-notificaciones-a-git-mcps-epcm-org-gitea/",
"source_path": "content/memorias/2026-08-25-mem-20260825-eed6f1-extender-el-correo-saliente-de-notificaciones-a-git-mcps-epcm-org-gitea.md",
"content_sha256": "08a71d39d9b0fab0f2c1cd6cec76fc087157ec007748be6361e0a90e40095235"
"content_sha256": "69f1610c2d9004fd7a0948af970a12c98178d701231461e2d18c2219c9cb13aa"
},
{
"entry_id": "MEM-20260824-254312",
@@ -258,7 +258,7 @@
"slug": "mem-20260824-254312-configurar-correo-saliente-para-recuperacion-de-contrasena-en-zammad-y-grafana",
"permalink": "/memorias/mem-20260824-254312-configurar-correo-saliente-para-recuperacion-de-contrasena-en-zammad-y-grafana/",
"source_path": "content/memorias/2026-08-24-mem-20260824-254312-configurar-correo-saliente-para-recuperacion-de-contrasena-en-zammad-y-grafana.md",
"content_sha256": "7e2cbe7e790e033eda43472177927d0c280dee7967090578e1142faf4ae15e52"
"content_sha256": "afdbe017e912bc7c5926ad5a66b9e79e055099c1eb564f72d6d6258698d5fcc9"
},
{
"entry_id": "MEM-20260824-C5E50A",
+15 -33
View File
@@ -1,34 +1,26 @@
#!/usr/bin/env bash
# Descarga un artefacto del release fijado del motor (fenandosr/clusterlog)
# y verifica su checksum contra checksums.txt del mismo release. Nunca usa
# Descarga el binario del release fijado del motor (fenandosr/clusterlog) y
# verifica su checksum contra checksums.txt del mismo release. Nunca usa
# `latest`: la versión viene de .clusterlog-version.
#
# Las plantillas ya no se descargan aparte (desde v0.2.0 del motor viajan
# embebidas en el propio binario): use "clusterlog templates extract"
# después de este script, ver el target "templates" del Makefile.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
ENGINE_REPO="${CLUSTERLOG_ENGINE_REPO:-fenandosr/clusterlog}"
VERSION="$(cat "$ROOT/.clusterlog-version")"
KIND="${1:?uso: fetch-engine.sh <bin|templates> <destino>}"
DEST="${2:?uso: fetch-engine.sh <bin|templates> <destino>}"
DEST="${1:?uso: fetch-engine.sh <destino-del-binario>}"
BASE_URL="https://github.com/${ENGINE_REPO}/releases/download/${VERSION}"
TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT
case "$KIND" in
bin)
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
arch="$(uname -m)"
case "$arch" in x86_64) arch=amd64 ;; aarch64) arch=arm64 ;; esac
asset="clusterlog_${os}_${arch}.tar.gz"
;;
templates)
asset="clusterlog-templates_${VERSION}.tar.gz"
;;
*)
echo "Tipo de artefacto desconocido: $KIND (use bin o templates)" >&2
exit 1
;;
esac
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
arch="$(uname -m)"
case "$arch" in x86_64) arch=amd64 ;; aarch64) arch=arm64 ;; esac
asset="clusterlog_${os}_${arch}.tar.gz"
echo "Descargando $asset (clusterlog $VERSION, $ENGINE_REPO)..."
curl -fsSL -o "$TMP/checksums.txt" "$BASE_URL/checksums.txt"
@@ -48,17 +40,7 @@ if [ "$computed" != "$expected" ]; then
fi
echo "Checksum verificado."
case "$KIND" in
bin)
mkdir -p "$(dirname "$DEST")"
tar xzf "$TMP/$asset" -C "$TMP" clusterlog
install -m 0755 "$TMP/clusterlog" "$DEST"
echo "Binario en $DEST ($("$DEST" version 2>/dev/null || true))"
;;
templates)
rm -rf "$DEST"
mkdir -p "$DEST"
tar xzf "$TMP/$asset" -C "$DEST"
echo "Plantillas en $DEST"
;;
esac
mkdir -p "$(dirname "$DEST")"
tar xzf "$TMP/$asset" -C "$TMP" clusterlog
install -m 0755 "$TMP/clusterlog" "$DEST"
echo "Binario en $DEST ($("$DEST" version 2>/dev/null || true))"
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# Corre cada celda ci-safe de RUNBOOK.md, una por una, extrayendo su script
# real con "runme run --dry-run <celda>" y ejecutándolo con bash — sin usar
# el motor de ejecución de Runme.
#
# Se intentó "runme run --tag ci-safe --all --skip-prompts" y también
# invocar cada celda por nombre sin --all: ambas formas abortan de
# inmediato en el runner real de esta instancia ("could not execute
# command: aborted", justo al entrar a "Parsing files..."), algo que no se
# pudo reproducir en ninguna terminal local (interactiva, con stdin/stdout
# redirigidos, con CI=true/TERM=dumb). "--dry-run" sí funciona en ambos
# lados: no dispara esa ruta de código porque nunca ejecuta nada él mismo,
# sólo imprime el script resuelto de la celda.
#
# Esto sacrifica que sea Runme quien de verdad ejecute el comando en CI,
# pero preserva lo esencial: el Markdown con atributos de celda sigue
# siendo la única fuente de verdad de qué corre, y localmente (fuera de
# este runner) "runme run <celda>" sigue funcionando de forma normal.
#
# La lista debe coincidir con las celdas "ci-safe" de RUNBOOK.md.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
CI_SAFE_CELLS=(
clusterlog-runme-preflight
clusterlog-sync-check
clusterlog-validate-local
clusterlog-verify-head
)
for cell in "${CI_SAFE_CELLS[@]}"; do
echo "== $cell =="
# --dry-run escribe el script resuelto a stderr, no a stdout.
runme run --filename RUNBOOK.md --dry-run "$cell" 2>&1 >/dev/null | bash
done