diff --git a/.gitea/workflows/pr-automation.yml b/.gitea/workflows/pr-automation.yml index 9f54cd31c..b107783bf 100755 --- a/.gitea/workflows/pr-automation.yml +++ b/.gitea/workflows/pr-automation.yml @@ -240,9 +240,6 @@ jobs: "CI/CD Pipeline / Validate - Type Check (mypy) (pull_request)" "CI/CD Pipeline / Validate - Migration (alembic) (pull_request)" "CI/CD Pipeline / Frontend Lint (pull_request)" - "CI/CD Pipeline / PR Build API Image (pull_request)" - "CI/CD Pipeline / PR Build Worker Image (pull_request)" - "CI/CD Pipeline / PR Build Web Image (pull_request)" ) echo "检查required门禁(与分支保护一致)" fi diff --git a/scripts/ci/docker_build_only.sh b/scripts/ci/docker_build_only.sh index ad5c78e4b..d0aaa18d7 100755 --- a/scripts/ci/docker_build_only.sh +++ b/scripts/ci/docker_build_only.sh @@ -1,5 +1,6 @@ #!/bin/bash -# PR构建专用:只构建不推送,只读缓存不写,用于PR阶段验证Dockerfile +# PR构建专用:只构建不输出,验证Dockerfile能否正常构建 +# 无本地缓存(12个runner不共享,反而添乱),只用ACR远程缓存 set -eu NO_CACHE_FLAG="" @@ -25,60 +26,18 @@ else fi docker buildx inspect --bootstrap -CACHE_NAME=$(echo "$CACHE_REF" | tr "/" "_" | tr ":" "-") -LOCAL_CACHE_DIR="/tmp/buildx-cache/${CACHE_NAME}" -mkdir -p "$LOCAL_CACHE_DIR" - -echo "=== PR Build: build only, no push, read-only cache ===" +echo "=== PR Build: build only, no output, remote cache only ===" echo "Dockerfile: ${DOCKERFILE}" echo "Image tag: ${IMAGE_TAG}" echo "" -build_with_retry() { - local attempt=1 - local max_attempts=2 - while [ $attempt -le $max_attempts ]; do - local build_output - local exit_code - set +e - build_output=$(docker buildx build \ - $NO_CACHE_FLAG \ - $BUILD_ARGS \ - --cache-from "type=local,src=${LOCAL_CACHE_DIR}" \ - --cache-from "type=registry,ref=${CACHE_REF}" \ - -f "${DOCKERFILE}" \ - -t "${IMAGE_TAG}" \ - --load \ - . 2>&1) - exit_code=$? - set -e - if [ $exit_code -eq 0 ]; then - echo "$build_output" - return 0 - fi - if echo "$build_output" | grep -qE "parent snapshot.*not found|snapshot.*does not exist|cache.*corrupt|failed to compute cache key"; then - echo "$build_output" - echo "Local cache corrupted, cleaning and retrying ($attempt/$max_attempts)..." - rm -rf "${LOCAL_CACHE_DIR}" - mkdir -p "${LOCAL_CACHE_DIR}" - docker buildx prune -f -a >/dev/null 2>&1 || true - attempt=$((attempt + 1)) - else - echo "$build_output" - return $exit_code - fi - done - echo "Local cache failed, building with registry cache only..." - docker buildx build \ - $NO_CACHE_FLAG \ - $BUILD_ARGS \ - --cache-from "type=registry,ref=${CACHE_REF}" \ - -f "${DOCKERFILE}" \ - -t "${IMAGE_TAG}" \ - --load \ - . -} +docker buildx build \ + $NO_CACHE_FLAG \ + $BUILD_ARGS \ + --cache-from "type=registry,ref=${CACHE_REF}" \ + -f "${DOCKERFILE}" \ + -t "${IMAGE_TAG}" \ + . -build_with_retry echo "" -echo "PR build OK (not pushed): ${IMAGE_TAG}" +echo "PR build OK (build only, no output): ${IMAGE_TAG}" diff --git a/scripts/ci/vitest_incremental.sh b/scripts/ci/vitest_incremental.sh old mode 100644 new mode 100755 index a91500730..7c5e73c59 --- a/scripts/ci/vitest_incremental.sh +++ b/scripts/ci/vitest_incremental.sh @@ -1,15 +1,12 @@ #!/bin/bash -# Vitest 增量执行脚本 +# Vitest 增量执行脚本(在Docker Node容器中运行) # PR模式下只跑与改动文件相关的测试,大幅节省时间 -# 用法: bash scripts/ci/vitest_incremental.sh set -eu -cd apps/web - # 如果不是PR事件,直接全量跑 if [ "${GITHUB_EVENT_NAME:-}" != "pull_request" ]; then echo "非PR模式,全量执行Vitest" - npx --no-install vitest run --coverage + bash scripts/ci/step_frontend_run.sh "npx vitest run --coverage" exit $? fi @@ -17,7 +14,7 @@ fi PR_NUMBER=$(echo "${GITHUB_REF:-}" | sed 's|refs/pull/||; s|/.*||') if [ -z "$PR_NUMBER" ]; then echo "无法获取PR编号,全量执行Vitest" - npx --no-install vitest run --coverage + bash scripts/ci/step_frontend_run.sh "npx vitest run --coverage" exit $? fi @@ -29,9 +26,7 @@ try: web_files = [] for f in files: fname = f['filename'] - # 只关注前端源码文件 if fname.startswith('apps/web/src/') and fname.endswith(('.ts', '.tsx', '.js', '.jsx')) and f['status'] != 'removed': - # 去掉apps/web/前缀,变成相对路径 web_files.append(fname.replace('apps/web/', '')) print(' '.join(web_files)) except Exception as e: @@ -40,36 +35,33 @@ except Exception as e: if [ -z "$CHANGED_FILES" ]; then echo "PR未改动前端源码文件,跳过Vitest" - echo "(如果配置了前端单测门禁,请确保至少有一个相关测试)" exit 0 fi FILE_COUNT=$(echo "$CHANGED_FILES" | wc -w) echo "PR改动了 $FILE_COUNT 个前端文件" -echo "改动文件: $CHANGED_FILES" # 如果改动文件太多(超过30个),全量跑更可靠 if [ "$FILE_COUNT" -gt 30 ]; then - echo "改动文件较多(>$FILE_COUNT),降级为全量执行以确保覆盖" - npx --no-install vitest run --coverage + echo "改动文件较多,全量执行Vitest" + bash scripts/ci/step_frontend_run.sh "npx vitest run --coverage" exit $? fi -# 使用vitest related 跑增量测试(子命令,非flag) echo "" echo "=== 增量执行 Vitest(只跑相关测试)===" echo "相关源文件: $CHANGED_FILES" echo "" +# 在Docker Node容器中执行增量测试 set +e -npx --no-install vitest run related $CHANGED_FILES +bash scripts/ci/step_frontend_run.sh "npx vitest run related $CHANGED_FILES" VITEST_EXIT=$? set -e if [ "$VITEST_EXIT" -eq 0 ]; then echo "" echo "✅ 增量测试通过" - echo "(仅覆盖与改动相关的测试用例)" exit 0 else echo ""