ci: expand host-verify with lint, typecheck, security, depscan and coverage gates

Phase 1 of audit-hardening CI expansion (baseline origin/main aebc623):
- lint: ruff E9 hard gate; full E,F@120 report-only (baseline 111 items)
- typecheck: mypy default mode, production scope, report-only (baseline 24)
- security: bandit production scope, report-only (baseline 287, High 5)
- depscan: pip-audit on requirements-ci.txt, hard gate (0 vulns; repo has
  no production dependency manifest, see summary)
- coverage: production 58 files, fail-under=75 (baseline measured 76%)
- release build: E9 + pip-audit hard gates before packaging; full reports
  stay in host-verify to avoid drift
No production code changed; CI billing failure mode unchanged.
This commit is contained in:
host committed 2026-11-03 02:48:54 +00:00
1 parent 7b537c31a6
commit c127beaa98
6 files changed
+204

No files matched your search

+134
View File
@@ -3,6 +3,23 @@ on:
pull_request:
push:
branches: [main]
# CI 扩项(审计加固第 2 步,基线 origin/main aebc623):
# 每个新检查的生效范围与存量如实写在步骤注释里,不写空转检查:
# - lint 全量 E,F@120:基线 111 项,见 PR 摘要存量清单,第一阶段
# 只报告不阻塞(continue-on-error),语法 E9 仍是硬门禁;
# - mypy 默认模式、生产范围:基线 24 项,第一阶段只报告不阻塞;
# - bandit 生产范围:基线 287 项(High 5),第一阶段只报告不阻塞;
# - pip-audit:只审计 requirements-ci.txt(仓库无生产依赖清单,
# 生产代码除宿主延迟加载的 psycopg 驱动外只用标准库,见摘要),
# 该文件 0 已知漏洞时硬通过,有漏洞即硬失败;
# - coverage:阈值见 coverage 作业的 --fail-under,取实测值向下取整,
# 防回归不冒充高覆盖;收紧计划见 PR 摘要。
# 账单说明:CI 目前仍是 GitHub 账单故障秒级失败模式,账单恢复是
# 用户在 GitHub Billing 侧的动作;本 workflow 的改动不声称改了账单、
# 也不为变绿绕过任何检查,账单恢复后上述检查才实际生效。
# 失败即停:同一作业内步骤按顺序执行,前一步硬失败则后一步不跑;
# 报告类步骤用 continue-on-error + always() 上传报告,作业本身仍绿,
# 但报告 artifact 里是失败的原始输出,不是“通过”。
jobs:
verify:
runs-on: ubuntu-latest
@@ -14,3 +31,120 @@ jobs:
- run: python3 -m unittest discover -s tests -v
- run: python3 -m unittest discover -s cloud/tests -v
- run: python3 -m unittest discover -s deploy/tests -v
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements-ci.txt
# 硬门禁:语法错误。基线 0 项,通过才继续;不是空集,
# E9 覆盖 SyntaxError / IndentationError 等编译级错误。
- name: lint 硬门禁(ruff E9 语法)
run: ruff check --select E9 .
# 报告类:全量 E,F@120,基线 111 项(F401 43、E702 40、E501 13、
# E402 8、F841 4、F811 1、F821 1、E741 1)。第二阶段清零存量后
# 删掉 continue-on-error,转硬门禁;删之前不声称 lint 已通过。
- name: lint 全量报告(ruff E,F)
continue-on-error: true
run: ruff check . | tee ruff-report.txt
- name: 上传 lint 报告
if: always()
uses: actions/upload-artifact@v4
with:
name: ruff-report
path: ruff-report.txt
if-no-files-found: warn
retention-days: 30
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements-ci.txt
# 报告类:mypy 默认模式、生产范围(mypy.ini 排除 tests/work)。
# 基线 24 项(8 文件,见 PR 摘要)。第二阶段清零后删掉
# continue-on-error,转硬门禁;不改生产代码凑通过。
- name: 类型检查报告(mypy 生产范围)
continue-on-error: true
run: mypy host.py cloud deploy client.py run_parallel.py | tee mypy-report.txt
- name: 上传类型检查报告
if: always()
uses: actions/upload-artifact@v4
with:
name: mypy-report
path: mypy-report.txt
if-no-files-found: warn
retention-days: 30
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements-ci.txt
# 报告类:bandit 生产范围,测试目录排除(测试故意用 shell/tmp)。
# 基线 287 项:Low 235、Medium 47、High 5。High 5 = host.py 的
# B602 shell=True 4 处(审计已知 P0)+ cloud/harness2.py 的
# B324 sha1 非安全用途 1 处。先修 High 再转硬门禁;不通过
# --skip 跳过 B602/B324 来假装通过。
- name: 安全扫描报告(bandit 生产范围)
continue-on-error: true
# bandit 有发现即 exit 1:该失败是步骤的真实状态,作业靠
# continue-on-error 继续到上传;不要用 `; cat` 吞掉 exit 码。
run: bandit -r host.py cloud deploy client.py run_parallel.py -x cloud/tests,tests,deploy/tests -f txt -o bandit-report.txt
- name: 上传安全扫描报告
if: always()
uses: actions/upload-artifact@v4
with:
name: bandit-report
path: bandit-report.txt
if-no-files-found: warn
retention-days: 30
depscan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements-ci.txt
# 硬门禁:审计 CI 工具链清单本身。基线 0 已知漏洞。
# 局限如实说明:仓库没有生产依赖清单可审计——生产代码只用
# 标准库,psycopg/psycopg2 只在宿主侧延迟加载、版本不在仓库
# 里;给生产依赖建清单并审计是第二阶段项,不是本作业的覆盖
# 范围,本作业不声称覆盖了生产依赖。
- name: 依赖扫描(pip-audit,CI 工具链清单)
run: pip-audit -r requirements-ci.txt
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r requirements-ci.txt
# 硬门禁:三套 unittest 在 coverage 下重跑(与 verify 作业同款
# 测试,只是加了计量),生产代码覆盖率低于门槛即失败。
# 门槛取基线实测值向下取整到 5 的倍数:基线实测 76%
# (22392 行,生产 58 文件),故门槛 75%,见 PR 摘要。
# 目的是防回归,不是 0 空转,也不是未经实测的 80%。
- name: 覆盖率计量与门槛
run: |
coverage run -m unittest discover -s tests
coverage run --append -m unittest discover -s cloud/tests
coverage run --append -m unittest discover -s deploy/tests
coverage report --fail-under=75
coverage xml -o coverage.xml
- name: 上传覆盖率报告
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-xml
path: coverage.xml
if-no-files-found: warn
retention-days: 30
+10
View File
@@ -42,6 +42,16 @@ jobs:
python3 -m unittest discover -s tests -v
python3 -m unittest discover -s cloud/tests -v
python3 -m unittest discover -s deploy/tests -v
# CI 扩项在发布链路的最小硬门禁:语法 E9 + CI 工具链依赖扫描。
# 全量 lint/mypy/bandit 报告与覆盖率门槛只在 host-verify 里跑
# (PR 与 main 推送都会跑,走到 tag 的提交此前已过 host-verify),
# 这里不重复跑三套报告,避免发布作业与 host-verify 的检查漂移;
# 这里的两项是硬失败,失败则不产发布包。
- name: CI 扩项硬门禁(语法 + 依赖扫描)
run: |
pip install -r requirements-ci.txt
ruff check --select E9 .
pip-audit -r requirements-ci.txt
- name: 构建发布包(git archive + DEPLOYED_COMMIT + sha256)
id: build
run: |