Skip to main content
A silent build needs no API key, and after decktalk setup it needs no network. Use this guide to build and check the video on every push, or on a machine that is offline. decktalk build can pass when decktalk check or decktalk verify fails. To gate a job on the video, run all three commands.

Add a GitHub Actions job

This job builds the video with no API key, checks it, and uploads the video and the verify results.
.github/workflows/video.yml
  • The cache paths are for Linux. Requirements lists the paths on macOS and Windows.
  • On Linux, setup installs Chromium’s system libraries, which needs sudo or root. Linux system libraries gives the full rule.
  • setup downloads ffmpeg into the static-ffmpeg package, inside the Python environment of DeckTalk. This job does not cache it, so each run downloads ffmpeg again.
  • DeckTalk’s own CI installs into .venv and caches .venv/lib/*/site-packages/static_ffmpeg/bin.
  • If a proxy blocks the Chromium download, set PLAYWRIGHT_DOWNLOAD_HOST to a mirror.

What each command catches

Each command exits 1 on a different set of problems. A silent build puts a click at every word start, so verify also reports an a/v value for each cue. The job fails when an a/v value is past max_av_frames, which is three frames at the defaults. A silent build therefore tests the recording, the cut, and the mix, not only the cues. build --strict fails on a missing clip, unless the clip section sets optional = true. With --silent, it cannot fail on loudness, because a silent build skips the loudness pass.

Fail the job on a bad video

status, beats, check, verify, and doctor share one exit rule. Use their exit codes as the assertions of a job.
  • A certain finding, such as OFF CUE or TRUNCATED, exits 1.
  • An uncertain finding ends in ?, such as BLACK? on a slide that is dark on purpose. It exits 1 only with --strict.
  • An error always exits 1.
To keep the job running and decide later, add --no-fail and read the JSON.
--no-fail makes the command exit 0 on findings, but an error still exits 1. The JSON ok is false when the command would exit 1 without --no-fail. jq -e then exits 1, and the second jq line lists the rows to look at. Output and exit flags lists every key.

Allow for slower runners

A hosted runner has no GPU that Chromium can use, so Chromium draws every frame in software. The macOS and Windows runners are slower than Linux.
  • A page renders more slowly on a runner than on a laptop.
  • A canvas figure or a large SVG renders more slowly still.
  • A reveal can start two or three frames late, and verify reports OFF CUE.
  • A long draw after narration t=0 can read STALLED.
If that happens only on a slower runner, widen the limits for that runner. Keep the defaults on the machine that records the published video. DeckTalk’s own CI uses these values. A reveal can also start late while a large layer moves, such as a canvas figure that pans. To gate a job on cue timing, verify a light deck whose reveals land on still pages, and report the busy deck without failing. DeckTalk’s own CI builds tests/timing and fails on any finding there. It runs decktalk verify --no-fail on the scaffold.
.github/workflows/video.yml

Build a voiced video in CI

Put ELEVENLABS_API_KEY and ELEVENLABS_VOICE_ID in the job’s secrets, and export them to the build step. DeckTalk never prints either value.
Never run decktalk build --silent in a build/ directory that you keep for voiced builds. It empties the narration cache, and the next voiced build spends credits on every section.
A silent build and a voiced build explains why.

Set the project directory

Every project command takes --project DIR. The DECKTALK_PROJECT variable sets the default, so a job can run from the repository root.

Build offline

A silent build runs with no network after these steps.
1

Download the tools

On a machine with network, run setup. It downloads Chromium, ffmpeg, and KaTeX.
2

Create the project

Run init after setup. init copies the cached KaTeX into deck/katex/.
3

Build the video

Run a silent build in the project directory.
In the scaffold, only deck/index.html loads KaTeX. If init ran before KaTeX was cached, that page loads KaTeX from a CDN. Offline, its equations then stay plain text, and check reports KATEX?. To fix a project that loads KaTeX from a CDN:
  1. Run decktalk setup.
  2. Copy the files in the cached KaTeX folder into deck/katex/. Requirements lists the cache folder.
  3. In deck/index.html, replace the two KaTeX CDN tags with these tags.
deck/index.html
If the project has no changes of its own yet, run decktalk init into a new directory instead.

Next