Initial import of cf-temp-email deploy CLI

This commit is contained in:
mmc
2026-03-26 08:06:02 +08:00
commit 4100e9cf72
29 changed files with 6703 additions and 0 deletions

363
README.md Normal file
View File

@@ -0,0 +1,363 @@
# cf-temp-email
Cloudflare Temp Email 的自动化部署 CLI。它会编排 Cloudflare REST API、`npm``wrangler`,统一处理以下资源:
- Pages
- Worker
- D1
- Email Routing
- Catch-all 到 Worker
适用场景:
- 从零部署一套 Cloudflare Temp Email
- 用一个 `config.toml` 管多个 Cloudflare 账号
- 从 Cloudflare 现有资源反推配置,再继续接管部署
## 快速开始
`cftemail/` 目录下执行:
```bash
uv sync
uv run cf-temp-email init-config --config config.toml
uv run cf-temp-email check --config config.toml
uv run cf-temp-email deploy --config config.toml
```
省略子命令时默认执行 `deploy`,所以:
```bash
uv run cf-temp-email --config config.toml
```
等价于:
```bash
uv run cf-temp-email deploy --config config.toml
```
## 命令
可用命令:
- `init-config`
- `check`
- `deploy`
- `resume`
- `discover-config`
常用示例:
```bash
uv run cf-temp-email check --config config.toml --profile kotei
uv run cf-temp-email deploy --config config.toml --profile kotei
uv run cf-temp-email resume --config config.toml --profile kotei
```
### `discover-config`
用于从 Cloudflare 现有资源反推配置,并写回 `config.toml`
示例:
```bash
uv run cf-temp-email discover-config \
--config config.toml \
--profile kotei \
--api-token "$CF_API_TOKEN_KOTEI" \
--zone-name "kotei.us.ci"
```
当前能自动发现并写入的字段包括:
- `cloudflare.account_id`
- `cloudflare.account_name`
- `cloudflare.zone_name`
- `mail.domains`
- `mail.verified_destination_address`
- `d1.database_name`
- `worker.script_name`
- `pages.project_name`
- `pages.custom_domain`
说明:
- 只有 Cloudflare 能读到的字段才会写入
- `ADMIN_PASSWORDS``JWT_SECRET` 之类的值无法从 Cloudflare 反读
- 如果候选资源不唯一,命令会跳过,不会乱猜
## 多账号配置
支持在一个 `config.toml` 里定义多个账号或环境,用 `profiles.<name>` 区分。
示例:
```toml
[profiles.account_a.cloudflare]
account_id = "acc-a"
api_token_env = "CF_API_TOKEN_A"
zone_name = "example.com"
[profiles.account_a.mail]
domains = ["mail.example.com", "mail2.example.com"]
[profiles.account_a.pages]
custom_domain = "email.example.com"
[profiles.account_b.cloudflare]
account_id = "acc-b"
api_token_env = "CF_API_TOKEN_B"
zone_name = "kotei.asia"
[profiles.account_b.mail]
domains = ["mail.kotei.asia", "maila.kotei.asia"]
[profiles.account_b.pages]
custom_domain = "email.kotei.asia"
```
执行时通过 `--profile` 选择:
```bash
uv run cf-temp-email deploy --config config.toml --profile account_a
uv run cf-temp-email deploy --config config.toml --profile account_b
```
行为说明:
- CLI 覆写会写入对应的 `profiles.<name>.*`
- 每个 profile 使用独立状态文件:
`.deploy/profiles/<profile>/state.toml`
- 默认 clone 模式下,每个 profile 也会使用独立工作目录
## 域名模型
这套工具把“邮箱域名”和“前端域名”分开管理。
### 1. 邮箱域名
来自 `mail.domains`,支持多个域名,也支持二级域名。
例如:
```toml
[mail]
domains = ["kotei.us.ci", "mail.kotei.us.ci"]
```
这表示系统会同时处理:
- `@kotei.us.ci`
- `@mail.kotei.us.ci`
### 2. 前端域名
来自 `pages.custom_domain`,当前一次部署只管理一个前端域名。
例如:
```toml
[pages]
custom_domain = "temp-mail.kotei.us.ci"
```
### 3. 约束
- `mail.domains` 可以是多个
- `pages.custom_domain` 当前是单个
- `pages.custom_domain` 不能和 `mail.domains` 中的任意一个重复
原因是:
- `mail.domains` 需要承载 Email Routing 的 `MX/TXT`
- `pages.custom_domain` 需要承载 Pages 的 `CNAME`
同一个主机名不能同时做这两件事。
## 配置要点
### `cloudflare`
至少需要:
- `zone_name`
- `api_token``api_token_env`
更推荐使用环境变量:
```toml
[cloudflare]
api_token_env = "CF_API_TOKEN_KOTEI"
zone_name = "kotei.us.ci"
```
### `mail.verified_destination_address`
现在是可选项。
行为如下:
- 有值:部署时会校验该地址是否已在 Cloudflare 侧可用
- 空值:跳过目标地址校验,仍继续配置 `MX/TXT` 和 Catch-all Worker
例如:
```toml
[mail]
verified_destination_address = ""
```
### `worker.vars.ADMIN_PASSWORDS`
这是必填项。部署时会使用第一个值请求:
```text
https://<worker.custom_domain>/admin/*
```
用于同步:
- 用户注册开关
- 登录配置
- 其他管理员接口设置
例如:
```toml
[worker.vars]
ADMIN_PASSWORDS = ["your-strong-password"]
```
### `worker.secrets.JWT_SECRET`
可以留空。首次部署前如果为空,脚本会自动生成并写回配置文件。
### `linuxdo`
如果不用 Linux.do保持
```toml
[linuxdo]
linuxdo_oauth = false
```
只有在 `linuxdo_oauth = true` 时,才需要填写:
- `client_id`
- `client_secret`
## CLI 覆写
支持显式参数覆写:
```bash
uv run cf-temp-email deploy \
--config config.toml \
--profile kotei \
--api-token "$CF_API_TOKEN_KOTEI" \
--zone-name "kotei.us.ci" \
--pages-domain "temp-mail.kotei.us.ci" \
--worker-name "cloudflare_temp_email"
```
也支持通用 `--set`
```bash
uv run cf-temp-email deploy \
--config config.toml \
--profile kotei \
--set worker.vars.ADMIN_PASSWORDS='["abc.123"]'
```
说明:
- CLI 覆写会先写回 `config.toml`
- 然后脚本会重新读取配置并执行
## 部署阶段
部署顺序如下:
1. 检查本地工具与 Cloudflare 授权
2. 准备源码目录
3. 创建或复用 Pages 项目
4. 配置 Pages CNAME
5. 创建或复用 D1并执行迁移
6. 生成 `worker/wrangler.toml` 并发布 Worker
7. 同步管理员接口配置
8. 配置 Email Routing DNS 与 Catch-all Worker
9. 构建并发布 Pages
10. 执行验收检查
运行状态会写入:
```text
.deploy/state.toml
```
如果使用 profile则写入
```text
.deploy/profiles/<profile>/state.toml
```
## Cloudflare Token 权限
最小部署权限建议包括:
1. `Cloudflare Pages: Edit`
2. `D1: Edit`
3. `Workers Scripts: Write`
4. `DNS: Write`
5. `Email Routing Rules: Edit`
如果你要使用 `discover-config`,再补这些读取权限:
1. `Zone: Read`
2. `DNS: Read`
3. `Cloudflare Pages: Read`
4. `Workers Scripts: Read`
5. `D1: Read`
6. `Email Routing Addresses: Read`
7. `Email Routing Rules: Read`
资源范围建议只限定到目标账户和目标 Zone。
## 常见问题
### 1. 多个邮箱域名是否需要多个 Pages
不需要。
通常一个 Pages 前端域名就够了,例如:
```toml
[mail]
domains = ["kotei.us.ci", "mail.kotei.us.ci"]
[pages]
custom_domain = "temp-mail.kotei.us.ci"
```
### 2. Catch-all 已经指向 Worker为什么还会提到 destination address
当前版本中,`verified_destination_address` 已经是可选项。留空时不会阻塞部署。
### 3. 旧的 `cf_temp_email_deploy.py` 还能用吗?
不能。当前统一入口是:
```bash
uv run cf-temp-email ...
```
## 建议流程
如果你是接管一个现有站点,推荐按这个顺序:
1. `discover-config`
2. 手动补 `ADMIN_PASSWORDS`
3. 检查 `mail.domains``pages.custom_domain``worker.custom_domain`
4. 运行 `check`
5. 再运行 `deploy`