Continuous integration
The checks, release, and docs GitHub Actions workflows, and how release binaries are built on a local Mac.
Overview
Three workflows live in .github/workflows/: checks.yml, release.yml and docs.yml. All of them run on Linux. There are no macOS GitHub Actions runners, because they cost money (owner decision, 2026-11-08). Every native build, test and release binary is made on a local Apple silicon Mac running macOS 27 or later.
checks.yml: Linux push checks
Runs on pushes that touch engine/, tests/, fixtures/, scripts/, packaging/, the Makefile, checks.yml itself or release.yml (and on manual dispatch). It has no pull-request trigger, to avoid duplicate runs. In-progress runs on the same ref are cancelled.
On Ubuntu with Python 3.12.14 it:
installs
engine/and printsrequirements. txt pip freeze;runs the engine and worker test suites, including the tests of the release-asset verifier;
runs
scripts/;verify_ fixtures. py - - repair runs
engine/;worker. py - - self- test byte-compiles the packaging scripts and syntax-checks
scripts/andbuild- macos. sh scripts/.release- macos- local. sh
release.yml: release asset verification
Runs on Linux when a GitHub Release is published, or by manual dispatch with a tag. It downloads the macOS archive and its .sha256 attached to that Release and runs scripts/, which checks:
the checksum;
that the version equals the tag;
that the archive was built from the tag's commit with a clean tree;
that the executables are arm64 with a macOS 27.0 minimum;
that the bundled helper is present.
It builds nothing and never publishes.
Making a release on a local Mac
On an Apple silicon Mac with macOS 27 or later, from a clean, pushed commit whose packaging/ CFBundleShortVersionString is the new version:
scripts/release-macos-local.sh --upload v0.1.0The script runs the full package gate (build-macos.sh), writes build/ and its .sha256, verifies them, and attaches them to the Release for the tag. If that Release does not exist yet, it is created as a draft. Without --upload it only writes the files. It uploads only to an unpublished draft that targets the same commit; to change assets after publishing, make a new version. The owner reviews and publishes the draft, then checks that release.yml passes.
No workflow signs with credentials, builds the app, creates or publishes a release, or changes repository protection.
docs.yml: documentation site
This workflow builds this documentation site. On pull requests and pushes to main that touch doc/**, it builds the site on Node.js 24 and runs check:html, check:links, and a wrangler dry run.
The site's home is https:main or a Run workflow on main; nobody deploys from a local machine. The job needs the CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID secrets; without them its deploy step skips with a warning and the job still succeeds, so a green deploy job is not proof that the site was published: check the job log. The setup guide is docs/ in the repository.