#!/usr/bin/env bash set -euo pipefail # 2026-05-21 Codex: act-runner host jobs bind-mount the checkout into # root-running CI containers. Clean generated cache/symlink trees before the # runner's post-job cleanup, otherwise successful jobs can end with misleading # permission-denied or errSymlink noise. ROOT="${1:-${GITHUB_WORKSPACE:-$PWD}}" ROOT="$(cd "$ROOT" && pwd)" CLEANUP_IMAGE="${HOST_RUNNER_CLEANUP_IMAGE:-${CI_IMAGE:-}}" cleanup_artifacts() { local root="$1" cd "$root" rm -rf \ .pytest_cache \ apps/api/.pytest_cache \ apps/api/tests/.pytest_cache \ apps/web/tests/e2e/.auth \ apps/web/test-results \ apps/web/playwright-report \ test-results \ playwright-report \ .awoooi-smoke-output \ 2>/dev/null || true find apps/api/tests apps/api/src \ -type d -name __pycache__ -prune -exec rm -rf {} + \ 2>/dev/null || true find apps packages \ -mindepth 2 -maxdepth 2 -type d -name node_modules -prune -exec rm -rf {} + \ 2>/dev/null || true rm -rf node_modules apps/web/node_modules 2>/dev/null || true } cleanup_empty_docker_network() { local network="$1" local containers_json command -v docker >/dev/null 2>&1 || return 0 containers_json="$(docker network inspect "$network" --format '{{json .Containers}}' 2>/dev/null || true)" [ "$containers_json" = "{}" ] || return 0 docker network rm "$network" >/dev/null 2>&1 || true } has_leftovers() { local root="$1" [ -d "$root/.pytest_cache" ] && return 0 [ -d "$root/apps/api/.pytest_cache" ] && return 0 [ -d "$root/apps/web/tests/e2e/.auth" ] && return 0 [ -d "$root/node_modules" ] && return 0 [ -d "$root/apps/web/node_modules" ] && return 0 find "$root/apps/api/tests" "$root/apps/api/src" \ -type d -name __pycache__ -print -quit \ 2>/dev/null | grep -q . && return 0 find "$root/apps" "$root/packages" \ -mindepth 2 -maxdepth 2 -type d -name node_modules -print -quit \ 2>/dev/null | grep -q . } cleanup_artifacts "$ROOT" cleanup_empty_docker_network "b5-test-net" if has_leftovers "$ROOT" && [ -n "$CLEANUP_IMAGE" ] && command -v docker >/dev/null 2>&1; then echo "host cleanup left root-owned artifacts; retrying through ${CLEANUP_IMAGE}" if ! docker run --rm \ -v "$ROOT:/workspace" \ "$CLEANUP_IMAGE" \ bash -lc ' set -euo pipefail cd /workspace rm -rf \ .pytest_cache \ apps/api/.pytest_cache \ apps/api/tests/.pytest_cache \ apps/web/tests/e2e/.auth \ apps/web/test-results \ apps/web/playwright-report \ test-results \ playwright-report \ .awoooi-smoke-output \ node_modules \ apps/web/node_modules find apps/api/tests apps/api/src \ -type d -name __pycache__ -prune -exec rm -rf {} + \ 2>/dev/null || true find apps packages \ -mindepth 2 -maxdepth 2 -type d -name node_modules -prune -exec rm -rf {} + \ 2>/dev/null || true '; then echo "WARNING: docker-based workspace artifact cleanup failed" fi fi if has_leftovers "$ROOT"; then echo "WARNING: host runner workspace artifacts remain after cleanup" find "$ROOT" -maxdepth 4 \ \( -name .pytest_cache -o -name node_modules -o -name test-results -o -name .auth \) \ -print 2>/dev/null | head -20 else echo "host runner workspace artifacts cleaned" fi