GitHub Action
Use Betamax Terminal Previews to run tapes in CI and upload recordings, an HTML
gallery, and diagnostic logs. The render job links the gallery in its summary. Add the separate
joshka/betamax-action/report action to create or update one pull request comment with gallery
links.
The actions support GitHub.com and Ubuntu 24.04 GitHub-hosted runners on x64 and ARM64.
The examples use @v1, which tracks compatible action releases. Full-version tags such as
v1.0.0 stay fixed. The action version is separate from the Betamax CLI version.
See the source repository for the implementation and release history.
For an immutable dependency, replace @v1 in both workflows with the full release commit SHA.
For v1.0.0, use:
# Renderer (in the read-only PR workflow):- uses: joshka/betamax-action@bc6fa6bfb5e20dd342b588601f4e1a945661d5fe # v1.0.0# Reporter (in the separate trusted workflow):- uses: joshka/betamax-action/report@bc6fa6bfb5e20dd342b588601f4e1a945661d5fe # v1.0.0Render tapes on pull requests
Section titled “Render tapes on pull requests”Save this as .github/workflows/betamax.yml. Replace demos/**/*.tape with your tape paths and
add any toolchain installation and application build steps before the render action.
name: Betamaxon: pull_requestpermissions: {}concurrency: group: betamax-${{ github.ref }} cancel-in-progress: truejobs: render: runs-on: ubuntu-24.04 timeout-minutes: 15 permissions: contents: read steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false # Install your application's toolchain and build it here. - uses: joshka/betamax-action@v1 with: tapes: demos/**/*.tape formats: gif,pngThe action downloads checksum-verified Betamax CLI 0.1.22 and installs fonts and ffmpeg by default. It adds output directives for the requested formats without changing your checked-in tapes. Build your application in an earlier step to keep build time outside each tape’s timeout.
Tapes execute shell commands with the render job’s privileges. Use a fresh runner with read-only permissions and no secrets throughout this job, including steps after rendering.
Run commands from the checkout
Section titled “Run commands from the checkout”The tape shell starts in the directory Betamax runs from. The action runs Betamax from the
checkout root, or the directory selected by working-directory, so project-relative commands work
without extra setup. The action also sets BETAMAX_WORKING_DIRECTORY to that directory for tapes
that change directory and need to return.
Betamax CLI 0.1.22 and earlier start the tape shell in the home directory instead. For those versions, change directory at the start of your tape:
HideType@0ms "cd \"$BETAMAX_WORKING_DIRECTORY\""EnterShowThen add the commands, waits, and captures for your application. See Tape files for authoring guidance.
Add a pull request comment
Section titled “Add a pull request comment”Save this as .github/workflows/betamax-report.yml on your default branch. The trigger selects
the render workflow’s name (Betamax); the workflow input selects its filename
(betamax.yml). Reporting only becomes active once this workflow is on the default branch.
name: Betamax reporton: workflow_run: workflows: [Betamax] types: [completed]permissions: {}concurrency: group: betamax-report-${{ github.event.workflow_run.head_repository.id }}-${{ github.event.workflow_run.head_branch }} cancel-in-progress: falsejobs: report: if: github.event.workflow_run.event == 'pull_request' runs-on: ubuntu-24.04 timeout-minutes: 5 permissions: actions: read pull-requests: write steps: - uses: joshka/betamax-action/report@v1 with: workflow: betamax.ymlKeep reporting on a fresh runner without checking out PR code or restoring PR caches. Its write
permission is used to update the comment; rendering remains in the separate read-only job.
The default artifact-link mode uses GITHUB_TOKEN and requires no additional secret.
New commits update the same comment. The reporter skips closed PRs, superseded heads, and older run attempts. Fork PRs can receive comments subject to the repository’s contributor-workflow approval policy. Gallery downloads require GitHub sign-in and repository access. Artifacts expire, so use release assets or a web host for permanent documentation media.
Configure captures
Section titled “Configure captures”Common render inputs are listed below. See the action reference for the full contract.
| Input | Default | Purpose |
|---|---|---|
tapes |
**/*.tape |
Newline-separated paths or globs; prefix exclusions with !. |
working-directory |
. |
Base directory for tape discovery and output paths inside the checkout. |
formats |
gif,png |
Comma-separated gif, png, webp, mp4, or webm. |
timeout-seconds |
120 |
Per-tape timeout, from 1 to 1800 seconds. |
retention-days |
14 |
Artifact retention, capped by repository policy. |
extra-outputs |
Empty | Newline-separated globs for checkpoints or existing media. |
version |
0.1.22 |
Betamax CLI release; separate from the action tag. |
binary |
Empty | Use a local Betamax executable instead of downloading a release. |
comment-key |
betamax |
Shared identifier for render artifacts and the report comment. |
variant |
default |
Unique identifier for each render job in a matrix. |
For a matrix, give each render job a distinct variant and share one comment-key. One report job
collects the variants after the workflow completes. Independent workflows should use different keys.
To collect screenshot checkpoints, set extra-outputs to their paths, such as
target/review/**/*.png. Use a fresh output directory because matching pre-existing files are also
collected. Each render invocation accepts up to 20 tapes and 20 media files, with at most 10 MiB per
file and 40 MiB of media total.
To select another CLI release, set version. If it has no bundled checksum, also supply its release
archive SHA-256 through sha256.
If you build Betamax itself before the action, set binary: target/debug/betamax. The path must
name an executable inside working-directory with no symlink components. It overrides version and
sha256; dependency installation remains enabled unless install-dependencies: false is set.
Inline images and videos
Section titled “Inline images and videos”Native inline attachments are optional and best effort. They use an undocumented GitHub upload endpoint that may change; an individual upload failure leaves an artifact link and a warning.
The report action supports mode: attachments for inline media. This requires a separate
repository-scoped user token, passed only to the reporter through attachment-token. Store it in an
environment restricted to the trusted default branch and select that environment on the report job.
Follow the attachment setup guide for token provisioning and branch rules before
enabling this mode. Keep the reporter’s token input at its default so the Actions bot owns the
comment.
Diagnose failed previews
Section titled “Diagnose failed previews”If a tape fails or times out, the action continues with the remaining tapes and uploads available media and diagnostics before failing the step. Download the diagnostics artifact to inspect process logs. Setup or discovery errors stop rendering immediately.
Betamax also saves a failure bundle for each failed tape
under target/betamax-failures in the working-directory. The action does not upload it; add an
upload step with if: ${{ failure() }} after the action.
If no comment appears, check that the report workflow is on the default branch, the workflow name and filename match, and the reporter has both required permissions. If a gallery has expired, rerun the render workflow for the current PR head. For missing inline attachments, inspect report warnings and rerun rendering after correcting the issue; rerunning only the reporter does not retry an already published attempt.
Inspect the recordings as well as the job status. A successful tape can still show an application error; keep terminal assertions alongside the previews.