Release pipeline
A devhost release publishes two things from one Git tag: the binaries and this documentation site. The site is deployed only by a release, so it describes the released version and not unreleased work on main.
The guide videos and the promo on the landing page follow a separate, manual track. No workflow records or renders video. A release downloads the videos that were published earlier and checks each against the hash pinned in the repository.
Pipeline
Section titled “Pipeline”The diagram has three stages. The films are made and published by hand, and only when a demo changed. A merge to main runs the checks and deploys nothing. A v* tag publishes the binaries and then the site. The dotted arrows are the pinned videos, which every docs build downloads from the media release.
How it works
Section titled “How it works”Binaries
Section titled “Binaries”Pushing a tag such as v0.0.2 starts .github/workflows/publish.yml. The workflow fails unless the tag matches the version in apps/devhost/metadata.json. The hosted Linux runner installs Playwright Chromium, FFmpeg (including ffprobe), unzip, and Xvfb for the native media and headed-browser tests. It then runs just check, builds the release archives, creates the GitHub release for the tag, and uploads the archives to it.
The Go checks include logpolicy, a type-aware analyzer that enforces the shared internal/cliout output boundary. Run just devhost lint-logging to check it alone. Diagnostics use the shared logger; machine-readable command results, child logs, HTTP responses, and file contents retain their separate output contracts.
just devhost test runs go test -count=1 ./..., including when invoked through just check locally or in CI. Every Go test runs afresh because the integration suite observes live processes, ports, and kernel state. This also prevents Go from recording and later validating millions of Linux /proc observations as test-cache inputs. Compiled packages still use Go’s build cache.
Documentation site
Section titled “Documentation site”The docs job of the same workflow runs after the release exists. It calls .github/workflows/docs.yml, which checks out the tag, builds packages/docs, and deploys the result to GitHub Pages. A failed release deploys nothing.
A push to main does not deploy the site; documentation merged to main, corrections included, is published with the next release.
The github-pages environment accepts deployments only from main and from tags that match v*. The Deploy docs to GitHub Pages workflow can also be run by hand, within those limits: a run from a release tag deploys that release’s documentation again, unchanged, and a run from main deploys everything on main, including documentation of unreleased behavior. A branch that holds only a correction cannot be deployed.
Guide videos
Section titled “Guide videos”The videos are assets of a GitHub release named media, not files in the repository. packages/docs/demo-media.json pins each one by name, release asset, SHA-256, and size. Every docs build downloads the pinned videos and rejects a file whose hash differs.
A tag carries its pins. The site built for a release therefore shows the videos that were pinned in the tagged commit, and an asset is never replaced, so an earlier tag still builds with the videos it pinned.
New videos need a Linux host with the recording tools, an operator to approve the coding agent’s requests during recording, an ElevenLabs key, and a review of the result. For that reason they are made by hand before the release:
just demo audio-guidesgenerates the narration of changed lines.just demo guidesrecords each guide and renders its film.just demo recorddoes the same for the promo.- After the films are reviewed,
just docs publish-mediauploads them and rewrites their pins. - The pins, posters, captions, and guide pages are committed together.
A change to the interface does not update a video. When a release changes what a guide shows, the film has to be recorded again before the tag is pushed; otherwise the release ships the earlier video beside the new text.