# @cloud-cli/on 中文文档

规范地址：https://npmcn.com/package/%40cloud-cli/on/

版本：1\.79\.0
npm 元数据更新时间：2026-10-15T04:35:24.825Z
中文译文更新时间：2026-11-10T04:38:55.206Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40cloud-cli/on
原文对照：https://npmcn.com/package/%40cloud-cli/on/?lang=original

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.2 MB，106 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：5 个
- 首次发布：2026-03-17T07:02:53.043Z
- 最新版本发布：2026-10-15T04:35:24.633Z
- 近 30 天下载量：2197（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：219（近 12 个月 219 个）

## 中文简介

插件生态系统上的 CLI 切入点 .

## 安装

```sh
npm install @cloud-cli/on
```

也可以使用：`pnpm add @cloud-cli/on`、`yarn add @cloud-cli/on`、`bun add @cloud-cli/on`

## README

# 🏃 `@cloud-cli/on`

普通用途工作流程

为Node.js所制造的自备,轻量级,高性能的CI/CD跑跑发动机.

设计严格 **安全第一边界**,当地 **JavaScript AST 评价**,0-DSL模板文字,以及 a **内建终端日志网络仪表板**。 。 。 .

* * *

## 关键要点

-   **严格代码/数据分离 :** `run:` 步骤作为原始进程脚本逐字执行。 表达式和动态数据绑定被严格隔离到 `env:`,完全消除外壳注射向量.
-   **标准 ES 模板语法(`${...}`:** 没有自定义的 DSL 包装 `${{ }}` 或者说 `{{ }}`。如果一个字段包含 `${...}`,它通过AST评价标准的JavaScript模板字符串逻辑.
-   **决定性外地评价:** 没有静态倒置或模糊类型转换. 平面字符串仍为字面字符串;条件为 `if:` 字段为严格的 JS 布尔表达式.
-   **已建入黑暗模式 Web UI (`/runs`:** 监测工作状态,检查工作空间输入,并查看实时提供的ANSI色终端日志流.
-   **系统及容器执行驱动程序 :** 直接以离散主机进程组或被隔离的多克/系统瞬态单元内运行步骤.
-   **DB 授权的工作流程 :** 通过认证的API起草、验证并公布便携式YAML工作流程.
-   **计划执行 :** 已发布的工作流程可以从克龙表达式或本地出日出/日出事件运行.
-   **加密秘密存储 :** 秘密密码文本被存储在数据库;主密钥仍保存在HTTP服务器上.

* * *

## 项目结构

```text
my-project/
├── runner.config.mjs        # Optional plugin/advanced configuration
└── package.json

```

* * *

## QQ 快速启动

### 1\. 安装和运行

直接通过引擎运行 `npx` 或者说 `pnpm dlx`数字 :

```bash
# Start each role (normally managed by the supplied systemd units)
npx @cloud-cli/on start-server
npx @cloud-cli/on start-scheduler
npx @cloud-cli/on start-workers

```

### 2\. 界定工作流程

```yaml
name: Build and Publish Release

on:
  github:
    events:
      - push
    owner: octocat
    repo:
      - example
      - another-example
    branches:
      - main
      - releases/*
    paths:
      - package*.json
    if: inputs.action !== 'deleted'

concurrency:
  group: release-${inputs.repo}
  cancel-in-progress: true

# Every tag must be advertised by the worker that claims this workflow.
tags: [linux, docker]

steps:
  - id: checkout
    name: Checkout Code Repository
    env:
      CLONE_URL: ${inputs.clone_url}
      COMMIT_SHA: ${inputs.commit_sha}
    run: |
      git clone --depth 1 "$CLONE_URL" .
      git checkout "$COMMIT_SHA"

  - id: install-and-build
    name: Install Dependencies & Build
    run: |
      pnpm install
      pnpm run build

  - id: publish
    name: Publish to NPM
    env:
      NPM_TOKEN: ${secrets.NPM_TOKEN}
    run: |
      echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" > ~/.npmrc
      npx --yes semantic-release@24 -b main --no-ci
```

将YAML作为草稿存储,并通过认证的API发布. 只有已出版的修订版才能收到webhoks或预定运行. 编辑马上进行测试,保存草稿和使用 **快点跑**; 此队列将保存的最新修改草稿不修改或发布:

```bash
curl -u admin:"$RUNNER_ADMIN_SECRET" -X POST http://localhost:11235/api/workflows/validate \
  -H 'Content-Type: application/json' --data '{"sourceYaml":"..."}'
curl -u admin:"$RUNNER_ADMIN_SECRET" -X PUT http://localhost:11235/api/workflows/build-and-publish-release \
  -H 'Content-Type: application/json' --data '{"sourceYaml":"..."}'
curl -u admin:"$RUNNER_ADMIN_SECRET" -X POST http://localhost:11235/api/workflows/build-and-publish-release/publish
```

时间触发器被定义在 Webhook 触发器旁边:

```yaml
on:
  schedule:
    - id: nightly
      cron: "0 2 * * *"
      timezone: Europe/Berlin
  solar:
    - id: morning
      event: sunrise
      latitude: 52.52
      longitude: 13.405
      offset: +15m
```

GitHub 触发器支持这些预处理器过滤器 :

| 外地 | 匹配行为 |
| --- | --- |
| `events` | 精确的 Webhook 事件名称 |
| `owner`, (中文(简体) ), `repo` | 一个或许多确切可以接受的名称 |
| `name` | 一个或许多确切可接受的名称,与Org/repo合并 |
| `branches` | 分支/资源表型,例如 `main` 或者说 `v1.*`,匹配分支和标签 |
| `refs` | 别名 `branches` |
| `tag` | `true` 需要标签推; `false` 需要非目标事件 |
| `paths` | 跨添加、修改并删除文件的已更改文件 glob 模式 |

配置的字段与AND结合. 一个列表中的值与OR结合. `tags` 还需要匹配标签值,同时 `branches` 需要匹配分支值。 一般情况 `if` 表达式在所有预处理器过滤器通过后分别进行评估.

例如,标签工作流程可以使用 `tag: true` 具有一个或多个正则表达式:

```yaml
on:
  github:
    events: [push]
    owner: octocat
    repo: example
    tag: true
    tags:
      - ^v1\..*
```

* * *

## QQ CLI 使用和命令

```bash
npx @cloud-cli/on [command] [options]

```

### 图标

| 命令 | 说明 |
| --- | --- |
| **`start-server`** | 运行 Webhook 入侵网关(接收webhooks的HTTP服务器). |
| **`start-scheduler`** | 调度发布克龙和太阳工作流程触发器. |
| **`start-workers`** | 运行事件驱动的工人调度器(可缩放的工人). |

### CLI 和环境选项

| 旗帜 | 选项 | 默认 | 信封 | 说明 |
| --- | --- | --- | --- | --- |
| `-h` | `--help` | —— 说 | \- 说吧 | 打印 CLI 帮助消息和退出 . |
| `-c` | `--config` | `./runner.config.mjs` | `RUNNER_CONFIG_FILE` | JavaScript 配置文件的路径 . |
| `-d` | `--database` | \- 说吧 | `DATABASE_URL` | 节点.js ES模块 URL导出数据库 API. |
| `-p` | `--port` | `11235` | `PORT` | 入侵HTTP服务器端口. |
| `-k` | `--workers` | `5` | `RUNNER_WORKERS` | 此节点的最大并行任务 . |
|  |  |  | `RUNNER_ADMIN_SECRET` | 通过 API 刷新秘密的代理令牌 |
|  |  |  | `RUNNER_WORKER_SECRET` | 工作活动和秘密检索的工人代号 |
|  |  |  | `OIDC_ISSUER` | 例如 OIDC 发行器 URL `https://auth.api.apphor.de` |
|  |  |  | `OIDC_CLIENT_ID` | 注册的 OIDC 客户端标识符 |
|  |  |  | `OIDC_CLIENT_SECRET` | 已注册的 OIDC 客户端秘密 |
|  |  |  | `RUNNER_OIDC_PROVIDER_URL`, (中文(简体) ), `RUNNER_OIDC_CLIENT_ID`, (中文(简体) ), `RUNNER_OIDC_CLIENT_SECRET` | 以上 OIDC 设置的后遗症别名 . |
|  |  |  | `RUNNER_SERVER_URL` | 工人使用的 Webhook 服务器 URL . |
|  |  |  | `RUNNER_TAGS` | 逗号分离工人能力标记. |
|  |  |  | `RUNNER_VAPID_PUBLIC_KEY` | 背景Web Push通知的公钥. |
|  |  |  | `RUNNER_VAPID_PRIVATE_KEY` | 背景Web Push通知的私钥. |
|  |  |  | `RUNNER_VAPID_SUBJECT` | VAPID 联系人,例如 `mailto:admin@example.com`。 。 。 . |

设定 `RUNNER_ADMIN_SECRET` 仅用于仪表板和管理API的HTTP服务器上. 设置相同的非空 `RUNNER_WORKER_SECRET` 在服务器和每个工人上发布工作状态更新事件并检索工作范围的秘密。 当三个 `RUNNER_OIDC_*` 数值被配置, `/auth/login` 允许浏览器登录入内,浏览器使用与外部消费者相同的无记名卡通 API 路径,认证用户可以读取日志,API 令牌设置 页面发布并通过OIDC 提供商取消被范围化的令牌. 登记册 `https://your-runner-host/auth/callback` 当OIDC重定向URI时. 仪表板工作流程 API 接受 Bearer 认证或 HTTP 使用用户名的基本认证 `admin` 还有管理员的秘密.

### 秘诀

秘密是写在 `PUT /api/secrets/:NAME` aES-256-GCM在数据库中加密。 设定 `RUNNER_MASTER_KEY` 仅在 HTTP 服务器上,或提供 `on-master-key` 系统证书。 工人只有在声称有工作时才得到解密的数值;数值不写给工作有效载荷或报告.

* * *

## QQ 配置参考

您可以使用 `runner.config.mjs` 在您的工程根中 :

```javascript
// runner.config.mjs
import { GitHubStatusPlugin } from "@cloud-cli/on";

export default {
  port: 3000,
  workers: 5,
  serverUrl: "https://runner.example.com/",
  tags: ["linux", "docker"],
  storagePath: "/tmp/workspaces",
  database: "https://remote.db.com/",

  // Global environment variables passed to all steps
  env: {
    NODE_ENV: "production",
  },

  plugins: [
    new GitHubStatusPlugin({
      token: process.env.SECRET_GITHUB_TOKEN,
      context: "on",
    }),
  ],
};
```

GitHub 状态插件会在工作流程开始和完成时发布承诺状态 。 它的令牌需要权限来为目标寄存器写入承诺状态 .

### 背景通知

仪表板可以在通过Web Push关闭时收到工作通知. 生成 VAPID 密钥配对 `npx web-push generate-vapid-keys`,配置三个 `RUNNER_VAPID_*` 值,并启用 HTTPS 上的仪表板通知。 没有VAPID配置,通知只在仪表板打开时有效.

运行细节作为 HTML 提供 `/runs/:id` 并且被消毒的JSON at `/api/runs/:id`。在运行活动时, HTML 视图通过特定任务 SSE 事件进行被动更新。 两种表示都省略了原始的webhook体,敏感的输入字段,执行环境值,以及内部重运行状态.

打开 `/workflows` 以列出工作流程并管理秘密值。 打开 `/workflows/new` 以创建定义或 `/workflows/:id` 要编辑一个。 这些页面由管理员HTTP Basic Certification保护;秘密值只写.

* * *

## 确定性评价规则

为防止语法模糊和注入风险,工作流程定义中的字段在 **三种严格模式**数字 :

```
┌──────────────────────────────────────────────────────────────────────────┐
│ 1. RAW PASSTHROUGH MODE (`run:`)                                         │
│ • Executed verbatim as a shell process command.                          │
│ • No string replacements or engine parsing performed.                    │
│ • Access environment variables strictly via shell syntax: $MY_VAR.       │
└──────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────┐
│ 2. EXPRESSION MODE (`if:`, `eval:`)                                      │
│ • Evaluated strictly as pure JavaScript expressions via Acorn AST.       │
│ • Must be valid JS syntax (e.g. `inputs.branch === 'main'`).             │
│ • Automatically coerced to boolean in `if:` conditions.                  │
└──────────────────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────────┐
│ 3. DETERMINISTIC VALUE MODE (`env:`, `name:`, `image:`, `group:`)        │
│ • Plain strings WITHOUT `${}` remain 100% raw literal strings.            │
│ • Strings WITH `${...}` evaluate as standard ES Template Literals.       │
│ • Example: `node:${inputs.node_version}-alpine`                          │
└──────────────────────────────────────────────────────────────────────────┘

```

### 背景范围可用表达式

内部 `${...}`, (中文(简体) ), `if:`,以及 `eval:` 上下文,以下对象范围被曝光: 1

-   **`inputs`**: 从接收到的webhooks收到的有效载重密钥值.
-   **`env`**: 从全球配置和工作流程定义中合并环境变量.
-   **`secrets`**: 来自加密中央密钥存储器的未显示任务范围值.
-   **`steps`**: 执行状况和工作流程中以往步骤的产出`steps.<id>.status`, (中文(简体) ), `steps.<id>.outputs`) (中文(简体) ).
-   **`files`**: 工作空间文件助手 `if:` 财务报告和审定财务报表 `eval:` 表达式 : `files.exists('Dockerfile')`, (中文(简体) ), `files.readFile('package.json')`,以及 `files.join('dist', 'artifact')`。任务以外的路径 `workingDir` 拒绝.
-   **`BUILTIN_HELPERS`**联合来文:公共事业 `String`, (中文(简体) ), `Number`, (中文(简体) ), `Boolean`,以及 `JSON.parse` 编号 : `JSON.stringify`。 。 。 .

* * *

## QQ Webhook 入侵网关和 Dashboard

Ingress Gateway为收到的HTTP请求收听并服务于活网络UI.

### 端点矩阵

| 方法 | 终点 | 说明 |
| --- | --- | --- |
| **`POST`** | `/webhooks/github` | GitHub 事件的 Webhook 端点 。 应用 GitHub 筛选和评价 `on.github.if`。 。 。 . |
| **`GET`** | `/runs` | **盘子 :** 公开直播暗模式监控页面列出近期工作. |
| **`GET`** | `/api/jobs?afterId=<id>&beforeId=<id>&limit=<n>` | 带有独有的下端和上端ID光标并有从1到500的限制(默认为50)的 Dashboard 任务. |
| **`GET`** | `/runs/:jobId` | **任务报告 :** 经认证的交互式跟踪,并带有步时和终端日志输出. |
| **`GET`** | `/workflows` | 认证工作流程列表并加密了秘密管理 UI. |
| **`GET`** | `/workflows/new`, (中文(简体) ), `/workflows/:id` | 认证 YAML 工作流程编辑器 . |
| **`POST`** | `/api/workflows/validate` | 已认证的 YAML 验证没有持久性 . |
| **`GET`, (中文(简体) ), `PUT`, (中文(简体) ), `DELETE`** | `/api/workflows/:id` | 经认证的修订工作流程读取,草稿保存并删除. |
| **`POST`** | `/api/workflows/:id/publish` | 最新修订草案的认证出版. |
| **`POST`** | `/api/workflows/:id/run` | 已认证的当前保存的最新修订稿 . |
| **`GET`, (中文(简体) ), `PUT`, (中文(简体) ), `DELETE`** | `/api/secrets`, (中文(简体) ), `/api/secrets/:name` | 已认证加密的秘密名称和只写值管理 . |

### 盘片特性

-   **实时自动更新 :** `/runs` 自动刷新任务队列状态( n)`PENDING`, (中文(简体) ), `RUNNING`, (中文(简体) ), `SUCCESS`, (中文(简体) ), `FAILED`, (中文(简体) ), `CANCELLED`) (中文(简体) ).
-   **ANSI 终端渲染 :** 用途 `ansi_up` 在步骤日志框中准确渲染出出彩色、粗体亮度和控制输出.
-   **有效载荷检查:** 查看从webhokes收到的 JSON 输入以方便调试 .
-   **工作流程管理:** 使用认证 `/workflows` 创建,验证,发布,编辑,并删除 DB 授权的工作流程修改的页面.

* * *

## 安全加硬化

1.  **环境可变边界 :** 强迫 shell 步骤通过进程环境变量消耗数据(`$CLONE_URL`),含有外壳分解器(例如:. `; rm -rf /`) 无法变换 shell 脚本执行树 .
2.  **原型污染保护:** AST评估明确阻止接触危险的JS财产(第5条)`constructor`, (中文(简体) ), `__proto__`, (中文(简体) ), `prototype`) (中文(简体) ).
3.  **有效载荷大小守护 :** Ingress服务器执行严格的5MB有效载荷限制,以防止出记忆(OOM)拒绝服务攻击.
4.  **范围化 API 认证 :** 工作流程验证、出版和秘密管理要求 `RUNNER_ADMIN_SECRET` 过HTTPS。 OIDC 会话和提供商发行的可扩展符号在批准时读取工作日志 `logs:read`工人使用单独的 `RUNNER_WORKER_SECRET` 只针对他们声称的生命周期事件和工作秘密.

## 部署

安装单元文件 `systemd/` 并创建 root 拥有的环境文件 `/etc/on/`数字 : `server.env` 页:1 `DATABASE_URL`, (中文(简体) ), `RUNNER_SERVER_URL`, (中文(简体) ), `RUNNER_ADMIN_SECRET`, (中文(简体) ), `RUNNER_WORKER_SECRET`三个 `RUNNER_OIDC_*` 数值; `scheduler.env` 页:1 `DATABASE_URL`; 和 : `worker.env` 页:1 `DATABASE_URL`, (中文(简体) ), `RUNNER_SERVER_URL`, (中文(简体) ), `RUNNER_WORKER_SECRET`, (中文(简体) ), `RUNNER_TAGS`,以及 `RUNNER_TMP`工人只领取 `RUNNER_WORKER_SECRET`;管理员和OIDC秘密留在了HTTP服务器上. 提供单位作为根运行,因为系统执行驱动程序创建了瞬态系统服务. 使用 `systemctl edit` 用于每台机器的重置.

将服务器主密钥放入 `/etc/on/credentials/on-master-key` 仅限根权限. `runner-server.service` 通过Systemd的证书目录私下揭露. 启动主控制平面 `systemctl enable --now runner.target`; 启用 `runner-worker.service` 单靠工人机器 使用 `systemctl edit runner-worker.service` 用于机器专用标签和路径.

对于一揽子管理的远程工人,启用 `runner-worker-update.timer`每天4:00运行,每台机时最多45分钟,安装 `@cloud-cli/on@latest` 输入 `/opt/on`,然后只有在安装成功时才能重新启动工人. `runner-worker.service` 在重启期间,运行的工作最多可以排出一个小时。 不要让这个定时器用于一个由来源管理的发展工作者,而是从它的停工楼中部署这个工作者.

手动排出一个工人而不离开它停止,发送 `SIGUSR1` 仅用于主要进程: `systemctl kill --kill-who=main --signal=SIGUSR1 runner-worker.service`工人停止要求新的工作,等待工作完成,退出状态0,以及 `Restart=always` 开始替换。 使用 `systemctl restart runner-worker.service` (d) 系统等待相同的排水行为直至 `TimeoutStopSec=1h`。 。 。 .

工人现在在申请工作时解决了不可改变的修订问题。 一个工作流程可以安全使用一个退出步骤,然后 `if: files.exists('Dockerfile')`· ; `files` 被限制在工作 `workingDir`,因此无法检查该工作空间外的文件.

## 未来安全工作

这个MVP有意支持一个被信任的操作员. 在共享UI或将其曝光于私人部署之外之前,加入个人账户和角色,安全浏览器会话和CSRF保护,审计日志,工人注册证书,秘密密钥旋转,加密系统证书,限制费率,以及数据库的高可用性.

## 计划推出的运行者

一揽子管理的工人目前更新一个错开的每日计时器。 在允许自动推广新发布的跑道版本之前,实施受控的金丝雀推出:

1.  发布一个新的不可移动 npm 版本,并解决候选人标签后面的确切版本.
2.  在一个指定的金丝雀工人身上安装精确的版本,在推出时从不移动标记.
3.  版本目录中的阶段发布和原子切换 a `current` 只有在安装和本地烟雾检查成功后才能连接.
4.  排出金丝雀与 `SIGUSR1`,重新启动,并保留先前的发布目录以回滚.
5.  要求金丝雀报告含有工人身份的心跳,运行版本,健康状况,以及最后一眼的时间.
6.  运行一个专用 `runner-health` 工作流程与 `tags: [canary]` 以验证队列要求、修订搜索、任务范围秘密检索以及执行驱动程序.
7.  记录推出状态持续:候选人版本、金丝雀工人、地位、晋升时间和失败原因.
8.  只提升健康候选人 `npm dist-tag add @cloud-cli/on@<version> stable`。 。 。 .
9.  配置要安装的普通工人日更新 `@cloud-cli/on@stable`一个工人的货币限额.
10.  安装失败时, 重新启动、 心跳或健康检查, 标记被拒绝的候选人, 离开 `stable` 不变,然后把金丝雀卷回原来的版本.

SSE应该通知工人有更新信息,但控制飞机数据库必须仍然是权威的推出状态,因此断开连接的工人在重新连接后安全地汇合.

## 发展

```bash
pnpm i
pnpm run lint
pnpm run test
pnpm run build
```

## 常见问题

### @cloud-cli/on 是什么？

插件生态系统上的 CLI 切入点 \.

### 如何安装 @cloud-cli/on？

在项目目录运行 npm install @cloud-cli/on，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 on，可以用 npx on 直接运行。

### @cloud-cli/on 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @cloud-cli/on 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @cloud-cli/on 可以商用吗？

@cloud-cli/on 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @cloud-cli/on 的下载量有多少？

根据 npm 官方下载统计，@cloud-cli/on 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,197 次，日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @cloud-cli/on 还在维护吗？

最新版本 1\.79\.0 发布于 2026/10/15（26 天前）；至今共发布 219 个版本，其中过去 12 个月发布了 219 个；首次发布于 2026/03/17。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

