Publier le site videolabs
« Publier » signifie que l'intégralité du site est déployée avec tous les labs, à chaque fois.
Dépôt du site : /opt/opus/videolabs (github.com/bigzaqui/videolabs, déploie sur https://videolabs.pages.dev lors d'un push sur main ; GitHub Actions publie le dossier site/).
Labs : /opt/opus/videolabs/labs/<slug>/ (un dossier par lab, dans le même dépôt ; le slug est le nom du fichier MP4 out/<slug>.mp4). Ils sont construits avec la compétence videolabs_create-video (node engine/cli.mjs <slug> ...).
Les vidéos résident dans le bucket R2 privé videolabs à l'emplacement <slug>/<slug>.mp4 et sont servies via /media/<slug>/<slug>.mp4, qui est protégé par une session Turnstile (une requête sans session renvoie 401).
Credentials : /opt/opus/videolabs/.env (chargé par les scripts ; modèle .env.example). Ne jamais imprimer, copier ou valider les secrets. Le dépôt GitHub est public (l'utilisateur est d'accord avec cela pour l'audio de narration, les scripts, les captures et la sortie du lab, et ne se soucie pas que des mots de passe jetables de labs détruits y apparaissent), donc aucun véritable credential ne peut apparaître dans aucun fichier. Le code source de cette compétence se trouve dans skills/videolabs_publish/ du dépôt, lié dans ~/.claude/skills par scripts/setup.sh.
Ce dont un lab a besoin (vérifié par le script)
out/<slug>.mp4(fast-start :moovavantmdat; corriger avecffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4),out/player/chapters.json(node engine/cli.mjs <slug> player),out/spot.jpg(poster ; capturer une image du diagramme avecffmpeg -ss 425 -i out/<slug>.mp4 -frames:v 1 -q:v 3 out/spot.jpg).- Optionnel :
out/player/lab.json(provenant denode engine/cli.mjs <slug> playerlorsque le lab contientlab/lab-meta.json,lab/*.sh,lab/captures/). S'il est présent,site/lab.jsaffiche les ressources du lab sur la page du lab. Relancer d'abordnode engine/cli.mjs <slug> playersi les captures oulab-meta.jsonont changé. labs/<slug>/lab.config.jsonavectitle,descriptionettags. Le script ajoute ou met à jour l'entrée danssite/labs.jsonà partir de ce fichier (et remplitminutesetlessons), donc ne jamais éditer le catalogue manuellement. Pour un nouveau lab, prendre le titre/la description/les tags dans le script du lab si c'est clair, sinon demander à l'utilisateur. Ne jamais les inventer silencieusement.
Étapes
- Planification.
cd /opt/opus/videolabs && scripts/publish-all.sh --dry-run. Il affiche une lignePLANpar lab (ce qui sera téléchargé ou ignoré, s'il contientlab.json), des lignesATTENTIONpour les labs qu'il ne peut pas publier (fichier manquant, pas fast-start, pas delab.config.json) et des lignesNOTEpour les entrées du catalogue sans projet. Le code de sortie 2 signifie qu'il y a au moins uneATTENTION. Corriger chacune (écrirelab.config.json, exécuternode engine/cli.mjs <slug> player, créer le poster, ...) et répéter jusqu'à ce qu'il n'y en ait plus, ou indiquer à l'utilisateur quel lab est exclu et pourquoi. Montrer le plan à l'utilisateur en quelques lignes, y compris quelles vidéos seront téléchargées et leur taille.- Un lab sans téléchargement enregistré (
state/<slug>.sha256manquant) est téléchargé. Si l'utilisateur dit que R2 contient déjà exactement ce fichier, utiliser--adopt <slug>pour enregistrer son hash au lieu de télécharger.--force-uploadretélécharge tout ; l'utiliser uniquement lorsque l'utilisateur demande de remplacer une vidéo (un retéléchargement peut rester en cache jusqu'à 24 h pour les spectateurs).
- Un lab sans téléchargement enregistré (
- Synchronisation.
scripts/publish-all.sh(mêmes options). Pour chaque lab prêt, il comprime d'abord le rendu enout/<slug>.web.mp4(scripts/compress-mp4.sh: mono AAC 64k + x264 CRF 28, environ -65 % de taille, ~5 min pour 12 min de vidéo, mis en cache tant que le rendu n'est pas modifié ; le rendu lui-même n'est jamais modifié), puis télécharge cette copie Web vers R2 si elle a changé, ajoute/met à jour l'entrée du catalogue à partir delab.config.json, copiechapters.json,poster.jpg,lab.json(supprimé du dossier du site lorsque le lab n'en a pas), crée la pageindex.htmlpour un nouveau lab (à partir du template partagé, avec titre et description), enregistre le hash de la vidéo dansstate/<slug>.sha256et rafraîchitminutes/lessonsdanssite/labs.json. Les téléchargements se produisent ici, avant que quoi que ce soit ne soit poussé, donc la page ne devient jamais publique sans sa vidéo. Il est sûr de réexécuter. - Révision et validation. Exécuter d'abord
scripts/check-secrets.sh(il échoue si une valeur de.envapparaît dans un fichier, si un fichier assigne une valeur à une variable de clé API, token ou mot de passe, ou si une clé privée est présente) et corriger tout ce qu'il signale avant de continuer. Montrer à l'utilisateurgit statuset un résumé des différences du dépôt videolabs (labs nouveaux/modifiés,labs.json,state/, et toute modification du code du player partagé, voir ci-dessous). Si le lab répond à une demande vidéo GitHub (un ticket étiquetévideo-request), mettreCloses #Ndans le corps du message de validation pour que le push surmainle ferme. Valider le tout, y comprislabs/*/audio/si modifié (message du genrePublish labs: ceph-first-steps (new), kafka-in-a-nutshell (lab page), avec la ligne Co-Authored-By provenant du rappel d'attribution de la session) etgit push origin main(le remote SSH est configuré). Si l'arbre de travail contient des modifications du code du player partagé qui ne faisaient pas partie de cette demande, demander avant de les inclure. - Déploiement. Attendre l'exécution de GitHub Actions (
curl -s https://api.github.com/repos/bigzaqui/videolabs/actions/runs?per_page=1, vérifierstatus/conclusion; interroger environ toutes les 20 s jusqu'à ~3 min). Si elle échoue, le signaler et ne pas réessayer aveuglément ; une erreur de secret manquant signifie que les secrets du dépôtCLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_IDnécessitent une attention. - Vérifier chaque lab dans
site/labs.json(pas seulement le nouveau) :/renvoie 200 et les liste ;/labs/<slug>/renvoie 200 ;/labs/<slug>/chapters.jsonrenvoie du JSON (pas le fallback HTML : le site répond 200 pour les chemins inconnus, donc vérifier le type de contenu ou le corps) ;/labs/<slug>/lab.jsonrenvoie du JSON pour les labs qui en ont un ;/media/<slug>/<slug>.mp4renvoie 401 sans session (prouve que la protection est active). La lecture elle-même nécessite une session navigateur avec la vérification Turnstile, donc dire qu'elle n'a pas été lue. Reporter les URL :https://videolabs.pages.dev/labs/<slug>/.
Pour publier un seul lab (rare), exécuter scripts/publish-lab.sh <lab-dir> <slug> "<title>" "<description>" et mettre à jour site/labs.json à la main, puis continuer à l'étape 3.
Code partagé
site/labs/kafka-in-a-nutshell/index.html est le template de page copié pour chaque nouveau lab (le titre, l'en-tête et la description proviennent de site/labs.json à l'exécution), site/lab.js rend les ressources du lab lorsque celui-ci possède lab.json, site/gate.js est la vérification Turnstile. Les modifier affecte tous les labs lors du prochain push, donc les tester d'abord sur un lab existant. Les labs existants conservent leur propre copie de index.html ; un changement de template ne les atteint que si leur copie est également mise à jour.