Skip to content

Commit a291ce4

Browse files
authored
Merge pull request #67 from google/restore/main-history
chore: restore main history
2 parents 92fa3bd + 6e33f3b commit a291ce4

1,057 files changed

Lines changed: 168983 additions & 66256 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.codex/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../skills

.cursor/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../skills

.gemini/skills

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../skills

.github/workflows/ci.yaml

Lines changed: 103 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,63 +7,69 @@ on:
77
permissions:
88
contents: read
99

10+
env:
11+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
12+
1013
jobs:
1114
# ---------------------------------------------------------------------------
12-
# Linux: compile + test KVM hypervisor backend (cfg(target_os = "linux"))
15+
# Linux: compile KVM hypervisor backend (cfg(target_os = "linux"))
1316
# ---------------------------------------------------------------------------
1417
test-linux:
1518
runs-on: ubuntu-24.04-arm
19+
env:
20+
# Hosted ARM runners can expose /dev/kvm but hang in nested/restricted
21+
# KVM ioctls. PR CI compiles the Linux KVM backend and test binaries.
22+
# The release pipeline owns real-KVM coverage.
23+
CAPSEM_SKIP_KVM_TESTS: "1"
1624
steps:
1725
- uses: actions/checkout@v5
1826

1927
- uses: dtolnay/rust-toolchain@stable
2028
with:
2129
components: llvm-tools
2230

23-
- uses: Swatinem/rust-cache@v2
31+
- name: Normalize cargo proxy
32+
run: bash scripts/ci/normalize-cargo.sh
2433

25-
# Try to enable KVM for integration tests. GitHub-hosted runners don't
26-
# always expose nested virt -- when /dev/kvm is absent the udev trigger
27-
# fails with "Failed to open the device 'kvm': Invalid argument". We
28-
# let that pass and fall through to a compile-only/no-KVM run; the
29-
# release pipeline owns real-KVM coverage. See sprints/done/ci-green.
30-
- name: Enable KVM (best-effort)
31-
continue-on-error: true
32-
run: |
33-
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
34-
sudo udevadm control --reload-rules
35-
sudo udevadm trigger --name-match=kvm
34+
- uses: Swatinem/rust-cache@v2
3635

37-
- name: Install tools
36+
# Collect KVM diagnostics only. GitHub-hosted runners don't always expose
37+
# nested virt -- and when they do, restricted ioctls can hang. PR CI
38+
# compiles the KVM backend with CAPSEM_SKIP_KVM_TESTS=1; the release
39+
# pipeline owns real-KVM coverage.
40+
- name: Collect KVM diagnostics
3841
run: |
39-
cargo install cargo-nextest --locked
40-
cargo install cargo-llvm-cov --locked
42+
if echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules >/dev/null; then
43+
sudo udevadm control --reload-rules || echo "::notice::udev reload failed; keeping KVM diagnostics non-blocking"
44+
sudo udevadm trigger --name-match=kvm || echo "::notice::udev trigger failed; keeping KVM diagnostics non-blocking"
45+
else
46+
echo "::notice::could not write KVM udev rule; keeping KVM diagnostics non-blocking"
47+
fi
48+
if [ -e /dev/kvm ]; then
49+
ls -l /dev/kvm
50+
else
51+
echo "::notice::/dev/kvm is not present on this runner"
52+
fi
4153
42-
# Library + service crate tests with coverage (capsem-core includes KVM backend on Linux).
54+
# Compile Linux library + service crate tests without executing them. The
55+
# macOS job owns runtime unit coverage for portable code; this job proves
56+
# the Linux-only/KVM cfg surface and test binaries compile on aarch64.
4357
# capsem-app (Tauri shell) and capsem-tray (macOS muda menu-bar) are macOS-only; every
44-
# other host crate is portable and runs here so it gets Linux-specific regression coverage.
45-
- name: Unit tests (KVM backend) with coverage
58+
# other host crate is portable and compiles here for Linux-specific regression coverage.
59+
- name: Compile tests (KVM backend, no live KVM)
60+
timeout-minutes: 15
4661
run: |
47-
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-linux.json --fail-under-lines 70 -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-process
48-
cargo llvm-cov report --no-cfg-coverage --summary-only -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-process 2>&1 | tee coverage-summary-linux.txt
62+
cargo test --no-run --all-targets -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-process
4963
50-
- name: Upload Linux coverage
51-
if: ${{ !cancelled() }}
52-
uses: codecov/codecov-action@v5
53-
with:
54-
files: codecov-linux.json
55-
flags: linux-unit
56-
token: ${{ secrets.CODECOV_TOKEN }}
57-
fail_ci_if_error: false
58-
59-
# Note KVM exercise status. Hosted ARM runners may lack /dev/kvm; the
60-
# compile-only path still catches Linux build/lint regressions, and
61-
# real-KVM coverage runs in the release pipeline. Surfacing as a
62-
# warning (not an error) keeps CI honest about what was actually
63-
# exercised without false-failing on a runner-fleet limitation.
64+
# Note KVM exercise status. Hosted ARM runners may lack /dev/kvm or
65+
# expose restricted nested KVM; PR CI keeps this compile/no-run and
66+
# release CI owns live-KVM coverage. Surfacing as a warning keeps CI
67+
# honest without false-failing or hanging on a runner-fleet limitation.
6468
- name: Note KVM exercise status
6569
run: |
66-
if [ -e /dev/kvm ]; then
70+
if [ "${CAPSEM_SKIP_KVM_TESTS:-}" = "1" ]; then
71+
echo "::warning::CAPSEM_SKIP_KVM_TESTS=1 -- PR CI compiled the KVM backend but did not exercise live KVM. Real-KVM coverage runs in release pipeline."
72+
elif [ -e /dev/kvm ]; then
6773
echo "KVM is available at /dev/kvm -- KVM-backed tests exercised."
6874
else
6975
echo "::warning::/dev/kvm not available on this runner -- compile + non-KVM tests only. Real-KVM coverage runs in release pipeline."
@@ -73,18 +79,20 @@ jobs:
7379
if: always()
7480
run: |
7581
KVM_STATUS="available"
76-
[ -e /dev/kvm ] || KVM_STATUS="not available"
77-
COV=$(grep 'TOTAL' coverage-summary-linux.txt 2>/dev/null | awk '{print $(NF)}' || echo "?")
78-
82+
if [ "${CAPSEM_SKIP_KVM_TESTS:-}" = "1" ]; then
83+
KVM_STATUS="skipped in PR CI"
84+
elif [ ! -e /dev/kvm ]; then
85+
KVM_STATUS="not available"
86+
fi
7987
cat >> "$GITHUB_STEP_SUMMARY" << EOF
8088
## Linux Test Results
8189
8290
| Metric | Result |
8391
|--------|--------|
8492
| Runner | ubuntu-24.04-arm (aarch64) |
8593
| /dev/kvm | $KVM_STATUS |
86-
| Line coverage | $COV |
87-
| KVM backend | compiled (real-KVM tests run only when /dev/kvm is present) |
94+
| Test execution | no-run in PR CI |
95+
| KVM backend | compiled with test binaries (real-KVM tests run in release pipeline) |
8896
EOF
8997
9098
# T5: preserve test artifacts on failure (Linux job).
@@ -96,6 +104,7 @@ jobs:
96104
path: |
97105
test-artifacts/
98106
frontend/test-artifacts/
107+
target/build.log
99108
retention-days: 7
100109
if-no-files-found: ignore
101110

@@ -112,6 +121,9 @@ jobs:
112121
targets: aarch64-unknown-linux-musl,x86_64-unknown-linux-musl
113122
components: llvm-tools
114123

124+
- name: Normalize cargo proxy
125+
run: bash scripts/ci/normalize-cargo.sh
126+
115127
- uses: Swatinem/rust-cache@v2
116128

117129
- uses: pnpm/action-setup@v5
@@ -127,6 +139,9 @@ jobs:
127139
- uses: astral-sh/setup-uv@v5
128140
- run: uv sync
129141

142+
- name: Normalize cargo proxy after Python setup
143+
run: bash scripts/ci/normalize-cargo.sh
144+
130145
- name: Dependency audit
131146
run: |
132147
cargo install cargo-audit --locked
@@ -138,18 +153,24 @@ jobs:
138153
cargo install cargo-llvm-cov --locked
139154
cargo install cargo-nextest --locked
140155
156+
- name: Create frontend dist for Tauri test build
157+
run: |
158+
mkdir -p frontend/dist
159+
printf '<!doctype html><html><body></body></html>\n' > frontend/dist/index.html
160+
141161
# Unit tests: all crates with coverage + JUnit XML for test analytics.
142162
# capsem-app (Tauri bin) is macOS-only; capsem-mcp-aggregator and
143163
# capsem-mcp-builtin are thin binaries that pull capsem-core logic.
144164
- name: Unit tests with coverage
145165
run: |
146-
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-unit.json --fail-under-lines 70 -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-tray -p capsem-app -p capsem-process
147-
cargo llvm-cov report --no-cfg-coverage --summary-only -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-tray -p capsem-app -p capsem-process 2>&1 | tee coverage-summary.txt
166+
set -o pipefail
167+
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-unit.json --fail-under-lines 65 -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-tray -p capsem-app -p capsem-process
168+
cargo llvm-cov report --summary-only -p capsem-core -p capsem-agent -p capsem-logger -p capsem-proto -p capsem-guard -p capsem-gateway -p capsem-service -p capsem -p capsem-mcp -p capsem-mcp-aggregator -p capsem-mcp-builtin -p capsem-tray -p capsem-app -p capsem-process 2>&1 | tee coverage-summary.txt
148169
149170
# Integration tests (tests/ directory, cross-crate)
150171
- name: Integration tests with coverage
151172
run: |
152-
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-integration.json -p capsem-core --test '*' || true
173+
cargo llvm-cov nextest --no-cfg-coverage --profile ci --codecov --output-path codecov-integration.json -p capsem-core --test '*'
153174
154175
# Frontend tests with coverage + JUnit output
155176
- name: Frontend type-check, test, and build
@@ -161,12 +182,15 @@ jobs:
161182
162183
# Python schema tests with coverage
163184
- name: Python schema tests with coverage
164-
run: uv run python -m pytest tests/ --cov=src/capsem --cov-report=xml:codecov-python.xml --cov-fail-under=90 --junitxml=python-junit.xml
185+
run: uv run python -m pytest tests/test_*.py --cov=src/capsem --cov-report=xml:codecov-python.xml --cov-fail-under=89 --junitxml=python-junit.xml
165186

166-
# Python integration tests that need no VM
187+
# Python integration tests that need no VM and no generated assets.
188+
# Bootstrap/codesign suites are artifact-dependent: full `just test`
189+
# runs them after assets and signed host binaries exist, while this PR
190+
# lane import-collects them below to catch syntax/fixture drift.
167191
- name: Python integration tests (non-VM suites)
168192
run: |
169-
uv run python -m pytest tests/capsem-bootstrap/ tests/capsem-codesign/ tests/capsem-rootfs-artifacts/ -v --tb=short
193+
uv run python -m pytest tests/capsem-rootfs-artifacts/ -v --tb=short
170194
171195
# Verify all integration test suites import cleanly (catches broken imports/syntax)
172196
- name: Verify all integration test imports
@@ -219,10 +243,11 @@ jobs:
219243
# Upload test results for test analytics
220244
- name: Upload test results to Codecov
221245
if: ${{ !cancelled() }}
222-
uses: codecov/test-results-action@v1
246+
uses: codecov/codecov-action@v5
223247
with:
224248
files: target/nextest/ci/junit.xml,frontend-junit.xml,python-junit.xml
225249
token: ${{ secrets.CODECOV_TOKEN }}
250+
report_type: test_results
226251

227252
# T5: preserve every test artifact (service.log / process.log /
228253
# session.db etc.) on failure so PR reviewers can debug without
@@ -237,11 +262,15 @@ jobs:
237262
path: |
238263
test-artifacts/
239264
frontend/test-artifacts/
265+
target/build.log
240266
retention-days: 7
241267
if-no-files-found: ignore
242268

243269
# Check-only (no link) -- actual cross-compile runs on Linux in release workflow
244270
- name: Cross-compile check (guest binaries)
271+
# Keep release-profile checks on PR validation, but skip them on
272+
# post-merge pushes to main.
273+
if: ${{ github.event_name == 'pull_request' }}
245274
run: |
246275
cargo check --release --target aarch64-unknown-linux-musl -p capsem-agent
247276
cargo check --release --target x86_64-unknown-linux-musl -p capsem-agent
@@ -273,8 +302,34 @@ jobs:
273302
steps:
274303
- uses: actions/checkout@v5
275304

305+
- uses: dtolnay/rust-toolchain@stable
306+
with:
307+
targets: aarch64-unknown-linux-musl
308+
components: llvm-tools
309+
310+
- name: Normalize cargo proxy
311+
run: bash scripts/ci/normalize-cargo.sh
312+
276313
- uses: extractions/setup-just@v3
277314

315+
- uses: pnpm/action-setup@v5
316+
with:
317+
version: 10
318+
- uses: actions/setup-node@v5
319+
with:
320+
node-version: 24
321+
322+
- uses: astral-sh/setup-uv@v5
323+
- run: uv sync
324+
325+
- name: Install install-test host tools
326+
run: |
327+
sudo apt-get update
328+
sudo apt-get install -y --no-install-recommends b3sum minisign
329+
330+
- name: Build install VM assets
331+
run: bash scripts/build-assets.sh --profile config/profiles/base/coding.profile.toml --assets-dir assets --arch arm64
332+
278333
- name: Build host builder Docker image
279334
run: just build-host-image
280335

.github/workflows/docs.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
deployments: write
1515

1616
env:
17+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
1718
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
1819
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
1920
steps:

0 commit comments

Comments
 (0)