Gate O — module production phải có ít nhất một nơi import --------------------------------------------------------- Ba cổng đang có đều không bắt được mã chết, đúng như 1.400 dòng ở commit trước đã chứng minh. Gate O dựng đồ thị import bằng AST từ `__init__`/`__main__`/`app`, theo cả import muộn trong thân hàm. Hai ngoại lệ tự động để `ALLOWLIST` không phải chép lại cùng một lý do nhiều lần: `__init__.py` của gói mà mọi thành viên đều dormant, và module chỉ được chính mã dormant đã miễn trừ import. Cổng cũng đếm tuổi 9 seam chưa nối dây (nhãn `SEAM · dựng <ngày>`) và nhắc khi quá 30 ngày. Chỉ [WARN], không làm CI đỏ: để nó đỏ thì CI sẽ đỏ vào một buổi sáng mà không ai sửa gì, và cách nhanh nhất để xanh lại là sửa ngày. Cổng LOC — quét 366 file thay vì 191 ------------------------------------ `DEFAULT_TARGET_DIRS` chỉ có 4 gói Clean Architecture, nên một file 944 dòng trong `ui/` vẫn qua cổng. Nay quét cả `ui/`, `core/`, `providers/`, `security/`, `mcp_servers/` và các module ở thư mục gốc. 18 file đã dài hơn 400 dòng từ trước nằm trong `LEGACY_ALLOWANCE` — bánh cóc chỉ quay một chiều, và nó đo DÒNG MÃ chứ không đo dòng vật lý. Bánh cóc chỉ hỏi một câu, "file này có đang để thêm việc vào không?", mà viết thêm một docstring thì không. Đếm dòng vật lý ở đó biến cổng thành thứ phạt người viết tài liệu, và cách dễ nhất để làm nó xanh lại sẽ là xoá bớt chú thích. Trần 400 vẫn đếm dòng vật lý — đó là hợp đồng đã chốt của cổng S. CI -- Ghim tên thư mục checkout là `cowork_local`: nhiều test characterization sinh tiến trình con `python -c "from cowork_local... import ..."`, mà tiến trình con chỉ import được khi trên sys.path có thư mục mang đúng tên gói. Checkout vào thư mục tên khác làm 73 test đỏ vì lý do không liên quan tới mã. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
91 lines
3.3 KiB
YAML
91 lines
3.3 KiB
YAML
name: CI
|
|
|
|
on:
|
|
push:
|
|
branches:
|
|
- main
|
|
pull_request:
|
|
branches:
|
|
- main
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
defaults:
|
|
run:
|
|
working-directory: cowork_local
|
|
env:
|
|
# Tiến trình con của test import `cowork_local` qua đường này.
|
|
PYTHONPATH: ${{ github.workspace }}
|
|
steps:
|
|
# Checkout PHẢI nằm trong thư mục tên đúng `cowork_local`.
|
|
# Nhiều test characterization sinh tiến trình con chạy
|
|
# `python -c "from cowork_local... import ..."`; tiến trình con đó chỉ
|
|
# import được khi trên sys.path có một thư mục mang đúng tên gói. Checkout
|
|
# vào thư mục tên khác làm 73 test đỏ vì lý do không liên quan tới mã.
|
|
- name: Check out source
|
|
uses: actions/checkout@v4
|
|
with:
|
|
path: cowork_local
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.11"
|
|
cache: pip
|
|
cache-dependency-path: cowork_local/requirements-test.txt
|
|
|
|
- name: Install test dependencies
|
|
run: python -m pip install --disable-pip-version-check -r requirements-test.txt
|
|
|
|
- name: Check Python syntax
|
|
run: |
|
|
python - <<'PY'
|
|
from pathlib import Path
|
|
|
|
files = list(Path(".").rglob("*.py"))
|
|
for path in files:
|
|
compile(path.read_text(encoding="utf-8"), str(path), "exec")
|
|
print(f"Parsed {len(files)} Python files")
|
|
PY
|
|
|
|
- name: Run tests
|
|
run: python -m pytest tests -q
|
|
|
|
# --- CASAN Verification Gate -------------------------------------
|
|
# Ba check này là điều kiện của cổng ngày 30/08. Chạy trên MỌI PR để
|
|
# biết vi phạm ngay hôm phát sinh, thay vì dồn tới ngày cổng.
|
|
#
|
|
# Check 1 do Team Gamma sở hữu và đã có. Check 2 (Team Hoa) và Check 3
|
|
# (Team Duy) chưa viết — bước dưới bỏ qua nếu script chưa tồn tại, để
|
|
# thêm cổng không làm đỏ CI của hai team kia.
|
|
|
|
- name: "CASAN Check 1 — không có credential lộ (Team Gamma)"
|
|
run: |
|
|
python scripts/audit_security.py --self-test
|
|
python scripts/audit_security.py
|
|
|
|
- name: "CASAN Check 2 — file production ≤ 400 dòng (Team Hoa)"
|
|
run: |
|
|
if [ -f scripts/check_loc.py ]; then
|
|
python scripts/check_loc.py
|
|
else
|
|
echo "scripts/check_loc.py chưa có — Team Hoa viết, hạn 30/08. Bỏ qua."
|
|
fi
|
|
|
|
- name: "CASAN Check 3 — domain/ và application/ không import PySide6 (Team Duy)"
|
|
run: |
|
|
if [ -f scripts/check_imports.py ]; then
|
|
python scripts/check_imports.py
|
|
else
|
|
echo "scripts/check_imports.py chưa có — Team Duy viết, hạn 30/08. Bỏ qua."
|
|
fi
|
|
|
|
# Cổng O bổ sung sau đợt đối chiếu AS-IS/TO-BE: ba check trên đều không
|
|
# bắt được mã chết (file không ai import vẫn đúng chiều phụ thuộc, vẫn
|
|
# sạch credential, vẫn dưới 400 dòng). Đợt đó tìm ra 1.400 dòng mã trùng
|
|
# lặp chết lọt qua đúng theo cách này.
|
|
- name: "CASAN Check O — module production phải có nơi import"
|
|
run: python scripts/check_orphan_modules.py
|