修复 GitHub Issue 工作流
SkillDev tools修复 GitHub Issue 的完整工作流
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the 修复 GitHub Issue 工作流 skill
What this skill tells your AI
The instructions your AI receives, as published by open-guji/luatex-cn in .claude/skills/fix-github-issue/SKILL.md and read by ahel’s review.
当需要修复 GitHub issue 时,请遵循以下完整流程以确保代码质量和正确性。
1. 获取 Issue 详情
// turbo
首先,使用 gh CLI 工具获取 issue 的完整信息:
gh issue view <issue-number> --repo open-guji/luatex-cn
目的:
- 理解问题的具体描述
- 查看附带的截图或示例
- 了解用户期望的行为
2. 定位相关代码
使用搜索工具找到相关的代码文件:
// turbo 按关键词搜索(中英文关键词):
# 使用 Grep 工具搜索 issue 中提到的关键词
# 支持中英文混合搜索
// turbo 按文件类型搜索:
# 使用 Glob 工具查找相关文件
# 例如:**/*.lua, **/*.sty, **/*.tex
关键文件结构:
tex/core/- 核心渲染逻辑tex/guji/- 古籍特定功能tex/banxin/- 版心相关功能tex/decorate/- 装饰元素test/regression_test/tex/- 测试文件
3. 理解代码逻辑
// turbo 阅读相关文件:
- 使用 Read 工具仔细阅读定位到的文件
- 理解渲染流程和数据流
- 找出问题的根本原因
系统架构:
- Stage 1: Flatten nodes(展平节点)
- Stage 2: Layout grid(布局计算)
- Stage 3: Render page(渲染应用)
- 绘制背景
- 绘制边框和装饰元素
- 应用节点坐标
- 插件渲染
关键概念:
- Z-order(层叠顺序):后渲染的元素显示在上层
- Node list order:节点在列表中的顺序决定渲染顺序
- Plugin system:功能通过插件系统集成
- 坐标系统:理解 xoffset/yoffset 和 kern/shift 的区别
4. 重现问题
关键步骤:在修复前,必须先成功重现问题。
4.1 在 test_example 中重现
使用 /home/lishaodong/workspace/luatex-cn/test_example 目录创建最小复现用例:
cd /home/lishaodong/workspace/luatex-cn/test_example
# 创建测试文件 issue_<number>.tex
cat > issue_<number>.tex << 'EOF'
\documentclass{ltc-guji} % 或 ltc-cn-vbook 等
% 根据 issue 描述添加相关配置
\begin{document}
% 最小化的测试内容
\end{document}
EOF
# 编译测试
lualatex -interaction=nonstopmode issue_<number>.tex
目的:
- 验证问题确实存在
- 理解问题的触发条件
- 创建简化的复现场景
4.2 决定测试用例位置
成功重现后,根据用法频率选择测试位置:
常见用法 → test/regression_test/basic/tex/
如果是常用功能或核心特性,在已有测试文件中添加测试用例:
# 例如:标点相关 → punctuation.tex
# 例如:夹注相关 → jiazhu.tex
# 例如:版心相关 → page.tex
特点:
- 会被频繁运行(每次 regression test)
- 应该保持文件小而快
- 覆盖该功能的多种使用场景
不常见用法 → test/regression_test/past_issue/tex/
如果是边缘场景或特定字体/配置,创建独立测试文件:
# 命名格式:<feature>_issue<number>.tex
# 例如:vert_font_kinsoku_issue71.tex
特点:
- 记录历史问题(防止回归)
- 可以包含特殊配置或依赖
- 文件名直接关联 issue 编号
判断标准:
| 条件 | 位置 |
|---|---|
| 使用通用字体(Source Han Serif SC/TW-Kai) | basic |
| 使用特殊字体(KingHwa_OldSong + vert) | past_issue |
| 核心功能的常见用法(句读、夹注、版心) | basic |
| 特殊组合或边缘场景 | past_issue |
| 简单示例(< 30 行) | basic(合并到已有文件) |
| 复杂示例(> 30 行) | past_issue(独立文件) |
4.3 创建测试用例
在 basic 中添加(合并到已有文件):
% 在 test/regression_test/basic/tex/punctuation.tex 中添加
\newpage
% Test for issue #71: PUA punctuation positioning
\setmainfont[RawFeature={vert}]{KingHwa_OldSong}
测试标点位置,。、
在 past_issue 中创建(独立文件):
cd test/regression_test/past_issue/tex
cat > vert_font_kinsoku_issue71.tex << 'EOF'
\documentclass{ltc-cn-vbook}
\setmainfont[RawFeature={vert}]{KingHwa_OldSong}
\begin{document}
\begin{正文}
% 从 test_example 复制已验证的最小复现用例
\end{正文}
\end{document}
EOF
5. 实现修复
修改代码时注意:
- 保持代码风格一致
- 添加清晰的注释说明修改意图
- 考虑性能影响
- 避免破坏现有功能
常见问题类型及修复思路:
- 渲染层级问题:调整节点插入位置或渲染顺序
- 位置计算问题:检查坐标计算逻辑和参数传递
- 视觉效果问题:确认渲染参数和颜色设置
- 布局问题:检查网格计算和列宽行高设置
6. 验证修复(关键!)
期望:修复后,regression test 应该在相关测试文件上显示变化。
6.1 编译测试
// turbo 找到或创建相关的测试文件并编译:
lualatex --interaction=nonstopmode test/regression_test/basic/tex/<test-file>.tex
# 或
lualatex --interaction=nonstopmode test/regression_test/past_issue/tex/<test-file>.tex
6.2 单元测试(如果修改了 Lua 代码)
// turbo
texlua test/run_all.lua
必须先通过 unit tests,再运行 regression tests。
6.3 回归测试
// turbo 运行完整的回归测试以确保没有破坏现有功能:
python3 test/regression_test.py check
关键验证点:
-
✅ 修复的测试文件应该显示差异(FAIL 或像素差异)
- 如果 regression test 显示所有测试都 PASSED(0 像素差异)
- 说明修复可能没有生效或测试用例不正确
-
✅ 其他测试文件应该保持通过(PASSED,0 像素差异)
- 如果其他文件也出现差异,说明修复影响了其他功能
- 需要检查是否引入了副作用
期望输出示例:
FAIL: vert_font_kinsoku_issue71.tex differs on pages: [1] ← 修复生效!
PASSED: punctuation.tex (0 pixels diff) ← 其他测试不受影响
PASSED: jiazhu.tex (0 pixels diff)
...
6.4 视觉验证
检查修复效果:
# 查看生成的 PDF
okular test/regression_test/basic/pdf/<test-file>.pdf
# 或
okular test/regression_test/past_issue/pdf/<test-file>.pdf
# 查看差异图像
ls -lh test/regression_test/basic/diff/
# 或
ls -lh test/regression_test/past_issue/diff/
确认要点:
- ✅ 生成的 PDF 中问题已修复
- ✅ 视觉效果符合 issue 描述的预期
- ✅ 没有引入新的视觉问题
- ✅ 如果修复涉及多个测试文件,确保都检查过
使用 overlay_compare.py 对比修复前后(可选):
python3 scripts/overlay_compare.py \
test/regression_test/past_issue/baseline/<test>-1.png \
test/regression_test/past_issue/current/<test>-1.png \
/tmp/overlay.png
# 查看叠加对比图
okular /tmp/overlay.png
7. 创建 past-issue 回归测试(必须!)
每个 issue 修复必须在 test/regression_test/past_issue/tex/ 中创建对应的回归测试文件,防止问题复发。
7.1 创建测试文件
# 命名格式:<feature>_issue<number>.tex
cat > test/regression_test/past_issue/tex/<feature>_issue<number>.tex << 'EOF'
% Issue #<number>: <问题简要描述>
% https://github.com/open-guji/luatex-cn/issues/<number>
%
% 修复前: <修复前的错误行为>
% 修复后: <修复后的正确行为>
\documentclass{ltc-guji}
\setmainfont{TW-Kai}
\关闭分页
\无标点模式
\title{测试}
\chapter{Issue <number>}
\begin{document}
\begin{正文}
% 从 test_example 复制已验证的最小复现用例
% 包含多个测试场景(正常用法 + 边缘情况)
\end{正文}
\end{document}
EOF
测试文件要求:
- 文件头注释包含 issue 编号、GitHub URL、修复前后行为描述
- 包含正常对照(不受影响的基线场景)
- 包含核心复现场景(触发 bug 的用例)
- 可选:包含边缘情况(auto-balance 切换、不同 textbox 类型等)
7.2 生成 baseline
# 生成 past_issue suite 的 baseline
python3 test/regression_test.py save --past-issues
7.3 验证测试通过
# 确认新测试能通过
python3 test/regression_test.py check --past-issues
8. 更新基线
仅当修复导致了预期的视觉变化时更新基线:
// turbo
# 更新所有有差异的测试文件
python3 test/regression_test.py save
# 或只更新特定测试文件
python3 test/regression_test.py save test/regression_test/past_issue/tex/<test-file>.tex
注意事项:
- ✅ 只保存真正需要更新的基线图像
- ✅ 确认所有视觉变化都是预期且正确的
- ❌ 不要提交临时文件(diff/ 和 current/ 目录)
- ❌ 不要提交 PDF 文件(会自动生成)
验证更新:
# 再次运行 regression test,应该全部 PASSED
python3 test/regression_test.py check
9. 提交代码
9.1 检查变更
// turbo
git status
git diff
预期应该看到:
- ✅ 修改的源代码文件(.lua, .sty, .tex)
- ✅ 新增或更新的 baseline 图片(.png)
- ✅ 新增的测试文件(如果在 past_issue 中创建了新测试)
- ❌ 不应该有 PDF、辅助文件、diff/current 目录下的文件
9.2 暂存文件
只暂存需要提交的文件:
git add <modified-source-files> # .lua, .sty 等
git add test/regression_test/basic/baseline/*.png # 如果更新了 basic 基线
git add test/regression_test/past_issue/baseline/*.png # 如果更新了 past_issue 基线
git add test/regression_test/past_issue/tex/<new-test>.tex # 如果创建了新测试
常见错误(不要提交):
- ❌
test/regression_test/*/pdf/*.pdf- PDF 文件(自动生成) - ❌
test/regression_test/*/diff/*.png- 差异图(临时文件) - ❌
test/regression_test/*/current/*.png- 当前输出(临时文件) - ❌
*.aux,*.log,*.out- LaTeX 辅助文件 - ❌
test_example/下的任何文件(仅用于本地测试)
9.3 编写提交信息
使用规范的提交信息格式。标题必须包含 fix #<number>(不是 (#number)),这样 GitHub Actions 才能自动关联 issue:
git commit -m "fix #<issue-number>: <简短标题>
<详细描述原问题是什么,为什么会出现>
Changes:
- <具体改动点1>
- <具体改动点2>
<如有必要,说明技术实现细节>
Co-Authored-By: Claude <model> <noreply@anthropic.com>
"
提交信息要素:
- 标题:以
fix #<number>:开头(不要 用(#number)— GitHub 不会识别) - 问题描述:说明原来的问题及其原因
- Changes:列出具体的代码改动
- 技术细节:如有必要,解释实现方案和考虑因素
- Co-Authored-By:标注协作者
10. 最终验证
// turbo 提交后再次运行回归测试确保一切正常:
python3 test/regression_test.py check
所有测试应该显示 PASSED(基线已更新,不应再有差异)
11. 推送代码
# 推送到远程 dev 分支
git push origin dev
12. 在 Issue 中添加修复总结
推送成功后,在 issue 中添加修复总结 comment。
流程:
- 先将 comment 内容展示给用户 review
- 用户确认后,使用
gh issue comment命令发布:
gh issue comment <issue-number> --repo open-guji/luatex-cn --body "$(cat <<'COMMENT'
✅ 修复已推送到 dev 分支。
## 问题总结
<简要说明问题是什么>
## 根本原因
<解释为什么会出现这个问题>
## 解决方案
<说明如何修复的>
## 测试验证
- ✓ unit tests 通过
- ✓ regression tests 通过
- ✓ 新增/更新测试: <test-file-name>
## 相关提交
- <commit-hash>: <commit-title>
COMMENT
)"
重要:
- 不要手动关闭 issue — GitHub Actions 会自动标记为 fix ready,发布新版本时统一关闭
- comment 内容必须先给用户 review — 确认后再发布
最佳实践
- 小步提交:一次只修复一个问题,避免混杂多个改动
- 充分测试:确保回归测试全部通过,验证视觉效果
- 详细文档:提交信息要清晰完整,便于代码审查和后续维护
- 保持沟通:不确定时在 issue 中与维护者讨论方案
- 代码审查:推送前自己先仔细审查所有改动
- 理解原理:深入理解代码逻辑,避免临时性的 hack 方案
- 考虑兼容性:确保修复不会影响其他功能或破坏向后兼容性
Signals
- GitHub stars
- 105
- Forks
- 10
- Last commit
- Sep 2026
ahel review
S4info
community integration — published by open-guji, not github
Automated review, not a security audit. Ruleset v1.
Advanced
- Catalog kind
- skill
- Gateway key
fix-github-issue-open-guji- Source
- github.com/open-guji/luatex-cn