命令行工具
最后更新:2026 年 8 月 6 日
playserv 是这个平台的运维 CLI。在本机上,你可以用它对自己的 Project 完成认证、部署和管理 Functions(cloud function 与 game server)、管理按 Environment 划分的 secret,以及轮换公开 slug。
它是个轻客户端:你只需要上传自己 handler 的源码 —— Dockerfile 和构建文件由平台合成,镜像由平台构建并发布。你这边不需要 Dockerfile,不需要容器镜像仓库,也不需要 git 提交。
安装
这个 CLI 是一个名为 playserv 的 .NET 10 全局工具。
- dotnet tool
- 从源码安装
dotnet tool install --global PlayServ.Platform.Cli
playserv status # verify it's on your PATH
日后用 dotnet tool update --global PlayServ.Platform.Cli 升级。
dotnet pack src/PlayServ.Platform.Cli # → artifacts/nupkg/*.nupkg
dotnet tool install --global PlayServ.Platform.Cli --add-source artifacts/nupkg
# or run without installing:
dotnet run --project src/PlayServ.Platform.Cli -- functions list
平台的 API endpoint 是内置在 CLI 里的,用户不可配置。本地状态(会话 + 已解析的身份)存放在 ~/.playserv/config.json,登录时以原子方式写入。
认证
取得 Platform API key
在 Backoffice 中为你的 Project 创建一个 Platform API key —— 可公开的 pk_* 或保密的 sk_*。每个 key 都绑定到一个 Project 和一个 Environment(dev 或 prod)。见 API Key Management。
登录
playserv login <key> # or: playserv login (hidden prompt)
这一步会把 key 拿到平台换成一个运维会话,并保存 access 与 refresh token,以及解析出的 org / Project / env。**原始 key 从不落盘。**会话会自动续期(30 天窗口),改过 slug 之后也一样,所以你不会在工作中途被要求重新登录。
确认并管理会话
playserv status 会实时探测并显示当前的 Project/org/env;playserv logout 清除会话。
每个作用于 Project 的命令都会发送 Authorization: Bearer <session>、X-Project-Slug 和 X-Env。--env 是可选的,默认取会话的 env;若给了冲突的值,会在本地就被拒。
部署 Function
functions deploy(别名 fn deploy)是核心流程:它把你本地的源码打包上传,再由平台构建并发布服务 —— 全程轮询直到结束。
playserv fn deploy --slug <slug> --kind <game_server|cloud_function> --src <path> \
[--language <csharp|node|python|go>] [--env <dev|prod>] [--poll-timeout <seconds>]
| 选项 | 必填 | 说明 |
|---|---|---|
--slug | 是 | Function 的公开名称。必须是合法的 Cloud Run 名称 —— 小写字母、数 字、连字符,3 到 50 个字符。上传前在本地校验。 |
--kind | 是 | cloud_function(HTTP function)或 game_server(长驻服务)。 |
--src | 是 | 单个源文件或一个目录。bin/、obj/、.git/ 和 node_modules/ 不会进包。 |
--language | 否 | csharp、node、python 或 go。省略时从 --src 自动识别(见下)。 |
--env | 否 | 目标 Environment;默认取会话的 env。 |
--poll-timeout | 否 | 等待构建/发布多久之后放弃。 |
**部署时发生了什么:**CLI 把 --src 打包成 .tar.gz 并上传(同时转发 platform.json 中的绑定 —— 环境变量、secret、伸缩、触发器),然后沿着 queued → uploading → building → deploying → deployed 轮询整个部署过程。Dockerfile 和构建文件由平台合成并执行构建,这些都不需要你提供。
语言
这个 CLI 支持多种语言,具体支持哪些取决于 kind:
| Kind | csharp | node | python | go |
|---|---|---|---|---|
cloud_function | ✓ | ✓ | ✓ | ✓ |
game_server | ✓ | ✓ | — | — |
python 和 go 的 game server 目前会被拒 —— 它们还没有对应的运行时方案。cloud function 四种都支持。
自动识别(省略 --language 时):
- 按文件扩展名 ——
.cs→csharp,.js/.mjs/.cjs→node,.py→python,.go→go; - 按目录标志文件 —— 有
.csproj→csharp,package.json→node,go.mod→go,requirements.txt或main.py→python; - 都不匹配则回落到
csharp。
- C#
- Node / TypeScript
- Python
- Go
playserv fn deploy --slug match-maker --kind game_server --src ./server --language csharp
playserv fn deploy --slug leaderboard --kind cloud_function --src ./fn --language node
--language node 接受原始 TypeScript —— 把 --src 指向一个含 package.json + tsconfig.json + src/** 的目录即可,不需要预先构建出 index.js。平台会在构建时用 esbuild 转译入口文件(默认 src/index.ts,也可由 platform.json 的 entry 字段指定)。它只做转译 —— 类型检查请放在你的 CI 里跑。node_modules/** 和任何 .env* 文件都不会被上传;npm 包在构建时安装,运行时解析。
playserv fn deploy --slug webhook --kind cloud_function --src ./fn --language python
Python 仅对 cloud_function 可用。
playserv fn deploy --slug webhook --kind cloud_function --src ./fn --language go
Go 仅对 cloud_function 可用。
放在源码旁边的 platform.json 是环境变量、secret、伸缩和触发器的唯一依据 —— 部署会转发这些绑定。secret 的值要另外用 secrets set 设置;清单里只声明这个 Function 用到哪些 secret 名称。
对于 node,如果某个本地 file: 依赖的源码位于 --src 之外(例如 "@scope/shared": "file:../shared"),部署时会把它一并打进包,并为平台的 esbuild 步骤设好别名 —— 因此一个 import 了 ../shared 的服务,依然可以用 --src ./server 部署,不需要本地构建。来自 registry 的依赖仍按外部处理。
- **复制出来的 Environment 是被拦住的。**由另一个 env 复制而来的 Environment 不带部署链接:往里面
fn deploy会以409 env_not_linked失败,直到运维人员重新链接(Environments 标签页 → Re-link deploys)。已经在那里运行的构建不受影响。 - 重建一个曾经存在过的 slug 可能导致构建失败 —— 遇到这种情况,先
fn delete掉它,再重新部署。 - 刚部署好的
game_server在内部上行链路上可能返回401,直到它的 compute 服务账号被授予正确的 run 角色(组织策略可能会移除未认证绑定)。
管理 Function
playserv fn list [--env <env>]
playserv fn invoke --slug <slug> (--json '<json>' | --body <file>)
playserv fn delete --slug <slug> [-y]
list—— 已置备 Function 的表格:slug、kind、语言、状态、公开 URL 和 id。invoke—— 通过POST /fn/<slug>网关调用某个cloud_function,请求体可以内联给出(--json)或来自文件(--body)。delete—— 拆掉 Cloud Run 服务和平台上的记录(-y跳过确认)。
Secrets
按 Environment 划分的 Function secret。取值只从 stdin 读入 —— 绝不从参数读 —— 这样它们就不会留在 shell 历史里。
printf '%s' "$MY_VALUE" | playserv secrets set STRIPE_KEY --env prod
playserv secrets list [--env <env>]
playserv secrets delete STRIPE_KEY [--env <env>]
set创建或轮换一个 secret,并对用到它的 Function 做滚动重启。list显示名称以及last_set_at和in_use_by—— 从不显示取值。delete在仍有 Function 声明该 secret 时会以409 in_use被拒。
Function 在 platform.json 中声明自己需要哪些 secret 名称,secrets set 提供对应的值。
公开 slug
轮换 org/Project 的公开 slug,仅 owner 可用。有频率限制(每 30 天一次,终身 5 次);旧 slug 会在一段窗口期内重定向,之后返回 404。
playserv org:regenerate-slug --confirmation <current-slug> [--redirect-window-days <N>]
playserv project:regenerate-slug --confirmation <current-slug> [--redirect-window-days <N>]
命令速查
| 命令 | 用途 |
|---|---|
playserv login [token] | 用 pk_*/sk_* key 换取一个运维会话。 |
playserv logout | 清除本地会话。 |
playserv status | 实时探测并显示登录状态。 |
playserv fn list [--env] | 列出已置备的 Function。 |
playserv fn deploy --slug --kind --src [--language] [--env] [--poll-timeout] | 打包、上传、构建并发布一个 Function。 |
playserv fn invoke --slug (--json | --body) | 调用一个 cloud function。 |
playserv fn delete --slug [-y] | 删除一个 Function。 |
playserv secrets set <NAME> [--env] | 创建/轮换一个 secret(值经 stdin 传入)。 |
playserv secrets list [--env] | 列出 secret 名称。 |
playserv secrets delete <NAME> [--env] | 删除一个 secret。 |
playserv org:regenerate-slug --confirmation <slug> | 轮换 org 的公开 slug。 |
playserv project:regenerate-slug --confirmation <slug> | 轮换 Project 的公开 slug。 |
fn 是 functions 的别名。成功时退出码为 0;部署会用不同的非零退出码区分不同类别的失败。
下一步
- Functions —— cloud function 和 game server 是什么、怎么运行
- API Key Management —— 你用来登录的那些 key