@@ -55,17 +55,45 @@ jobs:
5555 exit 1
5656 fi
5757
58+ build :
59+ name : Build Charm
60+ runs-on : ubuntu-24.04
61+ needs : lint
62+ steps :
63+ - name : Checkout code
64+ uses : actions/checkout@v6
65+
66+ - name : Install charmcraft
67+ run : |
68+ sudo snap install charmcraft --classic
69+
70+ - name : Pack charm
71+ run : |
72+ charmcraft pack --destructive-mode
73+
74+ - name : Upload charm artifact
75+ uses : actions/upload-artifact@v4
76+ with :
77+ name : openclaw-charm
78+ path : openclaw_*.charm
79+ retention-days : 1
80+
5881 test-install :
5982 name : Test Charm Installation
6083 runs-on : ubuntu-24.04
61- needs : lint
84+ needs : build
6285 strategy :
6386 matrix :
6487 install-method : [npm, pnpm, bun]
6588 steps :
6689 - name : Checkout code
6790 uses : actions/checkout@v6
6891
92+ - name : Download charm artifact
93+ uses : actions/download-artifact@v4
94+ with :
95+ name : openclaw-charm
96+
6997 - name : Set up LXD
7098 uses : canonical/setup-lxd@main
7199 with :
75103 run : |
76104 sudo snap install juju --channel=3/stable
77105 sudo snap install juju-wait --classic
78- sudo snap install charmcraft --classic
79106
80107 - name : Bootstrap Juju
81108 run : |
@@ -86,10 +113,6 @@ jobs:
86113 run : |
87114 juju add-model test-openclaw
88115
89- - name : Pack charm
90- run : |
91- charmcraft pack --destructive-mode
92-
93116 - name : Deploy charm
94117 run : |
95118 CHARM_FILE=$(ls openclaw_*.charm | head -1)
@@ -160,19 +183,23 @@ jobs:
160183 test-channels :
161184 name : Test Messaging Channel Configuration
162185 runs-on : ubuntu-24.04
163- needs : lint
186+ needs : build
164187 steps :
165188 - name : Checkout code
166189 uses : actions/checkout@v6
167190
191+ - name : Download charm artifact
192+ uses : actions/download-artifact@v4
193+ with :
194+ name : openclaw-charm
195+
168196 - name : Set up LXD
169197 uses : canonical/setup-lxd@main
170198
171199 - name : Install Juju
172200 run : |
173201 sudo snap install juju --channel=3/stable
174202 sudo snap install juju-wait --classic
175- sudo snap install charmcraft --classic
176203
177204 - name : Bootstrap Juju
178205 run : |
@@ -183,10 +210,6 @@ jobs:
183210 run : |
184211 juju add-model test-channels
185212
186- - name : Pack charm
187- run : |
188- charmcraft pack --destructive-mode
189-
190213 - name : Deploy with channel config
191214 run : |
192215 CHARM_FILE=$(ls openclaw_*.charm | head -1)
@@ -218,178 +241,26 @@ jobs:
218241 juju destroy-model test-channels -y --force --no-wait || true
219242 juju destroy-controller test-controller -y --destroy-all-models --force --no-wait || true
220243
221- test-manual-mode :
222- name : Test Manual Configuration Mode
223- runs-on : ubuntu-24.04
224- needs : lint
225- steps :
226- - name : Checkout code
227- uses : actions/checkout@v6
228-
229- - name : Set up LXD
230- uses : canonical/setup-lxd@main
231-
232- - name : Install Juju
233- run : |
234- sudo snap install juju --channel=3/stable
235- sudo snap install juju-wait --classic
236- sudo snap install charmcraft --classic
237-
238- - name : Bootstrap Juju
239- run : |
240- lxc network set lxdbr0 ipv6.address none
241- juju bootstrap localhost test-controller
242-
243- - name : Create test model
244- run : |
245- juju add-model test-manual
246-
247- - name : Pack charm
248- run : |
249- charmcraft pack --destructive-mode
250-
251- - name : Deploy with manual=true
252- run : |
253- CHARM_FILE=$(ls openclaw_*.charm | head -1)
254- juju deploy ./$CHARM_FILE \
255- --config manual=true \
256- --config install-method=npm
257-
258- - name : Wait for deployment
259- run : |
260- juju-wait -v -m test-manual -t 900
261-
262- - name : Verify manual mode behavior
263- run : |
264- # Check status message indicates manual mode
265- status_msg=$(juju status openclaw --format=json | jq -r '.applications.openclaw.units[]["workload-status"].message' | head -1)
266- echo "Status message: $status_msg"
267-
268- if echo "$status_msg" | grep -qi "manual"; then
269- echo "✓ Manual mode status verified"
270- else
271- echo "✗ Status does not indicate manual mode: $status_msg"
272- exit 1
273- fi
274-
275- # Verify OpenClaw is installed
276- juju ssh openclaw/0 'sudo -u ubuntu bash -l -c ". ~/.nvm/nvm.sh && nvm use 24 && which openclaw"'
277- echo "✓ OpenClaw binary installed"
278-
279- # Verify version
280- version=$(juju ssh openclaw/0 'sudo -u ubuntu bash -l -c ". ~/.nvm/nvm.sh && nvm use 24 && openclaw --version 2>&1 | tail -1"')
281- echo "OpenClaw version: $version"
282-
283- # Check that config files were NOT auto-generated
284- if juju ssh openclaw/0 'test -f /home/ubuntu/.openclaw/openclaw.json'; then
285- echo "⚠ Config file exists (may be from OpenClaw itself, not charm)"
286- # Verify it doesn't contain charm-managed settings
287- if juju ssh openclaw/0 'grep -q "ai-provider\|ai-model" /home/ubuntu/.openclaw/openclaw.json 2>/dev/null'; then
288- echo "✗ Config contains charm-managed settings in manual mode"
289- exit 1
290- fi
291- fi
292- echo "✓ No charm-managed config generated"
293-
294- # Verify Chrome was NOT installed
295- if juju ssh openclaw/0 'which google-chrome 2>/dev/null'; then
296- echo "✗ Chrome was installed in manual mode"
297- exit 1
298- fi
299- echo "✓ Chrome not installed in manual mode"
300-
301- - name : Test user config preservation
302- run : |
303- # Create a custom config file
304- juju ssh openclaw/0 'cat > /tmp/custom-config.json << "EOF"
305- {
306- "user_custom_field": "test-value-12345",
307- "gateway": {
308- "mode": "local",
309- "port": 18789
310- }
311- }
312- EOF'
313-
314- # Copy it to OpenClaw directory
315- juju ssh openclaw/0 'cp /tmp/custom-config.json /home/ubuntu/.openclaw/openclaw.json'
316-
317- # Trigger a config change (this would normally regenerate config in automatic mode)
318- juju config openclaw gateway-port=18790
319- sleep 30
320-
321- # Verify custom field still exists
322- if juju ssh openclaw/0 'grep -q "user_custom_field.*test-value-12345" /home/ubuntu/.openclaw/openclaw.json'; then
323- echo "✓ User config preserved after charm config change"
324- else
325- echo "✗ User config was overwritten"
326- juju ssh openclaw/0 'cat /home/ubuntu/.openclaw/openclaw.json'
327- exit 1
328- fi
329-
330- - name : Test multi-unit with manual mode
331- run : |
332- # Add a second unit
333- juju add-unit openclaw
334-
335- # Wait for it to deploy
336- timeout 900 bash -c 'until juju status openclaw --format=json | jq -e ".applications.openclaw.units[\"openclaw/1\"]" > /dev/null 2>&1; do sleep 10; done'
337- sleep 60 # Additional wait for installation
338-
339- # Check second unit has manual mode
340- unit1_status=$(juju status openclaw --format=json | jq -r '.applications.openclaw.units["openclaw/1"]["workload-status"].message' 2>/dev/null || echo "not-ready")
341- echo "Unit 1 status: $unit1_status"
342-
343- # Verify OpenClaw installed on second unit
344- juju ssh openclaw/1 'sudo -u ubuntu bash -l -c ". ~/.nvm/nvm.sh && nvm use 24 && which openclaw"' || echo "Unit 1 still installing"
345-
346- # Verify peer relation config exists on Node unit
347- if juju ssh openclaw/1 'test -f /home/ubuntu/.openclaw/openclaw-node.json'; then
348- echo "✓ Node peer relation config exists"
349- juju ssh openclaw/1 'cat /home/ubuntu/.openclaw/openclaw-node.json'
350- else
351- echo "⚠ Node config not yet created (unit may still be starting)"
352- fi
353-
354- - name : Collect logs on failure
355- if : failure()
356- run : |
357- echo "=== Juju Status ==="
358- juju status --format=yaml
359-
360- echo "=== Debug Log ==="
361- juju debug-log --replay --no-tail --limit 500
362-
363- echo "=== Unit 0 Config ==="
364- juju ssh openclaw/0 'ls -la /home/ubuntu/.openclaw/' || true
365- juju ssh openclaw/0 'cat /home/ubuntu/.openclaw/openclaw.json 2>/dev/null' || true
366-
367- echo "=== Unit 1 Config ==="
368- juju ssh openclaw/1 'ls -la /home/ubuntu/.openclaw/' || true
369- juju ssh openclaw/1 'cat /home/ubuntu/.openclaw/openclaw-node.json 2>/dev/null' || true
370-
371- - name : Cleanup
372- if : always()
373- run : |
374- juju destroy-model test-manual -y --force --no-wait || true
375- juju destroy-controller test-controller -y --destroy-all-models --force --no-wait || true
376-
377244 test-upgrade :
378245 name : Test Charm Upgrade
379246 runs-on : ubuntu-24.04
380- needs : lint
247+ needs : build
381248 steps :
382249 - name : Checkout code
383250 uses : actions/checkout@v6
384251
252+ - name : Download charm artifact
253+ uses : actions/download-artifact@v4
254+ with :
255+ name : openclaw-charm
256+
385257 - name : Set up LXD
386258 uses : canonical/setup-lxd@main
387259
388260 - name : Install Juju
389261 run : |
390262 sudo snap install juju --channel=3/stable
391263 sudo snap install juju-wait --classic
392- sudo snap install charmcraft --classic
393264
394265 - name : Bootstrap Juju
395266 run : |
@@ -400,14 +271,10 @@ jobs:
400271 run : |
401272 juju add-model test-upgrade
402273
403- - name : Pack charm (v1)
404- run : |
405- charmcraft pack --destructive-mode
406- mv openclaw_*.charm openclaw-v1.charm
407-
408274 - name : Deploy v1
409275 run : |
410- juju deploy ./openclaw-v1.charm \
276+ CHARM_FILE=$(ls openclaw_*.charm | head -1)
277+ juju deploy ./$CHARM_FILE \
411278 --config ai-provider="anthropic" \
412279 --config ai-model="claude-sonnet-3-5" \
413280 --config ai-api-key="test-key"
@@ -418,7 +285,8 @@ jobs:
418285
419286 - name : Refresh charm (simulate upgrade)
420287 run : |
421- juju refresh openclaw --path ./openclaw-v1.charm
288+ CHARM_FILE=$(ls openclaw_*.charm | head -1)
289+ juju refresh openclaw --path ./$CHARM_FILE
422290 sleep 60 # Give upgrade-charm hook time to complete
423291
424292 - name : Verify upgrade success
0 commit comments