Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CI and Release

Status: Current Last updated: 2026-07-07 21:20 EDT

Pre-Merge Verification

Use the concrete local verification commands from Setup and Developer Verification Checks:

cargo fmt --all -- --check
cargo build --workspace --all-targets --locked
cargo test --workspace
cargo test --doc

Then rely on GitHub Actions CI as the authoritative shared signal before you announce a change as ready.

Generated artifact drift

Generated artifacts are still important, but the old root wrappers from the predecessor workspace are not yet ported into this repo. In practice:

  • regenerate only the affected spec/symbol outputs,
  • do not hand-edit generated artifacts,
  • and run the surface-specific verification commands that match the change.

See Spec Workflow and spec/CLAUDE.md for the current source-of-truth guidance.

Release Process

TalkBank/chatter is the public release source of truth: release.yml (cargo-dist) publishes the signed GitHub Releases for the CLI and the desktop app.

Cutting a release: the two-command procedure

The version literal lives in many places (the workspace version, every internal path-dep pin, the desktop package.json, the CHANGELOG section), and the tag is the release trigger, so both steps are mechanized and fail-closed. Hand-editing version fields or tagging with raw git tag is how releases break (v0.1.1 shipped a desktop version mismatch; v0.5.0 tagged a bump commit before its CI reported and the desktop build died on drift CI would have caught). The procedure:

  1. just release-bump X.Y.Z rewrites the canonical [workspace.package] version, every path = "crates/…" pin, and package.json, then refreshes both lockfiles (root + spec/).
  2. Write the ## [X.Y.Z] CHANGELOG section (the one deliberately manual step; every gate enforces its presence).
  3. Commit and just push, then wait for CI on that commit.
  4. just release-tag X.Y.Z tags and pushes vX.Y.Z, refusing on a dirty tree, an unpushed HEAD, any version-copy drift, a missing CHANGELOG section, or CI/Cross-platform not yet green on the exact tagged commit.

After the tag: release.yml and release-desktop.yml build and publish; verify the release page carries the CLI archives, the LSP standalone artifacts, and the desktop installers before announcing.

Workflows that actually exist in this repo

WorkflowPurposeNotes
.github/workflows/ci.ymlMain build/test/book CIPrimary shared signal on pushes and PRs
.github/workflows/cross-platform.ymlCross-platform build coverageSupplements the main CI workflow
.github/workflows/crates-io-foundation.ymlFirst-wave crates.io readinessChecks foundation-crate metadata, package surfaces, hold-backs, and publish order
.github/workflows/release.ymlcargo-dist release automationBuilds dist-enabled workspace artifacts from version tags; owns the GitHub Release
.github/workflows/release-desktop.ymlDesktop installer release automationBuilds chatter-desktop installers on the same version tags and uploads them into the release that release.yml creates; workflow_dispatch runs build-only
.github/workflows/clippy-rolling.ymlNew-stable clippy drift detectionWeekly maintenance workflow

Current release stance

  • release.yml is about workspace artifact packaging via cargo-dist, not about crates.io publication.
  • The first-wave crates.io path is documented separately in Crates.io Publication and is checked by just crates-io-foundation-check plus .github/workflows/crates-io-foundation.yml.

Desktop release workflow: how the two tag workflows compose

On a version tag, release.yml (cargo-dist) and release-desktop.yml run in parallel. cargo-dist owns creating the GitHub Release and attaching the CLI archives, checksums, and installer scripts; release-desktop.yml builds the Tauri installers, then polls until the release exists and uploads its installers into it. Two platform notes baked into the workflow:

  • macOS: Tauri signs, notarizes, and staples the .app, but NOT the .dmg it wraps around it. The workflow therefore submits the .dmg itself to the notary service and staples it, then verifies codesign, spctl, and stapler validate on both artifacts. The signing identity is supplied via environment, never hardcoded in tauri.conf.json.
  • Windows / Linux: artifacts are currently unsigned by decision; see docs/strategy/distribution-and-signing.md (“Decisions, 2026-06-12”) and the SmartScreen guidance in the install docs.

Release secrets (Actions secrets on this repository)

Required by the macOS jobs of release-desktop.yml (and by cargo-dist macOS codesigning if macos-sign is enabled, which uses the separate CODESIGN_* names documented in the strategy doc):

SecretContent
APPLE_CERTIFICATEbase64-encoded Developer ID Application .p12
APPLE_CERTIFICATE_PASSWORDpassword for the .p12
APPLE_SIGNING_IDENTITYfull identity string, Developer ID Application: <Name> (<TEAMID>)
APPLE_API_KEYApp Store Connect API key ID (notarization)
APPLE_API_ISSUERApp Store Connect issuer ID
APPLE_API_KEY_CONTENTcontents of the AuthKey_*.p8 file

Rotation: replacing the certificate or notary key means updating these secrets and nothing else; no workflow edits are needed. A maintainer must re-create all of them on any new repository (secrets do not transfer).