fix: CI全面修复 - node镜像拉取/204响应体断言/phash测试用例
Deploy / Staging E2E Tests (push) Has been cancelled
Deploy / Build Production Runtime Images (push) Has been cancelled
Deploy / Deploy Production (push) Has been cancelled
Deploy / Production Browser E2E (push) Has been cancelled
Deploy / Deploy Staging (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Failing after 135h4m5s
CI/CD Pipeline / Validate Code Quality And Tests (push) Failing after 135h4m5s

1. 前端node镜像去掉--pull=never,缺失时自动拉取
   - ci-cd.yml: 5处前端lint/test步骤
   - deploy.yml: 2处web构建步骤

2. 修复from __future__ import annotations导致的204路由断言失败
   - FastAPI 0.115 把字符串"None"当作有效response_model
   - 给9个路由文件的204 DELETE路由显式加response_model=None

3. 修复phash测试用例:纯色图pHash必然相同(DC分量被排除)
   - 改用随机噪声图测试差异性
This commit is contained in:
xiaoxia
2026-07-03 21:49:48 +08:00
parent 03e54fc234
commit fd90d7730c
12 changed files with 15 additions and 19 deletions
-5
View File
@@ -194,7 +194,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
@@ -205,7 +204,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
@@ -216,7 +214,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
@@ -227,7 +224,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
@@ -238,7 +234,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
-2
View File
@@ -75,7 +75,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
@@ -394,7 +393,6 @@ jobs:
run: |
set -eu
docker run --rm \
--pull=never \
-v "$PWD:/workspace" \
-w /workspace/apps/web \
docker.m.daocloud.io/library/node:20 \
+1 -1
View File
@@ -239,7 +239,7 @@ def get_duplication_detail(
return _to_detail_response(record)
@router.delete("/records/{record_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/records/{record_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_duplication_record(
record_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
+1 -1
View File
@@ -279,7 +279,7 @@ def update_plan(
return _to_response(result)
@router.delete("/{plan_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{plan_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_plan(
plan_id: str,
db: Session = Depends(get_db_session),
+1 -1
View File
@@ -241,7 +241,7 @@ def update_template(
return _to_response(result)
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_template(
template_id: str,
db: Session = Depends(get_db_session),
+1 -1
View File
@@ -172,7 +172,7 @@ def update_recipe(
return _to_response(recipe)
@router.delete("/{recipe_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{recipe_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_recipe(
recipe_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
+2 -2
View File
@@ -193,7 +193,7 @@ def update_template(
return _to_response(template)
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_template(
template_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
@@ -271,7 +271,7 @@ def create_category(
)
@router.delete("/categories/{category_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/categories/{category_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_category(
category_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
+1 -1
View File
@@ -143,7 +143,7 @@ def update_title(
return _to_response(item)
@router.delete("/{title_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{title_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_title(
title_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
+1 -1
View File
@@ -174,7 +174,7 @@ def get_tts_job_status(
)
@router.delete("/jobs/{job_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/jobs/{job_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_tts_job(
job_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
+1 -1
View File
@@ -170,7 +170,7 @@ def get_voice_clone_status(
@router.delete(
"/{clone_id}",
status_code=status.HTTP_204_NO_CONTENT,
status_code=status.HTTP_204_NO_CONTENT, response_model=None,
)
def delete_voice_clone(
clone_id: str,
+1 -1
View File
@@ -316,7 +316,7 @@ def update_voice(
return _to_response(item)
@router.delete("/{voice_id}", status_code=status.HTTP_204_NO_CONTENT)
@router.delete("/{voice_id}", status_code=status.HTTP_204_NO_CONTENT, response_model=None)
def delete_voice(
voice_id: str,
authenticated_user: AuthenticatedUser = Depends(get_current_user),
+5 -2
View File
@@ -164,8 +164,11 @@ class TestComputePhash:
assert hash1 == hash2
def test_different_images_different_hash(self):
img1 = np.zeros((64, 64, 3), dtype=np.uint8)
img2 = np.full((64, 64, 3), 255, dtype=np.uint8)
# 用两张不同的随机噪声图测试(纯色图 pHash 会相同,因为排除了 DC 分量)
rng = np.random.RandomState(42)
img1 = rng.randint(0, 256, (64, 64, 3), dtype=np.uint8)
rng2 = np.random.RandomState(99)
img2 = rng2.randint(0, 256, (64, 64, 3), dtype=np.uint8)
hash1 = compute_phash(img1)
hash2 = compute_phash(img2)
assert hash1 != hash2