Skip to content

CI/CD

Speedwave’s checks, builds, and releases all run through GitHub Actions. Workflow files live in .github/workflows/, and most pin the actions they call to a commit SHA with a version comment, for example actions/checkout@de0fac2e... # v6.0.2. The two Claude Code workflows are the exception: they use floating tags like actions/checkout@v4 instead.

test.yml runs on push and on pull requests targeting main or dev, canceling superseded runs. It has seven jobs:

JobRunnerWhat it does
lintmacos-latestRust clippy and format check, Prettier, MCP TypeScript type-check, MCP ESLint
testmacos-latestRust tests, transcription tests, MCP tests with coverage, MCP Office Python tests, entrypoint bats tests
desktopmacos-latestDesktop clippy, Angular ESLint and tests with coverage, desktop config and release-gate tests, Tauri build tests
auditubuntu-latestnpm audit for the MCP servers and desktop app, cargo audit for both Rust workspaces
swiftmacos-latestPull requests only: builds universal native macOS CLI binaries, then runs the Swift tests
runtime-windowswindows-latestRust tests for the Lima, WSL, build, and job-object modules, plus a check that shell scripts stay LF-clean on Windows checkouts
desktop-windows-checkwindows-latestCompiles the desktop app for Windows to catch Windows-only errors, without producing a full bundle

The macOS-only jobs run there because part of the Rust workspace only compiles on macOS and Windows. For what the coverage numbers mean and where the thresholds live, see testing.

desktop-build.yml runs on pull requests and on push to main and dev, only when relevant paths change: desktop code, Rust crates, MCP servers, containers. A pull request builds macOS on Apple Silicon only, while a push also covers Intel and Windows. Without a signing key, for example on a fork’s pull request, you get an unsigned bundle instead of a failed build.

release-please.yml runs on push to main and manages the release pull request, its version bump, and its tag. Merging that pull request triggers desktop-release.yml, which:

  1. Validates the version and finds the matching draft release.
  2. Builds and signs the desktop app for macOS (both architectures) and Windows, then notarizes the macOS build.
  3. Cross-compiles the CLI for macOS and Windows and attaches the archives to the release.
  4. Verifies every expected asset is present, then flips the release from draft to live. If that final check fails, the release goes back to draft.

A missing signing secret skips that step instead of failing the workflow, leaving the artifact unsigned or un-notarized. See release process for the full setup and what ships in a release.

Two more workflows keep Cargo.lock and package-lock.json current on release branches, and a backmerge workflow folds main back into dev after each release, directly or through a pull request when dev has diverged.

Two workflows guard what can merge toward a release, and you’ll meet both on any pull request into main or dev:

  • pr-title.yml checks that your pull request title follows the conventional-commit format.
  • merge-strategy-check.yml runs on pull requests to main and requires a release-triggering conventional-commit title before it lets you squash-merge, with an exemption for the automated release and backmerge pull requests.

Together these are why a merge to main reliably produces the release note and version bump you expect. See release process for how commit titles map to version bumps.

A Dependabot config manages dependency updates, and a companion workflow rebases its open pull requests after each push to main. Two Claude Code workflows also run in CI, both restricted to a fixed list of maintainers: one responds when a pull request, issue, or comment mentions @claude, and one reviews pull requests automatically in read-only mode.