☰
RocketRide Python SDK 部署指南:不可变版本、团队即环境、调度与 App 发布阶梯
2026/9/25 5:09:19 网站建设 项目流程

【免费下载链接】rocketride-server

High-performance AI pipeline engine with a C++ core and 50+ Python-extensible nodes. Build, debug, and scale LLM workflows with 13+ model providers, 8+ vector databases, and agent orchestration, all from your IDE. Includes VS Code extension, TypeScript/Python SDKs, and Docker deployment.

项目地址:https://gitcode.com/gh_mirrors/ro/rocketride-server
点击查看免费下载

RocketRide 的部署体系把"环境"建模为团队(team):client.deploy.add将一条 pipeline 固化为不可变、sha256 锁定的注册表版本,client.deploy.deploy则把一个团队指针指向某个版本——晋升(Staging → Production)与回滚(v3 → v2)本质上是同一次指针移动。本文基于 docs/public/python/deploy.md 展开,并结合 Python SDK 源码 深入讲解版本管理、cron 调度、部署状态机、权限模型,以及 RocketRide App 从 Deploy 到 Publish 的完整发布阶梯,读完你可以在自己的项目里用十几行 Python 完成"发布版本 → 部署到环境 → 挂调度 → 审计追溯"的完整闭环。

核心模型:Teams as Environments

RocketRide 的部署模型围绕三个不可动摇的设定展开:

  1. 不可变版本:deploy.add把一条 pipeline 快照为不可变、sha256 锁定的注册表工件版本(artifact version),存放在组织注册表中。部署什么,运行的就是什么,可证明(provably)。
  2. 团队即环境:deploy.deploy让一个团队(环境:Staging、Production……)指向某个版本。晋升与回滚是同一个指针移动——只是目标版本或目标团队不同。部署目标永远是显式给出的,没有默认团队回退。
  3. 不可变审计历史:每次注册表添加和指针变更都会落入不可变审计历史(deploy.history),行记录以seq作为稳定的追加序标识(append-order identity)。

一次典型的部署闭环如下(来自 deploy.py 文档字符串 与 deploy.md):

result = await client.deploy.add(my_pipeline, comment='v2 prompt fix') await client.deploy.deploy('proj-1', result['artifact']['version'], 'team-staging') await client.deploy.set_schedule('proj-1', 'webhook_1', '*/15 * * * *', 'team-staging') # 稍后把同一版本晋升到 Production —— 完全相同的调用。 await client.deploy.deploy('proj-1', result['artifact']['version'], 'team-prod') live = await client.deploy.list() for dep in live['rows']: print(dep['teamId'], dep['projectId'], 'v', dep['version'], dep['state'])

这段代码演示了三个关键动词:add(发布版本)、deploy(部署/晋升/回滚)、list(查看线上部署)。注意晋升 Production 与最初部署 Staging 用的是同一个函数、同一套参数,只是team_id不同——这正是"指针移动"设计带来的操作统一性。

一步式 add + deploy

add(..., deploy_to=<team>)可以把"发布版本 + 部署到团队"折叠为一步。此时返回值PublishResult同时携带artifact(新版本)和deployment(该团队的部署记录),这在 types/deploy.py 的 PublishResult 定义 中有明确体现:

class PublishResult(TypedDict, total=False): artifact: DeployArtifact # 仅当传入 deploy_to 时出现(一步式 add+deploy)。 deployment: Deployment

标准列表信封与分页

deploy.list、deploy.versions、deploy.history都返回标准服务端分页信封{rows, total, page, pageSize}。源码_list_args(deploy.py)统一折叠了分页参数,只发送调用方显式给出的值,缺失项由服务端应用默认值(page 1、分页大小钳制)。所有列表方法还支持自由文本search、列过滤filters(如{'state': 'enabled'})与sort([{'field': ..., 'dir': 'asc'|'desc'}])。deploy.list还可以通过team_id限定到单一团队。

读取不可变版本:deploy.artifact

deploy.artifact(project_id, version)从注册表抓取某个不可变版本的真实 pipeline JSON,服务端加载时做 sha256 校验——你拿到的东西可证明与当初发布的一致。源码注释强调,这是"已部署版本只读渲染的唯一事实来源——绝不是本地文件,也不是运行中的任务"(deploy.py)。DeployArtifact类型(types/deploy.py)携带version、sha256、bytes、pipelineName、publishedBy、publishedAt、comment等字段,其中comment是发布时可选填的"改了什么"备注。

调度(Schedules)

调度是部署体系的核心价值:把 pipeline 变成按 cron 自动触发的服务。

设置 / 清除调度

await client.deploy.set_schedule('proj-1', 'webhook_1', '*/15 * * * *', 'team-staging')

set_schedule(project_id, source_id, schedule, team_id, ttl=None)设置(或清除)某个 source 的5 字段 cron 调度:

  • schedule:标准 5 字段 cron 表达式;传None或'manual'清除调度。
  • ttl:运行窗口(秒),即"固定窗口"模式;None表示每个任务运行到 pipeline 完成。对应类型定义中的DeploymentSchedule.ttl(types/deploy.py)。
  • 源码实现细节:set_schedule发送rrext_deploy_pipe的schedule_set子命令,且不触碰 paused 标志——编辑 cron/ttl 会保留暂停状态(新调度默认以未暂停开始),暂停/恢复由专门的动词管理(deploy.py)。

暂停与恢复

pause_schedule/resume_schedule停止并重启单个 source的触发,不动它的 cron——调度配置保留,只是不再触发。这是运维中"临时停一下、不改配置"的标准姿势。暂停期间DeploymentSchedule.paused = true(types/deploy.py)。

单一 cron 求值器:deploy.preview

deploy.preview(schedule, count=None)是唯一的 cron 求值器——校验有效性并返回接下来若干次触发时刻:

preview = await client.deploy.preview('*/15 * * * *', count=4) # -> {'valid': True, 'next': [epoch_seconds, ...]}

源码注释明确指出:面板校验、"next:" 行、DVR 幻影轨道(ghost tracks)全部由此渲染,客户端从不自己解析 cron——这样预览结果永远不会与调度器实际触发不一致(deploy.py)。返回类型SchedulePreview(types/deploy.py)包含valid、error(无效时的人类可读原因)、next(下次触发的时间戳列表,服务端封顶)。

手动触发:deploy.run

deploy.run(project_id, source_id, team_id)立刻触发一个已部署的 source——与调度器使用的同一套可信、无人工身份的团队分发机制,返回{token, version}。运行以团队身份执行、不携带任何人类身份;计费归属组织与团队,谁触发的仅记录在部署的审计历史中。前提是部署必须处于enabled状态(deploy.py)。

每 source 执行配置:deploy.set_source_config

await client.deploy.set_source_config('proj-1', 'webhook_1', 'team-staging', trace_level='full', debug_out=False)

为 deploy 运行设置单 source 的执行设置:trace_level('none'|'metadata'|'summary'|'full',None= 部署默认 full)与debug_out(完整任务调试输出,对应--trace=debugOut)。这些设置会搭载该 source 的每一次deploy 运行(调度触发与手动触发一致),编辑调度不会触碰它们;source 即使没有调度也保留自己的设置(deploy.py、types/deploy.py)。

调度运行的日志落点

调度运行以团队身份执行(不存储用户凭据),其日志落入团队的 run-log 连续体(run-log continuum)。队友通过client.log并传入team_id即可读取——DVR 会话的open_event_stream()传team_id='team-prod'就是读取该团队部署连续体的日志(详见 docs/public/python/logs.md)。日志按环形保留(最近约 1 GB),历史年龄为 dev 7 天 / deploy 30 天。

部署状态机(States)

每个团队部署都处于四个状态之一:

State含义
enabled调度按 cron 触发。
disabled总开关(deploy.disable)——在重新启用前什么都不运行(调度停止触发、手动运行被拒绝)。
errored某次调度分发失败——权限问题,或工件不可用(缺失或 sha256 被篡改)——且调度器已停止重试。
removed软删除(deploy.remove):从列表隐藏,历史与工件仍保留;重新部署可复活。

对应的生命周期动词都在client.deploy上:disable(kill switch)、enable(复活)、remove(软删除)。源码注释把remove的语义讲得很透:"列表隐藏它;审计历史与每个注册表工件永远存活(企业级要求)。重新部署任意版本即复活"(deploy.py)。Deployment.state的取值由 types/deploy.py 的类型标注锁定为Literal['enabled', 'disabled', 'errored', 'removed']。

审计历史行DeployHistoryEntry的action字段还包括publish、deploy、rollback、enable、disable、remove、errored等(pause/resume只出现在旧词汇行,因为历史不可变)(types/deploy.py)。值得注意的是Deployment.deployedAt是"最近一次指针移动(deploy 或 rollback)"的时刻,从审计轨迹计算而来——updatedAt不会因 disable/enable 或调度编辑而变动,两者语义不同(types/deploy.py)。

权限模型

  • 变更操作(add、deploy、schedule、disable 等)要求对目标团队拥有task.control权限。
  • 读取遵循可见性模型:组织管理员可以看到每个团队与每个个人空间;普通用户只能看到自己的个人空间和自己所属的团队。deploy.list省略team_id时即按此模型返回可见部署。

App 发布阶梯(App Publish Ladder)

对 RocketRide App(运行在 Shell 内的界面应用),部署与发布是两个语义分离的阶段,全部通过rrext_deploy_appDAP 命令的 typed 包装实现(mixins/apps.py)。

Deploy vs Publish:两个阶段,一个阶梯

  • Deploy把代码复制到服务端,成为下一个不可变注册表版本(client.deploy.add);部署在自身state中承载评审生命周期(private→submit→ready|rejected)。
  • Publish把部署绑定到受众——@me、@team/<name>或@public——作为纯指针(@user是@me的遗留输入别名,永不显示);重新指向该绑定即可覆盖首次发布、更新、晋升与回滚四种操作。

评审状态存在于部署上,而非绑定上:app 以private部署,开发者submit,管理员批准(ready)或拒绝(rejected)。@public绑定只能指向ready的部署;@me/@team接受任意非failed的部署。

App id 命名空间

App id 按调用方组织的developer id分区:每个 app 都是<developerId>.<name>(全局唯一),因此一个组织只能部署/发布自己命名空间内的 id(平台保留rocketride)。部署或发布 app 要求组织已认领 developer id。id 语法由 _app_pack.py 的正则 定义:^[a-z][a-z_]*\.[a-z][a-zA-Z0-9_-]*$。

方法总表

deploy.add与deploy.add_app位于client.deploy上;其余动词是客户端本身的方法(client.list_deployments(...)、client.publish_app(...)),不在client.deploy命名空间上:

方法说明
deploy.add唯一的通用闸门(在client.deploy命名空间上):把任意对象作为下一个不可变注册表版本部署。kind='pipe'(默认)接收pipeline字典;kind='app'接收一份app 源码 zip(服务端执行构建,客户端产出的二进制永不被信任),接收时保留并在到达时解包,出生即部署状态private。app id 必须位于你的 developer 命名空间内。
deploy.add_app打包 app 文件夹源码并部署为下一个注册表版本——App Builder 的 Deploy 按钮与 CI 脚本背后的唯一次调用。按 App Builder 规则打包(工作区根 zip、appManifest.include、层级 gitignore + 硬基线 node_modules/dist/.git、symlink 包含约束、50MB zip / 512MB 未压缩上限);on_progress逐步输出一行叙述。部署本身不激活任何东西——之后用publish_app绑定受众。
deploy.verify_appadd_app的无副作用预检——纯本地、无服务端调用:manifest 形状与 id 语法、声明的 icon/README 资产、appManifest.include条目、针对大小上限的打包试运行。服务端关注点(构建、商店评审)不在范围内。
list_deployments版本轨道,最新优先——开发者组织看到完整轨道(无论是否发布),其他调用者只看到自己可见的版本。每条记录携带部署state、buildStatus('ok' = 可服务)与rungs(绑定到它的受众列表)。
submit_app提交已部署版本供评审——翻转部署private→submit。
withdraw_app撤回待评审——开发者自己的取消:翻转部署submit→private,版本离开管理员队列,历史记录withdrawn。只有submit状态的版本可以撤回。开发者组织 + 命名空间门控,同 submit。
reply_app向 app 评审线程追加开发者消息——作为reply行(side'developer')写入deployment_history,与deploy.history()读取的同一流。开发者组织 + 命名空间门控。
build_log某版本持久的服务端构建日志——构建工件的逐阶段完整输出,存储在版本工件旁(错误文本不进入轨道行)。长日志只提供尾部;log为空 = 无日志。开发者组织门控。
publish_app把部署绑定到'@me'、'@team/<name>'或'@public'('@user'= 遗留输入别名)。绑定是出生即enabled的纯指针。'@public'要求部署ready;'@me'/'@team'接受任意非failed部署。把另一个组织的公共 app 固定到'@me'/'@team'是版本选择器;发布自己的 app 要求 id 在命名空间内。
where_app反向索引:每个受众一条{rung, handle, version, appVersion, state, deployedAt}——state是被绑定部署的评审状态。

评审模型与发布流程

deploy.md引用 reference.md 给出了走向公开的完整三步行流程:submit(部署 →submit,进入管理员队列)→admin_approve(→ready)→publish_app @public(把公共绑定指向ready版本)。拒绝则翻转部署为rejected;开发者修复后部署新版本。@me/@team绑定无需批准。

此外源码 AppsMixin 还提供了两个文档主表中未列出的受众级运维动词:remove_app_publish(移除受众绑定,软操作——注册表版本与审计历史保留,重新发布即复活)与disable_app_publish(禁用受众绑定——服务停止但行保留在 where-live 列表中并标记disabled,是一个可见的关断开关,区别于 remove 的隐藏语义)。

服务 URL:无需动词的加载

App 服务不需要任何动词:版本的 bundle 从稳定 URL/apps/<app_id>/v<N>/remoteEntry.js加载,该 URL 由其注册表版本号构造,服务路由在每个请求上强制执行授权(只认注册表整数——semver 仅用于展示)。旧app_entry能力已退役,因为版本从稳定构造 URL 服务,没有需要铸造的东西(apps.py 注释)。

源码级深入:打包规则与验证实现

add_app与verify_app背后是 _app_pack.py,它是 TypeScriptrocketride/app-pack的 Python 镜像,实现细节直接决定了"哪些文件会被带上服务端、能否通过验证":

  • 源码专属、工作区相对布局:zip 只携带源码,按工作区相对位置打包——app 文件夹在真实位置(部署元数据以appRoot命名),appManifest.include条目也在各自位置,服务端解包后打包根之间的相对引用依然解析(_app_pack.py)。
  • git 式过滤:硬基线node_modules/、dist/、.git/(不可被 negation 重新包含的底线)+ 工作区各层.gitignore,按 git 的 deepest-wins 优先级层级应用;被忽略的目录永不深入。*.rrapp标记(部署溯源)总是打包;用户显式命名的打包根胜出,即使规则本会排除它(L34-L41)。
  • symlink 包含约束(安全):symlink 只在工作区内被跟随——真实目标逃逸工作区根的链接被跳过(数据外泄路径),每根循环被打破(L39-L42、L187-L244)。
  • 大小上限:512MB 未压缩(内存构建边界)、50MB zip(服务端接收时拒绝更大上传)——客户端提前用同一边界快速失败(L66-L72)。
  • 固定时间戳:每个 zip 条目盖上(1980, 1, 1)固定时间,使两份相同源码的打包字节只由内容决定——这对不可变版本的机器级一致性至关重要(L74-L77)。
  • include 条目校验:appManifest.include条目必须是存在的工作区相对路径——拒绝绝对路径、盘符、./..;拼写错误会让打包响亮地失败(L302-L352)。

verify_app返回的AppVerifyReport(dataclass,由客户端构造而非服务端接收)包含ok、逐项checks(id/ok/note)、file_count与uncompressed_bytes,覆盖 manifest 形状、id 语法、icon/README 声明、include 条目与打包试运行五类检查(verify_app_source)。开发者可以在任何编辑器中先跑verify_app拿一份无副作用报告,再执行add_app真正部署。

从 CLI 到程序化:SDK 的完整部署工具链

除部署 API 外,Python SDK 还提供deploy.create_app(client.deploy.create_app(slug, ...),App Builder New App 向导的程序化孪生——脚手架写入./apps/<slug>、确保 pnpm workspace 文件与 ignore 卫生、vendor 连接服务器的 shell + client 包并运行工作区安装,返回{appId, folder, files, vendored, installed},见 deploy.py),配合 App Builder 指南 中展示的rocketride app create reports --template Dashboard与rocketride app verify ./apps/reports两条 CLI 命令,构成"脚手架 → 验证 → 打包 → 部署 → 绑定受众"的完整工具链。

小结

RocketRide 的部署体系把"环境即团队、版本即不可变 sha256 工件、发布即指针移动"贯彻到底:pipeline 的晋升/回滚是同一调用、调度与手动运行共用同一团队分发、审计历史以seq无界追溯,而 App 的发布把部署与受众绑定解耦、评审状态挂在部署上。所有方法均有 typed 包装(DeployApi、AppsMixin,类型定义见 types/deploy.py),完整签名表见 API reference,App 模型本身见 Shell API guide。

【免费下载链接】rocketride-server

High-performance AI pipeline engine with a C++ core and 50+ Python-extensible nodes. Build, debug, and scale LLM workflows with 13+ model providers, 8+ vector databases, and agent orchestration, all from your IDE. Includes VS Code extension, TypeScript/Python SDKs, and Docker deployment.

项目地址:https://gitcode.com/gh_mirrors/ro/rocketride-server
点击查看免费下载
上一篇:快速关闭 SystemInformer 鼠标悬停提示窗口:3 步禁用弹窗的完整指南
下一篇:Python语法高亮终极指南:MagicPython让你的代码焕发光彩 🐍

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询