21篇技术草稿躺在文件夹里吃灰,每篇都写着"下次一定"。这位开发者用GitHub Actions+Supabase(一种开源后端即服务平台)造了个流水线,一天全清空了。
事件现场:从"下次一定"到"一键全发"
事情始于一个典型的开发者困境。他在搭建Flutter Web+Supabase应用时,每个新功能都触发写作灵感,但手动发布流程繁琐到足以杀死所有动力。
文件夹里的草稿越积越多:note-comments.md、app-feedback.md、workflow-automation.md……21个.md文件,21个未完成的承诺。
他决定用技术解决技术人的拖延。不是逼自己自律,而是把 friction(摩擦成本)降到零。
核心设计:把发布流程变成API调用
整个系统的枢纽是一个Supabase Edge Function,命名为schedule-hub。所有平台API调用都汇聚到这里,像机场的中转航站楼。
关键代码逻辑很直白:接收标题、内容、目标平台、标签,然后分流到Qiita或dev.to。但有个细节值得注意——前端元数据的处理。
他的草稿沿用Zenn/Qiita的frontmatter格式(文件顶部的YAML配置块),但发布时这些元数据不该出现在正文里。Edge Function在服务端执行stripFrontmatter(),用字符串操作精准切除:
检测"---"开头,找第二个"---"位置,切片返回。三行代码解决格式兼容问题,避免客户端预处理。
更关键的设计决策在权限层。他把blog.auto_publish加入publicActions列表,这意味着GitHub Actions可以直接用SERVICE_ROLE_KEY调用,跳过JWT(一种令牌认证机制)的繁琐流程。
「No token juggling needed」,他在代码注释里写道。一个布尔值的配置,省下一整套令牌刷新逻辑。
双语言并行:一套代码,两个市场
技术内容的地域割裂是个真问题。日本开发者刷Qiita,国际开发者看dev.to,两个池子不互通。
他的解决方案是文件级分离:同主题的日文版和英文版分别存储,通过命令行参数指定路径。workflow_dispatch(一种手动触发的工作流机制)接受四个输入:
draft_path指向日文版,draft_path_en指向英文版,platforms控制目标平台,dry_run提供安全预览。
命令行调用示例:
gh workflow run blog-publish.yml --field draft_path="..." --field platforms="qiita,devto"
这种设计暴露了一个产品洞察:自动化不是消灭人工判断,而是把决策点前置到触发时刻。发哪个版本、上哪个平台、是否仅预览——这些选择仍然需要人做,但执行成本归零。
数据收束:这件事为什么重要
21篇草稿的清理,表面是效率工具的胜利,实质是内容生产关系的重构。
技术写作的长期痛点在于:创作和发布是两个不同的心智模式。创作需要深度思考,发布需要处理格式、标签、平台差异、登录状态——这些琐碎足够让任何灵感熄火。
他的流水线把后者封装成基础设施。结果不是"写得更多",而是"写完就能发",心理账户从"项目"降级为"动作"。
更深层的影响在于双语言策略的可行性验证。过去维护双语内容需要双倍工时,现在边际成本趋近于零。这对技术布道者、开源项目维护者、出海创业者都是可复用的模板。
GitHub Actions的workflow_dispatch+Supabase Edge Function的组合,本质上是用Serverless(无服务器架构)的计费模型替代了自建CI/CD(持续集成/持续部署)的固定成本。按调用付费,闲置归零。
最后看一组隐性数据:21篇草稿的积压周期未公开,但从文件名日期跨度(3月28日至4月12日)推算,平均积压约15天。自动化后,发布延迟从"周级"压缩到"分钟级"。
这不是关于写作速度的故事,是关于决策损耗的消除。每个"下次一定"背后,都是一次微型的自我谈判失败。而他选择不跟自己谈判,直接改系统。
热门跟贴