@h-ai/deploy 0.1.0-alpha.65 → 0.1.0-alpha.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +46 -169
- package/README.ja.md +46 -169
- package/README.md +88 -144
- package/dist/index.d.ts +51 -26
- package/dist/index.js +486 -470
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,201 +1,145 @@
|
|
|
1
1
|
# @h-ai/deploy
|
|
2
2
|
|
|
3
|
-
[简体中文](
|
|
3
|
+
[简体中文](README.md) | [English](README.en.md) | [日本語](README.ja.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
部署 SDK,也是 `@h-ai/cli` 的 `hai deploy` 后端。**只部署已有产物,不编译源码、不构建镜像。**
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
完整的创建、开发、构建与部署流程见[使用指南](../../docs/usage/README.md);下文侧重部署准备、SDK 与二次开发。
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 功能
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
- `docker-ssh`:读取镜像清单,选择环境和中间件,生成一个 Compose tar;上传到 Linux 后解包、导入镜像、启动并检查健康状态。
|
|
12
|
+
- `--bundle-only`:只生成同样的 tar 和操作说明,不连接 SSH;支持 U 盘或其他手工搬运方式。
|
|
13
|
+
- fullstack 的构建清单含 app/web 两个镜像时一起部署。公开端口提供 Web 和同源 API;Web 不接收 API 的私有变量,支持 hash 页面刷新。
|
|
14
|
+
- `vercel`:上传已有 `.vercel/output` 并设置运行变量;需要网络,按 [Build Output API](https://vercel.com/docs/build-output-api/primitives) 的 prebuilt 协议部署,不执行本地或平台源码构建。
|
|
15
|
+
- 只从目标 importer 的 `pnpm-lock.yaml` 遍历运行依赖(含 workspace link),排除 dev/peer,识别数据库、cache、storage、vecdb、LDAP、邮件和短信等中间件。
|
|
16
|
+
- 中间件逐项选择默认、自定义或保持不变;配置完整时用 `--skip-middleware` 跳过全部处理。Compose 默认支持 PostgreSQL、MySQL、Redis、RustFS/MinIO、Qdrant、pgvector、Chroma、OpenLDAP、Mailpit;云开通支持 Neon、Upstash、R2、Resend、阿里云短信。详细字段见 [环境与中间件](../cli/templates/skills/hai-deploy/middleware.md)。
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
- 先选择环境并检查 `.env.<mode>`,再逐项选择默认配置、自定义连接或保持不变。环境已配置完整时可跳过全部中间件处理。
|
|
18
|
-
- Compose 支持 PostgreSQL、MySQL、Redis、RustFS/MinIO、Qdrant、pgvector、Chroma、OpenLDAP、Mailpit;SQLite、memory、local、LanceDB 按各自本地存储方式处理。Mailpit 只捕获测试邮件。
|
|
19
|
-
- 云开通支持 Neon、Upstash、Cloudflare R2、Resend、阿里云短信。R2 需要已有 S3 密钥,Resend 需要已验证发件域名,短信需要已审核签名与模板;其他后端使用自定义连接。
|
|
18
|
+
## 构建与部署
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
当前工程要求 Node `^22.22.2 || ^24.15.0 || >=26.0.0`、pnpm 12.11.2。Windows 用 `pnpm.cmd`;Node 20 / pnpm 9.5.0 不受支持。
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
### 1. 安装与准备
|
|
26
|
-
|
|
27
|
-
当前 Node 要求为 `^22.22.2 || ^24.15.0 || >=26.0.0`,生成工程固定 `pnpm@12.11.2`。Node 20 / pnpm 9.5.0 不受支持。Windows 使用 `pnpm.cmd`。
|
|
28
|
-
|
|
29
|
-
在生成工程根目录安装与应用框架版本匹配的 CLI 和 SDK,并保留 lockfile(此步骤需要包源或完整离线依赖):
|
|
22
|
+
生成工程的 `pnpm build` 调用 `hai build`,默认只编译源码。镜像和原生安装包按目标显式构建,**不选择 dev/test/prod,不读部署文件,也不注入运行期凭据**:
|
|
30
23
|
|
|
31
24
|
```powershell
|
|
32
|
-
pnpm.cmd
|
|
33
|
-
pnpm.cmd
|
|
25
|
+
pnpm.cmd build
|
|
26
|
+
pnpm.cmd build --target docker
|
|
27
|
+
# 自动选择可用的 Podman,失败后尝试 Docker;也可显式指定
|
|
28
|
+
pnpm.cmd build --target docker --runtime docker
|
|
29
|
+
# 启用 desktop 的 fullstack;需在对应系统上安装 Rust target/系统 SDK/打包工具
|
|
30
|
+
pnpm.cmd build --target desktop --platform windows --arch x64
|
|
34
31
|
```
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
`hai.build.json` 指定 Dockerfile 阶段、context 和 Tauri 目录。compile 只编译源码,docker 导出镜像,desktop 调用 Tauri,具体默认值和示例见[构建参数](../../docs/usage/README.md#build-的可选参数)。版本取应用根 package.json.version;以 1.2.3 为例,输出 `.hai/build/docker/1.2.3-<构建编号>/`,含格式版本 2 的 manifest.json(appVersion 为应用版本)、app-1.2.3.tar、可选 web-1.2.3.tar 和 SHA-256。全部成功才更新 latest。Tauri 使用相同根版本,安装包在对应工程 src-tauri/target/<Rust target>/release/bundle/。各 OS 分别准备主机/runner 与 SDK,不承诺跨系统编译。
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
fullstack 在工程根执行:
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
37
|
+
```powershell
|
|
38
|
+
pnpm.cmd run deploy --env test
|
|
39
|
+
pnpm.cmd run deploy --env prod --skip-middleware
|
|
40
|
+
# 精确复用一次构建,绝不重新构建
|
|
41
|
+
pnpm.cmd run deploy --env prod --artifact-dir .hai/build/docker/<buildId>
|
|
42
|
+
# 服务器网络不通,只交付包
|
|
43
|
+
pnpm.cmd run deploy --env prod --bundle-only --output release-prod.tar
|
|
44
|
+
```
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
等价命令为 `pnpm exec hai deploy packages/my-app-serv --env prod --env-dir .`。API workspace 的服务目录为 `apps/my-app-service`。模板已安装项目 CLI;选择 deploy 功能时安装对应 SDK。旧工程需自行安装与框架版本匹配的 `@h-ai/cli`、`@h-ai/deploy`,并提供构建配置和 `_deploy.yml`。
|
|
46
47
|
|
|
47
|
-
`
|
|
48
|
+
先检查 `.env.<mode>`;缺少则停止并提示创建。`.env` 公共基础、`.env.dev/test/prod` 环境覆盖和完整说明 `.env.example` 提交 Git;`.env.local` 保存私有值并忽略。优先级:进程 > `.env.local` > 环境文件 > `.env`,整体 JSON 节点优先于子字段。
|
|
48
49
|
|
|
49
50
|
```yaml
|
|
51
|
+
# packages/my-app-serv/config/_deploy.yml
|
|
50
52
|
provider:
|
|
51
53
|
type: docker-ssh
|
|
54
|
+
expose:
|
|
55
|
+
hostPort: 18080
|
|
52
56
|
container:
|
|
53
|
-
|
|
54
|
-
s3Engine: rustfs
|
|
55
|
-
services: {}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
```dotenv
|
|
59
|
-
# .env.local:不提交 Git;地址、用户名、端口及路径按实际环境替换
|
|
60
|
-
HAI_DEPLOY_PROVIDER='{"type":"docker-ssh","ssh":{"host":"10.0.0.20","port":22,"username":"deploy","identityFile":"C:/Users/me/.ssh/hai_deploy"},"remote":{"baseDir":"/opt/hai/apps","runtime":"docker"},"expose":{"type":"port","containerPort":3000,"hostPort":18080}}'
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
也可让交互向导填写缺失的目标参数,保存 `.env.local` 后复用。私钥只记录路径。已有完整目标会直接复用,切换目标时修改 `HAI_DEPLOY_PROVIDER`。
|
|
64
|
-
|
|
65
|
-
覆盖顺序为 `.env` → `.env.<mode>` → `.env.local` → 当前进程变量;父节点 JSON(如 `HAI_DB`)优先于叶子变量。`.env.example` 记录完整字段、说明与枚举;`.env`、`.env.dev/test/prod` 提交 Git,真实凭据只放 `.env.local`。首次启动 fullstack 需在私有配置中设置符合 IAM 策略的 `HAI_ADMIN_DEFAULT_PASSWORD`。
|
|
66
|
-
|
|
67
|
-
fullstack 生产环境还必须在 `.env.prod` 设置明确的 Web Origin,例如 `HAI_SERV_CORS_ORIGIN=https://app.hai.internal`;默认 `*` 会使生产启动失败。生产 refresh Cookie 启用 Secure,Web/API 应通过已配置信任证书的 HTTPS 入口访问;只开放 HTTP 端口不足以验收完整登录与刷新会话。
|
|
68
|
-
|
|
69
|
-
### 3. 执行部署
|
|
70
|
-
|
|
71
|
-
从 fullstack 工程根目录运行,替换实际服务目录:
|
|
72
|
-
|
|
73
|
-
```powershell
|
|
74
|
-
pnpm.cmd exec hai deploy packages/my-app-serv --env prod --env-dir .
|
|
57
|
+
s3Engine: ${HAI_DEPLOY_CONTAINER_S3ENGINE:rustfs}
|
|
75
58
|
```
|
|
76
59
|
|
|
77
|
-
|
|
60
|
+
container.s3Engine 可省略,默认 rustfs;仅自动创建 Compose S3 服务时区分 RustFS/MinIO 的镜像和桶初始化,既有自定义 S3 不受它影响。向导会保存选择,完整说明见[使用指南](../../docs/usage/README.md#先准备环境与部署目标)。跳过全部中间件处理使用 --skip-middleware,SDK 对应 skipMiddleware。
|
|
78
61
|
|
|
79
|
-
|
|
62
|
+
自动 SSH 部署首次向导填写目标,写入 `.env.local` 后复用;也可直接配置:
|
|
80
63
|
|
|
81
|
-
```
|
|
82
|
-
|
|
64
|
+
```dotenv
|
|
65
|
+
HAI_DEPLOY_PROVIDER='{"type":"docker-ssh","ssh":{"host":"10.0.0.20","username":"deploy","port":22,"identityFile":"C:/Users/me/.ssh/hai_deploy"},"remote":{"baseDir":"/opt/hai/apps","runtime":"docker"},"expose":{"hostPort":18080,"containerPort":3000}}'
|
|
83
66
|
```
|
|
84
67
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
`--project-name <name>` 指定名称,选定环境后名称追加环境后缀。**`--skip-build` 当前仅跳过 Vercel 的应用构建;docker-ssh 始终构建镜像,不支持直接指定已有应用镜像。** 命令失败返回非零退出码。
|
|
88
|
-
|
|
89
|
-
## docker-ssh 的文件与执行流程
|
|
68
|
+
仅打包不要求 SSH 参数。本地部署工具只需要已安装依赖、`tar` 和构建产物;**不需要本地 Docker/Podman**。自动部署另外需要 `ssh/scp`、服务器指纹与非交互登录权限、可写部署目录、SSH 及应用端口可达。
|
|
90
69
|
|
|
91
|
-
|
|
92
|
-
2. 本地构建应用镜像,使用 `docker/podman save` 导出 tar。
|
|
93
|
-
3. SSH 检查远程容器引擎与 Compose;SCP 上传 tar,远程执行 `load`。
|
|
94
|
-
4. 本地生成 `compose.yml`、`.env.runtime`、`start-<mode>.sh`,分别上传至 `<baseDir>/<projectName>-<mode>/`。它们与镜像归档分开传输,不打成一个 Compose 压缩包,也不把源码上传后在 Linux 构建。
|
|
95
|
-
5. 远程脚本设置 `HAI_DEPLOY_ENVIRONMENT`、`HAI_CORE_ENV`,执行 `compose --env-file .env.runtime ... up -d`。SDK 从本地访问原生服务 `/health` 或 SvelteKit `/`,通过后才返回成功。
|
|
70
|
+
## tar 内容与手工启动
|
|
96
71
|
|
|
97
|
-
|
|
72
|
+
部署 tar 默认名为 bundle-<项目>-<部署ID>-<应用版本>.tar,自定义 --output release-prod.tar 也会自动得到 release-prod-1.2.3.tar(示例版本 1.2.3)。包含 docker-compose-1.2.3.yml、manifest.json、.env.runtime、可选 web.conf、镜像归档、SHA256SUMS、start-<mode>.sh 和 README.txt。它含私有凭据,权限 600,不提交 Git。packaged 不代表服务器已运行;自动部署上传一个 tar,在远程解包启动,不传源码或构建镜像。
|
|
98
73
|
|
|
99
|
-
|
|
74
|
+
将包搬到 Linux 后,按包内 README 操作:
|
|
100
75
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
107
|
-
| Windows 工具 | 兼容的 Node(例如满足要求的 Node 24)、pnpm 12.11.2、已安装的 CLI/SDK 及传递依赖;OpenSSH;已初始化且可启动的 Linux 容器引擎 |
|
|
108
|
-
| 项目 | 完整工程、固定版本 lockfile、环境文件及私有凭据;能离线运行 `pnpm.cmd exec hai --help`。现场不要使用 `npx` / `pnpm dlx` 临时下载 |
|
|
109
|
-
| Linux | Docker CLI/Engine、Compose 插件(`docker compose version` 成功)、SSH 公钥授权、容器权限、可写目录、开放端口及足够镜像/卷空间;仅运行镜像不需要主机 Node/pnpm |
|
|
110
|
-
| 镜像 | 与 Linux CPU 架构一致的 API、Web 及中间件镜像;名称与 tag 和 Compose 完全一致;导入用 `docker load -i <archive.tar>` |
|
|
111
|
-
| 业务配置 | PostgreSQL 数据库/账号、Redis 连接及密码、RustFS 密钥/桶、首次管理员密码;已有服务须已启动且可从应用容器访问,`localhost` 指应用容器自身 |
|
|
112
|
-
|
|
113
|
-
默认 Compose 使用 `postgres:16-alpine`、`redis:7-alpine`、`ghcr.io/rustfs/rustfs:1.0.1`。已有其他 tag 不等于命中这些镜像;先核对并导入/正确标记已验证兼容的镜像,或使用自定义连接。中间件镜像不会由 SDK 自动打包上传。其他固定镜像见 [Compose 实现](src/container/deploy-container-compose.ts)。
|
|
114
|
-
|
|
115
|
-
**默认源码构建并非开箱即用的离线构建。** Dockerfile 会准备 pnpm、下载包和 SQLite 预编译驱动;fullstack 根 Dockerfile 还使用 `pnpm fetch` 与外部 Dockerfile frontend。Windows 的 `node_modules` 或 pnpm store 不能代替 Linux 构建依赖。若现场从源码构建,应带齐本地引擎中的 Node 基础镜像、构建 frontend、Corepack/pnpm、Linux 平台依赖和原生二进制缓存,并调整 Dockerfile 使用这些材料。在准备环境断开外网完整构建一次;`pnpm install --offline --frozen-lockfile` 仅解决包存储读取,不覆盖安装脚本的额外下载。
|
|
116
|
-
|
|
117
|
-
SQLite 预编译包须匹配 better-sqlite3 版本、Node ABI、CPU 架构和 libc。即使运行期选 PostgreSQL,当前依赖安装仍可能需要该包。可预置 Linux 构建环境的 prebuild-install 缓存,或通过 `container.sqlitePrebuildMirror` 指向内网镜像;两者都没有时需提前带入二进制或成品镜像。默认 fullstack 不需要 CUDA。
|
|
118
|
-
|
|
119
|
-
### 使用预构建镜像离线执行 SDK
|
|
120
|
-
|
|
121
|
-
较易交付的方式是提前构建镜像,现场让 SDK 复用它。以下以工程名 `my-app`、Web 前端和与服务器一致的构建架构为前提;在可提供依赖的材料准备环境执行,不是在离线现场下载:
|
|
122
|
-
|
|
123
|
-
```powershell
|
|
124
|
-
docker build --target runtime -t my-app-api:offline .
|
|
125
|
-
docker build --target web -t my-app-web:offline .
|
|
126
|
-
docker save -o my-app-images.tar my-app-api:offline my-app-web:offline
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
把归档带入离线 Windows 的本地 Linux 引擎,执行 `docker load -i my-app-images.tar`。在 `packages/my-app-serv/Dockerfile` 写入下列内容,使 SDK 的必经构建只复用成品镜像,无包安装步骤;业务代码变化后须重制成品镜像:
|
|
130
|
-
|
|
131
|
-
```dockerfile
|
|
132
|
-
FROM my-app-api:offline
|
|
76
|
+
```sh
|
|
77
|
+
mkdir -p release && chmod 700 release
|
|
78
|
+
tar -xf release-prod-1.2.3.tar -C release
|
|
79
|
+
cd release
|
|
80
|
+
HAI_DEPLOY_PROVIDER_REMOTE_RUNTIME=docker sh start-prod.sh
|
|
133
81
|
```
|
|
134
82
|
|
|
135
|
-
|
|
83
|
+
启动脚本自动 -f 选择带版本的 Compose,检查归档和镜像、导入 app/web、导出环境标识后启动。缺中间件镜像时停止,不联网下载。卷按项目和环境隔离,跨版本重复部署保留数据。手工检查使用 `docker compose -f docker-compose-1.2.3.yml --env-file .env.runtime ps`(或 logs),并验证 Web、/health。生产 HTTPS、CORS、DNS 与证书须另行配置。
|
|
136
84
|
|
|
137
|
-
|
|
85
|
+
## 完全离线准备(Windows → Linux)
|
|
138
86
|
|
|
139
|
-
|
|
140
|
-
docker load -i /path/to/my-app-images.tar
|
|
141
|
-
docker run -d --name my-app-web-prod --restart unless-stopped -p 18081:8080 -e PUBLIC_API_BASE=https://api.hai.internal my-app-web:offline
|
|
142
|
-
```
|
|
87
|
+
已有 PostgreSQL、Redis、RustFS 镜像还不够,准备以下内容:
|
|
143
88
|
|
|
144
|
-
|
|
89
|
+
1. Windows 上受支持的 Node/pnpm、完整项目、锁文件和已安装 CLI/SDK 依赖;验证断网后命令可启动。本机无容器引擎时,从构建机复制完整 `.hai/build/docker/<buildId>`。
|
|
90
|
+
2. 在构建机预先执行 `pnpm build --target docker`,确认镜像架构与服务器一致。离线部署只消费这些 tar,不需要 Node 基础镜像、pnpm store、CUDA、编译器或 SQLite 下载。无 AI 运行依赖的 fullstack 不安装 AI/CUDA。
|
|
91
|
+
3. 若连构建也要离线,则构建机另需 Linux 容器引擎、所有基础镜像、pnpm/Corepack、完整 Linux 依赖缓存、SQLite 对应驱动版本/Node ABI/架构/libc 的预编译包。Windows node_modules 不能替代 Linux 原生依赖。镜像构建可用 `--sqlite-prebuild-mirror http://<可信地址>/better-sqlite3`;下载失败应修复缓存/网络,不在 deploy 安装编译环境。
|
|
92
|
+
4. Linux 上安装对应架构 Docker/Podman、可执行的 Compose 命令、`sh`、`tar`、`sha256sum`;运行用户有容器/目录/卷权限。中间件镜像**名称和标签**须与生成 README 一致,先用 `docker load` 导入;SDK 不自动捆绑中间件镜像。自定义连接则要准备已运行的服务、账号、数据库/桶、容器可达地址。
|
|
93
|
+
5. `.env.prod`、私有管理员密码/连接密钥、部署公开端口、持久化磁盘和必要证书。切勿把容器内 localhost 当服务器宿主机。
|
|
94
|
+
6. 无任何两机网络时,用 `--bundle-only`,手工复制包;有内网但无互联网时也可 SSH 自动部署。云 Provider/Provisioner 不适用于完全离线,应选 Compose 或自定义已有服务。
|
|
145
95
|
|
|
146
|
-
|
|
96
|
+
离线验收须实际断开外网后打包/搬运/启动、登录、页面刷新、重启和数据持久化;联网通过不等于断网通过。
|
|
147
97
|
|
|
148
|
-
##
|
|
98
|
+
## Node API
|
|
149
99
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
import type { DeployConfigInput } from '@h-ai/deploy'
|
|
100
|
+
```ts
|
|
154
101
|
import { deploy } from '@h-ai/deploy'
|
|
155
102
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
103
|
+
const initialized = await deploy.init({
|
|
104
|
+
provider: { type: 'docker-ssh', expose: { hostPort: 18080 } },
|
|
105
|
+
})
|
|
106
|
+
if (!initialized.success)
|
|
107
|
+
throw new Error(initialized.error.message)
|
|
108
|
+
try {
|
|
109
|
+
const result = await deploy.deployApp('./packages/my-app-serv', {
|
|
110
|
+
environment: 'prod',
|
|
111
|
+
envDir: '.',
|
|
112
|
+
bundleOnly: true,
|
|
113
|
+
artifactDir: './.hai/build/docker/<buildId>',
|
|
114
|
+
skipMiddleware: true,
|
|
115
|
+
})
|
|
116
|
+
if (!result.success)
|
|
117
|
+
throw new Error(result.error.message)
|
|
118
|
+
// result.data.bundlePath / instructions;packaged 不代表服务器 ready。
|
|
119
|
+
}
|
|
120
|
+
finally {
|
|
121
|
+
await deploy.close()
|
|
176
122
|
}
|
|
177
123
|
```
|
|
178
124
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
云资源返回 `HAI_DB`、`HAI_CACHE`、`HAI_STORAGE` 或 `HAI_REACH_PROVIDERS` 整体配置;应用须加载对应 YAML 并初始化模块。失败时 `getDeployRecovery(result.error)` 返回阶段及资源 ID;`unknown` 表示结果不确定,应先在平台核对,同名重试复用资源,不自动删除。完整类型、配置及错误码见 [公开入口](src/index.ts)。
|
|
182
|
-
|
|
183
|
-
## 测试与二次开发
|
|
125
|
+
`deploy.scan` 与 `deploy.credentials` 不依赖 init;业务 API 返回 HaiResult,先检查 success。资源开通失败保留恢复信息,不自动删除已创建资源。
|
|
184
126
|
|
|
185
|
-
|
|
127
|
+
## 二次开发与验证
|
|
186
128
|
|
|
187
129
|
```powershell
|
|
188
130
|
pnpm.cmd --filter @h-ai/deploy typecheck
|
|
189
131
|
pnpm.cmd --filter @h-ai/deploy lint
|
|
190
132
|
pnpm.cmd --filter @h-ai/deploy build
|
|
191
133
|
pnpm.cmd --filter @h-ai/deploy test
|
|
192
|
-
pnpm.cmd
|
|
134
|
+
pnpm.cmd --filter @h-ai/cli test
|
|
135
|
+
pnpm.cmd --filter @h-ai/cli test:scaffold-gates
|
|
136
|
+
pnpm.cmd --filter @h-ai/cli test:deploy-gates
|
|
193
137
|
```
|
|
194
138
|
|
|
195
|
-
|
|
139
|
+
最后一项使用当前源码打包生成 fullstack,显式构建一次 API/Web,再验证 SSH 上传和手工 tar 启动、真实 Web 登录/刷新。需要运行的 Podman/Docker 和 OpenSSH。测试用 finally/teardown 清理临时工程、镜像、容器、报告、截图和辅助进程,失败同样清理;验收材料不提交 Git。原生安装包需在相应系统另做真实构建及安装验收。
|
|
196
140
|
|
|
197
|
-
|
|
141
|
+
部署门禁默认不传递本机代理。需要代理下载构建依赖时,设置测试专用 `HAI_DEPLOY_E2E_CONTAINER_PROXY`(默认不设置),例如 Windows Podman 在 PowerShell 中设置 `$env:HAI_DEPLOY_E2E_CONTAINER_PROXY='http://host.containers.internal:10808'`;地址必须能从构建容器访问,不写入应用配置或交付镜像。
|
|
198
142
|
|
|
199
|
-
|
|
143
|
+
测试专用 `HAI_DEPLOY_E2E_CONTAINER_NETWORK` 默认不设置,指定后传给 build 的 `--network`;例如 rootless Podman 可设置 `$env:HAI_DEPLOY_E2E_CONTAINER_NETWORK='pasta'`。构建与运行的网络可能不同,应同时校对代理在构建网络中的地址。
|
|
200
144
|
|
|
201
|
-
|
|
145
|
+
Windows runner 可设置测试开关 HAI_CLI_NATIVE_BUILD=1(默认不设置),再执行 `pnpm --filter @h-ai/cli test:scaffold-gates -t "fullstack scaffold"`,额外构建生成项目的 Tauri 安装包,检查根版本 2.4.6 进入 exe 文件名。需已安装 Rust/MSVC/Windows SDK;测试的原生输出也随临时工程自动清理。
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,35 @@ import { z } from 'zod';
|
|
|
2
2
|
import * as _h_ai_core from '@h-ai/core';
|
|
3
3
|
import { HaiResult, HaiError } from '@h-ai/core';
|
|
4
4
|
|
|
5
|
+
/** 镜像制品清单,例如 `{ version: 2, appVersion: '1.2.3', buildId: '1.2.3-build1', images: [{ name: 'app', file: 'app-1.2.3.tar', imageRef: 'localhost/demo:1.2.3-build1', sha256: '...' }] }`。 */
|
|
6
|
+
declare const DeploymentArtifactSchema: z.ZodObject<{
|
|
7
|
+
version: z.ZodLiteral<2>;
|
|
8
|
+
appVersion: z.ZodString;
|
|
9
|
+
buildId: z.ZodString;
|
|
10
|
+
images: z.ZodArray<z.ZodObject<{
|
|
11
|
+
name: z.ZodEnum<{
|
|
12
|
+
app: "app";
|
|
13
|
+
web: "web";
|
|
14
|
+
}>;
|
|
15
|
+
file: z.ZodString;
|
|
16
|
+
imageRef: z.ZodString;
|
|
17
|
+
sha256: z.ZodString;
|
|
18
|
+
containerPort: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
}, z.core.$strip>>;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
/** 构建器与部署器共享的镜像交付结构;参见 DeploymentArtifactSchema 示例。 */
|
|
22
|
+
type DeploymentArtifact = z.infer<typeof DeploymentArtifactSchema>;
|
|
23
|
+
/**
|
|
24
|
+
* 流式计算制品校验和,避免将大镜像一次性读入内存。
|
|
25
|
+
* @example `const checksum = await artifactChecksum("/release/app-1.2.3.tar")`
|
|
26
|
+
*/
|
|
27
|
+
declare function artifactChecksum(file: string): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* 校验完整构建产物;缺失、损坏或非法清单均抛错,由部署边界转换为 HaiResult。
|
|
30
|
+
* @example `const artifact = await readDeploymentArtifact("/release/build-1")`
|
|
31
|
+
*/
|
|
32
|
+
declare function readDeploymentArtifact(directory: string): Promise<DeploymentArtifact>;
|
|
33
|
+
|
|
5
34
|
/**
|
|
6
35
|
* @h-ai/deploy — 部署配置 Schema
|
|
7
36
|
*
|
|
@@ -28,7 +57,7 @@ declare const PortExposeSchema: z.ZodObject<{
|
|
|
28
57
|
/** docker-ssh 部署平台配置 */
|
|
29
58
|
declare const DockerSshProviderConfigSchema: z.ZodObject<{
|
|
30
59
|
type: z.ZodLiteral<"docker-ssh">;
|
|
31
|
-
ssh: z.ZodObject<{
|
|
60
|
+
ssh: z.ZodOptional<z.ZodObject<{
|
|
32
61
|
host: z.ZodString;
|
|
33
62
|
port: z.ZodDefault<z.ZodNumber>;
|
|
34
63
|
username: z.ZodString;
|
|
@@ -36,7 +65,7 @@ declare const DockerSshProviderConfigSchema: z.ZodObject<{
|
|
|
36
65
|
knownHostsFile: z.ZodOptional<z.ZodString>;
|
|
37
66
|
strictHostKeyChecking: z.ZodDefault<z.ZodBoolean>;
|
|
38
67
|
connectTimeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
39
|
-
}, z.core.$strip
|
|
68
|
+
}, z.core.$strip>>;
|
|
40
69
|
remote: z.ZodDefault<z.ZodObject<{
|
|
41
70
|
baseDir: z.ZodDefault<z.ZodString>;
|
|
42
71
|
runtime: z.ZodDefault<z.ZodEnum<{
|
|
@@ -57,7 +86,7 @@ declare const ProviderConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
57
86
|
token: z.ZodString;
|
|
58
87
|
}, z.core.$strip>, z.ZodObject<{
|
|
59
88
|
type: z.ZodLiteral<"docker-ssh">;
|
|
60
|
-
ssh: z.ZodObject<{
|
|
89
|
+
ssh: z.ZodOptional<z.ZodObject<{
|
|
61
90
|
host: z.ZodString;
|
|
62
91
|
port: z.ZodDefault<z.ZodNumber>;
|
|
63
92
|
username: z.ZodString;
|
|
@@ -65,7 +94,7 @@ declare const ProviderConfigSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
65
94
|
knownHostsFile: z.ZodOptional<z.ZodString>;
|
|
66
95
|
strictHostKeyChecking: z.ZodDefault<z.ZodBoolean>;
|
|
67
96
|
connectTimeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
68
|
-
}, z.core.$strip
|
|
97
|
+
}, z.core.$strip>>;
|
|
69
98
|
remote: z.ZodDefault<z.ZodObject<{
|
|
70
99
|
baseDir: z.ZodDefault<z.ZodString>;
|
|
71
100
|
runtime: z.ZodDefault<z.ZodEnum<{
|
|
@@ -94,7 +123,7 @@ declare const DeployConfigSchema: z.ZodObject<{
|
|
|
94
123
|
token: z.ZodString;
|
|
95
124
|
}, z.core.$strip>, z.ZodObject<{
|
|
96
125
|
type: z.ZodLiteral<"docker-ssh">;
|
|
97
|
-
ssh: z.ZodObject<{
|
|
126
|
+
ssh: z.ZodOptional<z.ZodObject<{
|
|
98
127
|
host: z.ZodString;
|
|
99
128
|
port: z.ZodDefault<z.ZodNumber>;
|
|
100
129
|
username: z.ZodString;
|
|
@@ -102,7 +131,7 @@ declare const DeployConfigSchema: z.ZodObject<{
|
|
|
102
131
|
knownHostsFile: z.ZodOptional<z.ZodString>;
|
|
103
132
|
strictHostKeyChecking: z.ZodDefault<z.ZodBoolean>;
|
|
104
133
|
connectTimeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
105
|
-
}, z.core.$strip
|
|
134
|
+
}, z.core.$strip>>;
|
|
106
135
|
remote: z.ZodDefault<z.ZodObject<{
|
|
107
136
|
baseDir: z.ZodDefault<z.ZodString>;
|
|
108
137
|
runtime: z.ZodDefault<z.ZodEnum<{
|
|
@@ -147,17 +176,10 @@ declare const DeployConfigSchema: z.ZodObject<{
|
|
|
147
176
|
}, z.core.$strip>], "provisioner">>;
|
|
148
177
|
}, z.core.$strip>>;
|
|
149
178
|
container: z.ZodOptional<z.ZodObject<{
|
|
150
|
-
runtime: z.ZodDefault<z.ZodEnum<{
|
|
151
|
-
auto: "auto";
|
|
152
|
-
docker: "docker";
|
|
153
|
-
podman: "podman";
|
|
154
|
-
}>>;
|
|
155
|
-
httpProxy: z.ZodDefault<z.ZodBoolean>;
|
|
156
179
|
s3Engine: z.ZodDefault<z.ZodEnum<{
|
|
157
180
|
rustfs: "rustfs";
|
|
158
181
|
minio: "minio";
|
|
159
182
|
}>>;
|
|
160
|
-
sqlitePrebuildMirror: z.ZodOptional<z.ZodURL>;
|
|
161
183
|
}, z.core.$strip>>;
|
|
162
184
|
}, z.core.$strip>;
|
|
163
185
|
/** 部署配置类型(parse 后) */
|
|
@@ -220,7 +242,6 @@ declare function saveDeploymentEnvironment(environment: DeploymentEnvironment, v
|
|
|
220
242
|
declare const HaiDeployError: {
|
|
221
243
|
readonly DEPLOY_FAILED: _h_ai_core.HaiErrorDef;
|
|
222
244
|
readonly PROJECT_CREATE_FAILED: _h_ai_core.HaiErrorDef;
|
|
223
|
-
readonly BUILD_FAILED: _h_ai_core.HaiErrorDef;
|
|
224
245
|
readonly UPLOAD_FAILED: _h_ai_core.HaiErrorDef;
|
|
225
246
|
readonly AUTH_REQUIRED: _h_ai_core.HaiErrorDef;
|
|
226
247
|
readonly AUTH_FAILED: _h_ai_core.HaiErrorDef;
|
|
@@ -232,8 +253,6 @@ declare const HaiDeployError: {
|
|
|
232
253
|
readonly UNSUPPORTED_TYPE: _h_ai_core.HaiErrorDef;
|
|
233
254
|
readonly CONFIG_ERROR: _h_ai_core.HaiErrorDef;
|
|
234
255
|
readonly CREDENTIAL_ERROR: _h_ai_core.HaiErrorDef;
|
|
235
|
-
readonly CONTAINER_RUNTIME_NOT_FOUND: _h_ai_core.HaiErrorDef;
|
|
236
|
-
readonly CONTAINER_BUILD_FAILED: _h_ai_core.HaiErrorDef;
|
|
237
256
|
readonly REMOTE_CONNECT_FAILED: _h_ai_core.HaiErrorDef;
|
|
238
257
|
readonly REMOTE_COMMAND_FAILED: _h_ai_core.HaiErrorDef;
|
|
239
258
|
readonly IMAGE_TRANSFER_FAILED: _h_ai_core.HaiErrorDef;
|
|
@@ -315,8 +334,6 @@ interface ScanResult {
|
|
|
315
334
|
requiredServices: ServiceType[];
|
|
316
335
|
/** 各服务检测到的后端类型(如 db→postgresql/mysql,vecdb→qdrant),用于生成匹配的 sidecar */
|
|
317
336
|
serviceBackends: Partial<Record<ServiceType, string>>;
|
|
318
|
-
/** 构建命令 */
|
|
319
|
-
buildCommand: string;
|
|
320
337
|
}
|
|
321
338
|
/**
|
|
322
339
|
* 部署结果
|
|
@@ -329,7 +346,11 @@ interface DeployResult {
|
|
|
329
346
|
/** 部署 ID */
|
|
330
347
|
deploymentId: string;
|
|
331
348
|
/** 部署状态 */
|
|
332
|
-
status: 'ready' | 'building' | 'error';
|
|
349
|
+
status: 'ready' | 'packaged' | 'building' | 'error';
|
|
350
|
+
/** Compose 部署 tar 的绝对路径;包含私有配置,应安全传输。 */
|
|
351
|
+
bundlePath?: string;
|
|
352
|
+
/** 手工搬运和启动说明;仅打包不代表服务器已运行。 */
|
|
353
|
+
instructions?: string;
|
|
333
354
|
/** 已设置的环境变量名列表 */
|
|
334
355
|
envVarsSet: string[];
|
|
335
356
|
/** 部署 Provider 名称(如 vercel / docker-ssh),容器部署时返回 */
|
|
@@ -376,10 +397,14 @@ interface DeployAppOptions {
|
|
|
376
397
|
serviceModes?: Partial<Record<string, MiddlewareMode>>;
|
|
377
398
|
/** 项目名称(默认使用明确指定的部署目录名称)。 */
|
|
378
399
|
projectName?: string;
|
|
379
|
-
/**
|
|
380
|
-
|
|
381
|
-
/**
|
|
382
|
-
|
|
400
|
+
/** 是否跳过全部中间件配置与开通,默认 false;例如配置完备时设为 true。 */
|
|
401
|
+
skipMiddleware?: boolean;
|
|
402
|
+
/** 已构建镜像目录;默认最近构建入口/锁文件目录下的 .hai/build/docker。 */
|
|
403
|
+
artifactDir?: string;
|
|
404
|
+
/** 只生成部署 tar,不连接 SSH;仅 docker-ssh 支持。 */
|
|
405
|
+
bundleOnly?: boolean;
|
|
406
|
+
/** 部署 tar 输出路径;默认 .hai/deploy/<环境>/bundle-<项目>-<部署ID>-<版本>.tar,自定义文件名自动补 -<版本>。 */
|
|
407
|
+
output?: string;
|
|
383
408
|
}
|
|
384
409
|
/**
|
|
385
410
|
* Deploy 凭证文件操作。
|
|
@@ -446,7 +471,7 @@ interface DeployFunctions {
|
|
|
446
471
|
*/
|
|
447
472
|
provisionAll: (projectName: string, services?: ServiceType[]) => Promise<HaiResult<ProvisionResult[]>>;
|
|
448
473
|
/**
|
|
449
|
-
*
|
|
474
|
+
* 部署已有构建产物(环境和中间件 → 打包 → 上传/启动);不会调用构建命令。
|
|
450
475
|
*
|
|
451
476
|
* @param appDir - 应用根目录路径
|
|
452
477
|
* @param options - 部署选项
|
|
@@ -493,7 +518,7 @@ declare const deploy: DeployFunctions;
|
|
|
493
518
|
* const text = deployM('deploy_notInitialized')
|
|
494
519
|
* ```
|
|
495
520
|
*/
|
|
496
|
-
declare const deployM: (key: "deploy_notInitialized" | "deploy_initFailed" | "deploy_unsupportedProviderType" | "deploy_unsupportedProvisionerType" | "deploy_configTokenRequired" | "deploy_authRequired" | "deploy_authFailed" | "deploy_projectCreateFailed" | "
|
|
521
|
+
declare const deployM: (key: "deploy_notInitialized" | "deploy_initFailed" | "deploy_unsupportedProviderType" | "deploy_unsupportedProvisionerType" | "deploy_configTokenRequired" | "deploy_authRequired" | "deploy_authFailed" | "deploy_projectCreateFailed" | "deploy_uploadFailed" | "deploy_deployFailed" | "deploy_provisionFailed" | "deploy_adapterMissing" | "deploy_scanFailed" | "deploy_envVarFailed" | "deploy_credentialError" | "deploy_credentialInvalidKey" | "deploy_credentialSaved" | "deploy_credentialLoaded" | "deploy_configError" | "deploy_credentialMissing" | "deploy_apiError" | "deploy_fileUploadFailed" | "deploy_provisionNoResult" | "deploy_recoveryFailure" | "deploy_recoverySuggestion" | "deploy_commandTimeout" | "deploy_commandFailed" | "deploy_remoteConnectFailed" | "deploy_remoteRuntimeMissing" | "deploy_imageTransferFailed" | "deploy_healthCheckFailed" | "deploy_invalidEnvironment" | "deploy_environmentMissing" | "deploy_environmentReadFailed" | "deploy_environmentWriteFailed" | "deploy_multipleApplications" | "deploy_purposeSqlite" | "deploy_purposeDatabase" | "deploy_purposeMemory" | "deploy_purposeLocal" | "deploy_purposeCache" | "deploy_purposeStorage" | "deploy_purposeVector" | "deploy_purposeDisabled" | "deploy_purposeLdap" | "deploy_purposeConsole" | "deploy_purposeEmail" | "deploy_purposeSms" | "deploy_webProxyInvalid" | "deploy_artifactInvalid" | "deploy_sshRequired" | "deploy_bundleInstructions" | "deploy_bundleMetadata" | "deploy_bundleOnlyContainer", options?: _h_ai_core.MessageOptions) => string;
|
|
497
522
|
|
|
498
523
|
/**
|
|
499
524
|
* 部署中间件的后端与连接字段目录,供扫描、CLI 和容器规划共同使用。
|
|
@@ -546,4 +571,4 @@ declare function describeMiddlewareBackend(backend: MiddlewareBackend): string;
|
|
|
546
571
|
/** 读取错误中的恢复清单;仅返回明确允许展示的字段。 */
|
|
547
572
|
declare function getDeployRecovery(error: HaiError): DeployRecoveryInfo | undefined;
|
|
548
573
|
|
|
549
|
-
export { DEPLOY_MIDDLEWARE, type DeployAppOptions, type DeployConfig, type DeployConfigInput, DeployConfigSchema, type DeployCredentialOperations, type DeployError, type DeployFunctions, type DeployRecoveryInfo, type DeployResult, type DeployScanOptions, type DeploymentEnvironment, type DockerSshProviderConfig, HaiDeployError, type MiddlewareBackend, type MiddlewareField, type MiddlewareMode, type MiddlewareRequirement, type PortExposeConfig, ProviderConfigSchema, type ProvisionResult, type ScanResult, type ServiceType, type SshConfig, deploy, describeMiddlewareBackend, getDeployRecovery, loadDeploymentConfig, loadDeploymentEnvironment, saveDeploymentEnvironment };
|
|
574
|
+
export { DEPLOY_MIDDLEWARE, type DeployAppOptions, type DeployConfig, type DeployConfigInput, DeployConfigSchema, type DeployCredentialOperations, type DeployError, type DeployFunctions, type DeployRecoveryInfo, type DeployResult, type DeployScanOptions, type DeploymentArtifact, DeploymentArtifactSchema, type DeploymentEnvironment, type DockerSshProviderConfig, HaiDeployError, type MiddlewareBackend, type MiddlewareField, type MiddlewareMode, type MiddlewareRequirement, type PortExposeConfig, ProviderConfigSchema, type ProvisionResult, type ScanResult, type ServiceType, type SshConfig, artifactChecksum, deploy, describeMiddlewareBackend, getDeployRecovery, loadDeploymentConfig, loadDeploymentEnvironment, readDeploymentArtifact, saveDeploymentEnvironment };
|