Skip to content

Commit 9d57315

Browse files
authored
Merge branch 'main' into fix-incluster-manager-workspace-sync
2 parents 0f71e10 + 14ac630 commit 9d57315

File tree

2 files changed

+153
-51
lines changed

2 files changed

+153
-51
lines changed

.github/workflows/test-integration.yml

Lines changed: 116 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -37,31 +37,36 @@ on:
3737
required: false
3838
default: ''
3939
worker_runtime:
40-
description: 'Worker runtime to use'
40+
description: 'Worker runtime to use (both = run openclaw and copaw in parallel)'
4141
required: false
4242
type: choice
4343
options:
44+
- both
4445
- openclaw
4546
- copaw
46-
default: 'openclaw'
47+
default: 'both'
4748
model:
4849
description: 'LLM model to use'
4950
required: false
5051
default: 'qwen3.5-plus'
5152

5253
env:
53-
# Tests that do not require a GitHub token, split into two shards for parallel execution
54+
# Tests that do not require a GitHub token, split into four shards for parallel execution
5455
# Shard A: LLM interaction tests (sequential dependency: 02 creates alice → 03-06 use alice)
55-
# Shard B: Controller/CR tests (independent, no cross-test dependencies)
56-
SHARD_A_TESTS: "01 02 03 04 05 06 100"
57-
SHARD_B_TESTS: "14 15 17 18 19 20"
58-
NON_GITHUB_TESTS: "01 02 03 04 05 06 14 15 17 18 19 20 100"
56+
# Shard B: LLM interaction tests 2 (task assignment with LLM)
57+
# Shard C: Controller/CR tests (independent, no cross-test dependencies)
58+
# Shard D: Controller/CR tests 2 (team project DAG)
59+
SHARD_A_TESTS: "01 02 03 04 05 06"
60+
SHARD_B_TESTS: "14"
61+
SHARD_C_TESTS: "15 17 18 19 20 100"
62+
SHARD_D_TESTS: "21"
63+
NON_GITHUB_TESTS: "01 02 03 04 05 06 14 15 17 18 19 20 21 100"
5964

6065
jobs:
61-
# Build all images once, shared across test shards
62-
build:
66+
# Step 1: Build the shared base image (hiclaw-controller)
67+
build-base:
6368
runs-on: ubuntu-latest
64-
timeout-minutes: 30
69+
timeout-minutes: 15
6570
steps:
6671
- name: Free Up Disk Space
6772
uses: jlumbroso/free-disk-space@main
@@ -82,34 +87,80 @@ jobs:
8287
- name: Set up Docker Buildx
8388
uses: docker/setup-buildx-action@v3
8489

85-
- name: Build images
86-
env:
87-
HICLAW_MANAGER_RUNTIME: ${{ inputs.worker_runtime || 'openclaw' }}
90+
- name: Build hiclaw-controller
91+
run: make build-hiclaw-controller DOCKER_BUILD_ARGS="--build-arg APT_MIRROR="
92+
93+
- name: Save image
8894
run: |
89-
if [ "${HICLAW_MANAGER_RUNTIME}" = "copaw" ]; then
90-
make build-embedded build-manager-copaw build-worker build-copaw-worker \
91-
DOCKER_BUILD_ARGS="--build-arg APT_MIRROR="
92-
else
93-
make build-embedded build-manager build-worker build-copaw-worker \
94-
DOCKER_BUILD_ARGS="--build-arg APT_MIRROR="
95-
fi
95+
docker save hiclaw/hiclaw-controller:latest | gzip > /tmp/hiclaw-controller.tar.gz
96+
97+
- name: Upload image
98+
uses: actions/upload-artifact@v4
99+
with:
100+
name: image-controller
101+
path: /tmp/hiclaw-controller.tar.gz
102+
retention-days: 1
103+
104+
# Step 2: Build downstream images in parallel (all depend on hiclaw-controller)
105+
build-images:
106+
needs: build-base
107+
runs-on: ubuntu-latest
108+
timeout-minutes: 20
109+
strategy:
110+
fail-fast: false
111+
matrix:
112+
target: [embedded, manager, manager-copaw, worker, copaw-worker]
113+
steps:
114+
- name: Free Up Disk Space
115+
uses: jlumbroso/free-disk-space@main
116+
with:
117+
tool-cache: false
118+
android: true
119+
dotnet: true
120+
haskell: true
121+
large-packages: true
122+
swap-storage: true
96123

97-
- name: Save images
124+
- name: Checkout code
125+
uses: actions/checkout@v4
126+
with:
127+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
128+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
129+
130+
- name: Set up Docker Buildx
131+
uses: docker/setup-buildx-action@v3
132+
133+
- name: Download controller image
134+
uses: actions/download-artifact@v4
135+
with:
136+
name: image-controller
137+
path: /tmp
138+
139+
- name: Load controller image
140+
run: gunzip -c /tmp/hiclaw-controller.tar.gz | docker load
141+
142+
- name: Build image
143+
run: make build-${{ matrix.target }} DOCKER_BUILD_ARGS="--build-arg APT_MIRROR="
144+
145+
- name: Save image
98146
run: |
99147
docker save \
100-
$(docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^hiclaw/' | grep -v '<none>') \
101-
| gzip > /tmp/hiclaw-images.tar.gz
148+
$(docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^hiclaw/' | grep -v '<none>' | grep -v 'hiclaw-controller') \
149+
| gzip > /tmp/hiclaw-${{ matrix.target }}.tar.gz
102150
103-
- name: Upload images artifact
151+
- name: Upload image
104152
uses: actions/upload-artifact@v4
105153
with:
106-
name: hiclaw-images
107-
path: /tmp/hiclaw-images.tar.gz
154+
name: image-${{ matrix.target }}
155+
path: /tmp/hiclaw-${{ matrix.target }}.tar.gz
108156
retention-days: 1
109157

110-
# Run test shards in parallel, each on its own runner with isolated cluster
158+
# Step 3: Run test shards in parallel, each on its own runner with isolated cluster
111159
integration-tests:
112-
needs: build
160+
needs: build-images
161+
if: >-
162+
inputs.worker_runtime == '' || inputs.worker_runtime == 'both'
163+
|| inputs.worker_runtime == matrix.runtime
113164
runs-on: ubuntu-latest
114165
timeout-minutes: 90
115166
permissions:
@@ -122,8 +173,28 @@ jobs:
122173
include:
123174
- shard: llm-interaction
124175
filter_env: SHARD_A_TESTS
176+
runtime: openclaw
177+
- shard: llm-interaction-2
178+
filter_env: SHARD_B_TESTS
179+
runtime: openclaw
125180
- shard: controller-cr
181+
filter_env: SHARD_C_TESTS
182+
runtime: openclaw
183+
- shard: controller-cr-2
184+
filter_env: SHARD_D_TESTS
185+
runtime: openclaw
186+
- shard: llm-interaction
187+
filter_env: SHARD_A_TESTS
188+
runtime: copaw
189+
- shard: llm-interaction-2
126190
filter_env: SHARD_B_TESTS
191+
runtime: copaw
192+
- shard: controller-cr
193+
filter_env: SHARD_C_TESTS
194+
runtime: copaw
195+
- shard: controller-cr-2
196+
filter_env: SHARD_D_TESTS
197+
runtime: copaw
127198

128199
steps:
129200
- name: Free Up Disk Space
@@ -142,14 +213,17 @@ jobs:
142213
ref: ${{ github.event.pull_request.head.sha || github.sha }}
143214
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
144215

145-
- name: Download pre-built images
216+
- name: Download all images
146217
uses: actions/download-artifact@v4
147218
with:
148-
name: hiclaw-images
149-
path: /tmp
219+
pattern: image-*
220+
path: /tmp/images
150221

151222
- name: Load images
152-
run: gunzip -c /tmp/hiclaw-images.tar.gz | docker load
223+
run: |
224+
for f in /tmp/images/image-*/*.tar.gz; do
225+
gunzip -c "$f" | docker load
226+
done
153227
154228
- name: Install dependencies
155229
run: sudo apt-get update && sudo apt-get install -y jq curl unzip
@@ -160,7 +234,7 @@ jobs:
160234
HICLAW_LLM_API_KEY: ${{ secrets.HICLAW_LLM_API_KEY }}
161235
HICLAW_LLM_PROVIDER: qwen
162236
HICLAW_DEFAULT_MODEL: ${{ inputs.model || 'qwen3.5-plus' }}
163-
HICLAW_MANAGER_RUNTIME: ${{ inputs.worker_runtime || 'openclaw' }}
237+
HICLAW_MANAGER_RUNTIME: ${{ matrix.runtime }}
164238
run: |
165239
FILTER="${{ github.event.inputs.test_filter }}"
166240
if [ -z "$FILTER" ]; then
@@ -174,7 +248,7 @@ jobs:
174248
# ============================================================
175249

176250
- name: Download latest release baseline
177-
if: github.event_name == 'pull_request_target' && matrix.shard == 'llm-interaction'
251+
if: github.event_name == 'pull_request_target' && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
178252
continue-on-error: true
179253
run: |
180254
mkdir -p baseline-metrics
@@ -194,7 +268,7 @@ jobs:
194268
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
195269

196270
- name: Generate metrics comparison and post PR comment
197-
if: github.event_name == 'pull_request_target' && matrix.shard == 'llm-interaction'
271+
if: github.event_name == 'pull_request_target' && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
198272
env:
199273
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
200274
run: |
@@ -281,7 +355,7 @@ jobs:
281355
DEBUG_TAIL=$(find "$DEBUG_DIR" -name "*.log" -exec tail -20 {} + 2>/dev/null | tail -80)
282356
fi
283357
284-
BODY="## ❌ Integration Tests Failed (${{ matrix.shard }})
358+
BODY="## ❌ Integration Tests Failed (${{ matrix.shard }} / ${{ matrix.runtime }})
285359
286360
**Commit:** ${{ github.event.pull_request.head.sha }}
287361
**Workflow run:** [#${{ github.run_number }}](${ARTIFACT_URL})
@@ -309,7 +383,7 @@ jobs:
309383
310384
# Update or create comment
311385
EXISTING=$(gh api "repos/$REPO/issues/$PR_NUM/comments" \
312-
--jq '.[] | select(.body | startswith("## ❌ Integration Tests Failed (${{ matrix.shard }})")) | .id' | head -1)
386+
--jq '.[] | select(.body | startswith("## ❌ Integration Tests Failed (${{ matrix.shard }} / ${{ matrix.runtime }})")) | .id' | head -1)
313387
if [ -n "$EXISTING" ]; then
314388
gh api --method PATCH "repos/$REPO/issues/comments/$EXISTING" -f body="$BODY"
315389
else
@@ -327,7 +401,7 @@ jobs:
327401
if: always()
328402
uses: actions/upload-artifact@v4
329403
with:
330-
name: test-artifacts-${{ matrix.shard }}-${{ github.sha }}
404+
name: test-artifacts-${{ matrix.shard }}-${{ matrix.runtime }}-${{ github.sha }}
331405
path: test-artifacts/
332406
retention-days: 7
333407

@@ -336,7 +410,7 @@ jobs:
336410
# ============================================================
337411

338412
- name: Generate release baseline
339-
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction'
413+
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
340414
run: |
341415
source tests/lib/agent-metrics.sh
342416
TEST_NAMES=$(echo "$NON_GITHUB_TESTS" | tr ' ' '\n' | while read n; do
@@ -348,7 +422,7 @@ jobs:
348422
cat metrics-baseline.json | jq '{totals: .totals, by_role: .by_role}'
349423
350424
- name: Upload baseline to release
351-
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction'
425+
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
352426
env:
353427
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
354428
run: |
@@ -357,7 +431,7 @@ jobs:
357431
echo "✅ Baseline uploaded to release ${GITHUB_REF_NAME}"
358432
359433
- name: Upload debug log to release
360-
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && always()
434+
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw' && always()
361435
continue-on-error: true
362436
env:
363437
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -379,7 +453,7 @@ jobs:
379453
echo "### Integration Test Summary" >> $GITHUB_STEP_SUMMARY
380454
echo "- Shard: \`${{ matrix.shard }}\`" >> $GITHUB_STEP_SUMMARY
381455
echo "- Tests: \`${{ env[matrix.filter_env] }}\`" >> $GITHUB_STEP_SUMMARY
382-
echo "- Worker Runtime: \`${{ inputs.worker_runtime || 'openclaw' }}\`" >> $GITHUB_STEP_SUMMARY
456+
echo "- Worker Runtime: \`${{ matrix.runtime }}\`" >> $GITHUB_STEP_SUMMARY
383457
echo "- Model: \`${{ inputs.model || 'qwen3.5-plus' }}\`" >> $GITHUB_STEP_SUMMARY
384458
echo "- Install Mode: embedded (make test-embedded)" >> $GITHUB_STEP_SUMMARY
385459

tests/lib/agent-metrics.sh

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,26 @@ export METRICS_THRESHOLD_WORKER_TOKENS_OUTPUT="${METRICS_THRESHOLD_WORKER_TOKENS
3232
# Output directory for metrics files
3333
export TEST_OUTPUT_DIR="${TEST_OUTPUT_DIR:-${PROJECT_ROOT:-.}/tests/output}"
3434

35+
# ============================================================
36+
# Runtime-aware Session Path Detection
37+
# ============================================================
38+
39+
# Detect session directory for a given container based on its runtime.
40+
# Usage: _detect_session_dir <container> <base_workspace_dir>
41+
# Output: session directory path (e.g. /root/manager-workspace/.openclaw/agents/main/sessions)
42+
_detect_session_dir() {
43+
local container="$1"
44+
local base_dir="$2"
45+
local runtime
46+
runtime=$(docker exec "$container" printenv HICLAW_MANAGER_RUNTIME 2>/dev/null || echo "openclaw")
47+
48+
if [ "$runtime" = "copaw" ]; then
49+
echo "${base_dir}/.copaw/sessions"
50+
else
51+
echo "${base_dir}/.openclaw/agents/main/sessions"
52+
fi
53+
}
54+
3555
# ============================================================
3656
# Session JSONL Parsing
3757
# ============================================================
@@ -155,7 +175,8 @@ wait_for_worker_session_stable() {
155175
local stable_seconds="${2:-5}"
156176
local max_wait="${3:-120}"
157177
local container="hiclaw-worker-${worker}"
158-
local session_dir="/root/hiclaw-fs/agents/${worker}/.openclaw/agents/main/sessions"
178+
local session_dir
179+
session_dir=$(_detect_session_dir "$container" "/root/hiclaw-fs/agents/${worker}")
159180

160181
if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${container}$"; then
161182
log_info "Worker '${worker}' container not running, skipping session wait" >&2
@@ -201,7 +222,8 @@ wait_for_session_stable() {
201222
local stable_seconds="${1:-5}"
202223
local max_wait="${2:-60}"
203224
local manager_container="${TEST_AGENT_CONTAINER:-${TEST_CONTROLLER_CONTAINER:-hiclaw-manager}}"
204-
local manager_session_dir="/root/manager-workspace/.openclaw/agents/main/sessions"
225+
local manager_session_dir
226+
manager_session_dir=$(_detect_session_dir "$manager_container" "/root/manager-workspace")
205227

206228
log_info "Waiting for Manager session to stabilize (up to ${max_wait}s)..." >&2
207229

@@ -248,7 +270,8 @@ snapshot_baseline() {
248270
local workers=("$@")
249271

250272
local manager_container="${TEST_AGENT_CONTAINER:-${TEST_CONTROLLER_CONTAINER:-hiclaw-manager}}"
251-
local manager_session_dir="/root/manager-workspace/.openclaw/agents/main/sessions"
273+
local manager_session_dir
274+
manager_session_dir=$(_detect_session_dir "$manager_container" "/root/manager-workspace")
252275

253276
local snapshot_result='{"offsets": {}}'
254277

@@ -269,7 +292,8 @@ snapshot_baseline() {
269292
# Snapshot all Worker session files
270293
for worker in "${workers[@]}"; do
271294
local worker_container="hiclaw-worker-${worker}"
272-
local worker_session_dir="/root/hiclaw-fs/agents/${worker}/.openclaw/agents/main/sessions"
295+
local worker_session_dir
296+
worker_session_dir=$(_detect_session_dir "$worker_container" "/root/hiclaw-fs/agents/${worker}")
273297

274298
if ! docker ps --format '{{.Names}}' 2>/dev/null | grep -q "^${worker_container}$"; then
275299
continue
@@ -383,7 +407,8 @@ collect_delta_metrics() {
383407
local workers=("$@")
384408

385409
local manager_container="${TEST_AGENT_CONTAINER:-${TEST_CONTROLLER_CONTAINER:-hiclaw-manager}}"
386-
local manager_session_dir="/root/manager-workspace/.openclaw/agents/main/sessions"
410+
local manager_session_dir
411+
manager_session_dir=$(_detect_session_dir "$manager_container" "/root/manager-workspace")
387412

388413
# Initialize result structure
389414
local delta_result='{"test_name": "'"${test_name}"'", "timestamp": "'"$(date -Iseconds)"'", "agents": {}, "totals": {"llm_calls": 0, "tokens": {"input": 0, "output": 0, "cache_read": 0, "cache_write": 0, "total": 0}, "timing": {"duration_seconds": 0}}}'
@@ -402,7 +427,8 @@ collect_delta_metrics() {
402427
# Collect Worker deltas
403428
for worker in "${workers[@]}"; do
404429
local worker_container="hiclaw-worker-${worker}"
405-
local worker_session_dir="/root/hiclaw-fs/agents/${worker}/.openclaw/agents/main/sessions"
430+
local worker_session_dir
431+
worker_session_dir=$(_detect_session_dir "$worker_container" "/root/hiclaw-fs/agents/${worker}")
406432

407433
log_info "Collecting Worker '${worker}' delta metrics..." >&2
408434

@@ -450,8 +476,9 @@ collect_test_metrics() {
450476
local workers=("$@")
451477

452478
local manager_container="${TEST_AGENT_CONTAINER:-${TEST_CONTROLLER_CONTAINER:-hiclaw-manager}}"
453-
local manager_session_dir="/root/manager-workspace/.openclaw/agents/main/sessions"
454-
479+
local manager_session_dir
480+
manager_session_dir=$(_detect_session_dir "$manager_container" "/root/manager-workspace")
481+
455482
# Initialize result structure
456483
local cumulative_result='{"test_name": "'"${test_name}"'", "timestamp": "'"$(date -Iseconds)"'", "agents": {}, "totals": {"llm_calls": 0, "tokens": {"input": 0, "output": 0, "cache_read": 0, "cache_write": 0, "total": 0}, "timing": {"duration_seconds": 0}}}'
457484

@@ -474,7 +501,8 @@ collect_test_metrics() {
474501
# Collect Worker metrics
475502
for worker in "${workers[@]}"; do
476503
local worker_container="hiclaw-worker-${worker}"
477-
local worker_session_dir="/root/hiclaw-fs/agents/${worker}/.openclaw/agents/main/sessions"
504+
local worker_session_dir
505+
worker_session_dir=$(_detect_session_dir "$worker_container" "/root/hiclaw-fs/agents/${worker}")
478506

479507
log_info "Collecting Worker '${worker}' metrics..." >&2
480508

0 commit comments

Comments
 (0)