2026-09-01 · 原文发布日
合并PR自动生成客户版更新日志草稿
n8n免费模板:每周五抓取指定GitHub仓库已合并的PR,剔除机器人提交和内部改动,查n8n数据表跳过已评估项,让OpenAI兼容模型判断哪些变化用户能感知,再按Added/Fixed/Changed分组写成更新日志,只生成Gmail草稿不发送,判定记录回写防止重复。
原文要点
原流程独有事实:每周五定时或手动触发,从Settings读仓库、时间窗、收件人;抓各仓库最近关闭issue,只留窗口内真实合并的PR;用conventional-commit前缀与skip标签剔除机器人和内部改动;查n8n Data Table跳过已评估PR并设max_changes上限;把剩余标题描述交给OpenAI兼容模型判断客户是否可感知,再按Added/Fixed/Changed写客户版日志,仅创建Gmail草稿不发送;每个已判PR upsert回shipped_changes防重。
这次做成什么
做一份只进Gmail草稿箱的客户版更新日志:本周合并PR先规则过滤,再模型判定是否用户可感知,已判记录写回数据表,下周不重复评估;本站用虚构仓库与PR练习。
准备什么
- n8n可编辑环境,能使用Schedule Trigger、GitHub、OpenAI兼容聊天模型、Gmail与Data Table功能
- GitHub凭据可读目标仓库,Gmail凭据只用于创建草稿,OpenAI兼容密钥可访问所选聊天模型
- n8n Data Table名为shipped_changes,且列含pr_key、repo、number、title、verdict、merged_on
- Settings中准备仓库列表owner/name逗号分隔、email_to、时间窗、skip_prefixes、skip_labels、max_changes
具体怎么做
配置周触发与仓库清单
Schedule Trigger设为每周五或手动;Settings节点放repos="acme/web,acme/api"、window_days=7、email_to="pm@example.test"、skip_prefixes=["chore","ci","docs","refactor"]、skip_labels=["internal","skip-changelog"]、max_changes=20;先只填沙盒仓库。
取合并PR并做硬过滤
GitHub节点按仓库读取最近关闭issues,Code节点只保留merged_at在窗口内的PR;删除author含bot或app的作者;title命中skip_prefixes或labels含skip_labels直接记verdict=skipped_internal,不送模型,但仍可upsert避免重复。
查重并限制一次提示长度
用pr_key=repo#number查询shipped_changes,存在即跳过;剩余按merged_on升序截到max_changes,超出的留到下周,避免PR清单过长导致输出被截;把本批送入模型前列成JSON。
模型判定并只建草稿
模型先输出每项{pr_key,noticeable,category,reason},再把noticeable=true的项按Added/Fixed/Changed写中文客户版;Gmail节点Create Draft,收件人用email_to,正文含摘要、日志、已判PR全清单;最后每个已判PR upsert一行,verdict存noticeable/skipped_internal/not_noticeable。
可直接复制的材料
Settings配置示例
本站独立示例;send_mode只是提醒不发送,实际仍需确认Gmail节点为Create Draft。
{"repos":"acme/web,acme/api","window_days":7,"email_to":"pm@example.test","skip_prefixes":["chore","ci","docs","refactor","test"],"skip_labels":["internal","skip-changelog"],"max_changes":20,"data_table":"shipped_changes","send_mode":"draft_only"}合成PR批次数据
虚构合成批次;acme仓库、人物与日期均为演示,不能当真实客户信息。
[{"repo":"acme/web","number":128,"title":"feat: 报表导出支持选择列","author":"lina","labels":["feature"],"merged_on":"2026-08-28","body":"客户可在导出面板勾选字段。"},{"repo":"acme/web","number":131,"title":"fix: 修复日期筛选少算一天","author":"kai","labels":["bug"],"merged_on":"2026-08-29","body":"时区边界导致截止日少一天。"},{"repo":"acme/api","number":77,"title":"chore: 更新内部依赖","author":"dependabot[bot]","labels":["internal"],"merged_on":"2026-08-27","body":"仅内部维护。"}]判定与成稿提示词
本站编写;{{prs_json}}注入上一步截断后的批次,max_changes需匹配模型上下文。
你将收到JSON数组PRs。两步输出严格JSON:第一步judgements逐项给{"pr_key":"repo#number","noticeable":true/false,"category":"Added|Fixed|Changed|Skip","reason":"客户是否能感知的一句话"};机器人、内部维护、仅重构文档测试一律noticeable=false。第二步changelog只用noticeable=true项,按Added/Fixed/Changed分组,面向非技术客户,不写commit hash,不夸大性能。输出格式:{"judgements":[...],"changelog":"...","summary":"80字内"}。PRs={{prs_json}}输入与输出示例
本站虚构演示,非作者结果,未运行;verdict与输入标签、作者和窗口一致。
输入
把合成PR批次放入流程,设window覆盖2026-08-24至2026-08-31,shipped_changes为空,max_changes=20。对应输出
判定示意:acme/web#128 noticeable=true Added;acme/web#131 noticeable=true Fixed;acme/api#77因bot与internal skipped_internal。Gmail草稿正文含“本周更新:报表导出可勾选字段;修复日期筛选少算一天”,summary为“2项客户可见变化,1项内部跳过”,并附已判PR全清单。做完检查这些
- 草稿只出现在Gmail Drafts,流程没有任何发送动作或按钮被触发
- shipped_changes运行后含repo#128、repo#131、repo#77三行,重复运行被跳过
- bot作者、chore前缀、internal标签在未进模型前就被硬过滤
- judgements数量不超过max_changes,超出批次在日志中标记留到下周
容易卡住的地方
- GitHub凭据缺仓库读权限会让issue抓取为空,误判成本周无变化
- email_to填错会把含内部清单的草稿建到错误收件人,虽不发送也泄露上下文
- 模型上下文小而max_changes过大,长清单可能被截断导致分组缺失
- Data Table列名不一致会upsert失败,下次重复评估同一批PR
本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。
- 原文标题
- Draft customer-facing changelogs from merged GitHub PRs with OpenAI and Gmail
- 原作者
- Daniel Shashko
- 原始发布日期
- 2026-09-01T05:26:05.562Z
- 来源
- https://n8n.io/workflows/18981