From 7947fa44a5ab8bf686b1632044f5849504278f93 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 23 Jul 2026 13:57:01 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(ci):=20Unit=20Tests=E6=B7=BB=E5=8A=A0wo?= =?UTF-8?q?rker=E4=BE=9D=E8=B5=96+=E4=BF=AE=E5=A4=8DPYTHONPATH+pip?= =?UTF-8?q?=E5=9B=BD=E5=86=85=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/ci/run_unit_tests.sh | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/scripts/ci/run_unit_tests.sh b/scripts/ci/run_unit_tests.sh index b5c673a28..146798a3b 100755 --- a/scripts/ci/run_unit_tests.sh +++ b/scripts/ci/run_unit_tests.sh @@ -7,6 +7,11 @@ JOB_NAME="${1:-Unit Tests}" echo "=== CI Unit Tests 开始 ===" +# --- 配置 pip 国内源(加速下载,减少网络失败)--- +python3 -m pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/ +python3 -m pip config set global.timeout 120 +python3 -m pip config set global.retries 5 + # --- 安装依赖 --- echo "" echo "=== 安装 Python 依赖 ===" @@ -23,6 +28,12 @@ for i in 1 2 3; do [ $i -eq 3 ] && exit 1 sleep 5 done +for i in 1 2 3; do + python3 -m pip install -q -r requirements-worker.txt && break + echo "pip install requirements-worker.txt 失败,重试 $i/3..." + [ $i -eq 3 ] && exit 1 + sleep 5 +done for i in 1 2 3; do python3 -m pip install -q -r requirements-dev.txt && break echo "pip install requirements-dev.txt 失败,重试 $i/3..." @@ -64,8 +75,8 @@ echo "=== 运行单元测试 (模式: $UNIT_TEST_MODE) ===" if [ "$UNIT_TEST_MODE" = "incremental" ]; then echo "=== 增量测试模式 ===" - PYTHONPATH="$PWD/apps/api:$PWD" python3 -m coverage run \ - --source=apps/api/app,packages \ + PYTHONPATH="$PWD/apps/api:$PWD/apps/worker:$PWD" python3 -m coverage run \ + --source=apps/api/app,apps/worker/worker_app,packages \ --omit="*/migrations/*,*/tests/*,*/test_*.py,*/site-packages/*" \ --branch \ -m pytest $SELECTED_TEST_FILES -q @@ -73,8 +84,8 @@ if [ "$UNIT_TEST_MODE" = "incremental" ]; then python3 -m coverage xml -o coverage.xml python3 -m coverage report --fail-under=10 > /dev/null || true else - PYTHONPATH="$PWD/apps/api:$PWD" python3 -m coverage run \ - --source=apps/api/app,packages \ + PYTHONPATH="$PWD/apps/api:$PWD/apps/worker:$PWD" python3 -m coverage run \ + --source=apps/api/app,apps/worker/worker_app,packages \ --omit="*/migrations/*,*/tests/*,*/test_*.py,*/site-packages/*" \ --branch \ -m pytest tests/unit -q -- 2.54.0 From ad304d5b8b9021c26236d4979300340dea0c57a0 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 23 Jul 2026 13:55:13 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix(ci):=20=E5=8E=BB=E6=8E=89=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E8=84=9A=E6=9C=ACDooD=E5=B5=8C=E5=A5=97=EF=BC=8C?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E5=9C=A8CI=E5=AE=B9=E5=99=A8=E5=86=85?= =?UTF-8?q?=E8=BF=90=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/ci/step_frontend_install.sh | 113 ++-------------------------- scripts/ci/step_frontend_run.sh | 25 +----- 2 files changed, 11 insertions(+), 127 deletions(-) diff --git a/scripts/ci/step_frontend_install.sh b/scripts/ci/step_frontend_install.sh index 42cdb3fdc..c2d9a429c 100755 --- a/scripts/ci/step_frontend_install.sh +++ b/scripts/ci/step_frontend_install.sh @@ -1,117 +1,18 @@ #!/bin/sh -# CI 公共步骤:前端依赖安装(Docker Volume 持久化缓存方案) -# 通过 Docker named volume 缓存 node_modules,按 package-lock.json hash 命名 -# 缓存命中时跳过 npm ci,直接复用已有 volume +# CI 公共步骤:前端依赖安装 +# 直接在 CI 容器内运行(CI 镜像已包含 Node.js + pnpm),无需 Docker 嵌套 set -eu MODE="${1:-full}" echo "=== 前端依赖安装开始 (模式: $MODE) ===" -# npm国内镜像源(加速下载,减少网络失败) -NPM_REGISTRY="https://registry.npmmirror.com" +cd apps/web -# 缓存配置 — 与 step_frontend_run.sh 保持一致 -LOCK_FILE="apps/web/package-lock.json" -VOLUME_PREFIX="ci-web-nm-" -KEEP_CACHE_COUNT=5 +# 配置国内镜像源加速 +pnpm config set registry https://registry.npmmirror.com -# 计算 package-lock.json 的 md5 hash 作为缓存 key -VOLUME_NAME="" -if [ -f "$LOCK_FILE" ]; then - LOCK_HASH=$(md5sum "$LOCK_FILE" | cut -c1-12) - VOLUME_NAME="${VOLUME_PREFIX}${LOCK_HASH}" - echo "缓存 key: $LOCK_HASH (volume: $VOLUME_NAME)" -else - echo "警告: 未找到 $LOCK_FILE,将不使用持久化缓存" -fi - -# 检查 volume 是否存在(缓存命中) -CACHE_HIT=0 -if [ -n "$VOLUME_NAME" ]; then - if docker volume inspect "$VOLUME_NAME" >/dev/null 2>&1; then - CACHE_HIT=1 - echo "缓存命中!复用 volume: $VOLUME_NAME" - else - echo "缓存未命中,创建 volume 并安装依赖..." - # 创建 volume(失败则降级为无缓存模式) - if ! docker volume create "$VOLUME_NAME" >/dev/null 2>&1; then - echo "警告: 创建 volume 失败,降级为无缓存模式" - VOLUME_NAME="" - fi - fi -fi - -# 构建 docker run 的 volume 挂载参数(空时不挂载) -VOLUME_ARGS="" -if [ -n "$VOLUME_NAME" ]; then - VOLUME_ARGS="-v ${VOLUME_NAME}:/workspace/apps/web/node_modules" -fi - -# 缓存未命中时执行 npm ci -if [ "$CACHE_HIT" -eq 0 ]; then - for i in 1 2 3; do - echo "npm ci 尝试 $i/3 (镜像: $NPM_REGISTRY)" - docker run --rm -v "$PWD:/workspace" $VOLUME_ARGS -w /workspace/apps/web docker.m.daocloud.io/library/node:20 sh -lc "npm config set registry $NPM_REGISTRY && npm ci --no-audit --no-fund" && break - echo "npm ci 失败,重试 $i/3..." - [ $i -eq 3 ] && exit 1 - sleep 10 - done -else - echo "缓存命中,验证依赖完整性..." - # 验证关键依赖是否存在(防止缓存损坏或版本漂移) - DEPS_OK=1 - if ! docker run --rm $VOLUME_ARGS -v "$PWD:/workspace" -w /workspace/apps/web docker.m.daocloud.io/library/node:20 sh -lc "npx --yes vitest --version > /dev/null 2>&1 && npx --yes vite --version > /dev/null 2>&1" 2>/dev/null; then - echo "⚠️ 缓存依赖不完整(vitest/vite缺失),废弃缓存重新安装" - DEPS_OK=0 - docker volume rm "$VOLUME_NAME" > /dev/null 2>&1 || true - docker volume create "$VOLUME_NAME" > /dev/null 2>&1 || true - fi - - if [ "$DEPS_OK" -eq 1 ]; then - echo "✅ 依赖完整性校验通过,跳过 npm ci" - else - # 重新安装 - for i in 1 2 3; do - echo "npm ci 重新安装尝试 $i/3 (镜像: $NPM_REGISTRY)" - docker run --rm -v "$PWD:/workspace" $VOLUME_ARGS -w /workspace/apps/web docker.m.daocloud.io/library/node:20 sh -lc "npm config set registry $NPM_REGISTRY && npm ci --no-audit --no-fund" && break - echo "npm ci 失败,重试 $i/3..." - [ $i -eq 3 ] && exit 1 - sleep 10 - done - fi -fi - -# 清理旧缓存 volume(保留最近 N 个,防止磁盘占用无限增长) -if [ -n "$VOLUME_PREFIX" ]; then - echo "清理旧缓存 volume(保留最近 ${KEEP_CACHE_COUNT} 个)..." - ALL_VOLUMES=$(docker volume ls -q --filter "name=${VOLUME_PREFIX}" 2>/dev/null || true) - if [ -n "$ALL_VOLUMES" ]; then - TOTAL=$(echo "$ALL_VOLUMES" | wc -l) - if [ "$TOTAL" -gt "$KEEP_CACHE_COUNT" ]; then - # 按创建时间排序,保留最新的 N 个 - SORTED_VOLUMES=$(for v in $ALL_VOLUMES; do - CREATED=$(docker volume inspect --format '{{.CreatedAt}}' "$v" 2>/dev/null || echo "0") - echo "$CREATED $v" - done | sort | awk '{print $2}') - - # 删除超出保留数量的旧 volume - REMOVE_COUNT=$((TOTAL - KEEP_CACHE_COUNT)) - TO_DELETE=$(echo "$SORTED_VOLUMES" | head -n "$REMOVE_COUNT") - REMOVED=0 - for v in $TO_DELETE; do - # 跳过当前正在使用的 volume - if [ "$v" != "$VOLUME_NAME" ]; then - if docker volume rm "$v" >/dev/null 2>&1; then - REMOVED=$((REMOVED + 1)) - fi - fi - done - echo "已清理 $REMOVED 个旧缓存 volume,当前共 $((TOTAL - REMOVED)) 个" - else - echo "当前缓存 volume 数量: $TOTAL,无需清理" - fi - fi -fi +# 安装依赖 +pnpm install --frozen-lockfile echo "=== 前端依赖安装完成 ===" diff --git a/scripts/ci/step_frontend_run.sh b/scripts/ci/step_frontend_run.sh index 3374b88a0..377c7a44f 100755 --- a/scripts/ci/step_frontend_run.sh +++ b/scripts/ci/step_frontend_run.sh @@ -1,26 +1,9 @@ #!/bin/sh -# CI 公共步骤:前端命令执行(在 docker node 容器中运行) -# 用法:step_frontend_run.sh "要执行的命令" -# 支持 Docker Volume 持久化缓存的 node_modules +# CI 公共步骤:前端命令执行 +# 直接在 CI 容器内运行(CI 镜像已包含 Node.js + pnpm),无需 Docker 嵌套 set -eu CMD="${1:-echo 'no command'}" -# 缓存配置 — 与 step_frontend_install.sh 保持一致 -LOCK_FILE="apps/web/package-lock.json" -VOLUME_PREFIX="ci-web-nm-" - -# 计算 package-lock.json 的 hash,挂载对应的 volume -VOLUME_ARGS="" -if [ -f "$LOCK_FILE" ]; then - LOCK_HASH=$(md5sum "$LOCK_FILE" | cut -c1-12) - VOLUME_NAME="${VOLUME_PREFIX}${LOCK_HASH}" - if docker volume inspect "$VOLUME_NAME" >/dev/null 2>&1; then - VOLUME_ARGS="-v ${VOLUME_NAME}:/workspace/apps/web/node_modules" - echo "使用缓存 volume: $VOLUME_NAME" - else - echo "提示: 未找到缓存 volume $VOLUME_NAME,将使用源码目录 node_modules" - fi -fi - -docker run --rm -v "$PWD:/workspace" $VOLUME_ARGS -w /workspace/apps/web docker.m.daocloud.io/library/node:20 sh -lc "$CMD" +cd apps/web +sh -lc "$CMD" -- 2.54.0 From d2eaae729270bf90a02867846ad3252d864afeb4 Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 23 Jul 2026 17:31:04 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(ci):=20=E5=89=8D=E7=AB=AF=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E6=94=B9=E7=94=A8npm=20ci=EF=BC=88=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=94=A8package-lock.json=E8=80=8C=E9=9D=9Epnpm=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/ci/step_frontend_install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/ci/step_frontend_install.sh b/scripts/ci/step_frontend_install.sh index c2d9a429c..8d1729b02 100755 --- a/scripts/ci/step_frontend_install.sh +++ b/scripts/ci/step_frontend_install.sh @@ -1,6 +1,6 @@ #!/bin/sh # CI 公共步骤:前端依赖安装 -# 直接在 CI 容器内运行(CI 镜像已包含 Node.js + pnpm),无需 Docker 嵌套 +# 直接在 CI 容器内运行(CI 镜像已包含 Node.js),无需 Docker 嵌套 set -eu MODE="${1:-full}" @@ -10,9 +10,9 @@ echo "=== 前端依赖安装开始 (模式: $MODE) ===" cd apps/web # 配置国内镜像源加速 -pnpm config set registry https://registry.npmmirror.com +npm config set registry https://registry.npmmirror.com # 安装依赖 -pnpm install --frozen-lockfile +npm ci --no-audit --no-fund echo "=== 前端依赖安装完成 ===" -- 2.54.0