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 modified: 2026-06-01 01:05 PDT

This is the top-level map of the CI and release surface. For per-product detail, see Release Pipeline; for code-signing posture, see Code Signing and Distribution.

Pre-merge verification

Every change must pass bazel build //... && bazel test //... before merging:

bazel build //... && bazel test //...

See Quality Gates and Testing for the full local gate definitions and the mapping into CI jobs.

The pre-push hook (scripts/pre-push.sh, installed via ln -sf ../../scripts/pre-push.sh .git/hooks/pre-push) runs the fast subset on git push.

Workflow map

flowchart LR
    subgraph PR["Per-PR (path-scoped)"]
        W1["bazel-rust.yml<br/>(ubuntu + macos-14)"]
        W2["bazel-python.yml<br/>(ubuntu + macos-14)"]
        W3["bazel-grammar.yml"]
        W4["bazel-typescript.yml"]
        W5["bazel-docs.yml"]
        W6["bazel-tauri-batchalign.yml<br/>smoke (+ bundle on main)"]
        W7["bazel-wheels.yml<br/>(4-platform matrix)"]
    end
    subgraph SCHED["Scheduled"]
        W8["bazel-build-all.yml<br/>(cron 06:00 UTC)"]
    end
    subgraph DISPATCH["workflow_dispatch"]
        W9["publish-pypi.yml"]
    end

    W9 --> PYPI[(PyPI)]
    W6 -->|"artifact, unsigned"| ART[(workflow artifacts)]
    W7 -->|"artifact (cp310-abi3)"| ART
    W4 -->|"vscode-extension-vsix artifact"| ART
    W5 -->|"book-html artifact"| ART

Verified against .github/workflows/ on 2026-06-01.

Workflows in detail

Workflow fileWorkflow nameTriggersJobs
bazel-rust.ymlbazel · rustpush/PR on Rust pathsbuild-and-test (ubuntu + macos-14)
bazel-python.ymlbazel · pythonpush/PR on Python / engine pathsbuild-and-test (ubuntu + macos-14)
bazel-grammar.ymlbazel · grammarpush/PR on grammar / symbol pathsrust-binding, generated-artifacts-fresh
bazel-typescript.ymlbazel · typescriptpush/PR on apps/vscode-extension/**, schemas/**vscode-extension
bazel-docs.ymlbazel · docspush/PR on book/**, bazel/book/**build-and-linkcheck
bazel-tauri-batchalign.ymlbazel · tauri-batchalignpush/PR/dispatch on Batchalign GUI pathssmoke (every PR), bundle (main + dispatch only; macOS arm64, macOS x86_64, Linux x86_64)
bazel-wheels.ymlbazel · wheels (PR matrix)push/PR on wheel-affecting pathsbuild (macos-14, macos-13, ubuntu, ubuntu-arm)
bazel-build-all.ymlbazel · build-all (nightly)cron 0 6 * * *, dispatchbuild-all (ubuntu + macos-14, full //...)
publish-pypi.ymlpublish · pypi (batchalign)workflow_dispatch onlyverify-version, build (5-platform matrix), publish (gated on publish=true input)

Windows is not exercised in any workflow today. The bundle matrix and the bazel-wheels.yml matrix both have Windows rows commented out (tools/bazel bash wrapper / multitool uv.exe layout, respectively).

Generated artifact freshness

The grammar’s generated artifacts (grammar/src/parser.c, grammar/src/grammar.json, grammar/src/node-types.json) are checked by bazel-grammar.yml’s generated-artifacts-fresh job. If they drift, regenerate locally:

cd grammar && tree-sitter generate
git diff grammar/src/parser.c grammar/src/grammar.json grammar/src/node-types.json
git add grammar/src/ && git commit -m "grammar: regenerate"

Spec-driven artifacts (tree-sitter corpus tests, generated Rust parser tests, error docs) are regenerated by:

just spec gen-tree-sitter-tests && just spec gen-rust-tests && just spec gen-error-docs
git diff --exit-code

Spec drift is not enforced by a dedicated CI job today; it’s caught by the per-package test jobs failing when generated tests don’t match generated source.

Release process, per surface

Only one surface has a fully automated release workflow today (batchalign → PyPI). The rest are either workflow-artifact-only or hand-published. Full per-surface narrative lives in Release Pipeline. Summary:

SurfaceBuild in CIRelease path todayGap
batchalign PyPI wheelbazel-python.yml + bazel-wheels.ymlpublish-pypi.yml (workflow_dispatch, OIDC trusted publisher)none for PyPI
chatter / chatter-lspbazel-rust.yml, nightly bazel-build-all.ymlNone — install from sourceNo release workflow
VS Code extension .vsixbazel-typescript.yml (artifact only)Manual vsce publish from operator workstationNo automated marketplace workflow
Batchalign desktop bundlebazel-tauri-batchalign.yml bundle job (main + dispatch)Workflow artifacts only; unsigned; macOS + LinuxNo GitHub Release upload; no Windows; no signing
Chatter desktop GUINightly bazel-build-all.yml onlyNoneNo CI bundle target; no release
mdBookbazel-docs.yml (artifact only)NoneNo GitHub Pages deploy

Promoting a surface

When automating a release for any surface above:

  1. Run the relevant per-PR workflow on a clean main and confirm green.
  2. Update the canonical version source for that surface (just versions to inspect — current values: batchalign wheel 0.3.0, Rust workspace 0.2.0, batchalign-engine 0.3.0, Chatter GUI bundle 0.1.0).
  3. Add the publish workflow alongside (e.g. a publish-chatter.yml modelled on publish-pypi.yml).
  4. Update Release Pipeline, Release Contract, and Code Signing and Distribution in the same patch.

First-release release-ops guardrails

  • VS Code stays manual-publish until a release workflow exists. Do not add marketplace-claiming language to install docs until automation lands.
  • Desktop bundles are unsigned. Any download instructions must mark them as “unsigned development build”. See Code Signing and Distribution.
  • publish-pypi.yml is the only publish workflow. Treat any reference to release.yml, vscode-release.yml, batchalign-release.yml, batchalign-desktop.yml, publish-chatter.yml, publish-vscode.yml, or publish-desktop.yml in older docs as obsolete — those workflows do not exist.

Cross-repo testing

After changes to core crates, verify the downstream consumer locally:

# batchalign (Python + Rust)
cd /path/to/batchalign
uv run maturin develop    # Rebuild Rust extension
uv run pytest

CLI, LSP, and CLAN coverage runs as part of bazel test //....