blog.dopana

Back

如果你曾经编写过 GitHub Actions 的流水线,你可能很清楚什么叫作“YAML 疲劳(YAML Fatigue)”。每当你想添加一个简单的条件步骤,或者让测试并行运行,你就会陷入与空格缩进的搏斗、在多行字符串中嵌套 Bash 脚本,以及为了调试一个语法错误而连续提交 20 次的困境。

但在 Cloudflare 全新的原生 CI/CD 系统中,再也不需要 YAML 了。我们使用 TypeScript。

因为 CI/CD 流水线配置本质上就是一组逐步执行的指令,Cloudflare 允许你直接使用类型安全的 TypeScript 代码 来进行配置。以下是关于如何编写该配置的详细、通俗易懂的指南。

YAML 与 TypeScript 的对比#

在传统配置下,流水线只是静态的配置文件。而在 Cloudflare CI Workflows 中,流水线本身就是一个处于运行状态的代码程序:

graph LR
    YAML["📄 静态 YAML 配置文件<br/>- 难以编写循环结构<br/>- 缺少原生函数支持<br/>- 嵌套繁琐的 Bash 脚本"]
    TS["🦕 TypeScript 代码程序<br/>- 支持循环与 Try/Catch 捕获<br/>- 极其简单的并行处理方式<br/>- 完整的类型推导与自动补全"]
    
    YAML -->|被替代为| TS

用 TypeScript 编写 CI 流水线#

以下是使用 TypeScript 配置的 CI/CD 工作流的完整、详细示例。

代码细节深度剖析#

1. 依赖安装与智能缓存#

deps = await ci.runner({
  name: 'install',
  command: 'bun install --frozen-lockfile',
  cache: { inputs: ['package.json', 'bun.lock'] },
});
typescript

你不再需要手动编写冗长复杂的目录缓存规则,只需传入一个指向依赖锁文件(lockfile)的 cache 参数。Cloudflare 会自动为你的依赖环境生成沙箱快照并将其保存到 R2 存储桶中。在锁文件没有更改的情况下,下次运行就会瞬间秒级加载!

2. 并行执行(并发性)#

await Promise.all([
  deps.runner({ name: 'lint', command: 'bun run lint' }),
  deps.runner({ name: 'test', command: 'bun run test' }),
  ...
]);
typescript

在 YAML 中,要实现并行任务,你必须定义复杂的独立 Jobs,并设置相互依赖的构建矩阵。而在 TypeScript 中,你只需要调用 JavaScript 原生的 Promise.all()。Cloudflare 会为每个命令启动完全隔离的沙盒并并发运行,从而大幅缩短你的 CI 执行总时长。

3. 可自我修复的 Try/Catch 异常捕获#

catch (failure) {
  if (isCiRunnerFailure(failure)) {
     // 触发 AI 代理人,自动修复代码并生成新的 Git 提交!
  }
}
typescript

如果测试运行失败,catch 代码块会捕捉到运行错误,自动召唤一个 AI 代理人(例如使用 Workers AI 模型)。AI 能够自动阅读报错日志,编写出修复代码,然后把它提交并推送至一个新的 Git 分支供你一键合并,无需人类程序员在线盯梢。

绑定触发器 (wrangler.toml)#

要将代码仓库推送事件与该 TypeScript 工作流进行绑定,只需在 wrangler.toml 文件中声明事件触发绑定:

每当有代码推送到你指定的 Artifacts 命名空间,Cloudflare 就会自动为你派生并启动该 TypeScript 脚本的一个新实例。

参考资料#