fix: stabilize docker test suite

This commit is contained in:
Peter Steinberger
2026-03-17 03:01:11 +00:00
parent ed248c76c7
commit 1ffe8fde84
17 changed files with 450 additions and 382 deletions

View File

@@ -20,7 +20,7 @@ WORKDIR /app
COPY --chown=appuser:appuser package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY --chown=appuser:appuser ui/package.json ./ui/package.json
COPY --chown=appuser:appuser extensions/memory-core/package.json ./extensions/memory-core/package.json
COPY --chown=appuser:appuser extensions ./extensions
COPY --chown=appuser:appuser patches ./patches
RUN --mount=type=cache,id=openclaw-pnpm-store,target=/home/appuser/.local/share/pnpm/store,sharing=locked \
@@ -39,6 +39,9 @@ COPY --chown=appuser:appuser apps/shared/OpenClawKit/Sources/OpenClawKit/Resourc
COPY --chown=appuser:appuser apps/shared/OpenClawKit/Tools/CanvasA2UI ./apps/shared/OpenClawKit/Tools/CanvasA2UI
RUN pnpm build
RUN pnpm ui:build
# Onboard Docker E2E does not exercise the Control UI itself; it only needs the
# asset-existence check to pass so configure/onboard can continue.
RUN mkdir -p dist/control-ui \
&& printf '%s\n' '<!doctype html><title>OpenClaw Control UI</title>' > dist/control-ui/index.html
CMD ["bash"]

View File

@@ -75,7 +75,7 @@ LOGINCTL
# Install the npm-global variant from the local /app source.
# `npm pack` can emit script output; keep only the tarball name.
pkg_tgz="$(npm pack --silent /app | tail -n 1 | tr -d '\r')"
pkg_tgz="$(npm pack --ignore-scripts --silent /app | tail -n 1 | tr -d '\r')"
if [ ! -f "/app/$pkg_tgz" ]; then
echo "npm pack failed (expected /app/$pkg_tgz)"
exit 1

View File

@@ -74,8 +74,14 @@ TRASH
try { text = fs.readFileSync(file, \"utf8\"); } catch { process.exit(1); }
// Clack/script output can include lots of control sequences; keep a larger tail and strip ANSI more robustly.
if (text.length > 120000) text = text.slice(-120000);
const stripAnsi = (value) =>
const normalizeScriptOutput = (value) =>
value
// util-linux script can emit each byte on its own CRLF-delimited line.
// Collapse those first so ANSI/control stripping works on real sequences.
.replace(/\\r?\\n/g, \"\")
.replace(/\\r/g, \"\");
const stripAnsi = (value) =>
normalizeScriptOutput(value)
// OSC: ESC ] ... BEL or ESC \\
.replace(/\\x1b\\][^\\x07]*(?:\\x07|\\x1b\\\\)/g, \"\")
// CSI: ESC [ ... cmd
@@ -269,23 +275,24 @@ TRASH
}
send_channels_flow() {
# Configure channels via configure wizard.
# Prompts are interactive; notes are not. Use conservative delays to stay in sync.
# Where will the Gateway run? -> Local (default)
send $'"'"'\r'"'"' 1.2
# Channels mode -> Configure/link (default)
send $'"'"'\r'"'"' 1.5
# Configure channels via configure wizard. Sync on prompt text so
# keystrokes do not drift into the wrong screen when render timing changes.
wait_for_log "Where will the Gateway run?" 120
send $'"'"'\r'"'"' 0.6
wait_for_log "Channels" 120
send $'"'"'\r'"'"' 0.6
# Select a channel -> Finished (last option; clack wraps on Up)
send $'"'"'\e[A\r'"'"' 2.0
wait_for_log "Select a channel" 120
send $'"'"'\e[A\r'"'"' 0.8
# Keep stdin open until wizard exits.
send "" 2.5
send "" 2.0
}
send_skills_flow() {
# configure --section skills still runs the configure wizard; the first prompt is gateway location.
# Avoid log-based synchronization here; clack output can fragment ANSI sequences and break matching.
send $'"'"'\r'"'"' 3.0
wait_for_log "Configure skills now?" 120 true || true
# configure --section skills still runs the configure wizard.
wait_for_log "Where will the Gateway run?" 120
send $'"'"'\r'"'"' 0.6
wait_for_log "Configure skills now?" 120
send $'"'"'n\r'"'"' 0.8
send "" 2.0
}

View File

@@ -8,7 +8,7 @@ echo "Building Docker image..."
docker build -t "$IMAGE_NAME" -f "$ROOT_DIR/scripts/e2e/Dockerfile" "$ROOT_DIR"
echo "Running plugins Docker E2E..."
docker run --rm -i "$IMAGE_NAME" bash -s <<'EOF'
docker run --rm -e COREPACK_ENABLE_DOWNLOAD_PROMPT=0 -i "$IMAGE_NAME" bash -s <<'EOF'
set -euo pipefail
if [ -f dist/index.mjs ]; then