Skip to content

Commit 475452e

Browse files
authored
Merge branch 'main' into hiclaw-controller-refactor-debugworker
2 parents 1f8e4df + 14ac630 commit 475452e

Some content is hidden

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

55 files changed

+4092
-2006
lines changed

.github/workflows/build-rc.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
7979
- name: Build and push multi-arch images
8080
run: |
81-
make push-manager push-manager-aliyun push-worker push-copaw-worker push-hiclaw-controller \
81+
make push-manager push-manager-copaw push-worker push-copaw-worker push-hiclaw-controller \
8282
VERSION=${{ inputs.version }} \
8383
OPENCLAW_BASE_VERSION=${{ inputs.version }} \
8484
REGISTRY=${{ env.REGISTRY }} \
@@ -90,7 +90,7 @@ jobs:
9090
env:
9191
BASE_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/openclaw-base
9292
MANAGER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-manager
93-
MANAGER_ALIYUN_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-manager-aliyun
93+
MANAGER_COPAW_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-manager-copaw
9494
WORKER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-worker
9595
COPAW_WORKER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-copaw-worker
9696
CONTROLLER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-controller
@@ -100,7 +100,7 @@ jobs:
100100
echo "" >> $GITHUB_STEP_SUMMARY
101101
echo "**Images:**" >> $GITHUB_STEP_SUMMARY
102102
echo "- Manager: \`${MANAGER_IMAGE}:${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY
103-
echo "- Manager Aliyun: \`${MANAGER_ALIYUN_IMAGE}:${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY
103+
echo "- Manager CoPaw: \`${MANAGER_COPAW_IMAGE}:${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY
104104
echo "- Worker: \`${WORKER_IMAGE}:${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY
105105
echo "- CoPaw Worker: \`${COPAW_WORKER_IMAGE}:${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY
106106
echo "- Controller: \`${CONTROLLER_IMAGE}:${{ inputs.version }}\`" >> $GITHUB_STEP_SUMMARY

.github/workflows/build.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ jobs:
6363
# also pushes :latest in the same buildx call, so no separate step needed.
6464
- name: Build and push multi-arch images
6565
run: |
66-
make push-manager push-manager-aliyun push-manager-copaw push-worker push-copaw-worker push-hiclaw-controller \
66+
make push-manager push-manager-copaw push-worker push-copaw-worker push-hiclaw-controller \
6767
VERSION=${{ steps.meta.outputs.version }} \
6868
REGISTRY=${{ env.REGISTRY }} \
6969
REPO=${{ env.REPO }} \
@@ -74,15 +74,13 @@ jobs:
7474
env:
7575
OPENCLAW_BASE_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/openclaw-base
7676
MANAGER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-manager
77-
MANAGER_ALIYUN_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-manager-aliyun
7877
MANAGER_COPAW_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-manager-copaw
7978
WORKER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-worker
8079
COPAW_WORKER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-copaw-worker
8180
CONTROLLER_IMAGE: ${{ env.REGISTRY }}/${{ env.REPO }}/hiclaw-controller
8281
run: |
8382
echo "### Build Summary" >> $GITHUB_STEP_SUMMARY
8483
echo "- Manager: \`${MANAGER_IMAGE}:${{ steps.meta.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
85-
echo "- Manager Aliyun: \`${MANAGER_ALIYUN_IMAGE}:${{ steps.meta.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
8684
echo "- Manager CoPaw: \`${MANAGER_COPAW_IMAGE}:${{ steps.meta.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
8785
echo "- Worker: \`${WORKER_IMAGE}:${{ steps.meta.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
8886
echo "- CoPaw Worker: \`${COPAW_WORKER_IMAGE}:${{ steps.meta.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: HiClaw Controller Tests
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'hiclaw-controller/**'
7+
- '.github/workflows/test-controller.yml'
8+
push:
9+
branches: [main]
10+
paths:
11+
- 'hiclaw-controller/**'
12+
workflow_dispatch:
13+
14+
jobs:
15+
test:
16+
runs-on: ubuntu-latest
17+
timeout-minutes: 10
18+
steps:
19+
- uses: actions/checkout@v4
20+
21+
- uses: actions/setup-go@v5
22+
with:
23+
go-version-file: hiclaw-controller/go.mod
24+
cache-dependency-path: hiclaw-controller/go.sum
25+
26+
- name: Unit tests
27+
working-directory: hiclaw-controller
28+
run: make test-unit
29+
30+
- name: Integration tests (envtest)
31+
working-directory: hiclaw-controller
32+
run: make test-integration

.github/workflows/test-integration.yml

Lines changed: 169 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,164 @@ 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
54-
NON_GITHUB_TESTS: "01 02 03 04 05 06 14 15 17 18 19 20 100"
54+
# Tests that do not require a GitHub token, split into four shards for parallel execution
55+
# Shard A: LLM interaction tests (sequential dependency: 02 creates alice → 03-06 use alice)
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"
5564

5665
jobs:
66+
# Step 1: Build the shared base image (hiclaw-controller)
67+
build-base:
68+
runs-on: ubuntu-latest
69+
timeout-minutes: 15
70+
steps:
71+
- name: Free Up Disk Space
72+
uses: jlumbroso/free-disk-space@main
73+
with:
74+
tool-cache: false
75+
android: true
76+
dotnet: true
77+
haskell: true
78+
large-packages: true
79+
swap-storage: true
80+
81+
- name: Checkout code
82+
uses: actions/checkout@v4
83+
with:
84+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
85+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
86+
87+
- name: Set up Docker Buildx
88+
uses: docker/setup-buildx-action@v3
89+
90+
- name: Build hiclaw-controller
91+
run: make build-hiclaw-controller DOCKER_BUILD_ARGS="--build-arg APT_MIRROR="
92+
93+
- name: Save image
94+
run: |
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
123+
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
146+
run: |
147+
docker save \
148+
$(docker images --format '{{.Repository}}:{{.Tag}}' | grep -E '^hiclaw/' | grep -v '<none>' | grep -v 'hiclaw-controller') \
149+
| gzip > /tmp/hiclaw-${{ matrix.target }}.tar.gz
150+
151+
- name: Upload image
152+
uses: actions/upload-artifact@v4
153+
with:
154+
name: image-${{ matrix.target }}
155+
path: /tmp/hiclaw-${{ matrix.target }}.tar.gz
156+
retention-days: 1
157+
158+
# Step 3: Run test shards in parallel, each on its own runner with isolated cluster
57159
integration-tests:
160+
needs: build-images
161+
if: >-
162+
inputs.worker_runtime == '' || inputs.worker_runtime == 'both'
163+
|| inputs.worker_runtime == matrix.runtime
58164
runs-on: ubuntu-latest
59-
timeout-minutes: 120
165+
timeout-minutes: 90
60166
permissions:
61167
contents: write
62168
pull-requests: write
63169
actions: read
170+
strategy:
171+
fail-fast: false
172+
matrix:
173+
include:
174+
- shard: llm-interaction
175+
filter_env: SHARD_A_TESTS
176+
runtime: openclaw
177+
- shard: llm-interaction-2
178+
filter_env: SHARD_B_TESTS
179+
runtime: openclaw
180+
- 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
190+
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
64198

65199
steps:
66200
- name: Free Up Disk Space
@@ -79,8 +213,17 @@ jobs:
79213
ref: ${{ github.event.pull_request.head.sha || github.sha }}
80214
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
81215

82-
- name: Set up Docker Buildx
83-
uses: docker/setup-buildx-action@v3
216+
- name: Download all images
217+
uses: actions/download-artifact@v4
218+
with:
219+
pattern: image-*
220+
path: /tmp/images
221+
222+
- name: Load images
223+
run: |
224+
for f in /tmp/images/image-*/*.tar.gz; do
225+
gunzip -c "$f" | docker load
226+
done
84227
85228
- name: Install dependencies
86229
run: sudo apt-get update && sudo apt-get install -y jq curl unzip
@@ -91,20 +234,21 @@ jobs:
91234
HICLAW_LLM_API_KEY: ${{ secrets.HICLAW_LLM_API_KEY }}
92235
HICLAW_LLM_PROVIDER: qwen
93236
HICLAW_DEFAULT_MODEL: ${{ inputs.model || 'qwen3.5-plus' }}
94-
HICLAW_MANAGER_RUNTIME: ${{ inputs.worker_runtime || 'openclaw' }}
237+
HICLAW_MANAGER_RUNTIME: ${{ matrix.runtime }}
95238
run: |
96239
FILTER="${{ github.event.inputs.test_filter }}"
97-
[ -z "$FILTER" ] && FILTER="${NON_GITHUB_TESTS}"
98-
make test-embedded \
99-
DOCKER_BUILD_ARGS="--build-arg APT_MIRROR=" \
240+
if [ -z "$FILTER" ]; then
241+
FILTER="${{ env[matrix.filter_env] }}"
242+
fi
243+
SKIP_BUILD=1 make test-embedded \
100244
TEST_FILTER="$FILTER"
101245
102246
# ============================================================
103247
# Metrics: download latest release baseline for comparison
104248
# ============================================================
105249

106250
- name: Download latest release baseline
107-
if: github.event_name == 'pull_request_target'
251+
if: github.event_name == 'pull_request_target' && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
108252
continue-on-error: true
109253
run: |
110254
mkdir -p baseline-metrics
@@ -124,15 +268,17 @@ jobs:
124268
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
125269

126270
- name: Generate metrics comparison and post PR comment
127-
if: github.event_name == 'pull_request_target'
271+
if: github.event_name == 'pull_request_target' && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
128272
env:
129273
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
130274
run: |
131275
source tests/lib/agent-metrics.sh
132276
133277
# Collect current summary across all tests that ran
134278
FILTER="${{ github.event.inputs.test_filter }}"
135-
[ -z "$FILTER" ] && FILTER="${NON_GITHUB_TESTS}"
279+
if [ -z "$FILTER" ]; then
280+
FILTER="${{ env[matrix.filter_env] }}"
281+
fi
136282
TEST_NAMES=$(echo "$FILTER" | tr ' ' '\n' | while read n; do
137283
f=$(ls tests/output/metrics-*${n}*.json 2>/dev/null | head -1)
138284
[ -n "$f" ] && basename "$f" .json | sed 's/^metrics-//'
@@ -209,7 +355,7 @@ jobs:
209355
DEBUG_TAIL=$(find "$DEBUG_DIR" -name "*.log" -exec tail -20 {} + 2>/dev/null | tail -80)
210356
fi
211357
212-
BODY="## ❌ Integration Tests Failed
358+
BODY="## ❌ Integration Tests Failed (${{ matrix.shard }} / ${{ matrix.runtime }})
213359
214360
**Commit:** ${{ github.event.pull_request.head.sha }}
215361
**Workflow run:** [#${{ github.run_number }}](${ARTIFACT_URL})
@@ -237,7 +383,7 @@ jobs:
237383
238384
# Update or create comment
239385
EXISTING=$(gh api "repos/$REPO/issues/$PR_NUM/comments" \
240-
--jq '.[] | select(.body | startswith("## ❌ Integration Tests Failed")) | .id' | head -1)
386+
--jq '.[] | select(.body | startswith("## ❌ Integration Tests Failed (${{ matrix.shard }} / ${{ matrix.runtime }})")) | .id' | head -1)
241387
if [ -n "$EXISTING" ]; then
242388
gh api --method PATCH "repos/$REPO/issues/comments/$EXISTING" -f body="$BODY"
243389
else
@@ -255,7 +401,7 @@ jobs:
255401
if: always()
256402
uses: actions/upload-artifact@v4
257403
with:
258-
name: test-artifacts-${{ github.sha }}
404+
name: test-artifacts-${{ matrix.shard }}-${{ matrix.runtime }}-${{ github.sha }}
259405
path: test-artifacts/
260406
retention-days: 7
261407

@@ -264,7 +410,7 @@ jobs:
264410
# ============================================================
265411

266412
- name: Generate release baseline
267-
if: startsWith(github.ref, 'refs/tags/v')
413+
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
268414
run: |
269415
source tests/lib/agent-metrics.sh
270416
TEST_NAMES=$(echo "$NON_GITHUB_TESTS" | tr ' ' '\n' | while read n; do
@@ -276,7 +422,7 @@ jobs:
276422
cat metrics-baseline.json | jq '{totals: .totals, by_role: .by_role}'
277423
278424
- name: Upload baseline to release
279-
if: startsWith(github.ref, 'refs/tags/v')
425+
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw'
280426
env:
281427
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
282428
run: |
@@ -285,7 +431,7 @@ jobs:
285431
echo "✅ Baseline uploaded to release ${GITHUB_REF_NAME}"
286432
287433
- name: Upload debug log to release
288-
if: startsWith(github.ref, 'refs/tags/v') && always()
434+
if: startsWith(github.ref, 'refs/tags/v') && matrix.shard == 'llm-interaction' && matrix.runtime == 'openclaw' && always()
289435
continue-on-error: true
290436
env:
291437
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -305,8 +451,9 @@ jobs:
305451
if: always()
306452
run: |
307453
echo "### Integration Test Summary" >> $GITHUB_STEP_SUMMARY
308-
echo "- Tests: \`$NON_GITHUB_TESTS\`" >> $GITHUB_STEP_SUMMARY
309-
echo "- Worker Runtime: \`${{ inputs.worker_runtime || 'openclaw' }}\`" >> $GITHUB_STEP_SUMMARY
454+
echo "- Shard: \`${{ matrix.shard }}\`" >> $GITHUB_STEP_SUMMARY
455+
echo "- Tests: \`${{ env[matrix.filter_env] }}\`" >> $GITHUB_STEP_SUMMARY
456+
echo "- Worker Runtime: \`${{ matrix.runtime }}\`" >> $GITHUB_STEP_SUMMARY
310457
echo "- Model: \`${{ inputs.model || 'qwen3.5-plus' }}\`" >> $GITHUB_STEP_SUMMARY
311458
echo "- Install Mode: embedded (make test-embedded)" >> $GITHUB_STEP_SUMMARY
312459

0 commit comments

Comments
 (0)