-
Notifications
You must be signed in to change notification settings - Fork 4
169 lines (152 loc) · 6.55 KB
/
Copy pathci-firecracker.yml
File metadata and controls
169 lines (152 loc) · 6.55 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
name: CI (Firecracker)
on:
workflow_dispatch:
inputs:
vm_type:
description: 'Firecracker VM image type'
required: false
default: 'focal-ci'
type: choice
options:
- focal-ci
- focal
pull_request:
paths:
- 'crates/**'
- 'Cargo.toml'
- 'Cargo.lock'
- 'terraphim_server/**'
# Cancel in-progress runs on the same branch
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
vm-infrastructure:
name: Firecracker VM lifecycle proof
# bigbox runners co-locate with fcctl-web at 127.0.0.1:8080 — must use bigbox label
runs-on: [self-hosted, bigbox]
timeout-minutes: 5
env:
FCCTL_URL: http://127.0.0.1:8080
VM_TYPE: ${{ inputs.vm_type || 'focal-ci' }}
steps:
- name: Health check fcctl-web
run: |
curl -sf --retry 3 --retry-delay 2 $FCCTL_URL/health
echo "fcctl-web is healthy"
- name: Create VM
id: vm
run: |
RESPONSE=$(curl -sf -X POST $FCCTL_URL/api/vms \
-H 'Content-Type: application/json' \
-d "{\"vm_type\": \"$VM_TYPE\"}")
echo "$RESPONSE"
VM_ID=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
if [ -z "$VM_ID" ] || [ "$VM_ID" = "null" ]; then
echo "ERROR: failed to parse vm id from response"
exit 1
fi
echo "vm_id=$VM_ID" >> $GITHUB_OUTPUT
echo "Created VM: $VM_ID"
- name: Wait for VM ready
run: |
VM_ID="${{ steps.vm.outputs.vm_id }}"
for i in $(seq 1 18); do
STATUS=$(curl -sf $FCCTL_URL/api/vms/$VM_ID \
| python3 -c "import sys,json; print(json.load(sys.stdin).get('status','unknown'))" 2>/dev/null || echo "unknown")
echo " attempt $i: status=$STATUS"
if [ "$STATUS" = "running" ]; then
echo "VM is running"
break
fi
if [ "$i" = "18" ]; then
echo "ERROR: VM did not reach running status within 90 seconds"
exit 1
fi
sleep 5
done
- name: Execute command in VM
# /api/vms/{id} returning status=running means firecracker VMM is up,
# but the in-guest sshd may still be initialising. Retry the execute
# call (which SSHes into the guest) until it returns exit_code=0 or
# until we exhaust attempts. Each retry has a short SSH timeout so a
# single failure doesn't burn the workflow timeout.
run: |
VM_ID="${{ steps.vm.outputs.vm_id }}"
PAYLOAD="{\"vm_id\":\"$VM_ID\",\"code\":\"echo vm-ok && uname -r && id\",\"language\":\"bash\",\"agent_id\":\"ci-probe-${{ github.run_id }}\",\"timeout_ms\":15000}"
for i in $(seq 1 6); do
RESULT=$(curl -sf -X POST $FCCTL_URL/api/llm/execute -H 'Content-Type: application/json' -d "$PAYLOAD" || echo '{"exit_code":-1,"stderr":"curl failed"}')
EXIT=$(echo "$RESULT" | python3 -c "import sys,json; print(json.load(sys.stdin).get('exit_code', -1))" 2>/dev/null || echo "-1")
echo "attempt $i: exit_code=$EXIT"
if [ "$EXIT" = "0" ]; then
echo "$RESULT" | python3 -m json.tool
exit 0
fi
sleep 5
done
echo "ERROR: VM did not accept SSH after 6 attempts"
echo "$RESULT" | python3 -m json.tool || echo "$RESULT"
exit 1
- name: Destroy VM
if: always()
run: |
VM_ID="${{ steps.vm.outputs.vm_id }}"
if [ -n "$VM_ID" ] && [ "$VM_ID" != "null" ]; then
curl -sf -X DELETE $FCCTL_URL/api/vms/$VM_ID && echo "VM $VM_ID destroyed" || echo "VM cleanup failed (non-fatal)"
fi
rust-build:
name: Rust build + test
# Must run on bigbox: sccache binary lives at /home/alex/.local/bin and the
# SeaweedFS S3 cache is bound to fcbr0 (172.26.0.1:8333), reachable only
# from this host. Mac runners would fail on both counts.
runs-on: [self-hosted, bigbox]
timeout-minutes: 30
# Route all rustc invocations through sccache backed by SeaweedFS S3 on
# fcbr0. See .docs/adr-rust-build-cache-seaweedfs.md. Env is applied to
# every step so cargo fmt/clippy/build/test all share the cache.
env:
RUSTC_WRAPPER: /home/alex/.local/bin/sccache
SCCACHE_BUCKET: rust-cache
SCCACHE_SERVER_PORT: "4231"
SCCACHE_ENDPOINT: http://172.26.0.1:8333
SCCACHE_S3_USE_SSL: "false"
SCCACHE_REGION: us-east-1
SCCACHE_S3_KEY_PREFIX: terraphim-ai
AWS_ACCESS_KEY_ID: any
AWS_SECRET_ACCESS_KEY: any
# sccache cannot cache incremental compilations; cargo dev profile
# defaults to incremental=true. Disable to push more rustc invocations
# through sccache. Cold-cache run showed 438 calls skipped for this
# reason. See .docs/adr-rust-build-cache-seaweedfs.md.
CARGO_INCREMENTAL: "0"
steps:
- uses: actions/checkout@v4
- name: sccache start and zero stats
run: |
/home/alex/.local/bin/sccache --start-server || true
/home/alex/.local/bin/sccache --zero-stats
# zlob is default on terraphim_file_search + terraphim_mcp_server, so
# fff-core/build.rs never hits its CI-detection panic branch and we
# don't need the old `unset CI` workaround. zig 0.16 is installed on
# bigbox; see .cargo/config.toml for the Darwin `dynamic_lookup`
# linker workaround on local Mac dev.
#
# All cargo invocations are dispatched via `rch exec --` so they
# share rchd's queue + slot accounting with ADF agents (see
# .docs/adr-rch-build-queue-not-firecracker-ci.md). Fail-open: if
# rchd is down or no slot is available, rch falls through to local
# cargo with no behaviour change.
- name: cargo fmt --check
run: /home/alex/.local/bin/rch exec -- cargo fmt -- --check
- name: cargo clippy
run: /home/alex/.local/bin/rch exec -- cargo clippy -- -D warnings
- name: cargo build --workspace
run: /home/alex/.local/bin/rch exec -- cargo build --workspace
- name: cargo test --workspace
# Only test_chat_command is skipped: it requires LLM API credentials
# not present in CI. All other failures must be fixed at the source,
# not skipped.
run: /home/alex/.local/bin/rch exec -- cargo test --workspace -- --skip test_chat_command
- name: sccache stats
if: always()
run: /home/alex/.local/bin/sccache --show-stats