跳到主要内容

环境分支 Branching

Private Alpha

环境分支目前处于 Private Alpha 阶段:

  • 功能仍在开发中,仅对受邀用户开放,需申请开通后使用。
  • 接口、参数和返回字段在正式发布前可能发生不兼容变更。
  • 不提供 SLA,请勿用于生产链路。

申请开通或反馈问题,请联系你的商务经理或提交工单。

环境分支让你像管理代码一样管理后端:从一个环境拉出一个分支,分支带着完整的数据库表结构、RLS 策略和数据,是一个完全隔离的环境。你可以在分支上随意改表、写数据、部署函数,或者交给 AI Agent 去改,main 环境不受任何影响。

一次调用 CreateBranch,就能拿到一个可用的分支环境,以及一把只能访问这个分支的临时密钥。

环境分支拓扑

交给 AI Agent 使用​

点击页面右侧的“复制文档”或“查看 Markdown”,把内容交给你的 Agent(Claude Code、Cursor、CodeBuddy 等),或者直接把本页链接发给它。

确认 Agent 的运行环境里已经配置好准备工作中的环境变量,然后给它一句指令,例如:

阅读 https://docs.cloudbase.net/database/postgresql/branching ,
用环境变量里的腾讯云密钥,从 main 拉一个叫 feat-login 的分支,
建好后在分支上给 users 表加一个 phone 字段。

适用场景​

  • 给 AI Agent 一个安全的工作区:Agent 在分支上建表、改 RLS、写测试数据。分支临时密钥无法访问 main,Agent 碰不到生产数据。
  • 上线前在真实数据上验证:分支带着 main 的完整数据,新功能、新查询和性能问题可以在接近生产的数据上提前暴露。
  • 演练破坏性迁移:删列、改类型、重建索引之前,先在分支上跑一遍,确认耗时和结果。
  • 每个任务一个环境:并行开发多个功能时,每个功能一个分支,互不干扰。

工作原理​

分支是一个独立的 CloudBase 环境,有自己的环境 ID(BranchId)、数据库、函数和访问地址,同时记录父分支,组成一棵分支树。根环境自身就是 main(Depth 为 0)。

创建分支时,平台把父分支的内容复制到新环境:

资源分支中的状态
PostgreSQL完整副本:表结构、索引、RLS 策略、函数和数据。分支数据库独立,读写互不影响
身份认证认证配置随数据库继承
云函数副本
API Key不复制。创建时返回一把分支专属临时密钥,详见分支临时密钥

分支规格与父分支一致。分支可以继续创建子分支,最多 5 层。

准备工作​

  1. 开通资格:已开通 Private Alpha 的腾讯云账号,以及一个平台版下、使用 PostgreSQL(共享实例)的 CloudBase 环境。
  2. 准备一个专用的 CAM 子账号:在访问管理控制台新建子账号,只授予云开发(tcb)相关权限,为它创建 API 密钥(SecretId / SecretKey)。不要使用主账号密钥。
  3. 把密钥配置为环境变量,放在运行脚本或 Agent 的环境中(例如 shell 配置、.env 文件或 CI 密钥):
export TENCENTCLOUD_SECRET_ID=<子账号 SecretId>
export TENCENTCLOUD_SECRET_KEY=<子账号 SecretKey>
export ENV_ID=<你的环境 ID>

⚠️ 注意:密钥只放在环境变量里,不要粘贴进 Agent 对话。Agent 只需要知道变量名,执行脚本时由 SDK 自动读取并签名。

  1. 安装 SDK(Node.js 18+):
npm install tencentcloud-sdk-nodejs-common

快速开始​

以下示例使用腾讯云 Node.js SDK 的通用客户端调用云开发 tcb 服务(版本 2018-06-08)。

第 1 步:创建分支​

// create-branch.js
const { CommonClient } = require("tencentcloud-sdk-nodejs-common");

const client = new CommonClient("tcb.tencentcloudapi.com", "2018-06-08", {
credential: {
secretId: process.env.TENCENTCLOUD_SECRET_ID,
secretKey: process.env.TENCENTCLOUD_SECRET_KEY,
},
region: "ap-shanghai",
});

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

async function main() {
const envId = process.env.ENV_ID;

// 1. 从 main(根环境自身)拉出一个分支
const res = await client.request("CreateBranch", {
EnvId: envId,
BranchSetting: { ParentBranchId: envId, BranchName: process.env.BRANCH_NAME },
});
const branchId = res.BranchId;
console.log("BranchId:", branchId);

// 2. 轮询到可用:Status 1 = 创建中,0 = 可用
while (true) {
await sleep(10_000);
const { BranchList } = await client.request("DescribeBranchList", { EnvId: envId, BranchId: branchId });
if (BranchList[0].Status !== 1) {
console.log("Status:", BranchList[0].Status, BranchList[0].FailReason || "ready");
break;
}
}
}

main();
BRANCH_NAME=feat-a node create-branch.js

CreateBranch 立即返回 BranchId,分支进入创建中状态(Status = 1)。轮询 DescribeBranchList,Status 变为 0 即可使用;创建失败时 FailReason 会给出原因。返回中的 ApiKey 是分支临时密钥,见分支临时密钥。

第 2 步:查看分支树​

const res = await client.request("DescribeBranchList", { EnvId: process.env.ENV_ID });
for (const b of res.BranchList) {
console.log(`${" ".repeat(b.Depth)}${b.BranchName} ${b.BranchId} status=${b.Status}`);
}
main my-app-xxxx status=0
feat-a feat-a-xxxx status=0

第 3 步:在分支上工作​

分支就是一个普通环境,所有接受环境 ID 的工具都可以直接使用 BranchId:

tcb fn deploy hello -e <BranchId>
tcb db execute -e <BranchId> --sql "ALTER TABLE notes ADD COLUMN title text"

也可以用分支临时密钥直接访问分支的数据接口:

# 读:返回分支里的数据(从 main 复制过来的)
curl -s "https://<BranchId>.api.tcloudbasegateway.com/v1/rdb/rest/notes?select=id,body" \
-H "Authorization: Bearer $BRANCH_KEY"

# 写:只写进分支,main 不受影响
curl -s -X POST "https://<BranchId>.api.tcloudbasegateway.com/v1/rdb/rest/notes" \
-H "Authorization: Bearer $BRANCH_KEY" -H "Content-Type: application/json" \
-d '{"body": "written on branch"}'

同一把密钥访问 main 会返回 401 INVALID_CREDENTIALS。

第 4 步:删除分支​

await client.request("DeleteBranch", {
EnvId: process.env.ENV_ID,
BranchId: "<BranchId>",
});

删除后分支立即从列表中移除,环境资源随后自动回收。分支下还有子分支时,需要先删除子分支。

分支临时密钥​

CreateBranch 的返回中包含一把分支专属的服务端密钥(KeyType 为 ephemeral_secret,以 cb_secret_ 开头):

  • 有效期 1 小时,到期自动失效。
  • 只能访问这个分支,用于 main 或其他分支会返回 401。
  • 等同于该分支的管理员身份,不受 RLS 限制。只能在服务端或 Agent 运行环境中使用,不要放进前端代码。

任务预计超过 1 小时的,建议由开发者本人用 CAM 身份为分支调用 CreateApiKey 创建长期密钥,直接写入环境变量文件,不要让 Agent 代为创建或在对话中粘贴:

tccli tcb CreateApiKey --EnvId <BranchId> --KeyType api_key --KeyName agent-dev \
--region ap-shanghai | jq -r '.ApiKey' > .cloudbase-branch.key
chmod 600 .cloudbase-branch.key

接口参考​

三个接口均属于云开发 tcb 服务,版本 2018-06-08,请求域名 tcb.tencentcloudapi.com,签名方式为 TC3-HMAC-SHA256。

CreateBranch​

从指定父分支创建一个新分支。

输入参数

参数名称类型必填说明
EnvIdString是根环境 ID
BranchSetting.ParentBranchIdString是父分支 ID。从 main 创建时填根环境 ID
BranchSetting.BranchNameString是分支名称,会作为 BranchId 的前缀
ReqKeyString否请求标识

输出参数

参数名称类型说明
BranchIdString新分支 ID,同时也是分支的环境 ID
BranchInfoObject分支信息,字段同 DescribeBranchList
ApiKeyObject分支临时密钥:ApiKey(密钥值)、KeyType(ephemeral_secret)、过期时间

DescribeBranchList​

查询环境下的分支列表。

输入参数

参数名称类型必填说明
EnvIdString是根环境 ID
BranchIdString否只查询指定分支
DepthInteger否按层级过滤,0–5,0 为 main
OffsetInteger否分页偏移
LimitInteger否分页大小

输出参数

参数名称类型说明
TotalInteger分支总数(含 main)
BranchList[].BranchIdString分支 ID
BranchList[].BranchNameString分支名称,main 为 main
BranchList[].DepthInteger层级,main 为 0
BranchList[].ParentBranchId / ParentBranchNameString父分支
BranchList[].StatusInteger1 创建中,0 可用
BranchList[].FailReasonString创建失败原因
BranchList[].CreateTimeString创建时间

DeleteBranch​

删除指定分支。分支下存在子分支时会返回错误,需先删除子分支。

输入参数

参数名称类型必填说明
EnvIdString是根环境 ID
BranchIdString是要删除的分支 ID

限制与说明​

  • 仅支持平台版下的环境,且数据库为 PostgreSQL 共享实例。普通套餐(个人版、标准版等)环境调用会返回 UnsupportedOperation.BranchOperation。
  • 分支规格与父分支一致;每个分支占用一个环境配额。
  • 分支创建完成后,main 的后续变化不会同步到分支。
  • 当前版本不提供分支对比(diff)、合并回 main、从父分支重置等能力。
  • 创建耗时与数据量和函数数量有关。