Communitygithub.com

bigzaqui/videolabs

Publish the whole videolabs site (https://videolabs.pages.dev): sync every lab in the repo's labs/ folder into the site (video to Cloudflare R2 only when it changed, player assets, lab resources, catalog), commit and push the videolabs repo so GitHub Actions deploys to Cloudflare Pages, then verify every lab. Use when the user wants to publish, deploy, add, update or re-upload video labs to videolabs.pages.dev. One run publishes all labs, not just one.

What is videolabs?

videolabs is a Claude Code agent skill that publish the whole videolabs site (https://videolabs.pages.dev): sync every lab in the repo's labs/ folder into the site (video to Cloudflare R2 only when it changed, player assets, lab resources, catalog), commit and push the videolabs repo so GitHub Actions deploys to Cloudflare Pages, then verify every lab. Use when the user wants to publish, deploy, add, update or re-upload video labs to videolabs.pages.dev. One run publishes all labs, not just one.

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

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation


name: videolabs_publish description: Publish the whole videolabs site (https://videolabs.pages.dev): sync every lab in the repo's labs/ folder into the site (video to Cloudflare R2 only when it changed, player assets, lab resources, catalog), commit and push the videolabs repo so GitHub Actions deploys to Cloudflare Pages, then verify every lab. Use when the user wants to publish, deploy, add, update or re-upload video labs to videolabs.pages.dev. One run publishes all labs, not just one.

Publish the videolabs site

"Publish" means the whole site is deployed with all labs, every time.

Site repo: /opt/opus/videolabs (github.com/bigzaqui/videolabs, deploys to https://videolabs.pages.dev on push to main; GitHub Actions publishes the site/ folder). Labs: /opt/opus/videolabs/labs/<slug>/ (one folder per lab, in the same repo; the slug is the MP4 name out/<slug>.mp4). They are built with the videolabs_create-video skill (node engine/cli.mjs <slug> ...). Videos live in the private R2 bucket videolabs at <slug>/<slug>.mp4 and are served through /media/<slug>/<slug>.mp4, which is behind a Turnstile session (a request without a session returns 401). Credentials: /opt/opus/videolabs/.env (loaded by the scripts; template .env.example). Never print, copy or commit secrets. The GitHub repo is public (the user is fine with that for the narration audio, scripts, captures and lab output, and does not mind throwaway passwords of destroyed labs appearing there), so no real credential may appear in any file. This skill's source is skills/videolabs_publish/ in the repo, linked into ~/.claude/skills by scripts/setup.sh.

What a lab needs (checked by the script)

  • out/<slug>.mp4 (fast-start: moov before mdat; fix with ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4), out/player/chapters.json (node engine/cli.mjs <slug> player), out/spot.jpg (poster; grab a diagram frame with ffmpeg -ss 425 -i out/<slug>.mp4 -frames:v 1 -q:v 3 out/spot.jpg).
  • Optional out/player/lab.json (from node engine/cli.mjs <slug> player when the lab has lab/lab-meta.json, lab/*.sh, lab/captures/). If present, site/lab.js shows the lab resources on the lab page. Re-run node engine/cli.mjs <slug> player first if captures or lab-meta.json changed.
  • labs/<slug>/lab.config.json with title, description and tags. The script adds or updates the entry in site/labs.json from it (and fills in minutes and lessons), so never edit the catalog by hand. For a new lab take title/description/tags from the lab's script if clear, otherwise ask the user. Never invent them silently.

Steps

  1. Plan. cd /opt/opus/videolabs && scripts/publish-all.sh --dry-run. It prints one PLAN line per lab (what will be uploaded or skipped, whether it has lab.json), ATTENTION lines for labs it cannot publish (missing file, not fast-start, no lab.config.json) and NOTE lines for catalog entries without a project. Exit code 2 means there is at least one ATTENTION. Fix each one (write lab.config.json, run node engine/cli.mjs <slug> player, make the poster, ...) and repeat until there are none, or tell the user which lab is being left out and why. Show the user the plan in a few lines, including which videos will be uploaded and their size.
    • A lab with no recorded upload (state/<slug>.sha256 missing) is uploaded. If the user says R2 already holds exactly that file, use --adopt <slug> to record its hash instead of uploading. --force-upload re-uploads everything; use it only when the user asks to replace a video (a re-upload may stay cached up to 24h for viewers).
  2. Sync. scripts/publish-all.sh (same flags). For every ready lab it first compresses the render to out/<slug>.web.mp4 (scripts/compress-mp4.sh: mono AAC 64k + x264 CRF 28, about -65% size, ~5 min per 12 min of video, cached while the render is unchanged; the render itself is never modified), then uploads that web copy to R2 if changed, adds/updates the catalog entry from lab.config.json, copies chapters.json, poster.jpg, lab.json (removed from the site folder when the lab has none), creates the page index.html for a new lab (from the shared template, with title and description), records the video hash in state/<slug>.sha256 and refreshes minutes/lessons in site/labs.json. Uploads happen here, before anything is pushed, so the page never goes live without its video. It is safe to run again.
  3. Review and commit. Run scripts/check-secrets.sh first (it fails if a value from .env appears in any file, if a file assigns a value to an API key, token or password variable, or if a private key is present) and fix whatever it reports before going on. Show the user git status and a diff summary of the videolabs repo (new/changed labs, labs.json, state/, and any change to shared player code, see below). If the lab answers a GitHub video request (an issue labeled video-request), put Closes #N in the commit message body so the push to main closes it. Commit everything, including labs/*/audio/ when it changed (message like Publish labs: ceph-first-steps (new), kafka-in-a-nutshell (lab page), with the Co-Authored-By line from the session's attribution reminder) and git push origin main (SSH remote is set up). If the working tree has changes to shared player code that were not part of this request, ask before including them.
  4. Deploy. Wait for the GitHub Actions run (curl -s https://api.github.com/repos/bigzaqui/videolabs/actions/runs?per_page=1, check status/conclusion; poll about every 20 s up to ~3 min). If it fails, report it and do not retry blindly; a missing-secret error means the repository secrets CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID need attention.
  5. Verify every lab in site/labs.json (not only the new one): / returns 200 and lists them; /labs/<slug>/ returns 200; /labs/<slug>/chapters.json returns JSON (not the HTML fallback: the site answers 200 for unknown paths, so check the content type or the body); /labs/<slug>/lab.json returns JSON for labs that have one; /media/<slug>/<slug>.mp4 returns 401 without a session (proves the gate is up). Playback itself needs a browser session with the Turnstile check, so say that it was not played. Report the URLs: https://videolabs.pages.dev/labs/<slug>/.

To publish only one lab (rare), run scripts/publish-lab.sh <lab-dir> <slug> "<title>" "<description>" and update site/labs.json by hand, then continue with step 3.

Shared code

site/labs/kafka-in-a-nutshell/index.html is the page template copied for every new lab (title, heading and description come from site/labs.json at runtime), site/lab.js renders lab resources when a lab has lab.json, site/gate.js is the Turnstile check. Changing them affects every lab on the next push, so check them against an existing lab first. Existing labs keep their own copy of index.html; a template change reaches them only if their copy is updated too.

Individual skills in this repo

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

Related Skills