小小免责声明:本文是一个 AI Coding 趣味实践,不是严肃的软件工程方法论。合历的"宜合并""忌发布"数据来自 GitHub 公开数据。技术大佬请轻喷,欢迎把它当成一个周末小玩具来试玩。
前天,我在知名交友网站刷着推,看到不愿意透露姓名的网友说:以后除非事态紧急,都挑有仪式感 / 特殊的时间合并代码。
我第一反应是"需求来了",这周的实践教程就它了。做一个会读项目气质的"代码老黄历",让合并代码的人择个良辰 merge,让提交 PR 的人知晓下一个吉时是何时。
需求梳理
这个项目叫"合历",名字自然不是我取的。而是我把需求交给 GPT 之后,它将其命名为合历,这很合理。
合历的功能很简单,你输入一个公开 GitHub 仓库地址,或者某个具体 PR 链接。页面读取项目的公开数据,再告诉你:未来 64 天内,下一次适合合并代码的时间是什么时候。
图注:合历的 v3 版本,第一个版本没能截图
一开始,我给 AI 的需求很朴素:
Plain
我想做一个项目。
用户输入 GitHub 项目地址,
你根据项目内容、提交记录和合并记录,
告诉用户下一个"合并代码的良辰吉时"是什么时候。
页面参考老黄历风格,但主色调改成蓝色。
搜索未来 64 天,而不是 45 天。
为了保持这个玩具项目的轻量感,我没让 AI 没有上框架,也没有 npm。整个项目只有简单的 index.html、styles.css 和 app.js文件,搭配一个七牛的 LAS 服务器就能跑。
在电脑本地环境下,执行 python3 -m http.server 4173,再访问 http://localhost:4173,就能看到页面样式。
到这里,是不是都很简单?一次性就能成功的项目,就写不出一篇稿子了。
下面,我们开始翻车。
AI 的执念是 09:09
第一版(下面简称 v1)跑出来之后,我兴冲冲地在 GitHub Trending 扒拉了两个 GitHub 项目给合历,想看看它们下一个 PR 的吉时是何时。
结果,awesome-llm-apps 推荐 9 月 9 日 09:00。ai-hedge-fund 还是 9 月 9 日,只是变成了 10:10。
我当时的反应是,Codex 你是在偷懒吗?经过我和 Codex 对线之后,好吧,是人类的问题。Codex 确实没有偷懒,是我给它的方向太容易让它去"偷懒"。
v1 的评分设计中,月日相同、时间成双、回文日期之类的"仪式感分数"太高。虽然该项目的提交习惯也参与计算,但权重不够,导致结果就是哪个数字漂亮,哪个日子就胜出。
新的计算逻辑
所以,后面让 Codex 调整了一波计算逻辑。仪式感只能是最后的一点加分项,绝对不能压过项目自己的节奏。
修改了不下 5 个版本之后,目前的"合历"会综合看这些信息:
-
最近的提交和 PR 合并更重要,较旧记录会逐渐降低权重;
-
团队经常在哪个星期、哪个时间段合并;
-
两次合并之间通常隔多久,节奏是否稳定;
-
PR 从创建到合并一般需要多长时间,给 Review 和 CI 留出缓冲;
-
最近 30 天的项目活跃度是在上升,还是在降温;
-
项目的语言、创建时间、提交 SHA 和 PR 会生成一个项目指纹,避免所有项目同分时得到同一个结果;
-
周末、深夜和周五下班后会扣分;
-
09:09、10:10、月日相合和回文日期仍然保留,但只负责最后那一点仪式感。
这样,同一个漂亮时间不再适合全世界所有仓库。
图注:合历优化之后,之前两个项目的吉时对比。某种程度上,你可以通过下一个 PR 合并时间来判断这个项目是否"活跃"
Merge & Release 傻傻分不清
合历做到一半的时候,我又提出一个看起来很有道理的需求:如果下一个 PR 正好让版本累计到 16、32、64、128 这种二进制进位,是不是就可以发版?还可以显示"距离下一次发布还差多少个 PR"。
Codex 只负责思考如何实现,不会判断你的需求是否合理。它照着这个方向,开始补逻辑了。
直到我突然反应过来:我提需求的时候,一直想的是"Release",但是和 Codex 交流的时候一直在说"合并 PR",我将 Merge 和 Release 完全搞混了。
PR 作为协作和代码合并事件,从提交到合并的时间,一般不会很长。而一次版本发布,通常要累积多个 PR,要几周甚至几个月才发一次版本。所以,上面那个看似不错的需求,其实并不存在合理点。
但既然已经有这种设定在了,Merge 和 Release 还是都在合历上体现了。它俩被拆分成了两条独立的线:
-
PR 和 Commit 用来分析"什么时候适合合并";
-
GitHub Release 历史用来分析"什么时候可能适合发版本"。
合历的主功能是 PR 合并良辰吉时,所以我让 Codex 把 Release 变成了一个小彩蛋。只有当项目仍然活跃,但已经明显超过自己的典型发版周期时,合历才会悄悄递上一枚"沉睡版本"。
点开之后,会看到发版吉时。
图注:沉睡版本 / 发版吉时彩蛋
有时候,功能不是越多越好。把某些功能藏起来,可能会更有意思,像个寻宝游戏。
界面迭代
虽然这个项目的页面叫"合历",如果只给一个时间还是差了点意思。
我参考了在线老黄历的布局,主色调是红色和金色。个人觉得有点土,让 Codex 把整个页面的色调限制在白、蓝、黑灰三组颜色中。不用渐变色,也不要米白色。而提示文案部分,则采用更轻的蓝灰色,不和正文抢注意力。
首页左右两侧,保留了"宜"和"忌":
-
宜:合并、评审、补文档、修 Bug、整理看板......
-
忌:跳过测试、强推主干、周五夜发、无预案、热修无记录......
这些内容会根据本地日期稳定生成,每天 00:00 换一签。不是每次刷新都乱跳,而是同一天看到同一份"代码运势"。
为了增加一点重复访问的新鲜感,我让 Codex 加了一个八日代码签册。不用登录,最近一次排盘和近 8 天的签到记录都会保存在当前浏览器里。下次再访问,合历页面会自动填入上次的项目,还可以直接恢复当时的排盘。
当然,本机保存不是云端同步。如果你换了浏览器、清理浏览器数据,上一次的签文记录就会消失。
吉时的六个栏目
随着需求一点点增加,合历页面最后有了六个入口:
-
首页:用来输入仓库或 PR,查看每日宜忌;
-
项目黄历:可查看项目年龄、语言、活跃度和成就签章;
-
合并吉时:设有首选时间、三个备选、完整评分和指定时刻验吉;
-
提交命理:查看提交与合并在星期和小时上的分布;
-
代码风水:用语言构成和项目节奏生成趣味解读;
-
发布宜忌:只使用真实 Release 记录推算版本窗口。
此外,还有一些我个人很喜欢的小功能:
-
从四个候选时间里"摇一支签";
-
合并前勾选 CI、Review、同步主分支和回滚预案;
-
四项完成后,盖一枚"今日合并许可证";
-
输入某个具体时间,看这个时刻是"宜"还是"忌";
-
生成签文分享图;
-
输入具体 PR 链接时,额外考虑 PR 是否开放、是否还是 Draft。
图注:合并之前的 checklist 已集齐
到这里,合历已经不是个单纯的日期计算器了,它像是个围绕 Merge PR 做的一些工作,能帮你 check PR 合并的条件等等细节。
又不是不能用
这个模块主要是本人给 Codex 提的需求,让它基于需求描述,再进行细化,最后生成代码实现。
这里也遇到了 AI Coding 的常见问题,就是它太擅长交付一个"截图看起来已经完成"的页面。至于按钮到底能不能点、状态能不能回来、手机上会不会横向溢出,都是需要我们最后做一遍人工验收。
下面是我实际验收过程中,先后遇到的问题:
-
除了首页,其他导航一概不能点击;
-
算完项目后,点首页不能正常回去;
-
点击"再算一个",上一轮结果没有完全清空;
-
模块需要输入项目时,居然又把用户赶回首页;
-
两个不同项目被漂亮数字带去了同一个时间;
-
GitHub 未登录接口的免费查询额度用完后,错误提示不够清楚;
-
页面回到首页后,URL 还留着
?repo=...,刷新一下又自动跳回结果页。
尤其是最后一个问题,太隐蔽了不仔细未必能发现。
毕竟我们点击首页,视觉上发现已经回去了,一切看起来完全正常。但地址栏还记着仓库参数。直到最后一轮真实浏览器回归,我点完首页又刷新了一次,才发现它会重新分析项目。
好吧,页面没有意见,URL 有自己的想法。
最终,我把首页、五个栏目、仓库提交、错误输入、重新计算、记忆恢复、指定时刻、抽签、合并仪式、分享图、发版彩蛋都重新走了一遍,又分别检查了桌面端和 390px 宽的移动端。
这也是这次实践里最重要的一课,不要只问 AI"做完了吗",要让它真的把项目跑起来。
GitHub 的免费额度
因为要频繁地测试合历推算的结果,中间我看到过这样一次提示:GitHub 免费查询额度暂时用完了。
第一反应是:我要不要充个钱?
但,事实上不用。这个项目读取的是 GitHub 公开 API,不登录也能访问,但匿名请求有频率限制。等额度恢复后可以继续使用;项目里也给仓库数据做了短期缓存,避免同一个仓库反复查询。
如果后续访问量真的上来了,再考虑后端代理、GitHub Token 或统一缓存。对于一个周末实践,先保持零登录和零后端,反而更轻。
重申免责声明
"合历"不是真的黄历。你的 PR 不会因为合历推荐了 10:24,就让一个没过测试的 PR 突然变得安全;也不会因为今天写着"宜合并",就替你承担线上事故。
这个小项目,最大的作用是按下 Merge 之前增加了一个停顿:CI 绿了吗?Review 过了吗?主分支同步了吗?回滚方案准备好了吗?
如果四件事都做完了,那么无论此刻是不是所谓的"良辰吉时",至少这是一次更从容的合并。
本项目采用纯 HTML、CSS 和原生 JavaScript 编写,由七牛云独家赞助 Token 开发,并托管在七牛云 LAS 服务上,通过 LAS 服务器自带的公网域名进行访问。
至此,愿你每一次合并,都顺利通过 CI。