diff --git a/scripts/ci/run_integration_tests.sh b/scripts/ci/run_integration_tests.sh index 1d05d85bd..3573c9bd8 100755 --- a/scripts/ci/run_integration_tests.sh +++ b/scripts/ci/run_integration_tests.sh @@ -120,6 +120,29 @@ wait_tcp_ready() { return 1 } +# --- 幂等容器清理(无论成功/失败/被取消都回收临时 PG、Redis,杜绝泄漏)--- +# 背景:服务容器用 docker run -d 起在宿主机上,仅在脚本走到结尾时清理; +# job 失败(set -e)或被取消(SIGTERM)时会永久残留,堆积压垮构建机。 +cleanup_containers() { + # 清理过程自身不能再次触发退出,避免掩盖原始退出码 + set +e + if [ -n "${PG_CONTAINER:-}" ]; then + docker rm -f "$PG_CONTAINER" >/dev/null 2>&1 && echo "✅ 已清理PG容器: $PG_CONTAINER" + fi + if [ -n "${REDIS_CONTAINER:-}" ]; then + docker rm -f "$REDIS_CONTAINER" >/dev/null 2>&1 && echo "✅ 已清理Redis容器: $REDIS_CONTAINER" + fi +} +on_exit() { + local code=$? + cleanup_containers + exit "$code" +} +# 必须在启动任何服务容器之前注册;INT/TERM 覆盖 Gitea 取消任务场景 +trap on_exit EXIT +trap 'exit 130' INT +trap 'exit 143' TERM + # --- 启动 Redis --- echo "" echo "=== 启动 Redis ===" @@ -302,14 +325,10 @@ conn.close() " 2>/dev/null || echo "WARN: 数据库清理失败(可能已被清理)" echo "✅ 共享PG数据库已清理" else - # 清理临时PG容器 - docker rm -f "$PG_CONTAINER" 2>/dev/null || true - echo "✅ PG容器已清理" + # 临时PG容器由 EXIT trap 的 cleanup_containers 统一回收(失败/取消也保证清理) + : fi - -# 清理Redis容器 -docker rm -f "$REDIS_CONTAINER" 2>/dev/null || true -echo "✅ Redis容器已清理" +# 临时Redis容器同样由 EXIT trap 统一回收 # --- 覆盖率汇总 --- echo "" diff --git a/scripts/ci/run_staging_tests.sh b/scripts/ci/run_staging_tests.sh index dda2144ae..7b8d06ffd 100755 --- a/scripts/ci/run_staging_tests.sh +++ b/scripts/ci/run_staging_tests.sh @@ -16,6 +16,17 @@ CONTAINER_NAME="staging-${MODE}-$$" # 强制清理可能残留的同名容器 docker rm -f "$CONTAINER_NAME" 2>/dev/null || true +# 任何退出路径(成功/失败/被取消 SIGTERM)都回收容器,杜绝 staging 测试容器泄漏 +cleanup_container() { + local code=$? + set +e + docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 && echo "✅ 已清理容器: $CONTAINER_NAME" + exit "$code" +} +trap cleanup_container EXIT +trap 'exit 130' INT +trap 'exit 143' TERM + if [ "$MODE" = "e2e" ]; then docker create --name "$CONTAINER_NAME" --ipc=host \ -e E2E_BASE_URL=https://staging.xiaoxiajianji.com \ @@ -44,7 +55,5 @@ docker cp apps "$CONTAINER_NAME:/workspace/" docker start -a "$CONTAINER_NAME" EXIT_CODE=$(docker wait "$CONTAINER_NAME") -# 清理容器 -docker rm "$CONTAINER_NAME" 2>/dev/null || true - +# 容器由 EXIT trap 的 cleanup_container 统一回收(失败/取消也保证清理) exit "$EXIT_CODE"