# CI/CD 流水线
**本文引用的文件**
- [package.json](file://package.json)
- [vitest.config.mts](file://vitest.config.mts)
- [wrangler.jsonc](file://wrangler.jsonc)
- [tsconfig.json](file://tsconfig.json)
- [src/index.ts](file://src/index.ts)
- [src/command/index.ts](file://src/command/index.ts)
- [src/scheduler/index.ts](file://src/scheduler/index.ts)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts)
- [test/index.spec.ts](file://test/index.spec.ts)
- [.gitignore](file://.gitignore)
- [worker-configuration.d.ts](file://worker-configuration.d.ts)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向 Cosmoe Bot 的 CI/CD 流水线设计与实施,目标是提供一套可落地的自动化测试、GitOps 工作流、多环境部署与安全策略,并给出监控与回滚的最佳实践。项目基于 Cloudflare Workers(Wrangler)与 Vitest 单元测试框架,具备定时任务与 KV 存储能力,适合在 GitHub Actions 等平台中实现端到端流水线。
## 项目结构
- 核心运行时入口为 src/index.ts,导出默认模块用于处理 HTTP 请求与计划任务。
- 命令与会话逻辑集中在 src/command/index.ts,使用 @grammyjs/conversations 与 @grammyjs/storage-cloudflare 进行对话状态持久化。
- 定时任务逻辑位于 src/scheduler/index.ts,通过 Wrangler 触发器周期性执行。
- 客户端封装了与外部 Cosmoe API 的交互,位于 src/client/cosmoe.ts。
- 测试使用 Vitest,配置于 vitest.config.mts,测试入口为 test/index.spec.ts。
- 部署与运行时配置由 wrangler.jsonc 提供,类型声明通过 worker-configuration.d.ts 生成。
```mermaid
graph TB
A["src/index.ts
导出默认模块"] --> B["src/command/index.ts
命令与会话"]
A --> C["src/scheduler/index.ts
计划任务"]
B --> D["src/client/cosmoe.ts
外部 API 客户端"]
E["test/index.spec.ts
单元测试入口"] --> A
F["vitest.config.mts
Vitest Workers 池配置"] --> E
G["wrangler.jsonc
部署与运行时配置"] --> A
H["tsconfig.json
编译配置"] --> A
```
**图表来源**
- [src/index.ts](file://src/index.ts#L1-L47)
- [src/command/index.ts](file://src/command/index.ts#L1-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503)
- [test/index.spec.ts](file://test/index.spec.ts#L1-L25)
- [vitest.config.mts](file://vitest.config.mts#L1-L12)
- [wrangler.jsonc](file://wrangler.jsonc#L1-L31)
- [tsconfig.json](file://tsconfig.json#L1-L46)
**章节来源**
- [src/index.ts](file://src/index.ts#L1-L47)
- [src/command/index.ts](file://src/command/index.ts#L1-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L1-L88)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L1-L503)
- [test/index.spec.ts](file://test/index.spec.ts#L1-L25)
- [vitest.config.mts](file://vitest.config.mts#L1-L12)
- [wrangler.jsonc](file://wrangler.jsonc#L1-L31)
- [tsconfig.json](file://tsconfig.json#L1-L46)
## 核心组件
- 入口模块与导出接口:负责初始化 Bot、注册命令菜单、转发请求至 grammY 处理器,并暴露 scheduled 方法以支持计划任务。
- 命令系统:集中注册 start、login、events、history、cancel 等命令,使用 KV 作为会话存储后端。
- 计划任务:周期性拉取新活动并通知已注册用户,使用 KV 记录最新事件 ID,避免重复推送。
- 外部 API 客户端:封装认证、查询活动、预订、取消等操作,统一返回结构体。
- 测试框架:Vitest + Workers 池,使用 cloudflare:test 环境进行单元与集成测试。
- 部署配置:Wrangler 统一管理名称、兼容时间、可观测性、触发器与 KV 绑定;tsconfig 控制编译行为。
**章节来源**
- [src/index.ts](file://src/index.ts#L6-L47)
- [src/command/index.ts](file://src/command/index.ts#L13-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
- [test/index.spec.ts](file://test/index.spec.ts#L1-L25)
- [vitest.config.mts](file://vitest.config.mts#L1-L12)
- [wrangler.jsonc](file://wrangler.jsonc#L5-L31)
- [tsconfig.json](file://tsconfig.json#L1-L46)
## 架构总览
下图展示从请求进入、命令处理、KV 会话存储、计划任务触发到外部 API 调用的整体流程。
```mermaid
graph TB
subgraph "运行时"
W["Worker 入口
src/index.ts"]
CMD["命令系统
src/command/index.ts"]
SCH["计划任务
src/scheduler/index.ts"]
KV["KV 命名空间
wrangler.jsonc"]
end
subgraph "外部服务"
TG["Telegram Bot API"]
API["Cosmoe API
src/client/cosmoe.ts"]
end
U["用户请求/回调"] --> W
W --> CMD
CMD --> KV
W --> SCH
SCH --> KV
SCH --> TG
CMD --> API
API --> CMD
```
**图表来源**
- [src/index.ts](file://src/index.ts#L13-L47)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
- [wrangler.jsonc](file://wrangler.jsonc#L21-L30)
## 详细组件分析
### 组件 A:Worker 入口与导出接口
- 责任边界:初始化 Bot、注册命令菜单、转发请求、暴露 scheduled。
- 关键点:Bot 初始化时读取环境变量中的 BOT_INFO 与 BOT_TOKEN;命令菜单一次性设置;scheduled 调用业务处理函数。
- 错误处理:命令菜单设置失败时记录错误日志;计划任务内捕获异常并记录。
```mermaid
sequenceDiagram
participant CF as "Cloudflare Workers"
participant IDX as "src/index.ts"
participant CMD as "src/command/index.ts"
participant API as "Telegram Bot API"
CF->>IDX : "fetch(request)"
IDX->>CMD : "setupCommands(bot, env)"
CMD-->>IDX : "命令注册完成"
IDX->>API : "setMyCommands([...])"
IDX-->>CF : "返回响应"
CF->>IDX : "scheduled(controller)"
IDX->>CMD : "调用计划任务处理"
```
**图表来源**
- [src/index.ts](file://src/index.ts#L13-L47)
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
**章节来源**
- [src/index.ts](file://src/index.ts#L13-L47)
### 组件 B:命令系统与会话存储
- 责任边界:注册命令、启动交互式登录会话、处理事件列表、历史记录、取消与登出。
- 会话存储:使用 @grammyjs/storage-cloudflare 将会话状态写入 KV,确保跨请求一致性。
- 回调处理:针对取消确认与优惠券选择的回调查询进行分发。
```mermaid
flowchart TD
Start(["进入命令处理"]) --> RegCmd["注册命令与会话"]
RegCmd --> Login["交互式登录会话"]
RegCmd --> Events["查询活动列表"]
RegCmd --> History["查看历史记录"]
RegCmd --> Cancel["发起取消流程"]
RegCmd --> Logout["执行登出"]
Login --> KVWrite["KV 写入会话状态"]
Events --> KVRead["KV 读取会话状态"]
History --> KVRead
Cancel --> KVRead
Logout --> KVDelete["KV 删除会话状态"]
KVWrite --> End(["结束"])
KVRead --> End
KVDelete --> End
```
**图表来源**
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
**章节来源**
- [src/command/index.ts](file://src/command/index.ts#L20-L110)
### 组件 C:计划任务与通知
- 责任边界:周期性检查新活动,向已注册用户发送 Markdown 通知,并更新最新事件 ID。
- 数据一致性:使用 KV 存储 latestEventId,避免重复推送。
- 异常处理:对单个用户的推送失败进行日志记录,不影响整体流程。
```mermaid
sequenceDiagram
participant CRON as "计划任务触发器"
participant SCH as "src/scheduler/index.ts"
participant KV as "KV 存储"
participant API as "Cosmoe API"
participant TG as "Telegram Bot API"
CRON->>SCH : "scheduled(controller)"
SCH->>KV : "读取 latestEventId"
SCH->>API : "获取所有活动"
API-->>SCH : "返回活动列表"
SCH->>KV : "遍历用户列表并发送通知"
KV-->>SCH : "返回用户键集合"
SCH->>TG : "sendMessage(userId, message)"
TG-->>SCH : "返回消息ID"
SCH->>KV : "更新 latestEventId"
SCH-->>CRON : "完成"
```
**图表来源**
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
- [wrangler.jsonc](file://wrangler.jsonc#L13-L17)
**章节来源**
- [src/scheduler/index.ts](file://src/scheduler/index.ts#L12-L88)
### 组件 D:外部 API 客户端
- 责任边界:封装认证、查询活动详情、用户资料、预订、取消、转场等 API。
- 数据模型:定义 ApiResponse、Event、EventDetail、Booking、Coupon 等接口,保证类型安全。
- 错误处理:未认证时抛出错误;密码长度校验;对网络请求结果进行结构化解析。
```mermaid
classDiagram
class CosmoeClient {
+getToken(username, password)
+getEvents()
+getEventDetail(eventId)
+getProfile()
+getMyBookings()
+bookEvent(request)
+changePassword(current, new)
+getUserProfile()
+getAvailableCoupons(eventId)
+updatePaymentOrder(bookingId, orderId)
+updateBookingNote(bookingId, note)
+cancelBooking(bookingId)
+selfReschedule(bookingId, newSlot)
+selfTransfer(bookingId, recipient)
+register(key, username, email, password, identity)
}
```
**图表来源**
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
**章节来源**
- [src/client/cosmoe.ts](file://src/client/cosmoe.ts#L113-L503)
### 组件 E:测试与配置
- 单元测试:使用 Vitest 与 @cloudflare/vitest-pool-workers,在 Workers 环境中模拟请求与上下文。
- 配置要点:Vitest 使用 defineWorkersConfig 指定 Wrangler 配置路径;tsconfig 启用严格模式与类型声明;.gitignore 排除 node_modules 与 wrangler 缓存目录。
```mermaid
flowchart TD
TStart(["执行测试"]) --> VConf["加载 Vitest Workers 配置"]
VConf --> Mock["创建请求与执行上下文"]
Mock --> Run["执行 worker.fetch()"]
Run --> Assert["断言响应内容"]
Assert --> End(["测试结束"])
```
**图表来源**
- [vitest.config.mts](file://vitest.config.mts#L1-L12)
- [test/index.spec.ts](file://test/index.spec.ts#L1-L25)
**章节来源**
- [test/index.spec.ts](file://test/index.spec.ts#L1-L25)
- [vitest.config.mts](file://vitest.config.mts#L1-L12)
- [.gitignore](file://.gitignore#L52-L168)
## 依赖关系分析
- 运行时依赖:grammy、@grammyjs/conversations、@grammyjs/storage-cloudflare。
- 开发依赖:vitest、@cloudflare/vitest-pool-workers、wrangler。
- 类型与编译:tsconfig 控制模块解析、严格模式与类型声明;worker-configuration.d.ts 由 wrangler 生成,提供运行时类型。
```mermaid
graph LR
P["package.json"] --> G["@grammyjs/conversations"]
P --> GC["@grammyjs/storage-cloudflare"]
P --> GR["grammy"]
P --> VT["vitest"]
P --> VP["@cloudflare/vitest-pool-workers"]
P --> WR["wrangler"]
TS["tsconfig.json"] --> SRC["src/**"]
WC["worker-configuration.d.ts"] --> SRC
WR --> CFG["wrangler.jsonc"]
```
**图表来源**
- [package.json](file://package.json#L12-L22)
- [tsconfig.json](file://tsconfig.json#L1-L46)
- [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L12)
- [wrangler.jsonc](file://wrangler.jsonc#L1-L31)
**章节来源**
- [package.json](file://package.json#L12-L22)
- [tsconfig.json](file://tsconfig.json#L1-L46)
- [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L12)
- [wrangler.jsonc](file://wrangler.jsonc#L1-L31)
## 性能考量
- 测试并发:Vitest Workers 池通过 poolOptions.workers.wrangler 指定配置路径,建议在 CI 中限制并发以平衡资源占用。
- KV 访问:会话与状态均依赖 KV,建议批量读取与写入,减少往返次数;对高频键值使用缓存策略。
- 计划任务频率:当前配置为每分钟一次,建议根据业务量调整,避免过度触发。
- 编译优化:tsconfig 启用严格模式与 isolatedModules,有助于早期发现潜在问题。
[本节为通用指导,无需具体文件引用]
## 故障排查指南
- 测试失败定位
- 使用 Vitest 输出与断言信息定位问题;结合 cloudflare:test 的 createExecutionContext 与 waitOnExecutionContext 确保异步任务完成。
- 参考测试入口与配置文件定位执行上下文与请求构造方式。
- 部署与运行时
- 检查 wrangler.jsonc 中的 triggers、vars、kv_namespaces 是否正确;确认 compatibility_date 与运行时版本匹配。
- 若类型报错,重新执行 wrangler types 生成 worker-configuration.d.ts。
- 计划任务异常
- 查看计划任务日志,确认 KV 读写是否成功;核对用户列表与消息发送返回值。
- 常见问题
- .gitignore 排除了 node_modules 与 wrangler 缓存,确保 CI 环境安装依赖后再执行测试与部署。
**章节来源**
- [test/index.spec.ts](file://test/index.spec.ts#L1-L25)
- [vitest.config.mts](file://vitest.config.mts#L1-L12)
- [wrangler.jsonc](file://wrangler.jsonc#L1-L31)
- [worker-configuration.d.ts](file://worker-configuration.d.ts#L1-L12)
- [.gitignore](file://.gitignore#L52-L168)
## 结论
本方案以 Wrangler 与 Vitest 为核心,结合 Cloudflare Workers 的 KV 与计划任务能力,提供了可扩展的 CI/CD 基础设施。通过严格的测试配置、清晰的命令与计划任务职责划分,以及完善的类型声明,能够支撑从开发到生产的全链路自动化。后续可在 CI 平台中按 GitOps 工作流推进,实现多环境自动化与安全治理。
[本节为总结性内容,无需具体文件引用]
## 附录
### GitOps 工作流设计建议
- 分支策略
- main:受保护分支,仅允许通过合并请求(含审查)合并。
- develop:每日构建与集成测试分支,合并前需通过 CI。
- feature/*:功能开发分支,定期 rebase develop。
- 代码审查
- 强制至少一名审查者批准;审查者不得为提交作者。
- 合并前必须通过测试与静态检查。
- 自动化部署触发条件
- main 分支 push:触发生产环境部署。
- develop 分支 push:触发测试环境部署。
- feature/* 合并:触发预发布环境部署(可选)。
### 多环境部署与自动化切换
- 环境变量与 KV
- 通过 wrangler.jsonc 的 vars 与 kv_namespaces 区分不同环境的配置与命名空间。
- 在 CI 中使用 secrets 注入敏感信息,避免硬编码。
- 部署策略
- 生产:手动批准或满足特定标签触发;部署后进行健康检查。
- 测试:自动部署并运行测试套件;失败时阻断。
- 开发:按需部署,支持快速迭代与回滚。
### 权限管理与安全策略
- 最小权限原则
- 为不同环境分配独立的 API 密钥与 KV 命名空间访问权限。
- 机密管理
- 使用 CI 平台的密钥管理服务存储 BOT_TOKEN、API 凭据等;禁止在仓库中提交。
- 审计与可观测性
- 启用 Wrangler observability;在 CI 日志中记录关键步骤与结果。
### 回滚机制与最佳实践
- 版本化与灰度
- 采用语义化版本号标记部署;先在测试环境验证,再灰度到生产。
- 快速回滚
- 保留最近若干次部署版本;出现严重问题时一键回滚至上一个稳定版本。
- 监控与告警
- 结合 Cloudflare Workers 日志与指标,建立失败率与延迟阈值告警。
### 监控流水线执行状态与失败分析
- 测试阶段
- 记录 Vitest 执行时间、断言失败详情与覆盖率报告。
- 构建阶段
- 记录编译耗时、类型检查结果与打包产物大小。
- 部署阶段
- 记录部署时间、环境变量注入情况与 KV 更新结果;对计划任务进行健康检查。
[本节为通用指导,无需具体文件引用]