Skip to content

Commit 1929140

Browse files
authored
增加 CI 质量与安全合并门禁 (#106)
新增前后端质量与安全检查,并将检查设为 main 分支的强制合并门禁。后端使用轻量测试依赖运行完整测试,前端执行测试、Lint、类型检查、构建与高危依赖审计。
1 parent ef1d4bb commit 1929140

3 files changed

Lines changed: 123 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
name: 质量与安全门禁
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
push:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
15+
concurrency:
16+
group: ci-${{ github.workflow }}-${{ github.ref }}
17+
cancel-in-progress: true
18+
19+
jobs:
20+
frontend:
21+
name: 前端质量与安全
22+
runs-on: ubuntu-24.04
23+
timeout-minutes: 20
24+
defaults:
25+
run:
26+
working-directory: apps/web
27+
steps:
28+
- name: 检出代码
29+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
30+
with:
31+
persist-credentials: false
32+
33+
- name: 配置 Node.js
34+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
35+
with:
36+
node-version: 22
37+
cache: npm
38+
cache-dependency-path: apps/web/package-lock.json
39+
40+
- name: 安装前端依赖
41+
run: npm ci --ignore-scripts --no-audit --no-fund --registry=https://registry.npmmirror.com
42+
43+
- name: 运行前端测试
44+
run: npm test -- --reporter=verbose
45+
46+
- name: 运行 ESLint
47+
run: npm run lint
48+
49+
- name: 运行 TypeScript 检查
50+
run: ./node_modules/.bin/tsc --noEmit
51+
52+
- name: 构建生产版本
53+
run: npm run build
54+
55+
- name: 审计生产依赖
56+
run: npm audit --omit=dev --audit-level=high --registry=https://registry.npmjs.org
57+
58+
backend:
59+
name: 后端测试
60+
runs-on: ubuntu-24.04
61+
timeout-minutes: 20
62+
steps:
63+
- name: 检出代码
64+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
65+
with:
66+
persist-credentials: false
67+
68+
- name: 配置 Python
69+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
70+
with:
71+
python-version: "3.12"
72+
cache: pip
73+
cache-dependency-path: backend/requirements-test.txt
74+
75+
- name: 安装后端测试依赖
76+
id: pip_aliyun
77+
continue-on-error: true
78+
run: python -m pip install -r backend/requirements-test.txt -i https://mirrors.aliyun.com/pypi/simple/
79+
80+
- name: 阿里云失败后使用清华镜像重试
81+
if: steps.pip_aliyun.outcome == 'failure'
82+
run: python -m pip install -r backend/requirements-test.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
83+
84+
- name: 检查轻量依赖边界
85+
run: |
86+
python -m pip check
87+
python - <<'PY'
88+
from importlib.util import find_spec
89+
90+
excluded = (
91+
"torch", "whisper", "demucs", "voxcpm", "modelscope",
92+
"librosa", "audiostretchy", "spacy", "openunmix",
93+
)
94+
installed = [name for name in excluded if find_spec(name) is not None]
95+
if installed:
96+
raise SystemExit(f"CI 测试环境意外安装了重型依赖: {', '.join(installed)}")
97+
PY
98+
99+
- name: 运行后端全量测试
100+
run: python -m pytest backend/tests -q

backend/app/adapters/audio.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@
33
import json
44
from pathlib import Path
55

6-
import librosa
76
import numpy as np
87
import soundfile as sf
9-
from audiostretchy.stretch import stretch_audio
108
from pydub import AudioSegment
119

1210
BASE_FACTOR_MIN = 0.8
@@ -35,6 +33,8 @@ def split_audio_by_translation(vocals_file: Path, translation_file: Path, sessio
3533

3634

3735
def _audio_duration(file: Path) -> tuple[float, int]:
36+
import librosa
37+
3838
y, sr = librosa.load(str(file), sr=None)
3939
return len(y) / sr, sr
4040

@@ -53,9 +53,13 @@ def _base_speed_factor(translation: list[dict], tts_files: list[Path]) -> float:
5353

5454

5555
def _stretch_segment(audio_file: Path, ratio: float, target_sec: float, cache_dir: Path) -> tuple[np.ndarray, int]:
56+
import librosa
57+
5658
if abs(ratio - 1.0) < SPEED_NOOP_EPSILON:
5759
y, sr = librosa.load(str(audio_file), sr=None)
5860
return y, sr
61+
from audiostretchy.stretch import stretch_audio
62+
5963
out_path = cache_dir / audio_file.name
6064
stretch_audio(str(audio_file), str(out_path), ratio=ratio)
6165
y, sr = librosa.load(str(out_path), sr=None)

backend/requirements-test.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Lightweight CPU-only dependencies for the complete backend unit-test suite.
2+
# Keep this list aligned with imports exercised by backend/tests. Runtime ML
3+
# packages such as Torch, Whisper, OpenUnmix, librosa, AudioStretchy and VoxCPM
4+
# are mocked or lazily imported by tests and intentionally do not belong here.
5+
fastapi
6+
pydantic
7+
python-dotenv
8+
python-multipart
9+
pwdlib[argon2]>=0.3,<1
10+
openai
11+
yt-dlp
12+
requests
13+
numpy
14+
soundfile
15+
pydub
16+
pytest
17+
httpx[socks]

0 commit comments

Comments
 (0)