Communitygithub.com

bigzaqui/videolabs

Publica todo el sitio videolabs (https://videolabs.pages.dev): sincroniza cada laboratorio de la carpeta labs/ del repositorio con el sitio (el video a Cloudflare R2 solo si cambió, los activos del reproductor, los recursos del laboratorio, el catálogo), confirma y envía el repositorio videolabs para que GitHub Actions despliegue en Cloudflare Pages, y luego verifica cada laboratorio. Úsalo cuando el usuario quiera publicar, desplegar, agregar, actualizar o volver a subir laboratorios de video a videolabs.pages.dev. Una sola ejecución publica todos los laboratorios, no solo uno.

¿Qué es videolabs?

Esta habilidad automatiza el flujo completo de publicación del sitio videolabs, donde cada laboratorio de la carpeta `labs/` del repositorio se vuelve a desplegar en su totalidad. Primero ejecuta un modo de planeación (dry-run) para identificar archivos faltantes, videos sin fast-start o configuraciones ausentes. Luego sincroniza cada laboratorio: comprime el video renderizado a un códec web optimizado (~65% de reducción de tamaño), lo sube al bucket privado de Cloudflare R2 si cambió, actualiza el catálogo `site/labs.json` con los metadatos de `lab.config.json`, copia los archivos del reproductor (capítulos, póster, recursos del laboratorio) y registra el hash del video. Todo esto ocurre antes de cualquier commit, asegurando que la página nunca se publique sin su video. Después revisa credenciales con `check-secrets.sh`, muestra al usuario un resumen de cambios y realiza un commit y push al repositorio público de GitHub (incluyendo un `Closes #N` si responde a una solicitud de video). Finalmente espera a que GitHub Actions despliegue en Cloudflare Pages y verifica que cada página del laboratorio cargue correctamente, incluyendo que el endpoint de video protegido por Turnstile devuelva 401 sin sesión. Soporta publicación de laboratorios individuales de forma manual y actualiza automáticamente las páginas existentes que usan la plantilla compartida de `index.html`.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bigzaqui/videolabs/tree/HEAD/skills/videolabs_publish

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Publicar el sitio videolabs

"Publicar" significa que todo el sitio se despliega con todos los laboratorios, cada vez.

Repositorio del sitio: /opt/opus/videolabs (github.com/bigzaqui/videolabs, se despliega en https://videolabs.pages.dev al hacer push a main; GitHub Actions publica la carpeta site/). Laboratorios: /opt/opus/videolabs/labs/<slug>/ (una carpeta por laboratorio, en el mismo repositorio; el slug es el nombre del MP4 out/<slug>.mp4). Se construyen con la habilidad videolabs_create-video (node engine/cli.mjs <slug> ...). Los videos viven en el bucket privado de R2 videolabs en <slug>/<slug>.mp4 y se sirven a través de /media/<slug>/<slug>.mp4, que está detrás de una sesión de Turnstile (una solicitud sin sesión devuelve 401). Credenciales: /opt/opus/videolabs/.env (cargadas por los scripts; plantilla .env.example). Nunca imprimas, copies ni confirmes secretos. El repositorio de GitHub es público (al usuario le parece bien para el audio de narración, scripts, capturas y salida del laboratorio, y no le importa que aparezcan contraseñas desechables de laboratorios destruidos), por lo que ninguna credencial real puede aparecer en ningún archivo. El origen de esta habilidad es skills/videolabs_publish/ en el repositorio, enlazado a ~/.claude/skills mediante scripts/setup.sh.

Qué necesita un laboratorio (verificado por el script)

  • out/<slug>.mp4 (fast-start: moov antes de mdat; corregir con ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4), out/player/chapters.json (node engine/cli.mjs <slug> player), out/spot.jpg (póster; capturar un fotograma del diagrama con ffmpeg -ss 425 -i out/<slug>.mp4 -frames:v 1 -q:v 3 out/spot.jpg).
  • Opcional: out/player/lab.json (de node engine/cli.mjs <slug> player cuando el laboratorio tiene lab/lab-meta.json, lab/*.sh, lab/captures/). Si está presente, site/lab.js muestra los recursos del laboratorio en la página del laboratorio. Vuelve a ejecutar node engine/cli.mjs <slug> player primero si las capturas o lab-meta.json cambiaron.
  • labs/<slug>/lab.config.json con title, description y tags. El script agrega o actualiza la entrada en site/labs.json a partir de ahí (y completa minutes y lessons), por lo que nunca edites el catálogo manualmente. Para un laboratorio nuevo, toma title/description/tags del script del laboratorio si está claro; de lo contrario, pregunta al usuario. Nunca los inventes en silencio.

Pasos

  1. Planificar. cd /opt/opus/videolabs && scripts/publish-all.sh --dry-run. Imprime una línea PLAN por laboratorio (lo que se subirá u omitirá, si tiene lab.json), líneas ATTENTION para laboratorios que no puede publicar (archivo faltante, sin fast-start, sin lab.config.json) y líneas NOTE para entradas del catálogo sin proyecto. El código de salida 2 significa que hay al menos una ATTENTION. Corrige cada una (escribe lab.config.json, ejecuta node engine/cli.mjs <slug> player, crea el póster, ...) y repite hasta que no haya ninguna, o dile al usuario qué laboratorio se omite y por qué. Muéstrale al usuario el plan en pocas líneas, incluyendo qué videos se subirán y su tamaño.
    • Un laboratorio sin carga registrada (falta state/<slug>.sha256) se sube. Si el usuario dice que R2 ya tiene exactamente ese archivo, usa --adopt <slug> para registrar su hash en lugar de subirlo. --force-upload vuelve a subir todo; úsalo solo cuando el usuario pida reemplazar un video (una re-subida puede permanecer en caché hasta 24h para los espectadores).
  2. Sincronizar. scripts/publish-all.sh (mismas banderas). Por cada laboratorio listo, primero comprime el renderizado a out/<slug>.web.mp4 (scripts/compress-mp4.sh: AAC mono 64k + x264 CRF 28, aproximadamente -65% de tamaño, ~5 min por 12 min de video, almacenado en caché mientras el renderizado no cambie; el renderizado en sí nunca se modifica), luego sube esa copia web a R2 si cambió, agrega/actualiza la entrada del catálogo desde lab.config.json, copia chapters.json, poster.jpg, lab.json (se elimina de la carpeta del sitio cuando el laboratorio no tiene ninguno), crea la página index.html para un laboratorio nuevo (a partir de la plantilla compartida, con título y descripción), registra el hash del video en state/<slug>.sha256 y actualiza minutes/lessons en site/labs.json. Las subidas ocurren aquí, antes de que se envíe nada, por lo que la página nunca se publica sin su video. Es seguro volver a ejecutarlo.
  3. Revisar y confirmar. Primero ejecuta scripts/check-secrets.sh (falla si un valor de .env aparece en algún archivo, si algún archivo asigna un valor a una variable de clave API, token o contraseña, o si hay una clave privada presente) y corrige lo que reporte antes de continuar. Muéstrale al usuario git status y un resumen de diferencias del repositorio videolabs (laboratorios nuevos/cambiados, labs.json, state/ y cualquier cambio en el código compartido del reproductor, ver más abajo). Si el laboratorio responde a una solicitud de video de GitHub (un issue etiquetado como video-request), pon Closes #N en el cuerpo del mensaje de confirmación para que el push a main lo cierre. Confirma todo, incluyendo labs/*/audio/ cuando haya cambiado (mensaje como Publish labs: ceph-first-steps (new), kafka-in-a-nutshell (lab page), con la línea Co-Authored-By del recordatorio de atribución de la sesión) y git push origin main (el remoto SSH está configurado). Si el árbol de trabajo tiene cambios en el código compartido del reproductor que no fueron parte de esta solicitud, pregunta antes de incluirlos.
  4. Desplegar. Espera a que la ejecución de GitHub Actions termine (curl -s https://api.github.com/repos/bigzaqui/videolabs/actions/runs?per_page=1, verifica status/conclusion; consulta cada ~20 s hasta ~3 min). Si falla, repórtalo y no lo reintentes a ciegas; un error de secreto faltante significa que los secretos del repositorio CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID necesitan atención.
  5. Verificar cada laboratorio en site/labs.json (no solo el nuevo): / devuelve 200 y los lista; /labs/<slug>/ devuelve 200; /labs/<slug>/chapters.json devuelve JSON (no el fallback HTML: el sitio responde 200 para rutas desconocidas, así que verifica el tipo de contenido o el cuerpo); /labs/<slug>/lab.json devuelve JSON para los laboratorios que lo tienen; /media/<slug>/<slug>.mp4 devuelve 401 sin sesión (prueba que la puerta está activa). La reproducción en sí necesita una sesión de navegador con la verificación de Turnstile, así que di que no se reprodujo. Reporta las URLs: https://videolabs.pages.dev/labs/<slug>/.

Para publicar solo un laboratorio (raro), ejecuta scripts/publish-lab.sh <lab-dir> <slug> "<title>" "<description>" y actualiza site/labs.json manualmente, luego continúa con el paso 3.

Código compartido

site/labs/kafka-in-a-nutshell/index.html es la plantilla de página copiada para cada laboratorio nuevo (título, encabezado y descripción provienen de site/labs.json en tiempo de ejecución), site/lab.js renderiza los recursos del laboratorio cuando un laboratorio tiene lab.json, site/gate.js es la verificación de Turnstile. Cambiarlos afecta a todos los laboratorios en el próximo push, así que compruébalos primero con un laboratorio existente. Los laboratorios existentes mantienen su propia copia de index.html; un cambio en la plantilla los alcanza solo si su copia también se actualiza.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados