154154log " Deployment active. Waiting 30s for s6-overlay init to complete..."
155155sleep 30
156156
157- # ─── Run health checks via console ──────────────────────────────────────────
157+ # ─── Get app URL ─────────────────────────────────────────────────────────────
158+
159+ APP_URL=$( doctl apps get " $APP_ID " --output json 2> /dev/null \
160+ | jq -r ' .[0].live_url // .[0].default_ingress // empty' 2> /dev/null || echo " " )
161+ # Strip trailing slash
162+ APP_URL=" ${APP_URL%/ } "
163+ log " App URL: $APP_URL "
164+
165+ # ─── Run health checks via HTTP + logs ───────────────────────────────────────
158166
159167PASS=0
160168FAIL_COUNT=0
@@ -164,88 +172,68 @@ check_fail() { echo " FAIL: $1"; FAIL_COUNT=$((FAIL_COUNT + 1)); }
164172
165173log " Running E2E health checks..."
166174
167- # Check 1: Config is valid JSON
168- CONFIG_VALID=$( doctl apps console " $APP_ID " openclaw --command " jq empty /data/.openclaw/openclaw.json && echo VALID" 2> /dev/null || echo " " )
169- if echo " $CONFIG_VALID " | grep -q " VALID" ; then
170- check_pass " Config is valid JSON"
171- else
172- check_fail " Config is invalid JSON"
173- fi
175+ # Grab runtime logs for verification
176+ LOGS=$( doctl apps logs " $APP_ID " --type=run 2> /dev/null || echo " " )
174177
175- # Check 2: tools.profile is coding
176- PROFILE=$( doctl apps console " $APP_ID " openclaw --command " jq -r '.tools.profile' /data/.openclaw/openclaw.json" 2> /dev/null || echo " " )
177- if echo " $PROFILE " | grep -q " coding" ; then
178- check_pass " tools.profile: coding"
178+ # Check 1: Gateway HTTP responds (public URL)
179+ if [ -n " $APP_URL " ]; then
180+ GW_HTTP=$( curl -s -o /dev/null -w ' %{http_code}' --max-time 30 " $APP_URL " 2> /dev/null || echo " 000" )
181+ if [ " $GW_HTTP " = " 200" ] || [ " $GW_HTTP " = " 401" ] || [ " $GW_HTTP " = " 403" ]; then
182+ check_pass " Gateway HTTP responds: $GW_HTTP "
183+ else
184+ check_fail " Gateway HTTP: $GW_HTTP (expected 200/401/403)"
185+ fi
179186else
180- check_fail " tools.profile: ' $PROFILE ' "
187+ check_fail " No app URL available "
181188fi
182189
183- # Check 3: Config owned by openclaw
184- OWNER=$( doctl apps console " $APP_ID " openclaw --command " stat -c '%U' /data/.openclaw/openclaw.json" 2> /dev/null || echo " " )
185- if echo " $OWNER " | grep -q " openclaw" ; then
186- check_pass " Config owned by openclaw"
190+ # Check 2: Config generation succeeded (from logs)
191+ if echo " $LOGS " | grep -q " generate-config.*Done\|generate-config.*Final config" ; then
192+ check_pass " Config generation completed"
187193else
188- check_fail " Config owned by: ' $OWNER ' "
194+ check_fail " Config generation not found in logs "
189195fi
190196
191- # Check 4: Gateway process running
192- GW_PROC=$( doctl apps console " $APP_ID " openclaw --command " pgrep -f openclaw-gateway >/dev/null 2>&1 && echo RUNNING" 2> /dev/null || echo " " )
193- if echo " $GW_PROC " | grep -q " RUNNING" ; then
194- check_pass " Gateway process running"
197+ # Check 3: tools.profile is coding (from logs)
198+ if echo " $LOGS " | grep -q ' tools.profile.*coding\|"profile":.*"coding"' ; then
199+ check_pass " tools.profile: coding"
195200else
196- check_fail " Gateway process not running "
201+ check_fail " tools.profile not set to coding in logs "
197202fi
198203
199- # Check 5: Gateway HTTP responds
200- GW_HTTP=$( doctl apps console " $APP_ID " openclaw --command " curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:18789/ 2>/dev/null" 2> /dev/null || echo " 000" )
201- if echo " $GW_HTTP " | grep -q " 200" ; then
202- check_pass " Gateway HTTP: 200"
204+ # Check 4: Gateway started (from logs)
205+ if echo " $LOGS " | grep -q " Starting openclaw gateway\|openclaw.*gateway.*started" ; then
206+ check_pass " Gateway service started"
203207else
204- check_fail " Gateway HTTP: $GW_HTTP "
208+ check_fail " Gateway start not found in logs "
205209fi
206210
207- # Check 6: Auth mode is token
208- AUTH_MODE=$( doctl apps console " $APP_ID " openclaw --command " jq -r '.gateway.auth.mode' /data/.openclaw/openclaw.json" 2> /dev/null || echo " " )
209- if echo " $AUTH_MODE " | grep -q " token" ; then
210- check_pass " Auth mode: token"
211+ # Check 5: Init scripts completed without errors (from logs)
212+ if echo " $LOGS " | grep -q " 20-setup-openclaw exited 0" ; then
213+ check_pass " Setup init script exited 0"
211214else
212- check_fail " Auth mode: ' $AUTH_MODE ' "
215+ check_fail " Setup init script did not exit cleanly "
213216fi
214217
215- # Check 7: Channel plugins loaded
216- PLUGINS=$( doctl apps console " $APP_ID " openclaw --command " jq -r '.plugins.entries | keys | sort | join(\" ,\" )' /data/.openclaw/openclaw.json" 2> /dev/null || echo " " )
217- if echo " $PLUGINS " | grep -q " telegram" ; then
218- check_pass " Channel plugins loaded"
218+ # Check 6: Permissions applied (from logs)
219+ if echo " $LOGS " | grep -q " 99999-apply-permissions exited 0" ; then
220+ check_pass " Permissions applied successfully"
219221else
220- check_fail " Channel plugins: ' $PLUGINS ' "
222+ check_fail " Permissions script did not complete "
221223fi
222224
223- # Check 8: Backup config valid
224- BACKUP_CFG=$( doctl apps console " $APP_ID " openclaw --command " yq eval '.repository' /etc/digitalocean/backup.yaml 2>/dev/null && echo CFG_OK" 2> /dev/null || echo " " )
225- if echo " $BACKUP_CFG " | grep -q " CFG_OK" ; then
226- check_pass " Backup config valid"
225+ # Check 7: s6 services started (from logs)
226+ if echo " $LOGS " | grep -q " legacy-services successfully started" ; then
227+ check_pass " s6 services started"
227228else
228- check_fail " Backup config not parseable "
229+ check_fail " s6 services did not start "
229230fi
230231
231- # Check 9: Telegram channel probe (optional)
232- if [ -n " ${TELEGRAM_BOT_TOKEN:- } " ]; then
233- log " Probing Telegram channel..."
234- doctl apps console " $APP_ID " openclaw --command "
235- jq '.plugins.entries.telegram.token = \" ${TELEGRAM_BOT_TOKEN} \" ' /data/.openclaw/openclaw.json > /tmp/oc_tg.json \
236- && cp /tmp/oc_tg.json /data/.openclaw/openclaw.json \
237- && chown openclaw:openclaw /data/.openclaw/openclaw.json \
238- && /command/s6-svc -r /run/service/openclaw
239- " 2> /dev/null || true
240- sleep 15
241- TG_STATUS=$( doctl apps console " $APP_ID " openclaw --command " su - openclaw -c 'openclaw channels status 2>/dev/null'" 2> /dev/null || echo " " )
242- if echo " $TG_STATUS " | grep -qi " connected\|available\|ok" ; then
243- check_pass " Telegram channel connected"
244- else
245- echo " WARN: Telegram channel status unclear: $TG_STATUS "
246- fi
232+ # Check 8: No fatal errors in logs
233+ if echo " $LOGS " | grep -qi " fatal\|panic\|segfault\|ENOSPC" ; then
234+ check_fail " Fatal errors found in logs"
247235else
248- echo " SKIP: Telegram probe (TELEGRAM_BOT_TOKEN not set) "
236+ check_pass " No fatal errors in logs "
249237fi
250238
251239# ─── Results ──────────────────────────────────────────────────────────────────
0 commit comments