ysoseri.us

实习日志 / 记一次迁workflow

记一次迁workflow

# 01

昨天下午突然队友的pr纷纷被卡,说是action配额的问题。打开action一看,坏菜,从16:28开始job runs全红。额度烧干了。

Private org给的配额也太少了,下个月更新等不了啊……于是想着抓紧迁出去吧。

第一反应是上自建 runner。问题是,手头压根没有能常驻跑东西的机器,就一个 CF 的域名,但Workers 是无状态的。

想了想,那就去薅 Oracle Free Tier 呗,ARM 4核24G 传说中的白嫖天花板

喜提abc,换网络清缓存试了好几轮,还是卡在最后一步,Oracle 这系统跟抽卡一样,感觉下班前应该是等不到它心情好的时候,先不管了。

90d224727bdbf776f2d88bcf26e72b13.png

转头去搞 Azure for Students的$100 credit,顺便让codex帮我改着工作流,把 runs-on: ubuntu-latest 换成自己的机器标签,理论上就能接着跑,计算资源我出,GitHub 负责派活,听起来相当文明。

注册登录这一步倒是很顺利,结果创建虚拟机的时候,换了六个区域都起不了免费机器,要么就是NotAvailableForSubscription。Claude告诉我可能是 Resource Provider 没注册,注册完以为有救了,又发现学生订阅还有个区域策略,只让部署到"最佳可用区域",但最佳可用区域也选不了能用的VM,1GB内存的都不给我用。好吧,Azure 那份 runner 安装脚本因此也只能先躺尸了

受不了,先下班,我需要食物(bushi

下班时间。再开电脑已经是晚上11点了,resume一下action页面,震撼404

吓得我赶紧去看了看setting

This setting has been disabled by organization administrators.

这下真的版本大削了

没办法,还是试试CircleCI吧。

来来回回不给我显示这个仓库,原来是差一个 Organization access 的申请,All I need is just点个 Request 按钮,等 owner 批准就完了

绕了这么大一圈最后落在一个最朴素的动作上,还不如一开始就发邮件。。。

# 02

想了想先不给David发邮件了,大晚上骚扰他怪不好的。

但 PR policy 和 Kanban 状态同步这两件事不能干等着,没有CI都不能没有他俩。它们本来也是塞在 Actions 里的,但仔细想想,好像挂cloudflare上也能行?接个webhook,感觉很有搞头。

熬大夜开干。其实现在的workflow确实有点重了,但目前来说,跑个PR policy检查和 Kanban sync对我的cf免费额度基本不算事。

于是又复习了一遍第一周写的自动化规则:依赖前序满足了就从backlog进入Ready → 建个带 closing reference 的 Draft PR 就进 In progress → PR 转 Ready for review 就进 In review → merge 了就是 Done。这里有个小坑:PR 描述里得写 Closes #123 才算数,写 Refs #123 不推动状态,这也是我专门写了个PR policy的原因,一直排查repo手动关issue麻烦死了,那还不如让队友的agent听话点。

Worker、Queue、定时触发器、webhook 都建好了,token 和 secret 也规规矩矩存成 Worker secret,没往仓库里塞。webhook 第一次 ping 是 500,重发变 200,跟 secret 更新时间点得比较近,猜测是传播延迟,但没抓到实锤日志

又拿一个真实 Issue 和 PR 完整跑了一遍状态流转,Draft PR 建好,卡片乖乖进了 In progress。结果把 PR 切成 Ready 之后,In review 死活不出现。查了半天 webhook 全部 202,Queue 也有生产者消费者,每个组件看起来都在正常上班,合起来就是没结果,翻 Worker 日志才挖出真凶:

Illegal invocation: function called with incorrect `this` reference.

原因是把 Cloudflare 平台的全局 fetch 直接存成了对象的成员方法,之后用 this.fetcher(...) 去调,本地测试的 mock fetch 完全不在乎这种事,但 Cloudflare 的 runtime 很在乎,JavaScript 在这种时候就会提醒你,函数不只是一段代码,它对自己的上下文归属还挺执着的()

改成显式调用重新部署之后,下一次真实事件就顺利推进到了 In review,PR 合并后 Issue 自动关闭,卡片也进了 Done。整条 Ready → In progress → In review → Done 算是走通了

1点半。本来打算关机睡觉,想了想15分钟一次的兜底扫描,工作时间内翻 Project、扫 open PR、读最近100条 closed/merged PR,CF倒是没啥,对 GitHub API 真不算友好,而且反复写入同样的状态属于纯浪费。

让AI写了个优化方案:webhook 走主路径,兜底扫描从15分钟拉长到一小时;写之前先读一下当前状态,一样就不写了;别死磕最近100条 closed PR,记个游标或者按时间窗口来;32KB 的原始 payload 也没必要整个搬进 Queue,挑真正要用的字段就够;用 delivery ID 去重,防止 webhook 重发导致重复写入。这些都是可靠性层面的打磨,不是在救火,现在这个量级下 Worker 大概率扛得住,更可能先遇到瓶颈的是 GitHub API 限额,或者是某个管理员还没看消息

先这样吧,明天再说

# 03

今早上standup,还没等我提起来,助教就给我们说我们组用了整个org 90%的月额度,怪不好意思的

找到David邮箱,10:35把邮件给他发过去了

有个 Request ,速点

没这么理直气壮

唉,技术能自动化很多事,但目前还没有哪个 workflow 能自动让管理员及时看消息,至少现在没有

本来还想写个总结升华一下,想想算了