1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
name: ci
on:
push:
branches:
pull_request:
branches:
# Nightly run of the hardening harness — gated by the `hardening` job's `if:` below.
schedule:
- cron: "0 4 * * *"
workflow_dispatch:
# Cancel superseded runs on the same ref — fresher pushes win.
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
test:
name: test / ${{ matrix.os }} / ${{ matrix.features }}
runs-on: ${{ matrix.os }}
# Per-leg backstop against a hung test (e.g. a Windows IPC deadlock) running to the 6h
# default — on main, concurrency is queue-not-cancel, so a 6h hang blocks every subsequent
# run. Windows stays tight (its build is light; the budget guards the comms hang); the heavy
# `full` builds (ONNX / kreuzberg / lance) get a generous ceiling so a cold cache compile is
# never mistaken for a hang.
timeout-minutes: ${{ matrix.timeout_minutes }}
strategy:
fail-fast: false
matrix:
include:
# Unix: default-features + full-features builds.
- os: ubuntu-latest
features: ''
timeout_minutes: 30
- os: ubuntu-latest
features: 'full'
timeout_minutes: 60
- os: macos-latest
features: ''
timeout_minutes: 30
- os: macos-latest
features: 'full'
timeout_minutes: 90
# Windows: comms+shells only (no heavy doc deps that require system libs).
- os: windows-latest
features: 'comms shells'
timeout_minutes: 30
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
# System dependencies for the full feature surface (image libs, tesseract, protoc, onnx runtime).
# Skipped for default-features builds and Windows (which uses comms+shells instead).
- name: Install system dependencies
if: matrix.features == 'full'
uses: ./.github/actions/install-system-deps
# protoc is required by lance-encoding's build script (transitive via the
# `full` feature). Install on default-features too for uniformity.
- name: Install protoc (Linux, default-features)
if: runner.os == 'Linux' && matrix.features == ''
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler
- name: Install protoc (macOS, default-features)
if: runner.os == 'macOS' && matrix.features == ''
run: brew install protobuf
- uses: Swatinem/rust-cache@v2
with:
# Differentiate caches per-OS and features so the cache key is stable across runs.
key: ${{ matrix.os }}-${{ matrix.features }}
- name: cargo fmt
run: cargo fmt --all --check
- name: cargo clippy
run: cargo clippy --workspace --all-targets --tests --features "${{ matrix.features }}" -- -D warnings
- name: cargo test
run: cargo test --workspace --features "${{ matrix.features }}" --quiet
- name: cargo build --release
run: cargo build --release --quiet --bin basemind --features "${{ matrix.features }}"
deny:
name: cargo-deny
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: EmbarkStudios/cargo-deny-action@v2
with:
# Uses deny.toml at the repo root.
command: check
# Real-OSS hardening harness. Clones large upstream repos and exercises every MCP tool
# against them — too heavy for per-PR but ideal as a nightly canary. Runs on manual
# dispatch and once a day.
hardening:
name: hardening harness (nightly)
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event_name == 'schedule'
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
# System dependencies for the `full` feature surface that harden.sh builds.
# Consolidated in the composite action; includes protoc, tesseract, libheif build from source.
- name: Install system dependencies
uses: ./.github/actions/install-system-deps
- uses: Swatinem/rust-cache@v2
- name: run harden.sh
run: ./scripts/harden.sh
- name: upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: harden-results
path: /tmp/basemind-harden/results.ndjson