* feat(cache): 节点缓存键纳入 CSV 文件签名 ComfyUI 默认只按输入参数判断缓存是否命中。两个节点读的都是外部 CSV, 参数不变而文件被替换时缓存会一直返回旧结果,用户换了数据却看不到变化。 把 CSV 的「路径 + 修改时间 + 大小」作为 IS_CHANGED 的返回值纳入缓存键: 文件一变就重算;文件与参数都不变时指纹稳定,缓存行为与 5.0.0 一致。 路径被防护拒绝时返回稳定哨兵而不抛异常,避免打断 ComfyUI 的缓存判断。 * perf(character): 派生索引随记录缓存,单次执行 62.6ms -> 26.7ms 角色节点每次执行都在 3.4 万条记录上重建 record_map / names / 作品筛选下标, CSV 没变时完全是重复劳动。把三者收进 CharacterIndex,与记录共用同一套 文件签名缓存(路径 + 列 + mtime + size),CSV 一变就重建。 顺带修掉作品下拉菜单的失效问题:菜单改为按默认 CSV 的文件签名缓存, 换 CSV 后自动重建,不再需要重启 ComfyUI。 实测(本机 7 次中位数):generate_characters 62.62ms -> 26.69ms(-57%)。 4 个 seed 下 prompt / characters_json / tested_count 逐字节一致。 剩余约 24ms 在 select_artists 的排除过滤里;改动它会改变 RNG 消耗顺序、 破坏同 seed 的可复现性,故本次不动。 * docs(db): 修正 generation_lock 的持锁范围说明 原文写「调用方应在进入本上下文之前完成抽样、权重计算、提示词拼装等纯 CPU 工作」, 但 RollingArtist 的重试循环必须待在事务里(命中已测组合要重新抽样), 实际持锁时长等于一次完整生成。文档与实现互相矛盾,读代码的人会误判并发行为。 改为如实描述:持锁时长由调用方决定,两种调用方式各自的代价是什么, 以及为什么不能简单把抽样挪到锁外(冲突只会推迟到写入时才被 INSERT OR IGNORE 吞掉)。 同时修正 __init__ 里「不覆盖事务内的业务计算」这句同样有歧义的注释。 纯注释改动,无代码行为变化。 * docs: 5.1.0 变更记录与 README 缓存/性能说明(T-04) * docs: 归档 v5.1.0 迭代计划至 docs/iteration * chore(release): 5.1.0 * docs: 回填 v5.1.0 执行记录至迭代计划 * docs: Sprint 2 文档三件套(决策登记/性能基线/测试口径) * ci/chore: mypy job 非阻断 + .comfyignore 收敛发布面
86 lines
2.3 KiB
YAML
86 lines
2.3 KiB
YAML
name: CI
|
|
|
|
# PR 与推送到长期分支时跑测试与静态检查。
|
|
# 额外提供一个聚合 job `ci`:分支保护只引用它一个名字,
|
|
# 以后增删矩阵项都不用改分支保护配置。
|
|
on:
|
|
push:
|
|
branches: [main, dev]
|
|
pull_request:
|
|
branches: [main, dev]
|
|
workflow_dispatch:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
test:
|
|
name: Test (py${{ matrix.python-version }} / ${{ matrix.os }})
|
|
runs-on: ${{ matrix.os }}
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
python-version: ["3.8", "3.11", "3.12"]
|
|
os: [ubuntu-latest]
|
|
include:
|
|
# 路径防护有 Windows 特有分支(扩展前缀 / ADS / UNC),必须覆盖
|
|
- os: windows-latest
|
|
python-version: "3.11"
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: ${{ matrix.python-version }}
|
|
- name: Install dev dependencies
|
|
run: |
|
|
python -m pip install --upgrade pip
|
|
pip install -e ".[dev]"
|
|
- name: Run tests
|
|
run: pytest -q
|
|
|
|
lint:
|
|
name: Lint
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.11"
|
|
- name: Install ruff
|
|
run: pip install ruff
|
|
- name: Ruff check
|
|
run: ruff check .
|
|
- name: Ruff format check
|
|
run: ruff format --check .
|
|
|
|
mypy:
|
|
name: Mypy
|
|
runs-on: ubuntu-latest
|
|
# 第一期非阻断:只报告不作为合并门禁;本地连续 2 周全绿后可转阻断(删去 continue-on-error 并纳入 ci 聚合)
|
|
continue-on-error: true
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
- uses: actions/setup-python@v5
|
|
with:
|
|
python-version: "3.11"
|
|
- name: Install dev dependencies
|
|
run: pip install -e ".[dev]"
|
|
- name: Run mypy
|
|
run: python -m mypy ra_core RollingArtist.py RollingCharacter.py
|
|
|
|
ci:
|
|
name: ci
|
|
if: always()
|
|
needs: [test, lint]
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Aggregate result
|
|
run: |
|
|
echo "test=${{ needs.test.result }} lint=${{ needs.lint.result }}"
|
|
test "${{ needs.test.result }}" = "success"
|
|
test "${{ needs.lint.result }}" = "success"
|