Compare commits
1
Commits
8d4a5c4f94
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29019fc5d5 |
@@ -35,8 +35,7 @@ Bun 工具链(选型见 `docs/design/技术选型.md`)。**Windows 上 `bun`
|
|||||||
| `bun run build:web` | 前端类型检查 + 产物构建 |
|
| `bun run build:web` | 前端类型检查 + 产物构建 |
|
||||||
| `bun run build:server` | 编译后端单文件 → `bin/naku-server`(当前平台) |
|
| `bun run build:server` | 编译后端单文件 → `bin/naku-server`(当前平台) |
|
||||||
| `bun run build:engine` | 编译同步引擎单文件 → `bin/naku-engine`(当前平台) |
|
| `bun run build:engine` | 编译同步引擎单文件 → `bin/naku-engine`(当前平台) |
|
||||||
| `bun run naku` | 打包/构建 CLI(citty + clack):`naku pack` 交互打部署包 → `release/`;`naku build` 本地构建 → `bin/`;支持 `--yes` / `--target` / `--only` |
|
| `bun run pack` | 打包/构建 CLI(citty + clack):`pack release` 交互打部署包 → `release/`;`pack build` 本地构建 → `bin/`;支持 `--yes` / `--target` / `--only`;`pack release --yes` 非交互打部署包(目标默认 linux-x64) |
|
||||||
| `bun run pack:release` | 非交互打部署包(= `naku pack --yes`,目标默认 linux-x64) |
|
|
||||||
|
|
||||||
环境变量见 `.env.example`(复制为 `.env` 后填写)。
|
环境变量见 `.env.example`(复制为 `.env` 后填写)。
|
||||||
|
|
||||||
|
|||||||
@@ -88,13 +88,13 @@ bun run dev:web # 前端 Vite(5175)
|
|||||||
### 本地打包
|
### 本地打包
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bun run naku pack
|
bun run pack release
|
||||||
# 交互选:目标平台 · 打包内容 · 是否 tar.gz
|
# 交互选:目标平台 · 打包内容 · 是否 tar.gz
|
||||||
# 产出 release/:dist · naku-server · naku-engine · naku-migrate · drizzle/
|
# 产出 release/:dist · naku-server · naku-engine · naku-migrate · drizzle/
|
||||||
|
|
||||||
# 非交互(CI / 一键):
|
# 非交互(CI / 一键):
|
||||||
bun run pack:release
|
bun run pack release --yes
|
||||||
# 或 bun run naku pack --yes --target=bun-linux-arm64 --only=dist,naku-server
|
# 或 bun run pack release --yes --target=bun-linux-arm64 --only=dist,naku-server
|
||||||
```
|
```
|
||||||
|
|
||||||
### 服务器
|
### 服务器
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@
|
|||||||
├─ packages/
|
├─ packages/
|
||||||
│ ├─ core/ # 业务核心:轮询与 request_id 去重 · 折算链 · 加密体系 · API 语义与 DTO 类型
|
│ ├─ core/ # 业务核心:轮询与 request_id 去重 · 折算链 · 加密体系 · API 语义与 DTO 类型
|
||||||
│ └─ db/ # 数据访问层:Drizzle schema(pg 方言)+ 仓储 + 迁移 CLI
|
│ └─ db/ # 数据访问层:Drizzle schema(pg 方言)+ 仓储 + 迁移 CLI
|
||||||
├─ scripts/ # 打包/构建 CLI(naku pack / build)
|
├─ scripts/ # 打包/构建 CLI(pack release / build)
|
||||||
```
|
```
|
||||||
|
|
||||||
**依赖规则(单向)**:`apps/*` → `packages/db` → `packages/core`;core 导出的 DTO 类型可被 web 以纯类型依赖引用(前后端共用一份契约类型)。
|
**依赖规则(单向)**:`apps/*` → `packages/db` → `packages/core`;core 导出的 DTO 类型可被 web 以纯类型依赖引用(前后端共用一份契约类型)。
|
||||||
|
|||||||
+12
-12
@@ -28,7 +28,7 @@
|
|||||||
```text
|
```text
|
||||||
本地(打包) 服务器(运营方)
|
本地(打包) 服务器(运营方)
|
||||||
────────── ────────────────
|
────────── ────────────────
|
||||||
bun run pack:release /opt/naku/ ← 约定目录
|
bun run pack release --yes /opt/naku/ ← 约定目录
|
||||||
├─ 前端 dist/ ├─ docker-compose.yml
|
├─ 前端 dist/ ├─ docker-compose.yml
|
||||||
├─ naku-server(linux 单文件) ├─ Dockerfile
|
├─ naku-server(linux 单文件) ├─ Dockerfile
|
||||||
├─ naku-engine(linux 单文件) ├─ .dockerignore
|
├─ naku-engine(linux 单文件) ├─ .dockerignore
|
||||||
@@ -53,7 +53,7 @@ bun run pack:release /opt/naku/ ← 约定目录
|
|||||||
|
|
||||||
## 3. 产物包 `release/`
|
## 3. 产物包 `release/`
|
||||||
|
|
||||||
本地 `bun run pack:release` 产出,内容固定为:
|
本地 `bun run pack release --yes` 产出,内容固定为:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
release/
|
release/
|
||||||
@@ -68,13 +68,13 @@ release/
|
|||||||
|
|
||||||
| 项 | 约定 |
|
| 项 | 约定 |
|
||||||
|----|------|
|
|----|------|
|
||||||
| 命令入口 | 优先 `bun run naku pack`(交互:平台 / 内容 / tar.gz);一键等价 `bun run pack:release` 或 `naku pack --yes` |
|
| 命令入口 | 优先 `bun run pack release`(交互:平台 / 内容 / tar.gz);一键等价 `bun run pack release --yes` |
|
||||||
| 脚本落点 | `scripts/cli.ts`(citty + clack)· `scripts/pack-core.ts`(纯打包逻辑)· `scripts/pack-release.ts`(非交互兼容入口) |
|
| 脚本落点 | `scripts/cli.ts`(citty + clack)· `scripts/pack-core.ts`(纯打包逻辑) |
|
||||||
| 目标平台 | 默认 `bun-linux-x64`;`--target=` 可切 `bun-linux-arm64` / `bun-darwin-*` / `bun-windows-*`(含 arm64) |
|
| 目标平台 | 默认 `bun-linux-x64`;`--target=` 可切 `bun-linux-arm64` / `bun-darwin-*` / `bun-windows-*`(含 arm64) |
|
||||||
| 构建顺序 | 清空输出目录 → `build:web` → 三次 `--compile` → 拷 `drizzle/` →(可选)tar.gz |
|
| 构建顺序 | 清空输出目录 → `build:web` → 三次 `--compile` → 拷 `drizzle/` →(可选)tar.gz |
|
||||||
| 禁止入包 | `.env` · 源码 · `node_modules` · 任何密钥 |
|
| 禁止入包 | `.env` · 源码 · `node_modules` · 任何密钥 |
|
||||||
| 校验 | 打包后检查五条目都在且非空(Windows 本机编译允许 `.exe` 后缀);缺一即失败退出 |
|
| 校验 | 打包后检查五条目都在且非空(Windows 本机编译允许 `.exe` 后缀);缺一即失败退出 |
|
||||||
| 本地试跑 | `naku build` / `build:server` / `build:engine` → `bin/`(当前平台),与部署包 `release/` 分离 |
|
| 本地试跑 | `pack build` / `build:server` / `build:engine` → `bin/`(当前平台),与部署包 `release/` 分离 |
|
||||||
|
|
||||||
### 3.2 为何是单文件而不是「服务器上构建」或「上传源码」
|
### 3.2 为何是单文件而不是「服务器上构建」或「上传源码」
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ loadEnv → createDb(DATABASE_URL) → runMigrations(db, MIGRATIONS_FOLDER) →
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 本地
|
# 本地
|
||||||
bun run pack:release
|
bun run pack release --yes
|
||||||
|
|
||||||
# 服务器
|
# 服务器
|
||||||
# 将 docker-compose.yml · Dockerfile · .dockerignore · Caddyfile · entrypoint-*.sh 放入 /opt/naku/
|
# 将 docker-compose.yml · Dockerfile · .dockerignore · Caddyfile · entrypoint-*.sh 放入 /opt/naku/
|
||||||
@@ -228,7 +228,7 @@ docker compose ps
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 本地
|
# 本地
|
||||||
bun run pack:release
|
bun run pack release --yes
|
||||||
# 上传,整目录覆盖 /opt/naku/release/
|
# 上传,整目录覆盖 /opt/naku/release/
|
||||||
|
|
||||||
# 服务器(固定命令)
|
# 服务器(固定命令)
|
||||||
@@ -299,13 +299,13 @@ docker compose ps
|
|||||||
|
|
||||||
| 文件 | 动作 |
|
| 文件 | 动作 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| `scripts/cli.ts` · `scripts/pack-core.ts` · `scripts/pack-release.ts` | 打包/构建 CLI 与核心逻辑 |
|
| `scripts/cli.ts` · `scripts/pack-core.ts` | 打包/构建 CLI 与核心逻辑 |
|
||||||
| `packages/db/src/migrate-cli.ts` | 迁移 CLI 入口 |
|
| `packages/db/src/migrate-cli.ts` | 迁移 CLI 入口 |
|
||||||
| `package.json` | `naku` · `pack:release` · `build:server` · `build:engine` |
|
| `package.json` | `pack` · `build:server` · `build:engine` |
|
||||||
| `Dockerfile` · `docker-compose.yml` · `.dockerignore` | 两阶段镜像 · 五服务(含 `container_name`) |
|
| `Dockerfile` · `docker-compose.yml` · `.dockerignore` | 两阶段镜像 · 五服务(含 `container_name`) |
|
||||||
| `Caddyfile` · `entrypoint-pg.sh` · `entrypoint-app.sh` | 与 compose 同级平铺 |
|
| `Caddyfile` · `entrypoint-pg.sh` · `entrypoint-app.sh` | 与 compose 同级平铺 |
|
||||||
| `README.md` | 「部署」章与文档地图 |
|
| `README.md` | 「部署」章与文档地图 |
|
||||||
| `AGENTS.md` | 命令表(pack / build / naku) |
|
| `AGENTS.md` | 命令表(pack / build) |
|
||||||
| `.env.example` | 部署语义注释 |
|
| `.env.example` | 部署语义注释 |
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -315,13 +315,13 @@ docker compose ps
|
|||||||
1. **`migrate` 独立单文件**:多一个产物,换来「先迁后跑、失败不启」的清晰门闩。若嫌多,可改为 server 启动时迁(仍幂等),但失去 migrate 失败阻断 engine 的不对称控制。
|
1. **`migrate` 独立单文件**:多一个产物,换来「先迁后跑、失败不启」的清晰门闩。若嫌多,可改为 server 启动时迁(仍幂等),但失去 migrate 失败阻断 engine 的不对称控制。
|
||||||
2. **目标平台写死 linux-x64**:匹配常见服务器;ARM 用打包参数切换,不为此引入交叉编译矩阵。
|
2. **目标平台写死 linux-x64**:匹配常见服务器;ARM 用打包参数切换,不为此引入交叉编译矩阵。
|
||||||
3. **`DATABASE_URL` 单源 + 两个 entrypoint**:少一处密码不一致;多两个常驻小 shell。若偏好 compose 原生 `POSTGRES_*`,需接受密码在 `.env` 写两处(或 `DATABASE_URL` 仅应用用)。
|
3. **`DATABASE_URL` 单源 + 两个 entrypoint**:少一处密码不一致;多两个常驻小 shell。若偏好 compose 原生 `POSTGRES_*`,需接受密码在 `.env` 写两处(或 `DATABASE_URL` 仅应用用)。
|
||||||
4. **产物包而非源码包**:服务器零构建;代价是发版必须在本地(或 CI)跑 `pack:release`。
|
4. **产物包而非源码包**:服务器零构建;代价是发版必须在本地(或 CI)跑 `pack release --yes`。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 12. 验收清单(实现后)
|
## 12. 验收清单(实现后)
|
||||||
|
|
||||||
- [ ] `bun run naku pack --yes`(或 `pack:release`)在 Windows 产出完整 `release/`(五条目齐全)
|
- [ ] `bun run pack release --yes` 在 Windows 产出完整 `release/`(五条目齐全)
|
||||||
- [ ] 首次安装按 §6.1 一次命令链可起,`docker compose ps` 形态符合 §6.4
|
- [ ] 首次安装按 §6.1 一次命令链可起,`docker compose ps` 形态符合 §6.4
|
||||||
- [ ] 仅替换 `release/` 后重跑固定命令,版本切换成功且数据保留(卷不重建)
|
- [ ] 仅替换 `release/` 后重跑固定命令,版本切换成功且数据保留(卷不重建)
|
||||||
- [ ] 连续两次固定命令:第二次 `migrate` 不重复应用已存在迁移(日志可证)
|
- [ ] 连续两次固定命令:第二次 `migrate` 不重复应用已存在迁移(日志可证)
|
||||||
|
|||||||
+1
-2
@@ -18,8 +18,7 @@
|
|||||||
"build:web": "bun run --cwd apps/web build",
|
"build:web": "bun run --cwd apps/web build",
|
||||||
"build:server": "bun build --compile --outfile=bin/naku-server apps/server/src/index.ts",
|
"build:server": "bun build --compile --outfile=bin/naku-server apps/server/src/index.ts",
|
||||||
"build:engine": "bun build --compile --outfile=bin/naku-engine apps/engine/src/index.ts",
|
"build:engine": "bun build --compile --outfile=bin/naku-engine apps/engine/src/index.ts",
|
||||||
"pack:release": "bun run scripts/pack-release.ts",
|
"pack": "bun run scripts/cli.ts"
|
||||||
"naku": "bun run scripts/cli.ts"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@clack/prompts": "^1.8.1",
|
"@clack/prompts": "^1.8.1",
|
||||||
|
|||||||
+8
-8
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* naku 打包/构建 CLI:citty 定义命令,@clack/prompts 负责交互。
|
* pack 打包/构建 CLI:citty 定义命令,@clack/prompts 负责交互。
|
||||||
* 有 TTY 且未给全 flag 时进交互;--yes / 无 TTY 则纯 flag。
|
* 有 TTY 且未给全 flag 时进交互;--yes / 无 TTY 则纯 flag。
|
||||||
*/
|
*/
|
||||||
import { defineCommand, runMain } from "citty";
|
import { defineCommand, runMain } from "citty";
|
||||||
@@ -34,9 +34,9 @@ const targetOption = {
|
|||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
const pack = defineCommand({
|
const release = defineCommand({
|
||||||
meta: {
|
meta: {
|
||||||
name: "pack",
|
name: "release",
|
||||||
description: "打部署产物包(dist + 单文件 + drizzle)",
|
description: "打部署产物包(dist + 单文件 + drizzle)",
|
||||||
},
|
},
|
||||||
args: {
|
args: {
|
||||||
@@ -62,7 +62,7 @@ const pack = defineCommand({
|
|||||||
},
|
},
|
||||||
async run({ args }) {
|
async run({ args }) {
|
||||||
const interactive = isInteractive(args.yes as boolean | undefined);
|
const interactive = isInteractive(args.yes as boolean | undefined);
|
||||||
p.intro("NAKU 打包");
|
p.intro("PACK 打包");
|
||||||
|
|
||||||
// --- target ---
|
// --- target ---
|
||||||
let target = args.target as string | undefined;
|
let target = args.target as string | undefined;
|
||||||
@@ -205,7 +205,7 @@ const build = defineCommand({
|
|||||||
}
|
}
|
||||||
only = [positional as PackItem];
|
only = [positional as PackItem];
|
||||||
} else if (interactive) {
|
} else if (interactive) {
|
||||||
p.intro("NAKU 本地构建");
|
p.intro("PACK 本地构建");
|
||||||
only = assertNotCancel(
|
only = assertNotCancel(
|
||||||
await p.multiselect({
|
await p.multiselect({
|
||||||
message: "构建什么",
|
message: "构建什么",
|
||||||
@@ -245,11 +245,11 @@ const build = defineCommand({
|
|||||||
|
|
||||||
const main = defineCommand({
|
const main = defineCommand({
|
||||||
meta: {
|
meta: {
|
||||||
name: "naku",
|
name: "pack",
|
||||||
version: "0.0.0",
|
version: "0.0.0",
|
||||||
description: "NAKU 打包 / 本地构建",
|
description: "PACK 打包 / 本地构建",
|
||||||
},
|
},
|
||||||
subCommands: { pack, build },
|
subCommands: { release, build },
|
||||||
});
|
});
|
||||||
|
|
||||||
runMain(main);
|
runMain(main);
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
/**
|
|
||||||
* 兼容入口:等价于 `naku pack --yes --target=bun-linux-x64`。
|
|
||||||
* 交互请用 `bun run naku pack`。
|
|
||||||
*/
|
|
||||||
import { packRelease } from "./pack-core.ts";
|
|
||||||
|
|
||||||
function readTarget(): string {
|
|
||||||
const arg = process.argv.find((a) => a.startsWith("--target="));
|
|
||||||
return arg?.slice("--target=".length) || process.env.PACK_TARGET || "bun-linux-x64";
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = readTarget();
|
|
||||||
console.log(`[pack-release] non-interactive pack (target=${target})`);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const out = await packRelease({
|
|
||||||
target,
|
|
||||||
only: ["dist", "naku-server", "naku-engine", "naku-migrate", "drizzle"],
|
|
||||||
outDir: "release",
|
|
||||||
tarball: false,
|
|
||||||
onLog: (m) => console.log("[pack-release]", m),
|
|
||||||
});
|
|
||||||
console.log("[pack-release] done →", out);
|
|
||||||
} catch (err) {
|
|
||||||
console.error("[pack-release]", err instanceof Error ? err.message : err);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user