@ depot/ sandbox (英语)
Beta TypeScript SDK 用于 Depot 沙盒.
此软件包包 depot.sandbox.v1 API 有 Vercel 形状的类,用于创建沙盒、运行命令、流出命令输出和使用 node:fs/promises- 形状的文件系统接口.
安装
Β包发布后:
pnpm add @depot/sandbox
使用量
设定 DEPOT_TOKEN 然后创建客户端并将其传递到静态沙盒入口。 返回的沙盒实例会保留该客户端,所以实例方法不会使用客户端的参数.
import {createClient, Sandbox} from '@depot/sandbox'
const client = createClient({token: process.env.DEPOT_TOKEN!})
const sandbox = await Sandbox.create(client, {
env: {NODE_ENV: 'development'},
})
const command = await sandbox.runCommand({cmd: 'echo', args: ['hello from depot']})
const finished = await command.wait()
console.log(finished.exitCode)
console.log(await command.stdout())
const fs = sandbox.fs()
await fs.writeFile('/tmp/message.txt', 'hello')
console.log(await fs.readFile('/tmp/message.txt', {encoding: 'utf8'}))
await sandbox.setTimeout({timeoutMinutes: 240})
await sandbox.stop({blocking: true})
也可以通过符号、组织和终点选项:
const client = createClient({
token: process.env.DEPOT_TOKEN!,
orgID: process.env.DEPOT_ORG_ID,
})
CI 机密
过 configuration.secrets 向沙盒里的每个指挥部揭发你的组织的秘密 每个密钥都是要设置的环境变量,每个值都是CI密钥的名称. environment 财务报告和审定财务报表 repository 选择每个秘密的哪一种变体, 和CI工作流程一样.
const sandbox = await Sandbox.create(client, {
configuration: {
secrets: {DATABASE_URL: 'PROD_DATABASE_URL'},
environment: 'production',
repository: 'acme/app',
},
})
await sandbox.runCommand({cmd: 'sh', args: ['-c', 'psql "$DATABASE_URL" -c "select 1"']})
- 未知或不适用的名称 :
Sandbox.create失败InvalidArgument当一个秘密不存在, 或没有给定的变体environment财务报告和审定财务报表repository。 。 。 . - 范围变式: 设置
environment或者说repository要求组织所有人或组织标志Sandbox.create失败PermissionDenied。这同样适用于:runCommand文件系统呼叫沙盒. - 删除的秘密 : 每个命令在开始时都会读取该秘密的当前值,所以一个旋转的值适用于下一个命令. 如果在沙盒创建后该秘密被删除, 命令失败
FailedPrecondition。创建新的沙盒以恢复. - 输出没有遮盖 : 将变量流的值反馈给您的命令.
建筑
沙盒运行在 amd64 除非你问 arm64没有 runtime,一个 arm64 沙盒靴 Depot's arm64 Base 图像. sandbox.architecture 报告沙盒的构造.
const sandbox = await Sandbox.create(client, {architecture: 'arm64'})
console.log(sandbox.architecture) // 'arm64'
习惯 runtime.imageRef 必须在 registry.depot.dev ; 任何其他注册失败 InvalidArgument用于 arm64,图像也必须发布 linux/arm64 变种. 如果它不这样做,创造成功 但沙盒结束在 failed 当它靴子.
抓图
sandbox.snapshot() 抓取运行中的沙盒主目录( s)/home/runner ),加 /workspace 当它存在并且可以写成快照时。 通过快照,或它的 snapshotId,改为 Sandbox.create 启动一个新的沙盒,在它开始运行前恢复这些文件.
await sandbox.fs().writeFile('/home/runner/notes.txt', 'hello')
const snapshot = await sandbox.snapshot()
const copy = await Sandbox.create(client, {snapshot})
console.log(await copy.fs().readFile('/home/runner/notes.txt', {encoding: 'utf8'}))
/workspace 包括所有依赖性。 在主目录中,缓存和默认图像的工具链(如 .nvm 财务报告和审定财务报表 .rustup)被忽略,所以安装了工具链版本,其中 nvm 或者说 rustup 需要再次在副本中安装 。 见 SDK 参考 完整名单.
新沙盒使用快照的运行时间和结构,除非你设定 runtime 你自己来 设置一个 architecture 与快照的失败创建不同 InvalidArgument。 。 。 . sandbox.snapshot() 失败 FailedPrecondition 在一个沙盒上 CI 机密 设定 environment 或者说 repository因为快照没有这个范围 获取或恢复快照需求 /bin/sh 和22.19节或较新的节点(如: node 编辑 PATH在沙盒的图像。 Depot的默认图像有两者. 在没有他们的图像上,呼叫失败 FailedPrecondition。 。 。 .
贝塔表面
此β包目前包括:
createClientSandbox.create(包括机密,architecture,以及snapshot, (中文(简体) ),Sandbox.get, (中文(简体) ),Sandbox.list, (中文(简体) ),Sandbox.listAllsandbox.stop, (中文(简体) ),sandbox.kill, (中文(简体) ),sandbox.setTimeout, (中文(简体) ),sandbox.runCommand, (中文(简体) ),sandbox.fs, (中文(简体) ),sandbox.snapshotSandboxCommandExecution.wait, (中文(简体) ),logs, (中文(简体) ),output, (中文(简体) ),stdout,以及stderrFileSystem用于常见文件操作的助手sandbox.tailnet数字 :status()财务报告和审定财务报表waitForAddress(),在您的组织尾网上报告沙盒的活的MagicDNS名称和IP;选择退出disableTailnet创建- Depot Cache:每个命令都会得到您的组织的 Depot Cache 证书,用于 scache, Turborepo, 和 Nx, +
DEPOT_CACHE_HOST财务报告和审定财务报表DEPOT_CACHE_TOKEN用于其他工具; 选择退出disableDepotCache创建
其他的沙盒能力,如管状的stdin,命令历史,和pty支持,目前还不是这个β表面的一部分.
生成的原生物
在这个寄存器中 depot.sandbox.v1 原生来源在 proto/,并在下面检查生成的 TypeScript 文件 src/gen。所出版的软件包船,编译生成的装订,因此客户不需要单独的原型模块.
更改原型后, 重生 TypeScript 绑定:
pnpm run gen
CI 运行 pnpm run gen:check 结束 pnpm run validate 以捕捉漂移之间 proto/ 财务报告和审定财务报表 src/gen。 。 。 .
释放
通过npm信任的出版,从GitHub发行中发布发行. 正常发布工作流程不需要npm令牌.
要发布新版本 :
- 更新
package.json到下一个版本或 semver 频道. - 合并更改为
main。 。 。 . - 审查由发行-起草者生成的发行草稿并编辑发行注释.
- 发布带有标签的 GitHub 发布 无 标签
v<release-version>。 。 。 .
释放起草器从承诺开始 package.json 版本。 如果该版本已经用未发行的草案作为代表,它将不断更新草案。 如果该版本已经发布或标记,则会推进到同一 semver 通道中下一个数字预发版本,例如 0.1.0-beta.1 改为 0.1.0-beta.2要切换频道,请合并 a package.json 选择新频道的版本,例如 0.1.0-alpha.1, (中文(简体) ), 0.1.0-rc.1,或 0.1.0。 。 。 .
Semver预放标识器仅为包版本通道. 他们不使 GitHub 发布预发版, 每个 npm 发布更新 latest dis.
这个 release.yml 工作流程集 package.json 从 GitHub 发布标记中验证软件包,并发布新 @depot/sandbox 版本为 npm latest。 。 。 .
npm 信任的出版必须配置到 depot/sandbox-sdk 仓库和 .github/workflows/release.yml 工作流程。 从此 repo 上发布的第一个 CI 应更新 Npm 注册元数据, 这些元数据仍然在较早的手册中指向 sdk-node 发布.
如果一个 GitHub 发布, 但 npm 发布工作流程在软件包版本达到 npm 之前失败, 则发布标记被消耗, 但是没有 npm 软件包版本需要修复 。 首先从 GitHub 动作重运行失败的发布工作流程 。 如果重运行无法恢复, 请删除 GitHub 释放并标记, 然后让 Release Draver 从下一个版本创建新草稿 main 运行.
如果已发布的版本有错误的发布元数据或 npm dist- tags , 则更倾向于通过起伏修复向前 package.json 到下一个版本并发布新版本。 避免在Repo中添加一次性元数据修复自动化.
许可证
麻省理工学院执照,见 LICENSE。 。 。 .
沙盒日志
使用 sandbox.logs.fetch(), (中文(简体) ), .tail(),以及 .stream() 用于获取的产出,
包括脱离命令。 这些取代了以前的 sandbox.readLogs() 财务报告和审定财务报表
sandbox.streamLogs() 方法及其选择/结果类型。 保留记录
是 UTF- 8 文本; API 不显示命令补全, 切换标记,
生字节编码选项,或自动读取重试. 空结果不能证明
摄入完成.
要选择一个命令的输出, 请将命令对象或其ID 传递到 fetch()数字 :
const since = new Date()
const command = await sandbox.runCommand({cmd: 'echo', args: ['hello'], detached: true})
for await (const entry of sandbox.logs.fetch({since, command, group: 'root'})) {
console.log(entry.message)
}
抓取和导出是同步的,所以即时查询可以是空的.
执行对象 logs(), (中文(简体) ), output(),以及 wait() 保持他们的附属命令
语义学, 并且仍然无法用于脱离命令 。 附加输出 API
提供精确的流程字节; 被捕获的记录去除线条分隔符.
查询保留了沙盒日志
使用 sandbox.logs 以查询捕获的记录和命令输出
流经. 两种方法都生成解码的 UTF-8 信件 source, (中文(简体) ), timestamp, (中文(简体) ),
objectId (沙盒身份证),和 contextIds (在出现时的命令ID).
for await (const entry of sandbox.logs.fetch({
since: new Date(Date.now() - 60_000),
source: 'stderr',
searchText: 'error',
})) {
console.log(entry.message)
}
for await (const entry of sandbox.logs.tail({entries: 20})) {
console.log(`${entry.source}: ${entry.message}`)
}
fetch() 查询 [since, until) 按时间顺序排列. until 默认为
目前时间。 来源可以是 stdout, (中文(简体) ), stderr, (中文(简体) ), unknown,或 system; 省略来源
包括所有允许来源. unknown 代表未具体说明的客户产出.
系统记录是工作人员独有的,从不以这些客户方法归还,
即使当 system 请求作为过滤器. searchText 是一个对大小写敏感的子字符串. command 选择一个已执行的命令(对象或ID); group 选择显示组( e)"root" 现今);
关闭过滤器以包含所有匹配的命令或组 。 这些滤波器结合了时间范围和源.
最大查询范围为35天;超大小查询失败
RESOURCE_EXHAUSTED 而不是默默地忽略记录.
tail() 返回按时间顺序排列的最新记录并完成
不跟随新日志。 它默认为100个记录,接受0到10,000个
最多30天的搜索,但需保留。 它接受 source, (中文(简体) ), command,以及 group 过滤器.
stream() 遵守命令, 它也接受 command 财务报告和审定财务报表 group; 命令过滤流在命令的 EOF 完成 。 也一样 LogEntry
形状为 fetch() 财务报告和审定财务报表 tail()。重放是明确的:
sandbox.logs.stream() // New arrivals only; same as {replay: 'none'}
sandbox.logs.stream({replay: 'all'}) // Everything still in Tail, then live
sandbox.logs.stream({replay: new Date(Date.now() - 60_000)}) // From a capture timestamp, then live
const controller = new AbortController()
for await (const entry of sandbox.logs.stream({replay: 'all', signal: controller.signal})) {
console.log(`${entry.source}: ${entry.message}`)
// Break the loop or call controller.abort() to stop.
}
'all' 只覆盖 Tail 保留的回放窗口,该窗口可能比
沙盒的寿命。 时间戳是包容性的,可以过滤回放和未来
捕捉时间到达. 'none' 接受时跳过已存在 Tail 的记录
订阅,不依赖客串时钟。 记录遵循抵达命令;
时间戳可能会出错. source 过滤输出, 如 tail()。 。 。 .
命令完成后,沙盒流会打开. 最多四通电话
分钟后失败 DEADLINE_EXCEEDED重设或意外关闭
返回时 UNAVAILABLE;没有自动重接或持久接续.
启用再播放时, 启动另一流可以重复记录 .
逻辑时间戳具有毫秒精度并下回圆. 重用退货 输入时间戳作为包容性重放截断包括该边界记录; 还可以重复在同一毫秒内记录的其他记录.
查询包括命令运行时被捕获的命令日志. 近期 记录可以来自Tail存储,而旧记录则可以在 持久的索引编制。 空结果不能确定摄入完成; 近期的留存和可持久获得之间可能存在差距。 捕获 删除行分隔符,所以所保留的记录与精确的流程输出不同.