forked from Gitlink/gitlink-cli
89 lines
4.0 KiB
Markdown
89 lines
4.0 KiB
Markdown
# 评分卡样例(scorecard-sample)
|
||
|
||
> 这是 `gitlink-gatekeeper` 渲染到 PR 评论的 **评分卡** 的样例输出,严格套用 [`REFERENCE.md`](../REFERENCE.md) 第 6 节模板。
|
||
> 本样例对应一个 **REQUEST_CHANGES**(含硬门禁失败)案例,用于展示模板的全部分区(硬门禁、Must fix、Should fix、Nits、Strengths、Next steps 同时出现)。
|
||
> 数值来自默认策略 `gatekeeper.yaml`(权重 40/20/15/15/10,blocker=100/major=25/minor=5/nit=1,pass=85、request_changes=60),可按第 3–5 节算法逐项复算。
|
||
|
||
---
|
||
|
||
## 输入快照(用于复算)
|
||
|
||
| 信号 | 值 |
|
||
|------|----|
|
||
| 变更文件总数 `changed_files` | 6 |
|
||
| 匹配 `source_globs` 的源码文件 `changed_src` | 4 |
|
||
| 匹配 `test_globs` 的测试文件 `changed_tests` | 0 |
|
||
| AI 审查发现 | 0 blocker / 1 major / 2 minor / 1 nit |
|
||
| PR 描述 | 非空,长度 64 字符(≥30) |
|
||
| 关联 Issue | 否(body 无 `#<n>`) |
|
||
| commits | 共 4 条,符合 Conventional Commits 的 3 条 |
|
||
| CI 状态 | passing |
|
||
|
||
## 逐维复算
|
||
|
||
- **review_findings(权重 40)**:`penalty = 25(major) + 2×5(minor) + 1(nit) = 36`;
|
||
`score = 40 × max(0, 1 − 36/40) = 40 × 0.1 = 4`
|
||
- **test_coverage(权重 20)**:`changed_src=4 > 0` 且 `changed_tests=0` → `score = 0`
|
||
- **pr_hygiene(权重 15)**:描述≥30 ✓(+1/3);关联 Issue ✗(0);体量 `changed_files=6 ≤ max_changed_files/2 = 40` ✓(+1/3) → 命中比例 `2/3`;
|
||
`score = round(15 × 2/3) = round(10.0) = 10`
|
||
- **commit_quality(权重 15)**:`conforming/total = 3/4`;`score = round(15 × 3/4) = round(11.25) = 11`
|
||
- **ci_status(权重 10)**:passing → `score = 10`
|
||
- **总分**:`4 + 0 + 10 + 11 + 10 = 35`
|
||
|
||
## 硬门禁判定
|
||
|
||
| 门禁 | 配置 | 命中? |
|
||
|------|------|:------:|
|
||
| `forbid_blocker_findings` | true | 否(无 blocker) |
|
||
| `require_ci_pass` | true | 否(CI passing) |
|
||
| `require_tests_for_src_changes` | true | **是**(changed_src=4>0 且 changed_tests=0) |
|
||
| `require_linked_issue` | false | —(未启用) |
|
||
| `max_changed_files` | 80 | 否(6 ≤ 80) |
|
||
|
||
`hard_gate_failed = true` → 裁决直接 **REQUEST_CHANGES**(无视总分;本例总分 35 < 60 亦指向 REQUEST_CHANGES,结论一致)。
|
||
|
||
---
|
||
|
||
## 渲染的评分卡(回写到 PR 的正文)
|
||
|
||
```markdown
|
||
## 🛡️ Gatekeeper Report — PR #128 feat(auth): add refresh-token rotation
|
||
|
||
**Verdict: ❌ REQUEST_CHANGES** · Score: 35/100 · policy: gatekeeper.yaml@v1
|
||
|
||
| Dimension | Weight | Score | Notes |
|
||
|-----------|:------:|:-----:|-------|
|
||
| Review findings | 40 | 4/40 | 0 blocker / 1 major / 2 minor / 1 nit |
|
||
| Test coverage | 20 | 0/20 | 4 src / 0 test files |
|
||
| PR hygiene | 15 | 10/15 | desc ✓ / linked issue ✗ / size ✓ |
|
||
| Commit quality | 15 | 11/15 | 3/4 conventional |
|
||
| CI status | 10 | 10/10 | passing |
|
||
|
||
### ⛔ Hard gate failures (1)
|
||
- `require_tests_for_src_changes`: 改动了 4 个源码文件,但本 PR 未包含任何测试文件
|
||
|
||
### 🔴 Must fix (1)
|
||
- [major] 刷新令牌轮换未对旧令牌做失效处理,存在重放风险 — internal/auth/refresh.go:88
|
||
|
||
### 🟡 Should fix (2)
|
||
- [minor] `rotateToken` 缺少超时上下文,可能阻塞请求 — internal/auth/refresh.go:54
|
||
- [minor] 错误信息直接回显内部字段名,建议脱敏 — internal/auth/handler.go:131
|
||
|
||
### 🔵 Nits (1)
|
||
- [nit] 导出函数 `NewRotator` 缺少 doc 注释 — internal/auth/refresh.go:22
|
||
|
||
### ✅ Strengths
|
||
- commit 历史清晰,3/4 符合 Conventional Commits
|
||
- CI 全绿,PR 描述完整
|
||
|
||
### Next steps
|
||
1. **补测试**:为改动的 4 个源码文件添加单元测试,解除 `require_tests_for_src_changes` 硬门禁
|
||
2. 修复 major 重放风险后重新触发 gatekeeper
|
||
---
|
||
*Generated by gitlink-gatekeeper · policy-as-code PR gate · re-run after changes*
|
||
```
|
||
|
||
---
|
||
|
||
> **复算提示**:把上表「输入快照」的数值代入 `REFERENCE.md` 第 3 节公式即可重现每一维得分;硬门禁按第 4 节逐项比对;最终裁决按第 5 节判定树得出。同策略 + 同输入 → 同评分卡(确定性)。
|