Publicar o site videolabs
"Publicar" significa que o site inteiro é implantado com todos os laboratórios, toda vez.
Repositório do site: /opt/opus/videolabs (github.com/bigzaqui/videolabs, implanta em https://videolabs.pages.dev ao fazer push para main; o GitHub Actions publica a pasta site/).
Laboratórios: /opt/opus/videolabs/labs/<slug>/ (uma pasta por laboratório, no mesmo repositório; o slug é o nome do MP4 out/<slug>.mp4). Eles são construídos com a skill videolabs_create-video (node engine/cli.mjs <slug> ...).
Os vídeos ficam no bucket privado R2 videolabs em <slug>/<slug>.mp4 e são servidos através de /media/<slug>/<slug>.mp4, que está atrás de uma sessão Turnstile (uma requisição sem sessão retorna 401).
Credenciais: /opt/opus/videolabs/.env (carregado pelos scripts; template .env.example). Nunca imprima, copie ou faça commit de segredos. O repositório GitHub é público (o usuário não se importa com isso para o áudio de narração, scripts, capturas e saída do laboratório, e não se importa com senhas descartáveis de laboratórios destruídos aparecendo lá), então nenhuma credencial real pode aparecer em qualquer arquivo. O código-fonte desta skill está em skills/videolabs_publish/ no repositório, vinculado a ~/.claude/skills por scripts/setup.sh.
O que um laboratório precisa (verificado pelo script)
out/<slug>.mp4(fast-start:moovantes demdat; corrija comffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4),out/player/chapters.json(node engine/cli.mjs <slug> player),out/spot.jpg(pôster; capture um quadro do diagrama comffmpeg -ss 425 -i out/<slug>.mp4 -frames:v 1 -q:v 3 out/spot.jpg).- Opcional
out/player/lab.json(denode engine/cli.mjs <slug> playerquando o laboratório possuilab/lab-meta.json,lab/*.sh,lab/captures/). Se presente,site/lab.jsmostra os recursos do laboratório na página do laboratório. Executenode engine/cli.mjs <slug> playernovamente primeiro se as capturas oulab-meta.jsonmudaram. labs/<slug>/lab.config.jsoncomtitle,descriptionetags. O script adiciona ou atualiza a entrada emsite/labs.jsona partir dele (e preencheminuteselessons), então nunca edite o catálogo manualmente. Para um novo laboratório, use título/descrição/tags do script do laboratório se estiver claro; caso contrário, pergunte ao usuário. Nunca os invente silenciosamente.
Passos
- Planejar.
cd /opt/opus/videolabs && scripts/publish-all.sh --dry-run. Ele imprime uma linhaPLANpor laboratório (o que será enviado ou ignorado, se possuilab.json), linhasATTENTIONpara laboratórios que não podem ser publicados (arquivo faltando, não fast-start, semlab.config.json) e linhasNOTEpara entradas de catálogo sem um projeto. Código de saída 2 significa que há pelo menos umaATTENTION. Corrija cada uma (escrevalab.config.json, executenode engine/cli.mjs <slug> player, faça o pôster, ...) e repita até que não haja nenhuma, ou diga ao usuário qual laboratório está sendo deixado de fora e por quê. Mostre ao usuário o plano em algumas linhas, incluindo quais vídeos serão enviados e seus tamanhos.- Um laboratório sem upload registrado (
state/<slug>.sha256ausente) é enviado. Se o usuário disser que o R2 já contém exatamente aquele arquivo, use--adopt <slug>para registrar seu hash em vez de fazer upload.--force-uploadreenvia tudo; use-o apenas quando o usuário pedir para substituir um vídeo (um re-upload pode permanecer em cache por até 24h para os espectadores).
- Um laboratório sem upload registrado (
- Sincronizar.
scripts/publish-all.sh(mesmas flags). Para cada laboratório pronto, ele primeiro comprime a renderização paraout/<slug>.web.mp4(scripts/compress-mp4.sh: mono AAC 64k + x264 CRF 28, cerca de -65% de tamanho, ~5 min por 12 min de vídeo, em cache enquanto a renderização não mudar; a renderização em si nunca é modificada), então envia essa cópia web para o R2 se alterada, adiciona/atualiza a entrada do catálogo a partir delab.config.json, copiachapters.json,poster.jpg,lab.json(removido da pasta do site quando o laboratório não possui um), cria a páginaindex.htmlpara um novo laboratório (a partir do template compartilhado, com título e descrição), registra o hash do vídeo emstate/<slug>.sha256e atualizaminutes/lessonsemsite/labs.json. Os uploads ocorrem aqui, antes de qualquer coisa ser enviada, então a página nunca vai ao ar sem seu vídeo. É seguro executar novamente. - Revisar e commitar. Execute
scripts/check-secrets.shprimeiro (ele falha se um valor de.envaparecer em qualquer arquivo, se um arquivo atribuir um valor a uma variável de chave de API, token ou senha, ou se uma chave privada estiver presente) e corrija o que ele relatar antes de prosseguir. Mostre ao usuáriogit statuse um resumo das diferenças do repositório videolabs (laboratórios novos/alterados,labs.json,state/e qualquer alteração no código compartilhado do player, veja abaixo). Se o laboratório atender a uma solicitação de vídeo no GitHub (uma issue com a labelvideo-request), coloqueCloses #Nno corpo da mensagem de commit para que o push paramaina feche. Faça commit de tudo, incluindolabs/*/audio/quando alterado (mensagem comoPublish labs: ceph-first-steps (new), kafka-in-a-nutshell (lab page), com a linha Co-Authored-By do lembrete de atribuição da sessão) egit push origin main(o remote SSH está configurado). Se a árvore de trabalho tiver alterações no código compartilhado do player que não faziam parte desta solicitação, pergunte antes de incluí-las. - Implantar. Aguarde a execução do GitHub Actions (
curl -s https://api.github.com/repos/bigzaqui/videolabs/actions/runs?per_page=1, verifiquestatus/conclusion; consulte a cada ~20 s por até ~3 min). Se falhar, relate e não tente novamente cegamente; um erro de segredo ausente significa que os segredos do repositórioCLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_IDprecisam de atenção. - Verificar cada laboratório em
site/labs.json(não apenas o novo):/retorna 200 e os lista;/labs/<slug>/retorna 200;/labs/<slug>/chapters.jsonretorna JSON (não o fallback HTML: o site responde com 200 para caminhos desconhecidos, então verifique o tipo de conteúdo ou o corpo);/labs/<slug>/lab.jsonretorna JSON para laboratórios que possuem um;/media/<slug>/<slug>.mp4retorna 401 sem uma sessão (prova que o gate está ativo). A reprodução em si precisa de uma sessão de navegador com a verificação Turnstile, então informe que não foi reproduzido. Relate as URLs:https://videolabs.pages.dev/labs/<slug>/.
Para publicar apenas um laboratório (raro), execute scripts/publish-lab.sh <lab-dir> <slug> "<title>" "<description>" e atualize site/labs.json manualmente, depois continue com o passo 3.
Código compartilhado
site/labs/kafka-in-a-nutshell/index.html é o template de página copiado para cada novo laboratório (título, cabeçalho e descrição vêm de site/labs.json em tempo de execução), site/lab.js renderiza os recursos do laboratório quando um laboratório possui lab.json, site/gate.js é a verificação Turnstile. Alterá-los afeta todos os laboratórios no próximo push, então verifique-os em um laboratório existente primeiro. Laboratórios existentes mantêm sua própria cópia de index.html; uma alteração no template os alcança apenas se a cópia deles também for atualizada.