@lark-apaas/miaoda-cli 0.1.18 → 0.1.19-alpha.4bf5458
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/dist/api/deploy/index.js +3 -1
- package/dist/api/deploy/modern-types.js +4 -1
- package/dist/api/deploy/modern.js +8 -0
- package/dist/cli/commands/app/index.js +5 -3
- package/dist/cli/commands/deploy/modern.js +30 -0
- package/dist/cli/commands/index.js +10 -0
- package/dist/cli/handlers/app/init.js +5 -4
- package/dist/cli/handlers/app/migrate.js +4 -5
- package/dist/cli/handlers/deploy/index.js +3 -1
- package/dist/cli/handlers/deploy/patch.js +16 -0
- package/dist/services/app/init/async-install.js +3 -7
- package/dist/services/app/init/index.js +1 -2
- package/dist/services/app/init/template.js +1 -0
- package/dist/services/deploy/modern/atoms/design-build.js +41 -0
- package/dist/services/deploy/modern/atoms/design-upload.js +74 -0
- package/dist/services/deploy/modern/atoms/index.js +5 -1
- package/dist/services/deploy/modern/atoms/tosutil.js +246 -0
- package/dist/services/deploy/modern/atoms/upload.js +4 -127
- package/dist/services/deploy/modern/check.js +28 -16
- package/dist/services/deploy/modern/patch/actions.js +60 -0
- package/dist/services/deploy/modern/patch/content.js +18 -0
- package/dist/services/deploy/modern/patch/index.js +41 -0
- package/dist/services/deploy/modern/patch/routes.js +28 -0
- package/dist/services/deploy/modern/patch/source-scan.js +56 -0
- package/dist/services/deploy/modern/pipelines/design-local.js +47 -0
- package/dist/services/deploy/modern/pipelines/index.js +3 -1
- package/dist/services/deploy/modern/protocol.js +7 -0
- package/dist/services/deploy/modern/run.js +10 -4
- package/dist/services/deploy/modern/template-key-map.js +4 -0
- package/dist/utils/coding-steering.js +6 -5
- package/dist/utils/env.js +19 -0
- package/dist/utils/index.js +3 -1
- package/package.json +1 -1
package/dist/api/deploy/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NodeStatus = exports.nodeStatusFromText = exports.nodeStatusText = exports.errorJobSchema = exports.deployGetSchema = exports.deployHistorySchema = exports.batchSavePluginInstances = exports.LocalReleaseStatus = exports.getModernLastPublishedVersion = exports.getModernReleaseStatus = exports.createModernRelease = exports.callbackStatic = exports.updateLocalRelease = exports.createLocalRelease = exports.preRelease = exports.queryPipelineInstance = exports.getErrorLog = exports.listPipelineInstances = exports.createRelease = void 0;
|
|
3
|
+
exports.NodeStatus = exports.nodeStatusFromText = exports.nodeStatusText = exports.errorJobSchema = exports.deployGetSchema = exports.deployHistorySchema = exports.batchSavePluginInstances = exports.TosActionType = exports.LocalReleaseStatus = exports.applyTosDiff = exports.getModernLastPublishedVersion = exports.getModernReleaseStatus = exports.createModernRelease = exports.callbackStatic = exports.updateLocalRelease = exports.createLocalRelease = exports.preRelease = exports.queryPipelineInstance = exports.getErrorLog = exports.listPipelineInstances = exports.createRelease = void 0;
|
|
4
4
|
var api_1 = require("./api");
|
|
5
5
|
Object.defineProperty(exports, "createRelease", { enumerable: true, get: function () { return api_1.createRelease; } });
|
|
6
6
|
Object.defineProperty(exports, "listPipelineInstances", { enumerable: true, get: function () { return api_1.listPipelineInstances; } });
|
|
@@ -14,8 +14,10 @@ Object.defineProperty(exports, "callbackStatic", { enumerable: true, get: functi
|
|
|
14
14
|
Object.defineProperty(exports, "createModernRelease", { enumerable: true, get: function () { return modern_1.createRelease; } });
|
|
15
15
|
Object.defineProperty(exports, "getModernReleaseStatus", { enumerable: true, get: function () { return modern_1.getReleaseStatus; } });
|
|
16
16
|
Object.defineProperty(exports, "getModernLastPublishedVersion", { enumerable: true, get: function () { return modern_1.getLastPublishedVersion; } });
|
|
17
|
+
Object.defineProperty(exports, "applyTosDiff", { enumerable: true, get: function () { return modern_1.applyTosDiff; } });
|
|
17
18
|
var modern_types_1 = require("./modern-types");
|
|
18
19
|
Object.defineProperty(exports, "LocalReleaseStatus", { enumerable: true, get: function () { return modern_types_1.LocalReleaseStatus; } });
|
|
20
|
+
Object.defineProperty(exports, "TosActionType", { enumerable: true, get: function () { return modern_types_1.TosActionType; } });
|
|
19
21
|
var plugin_instances_1 = require("./plugin-instances");
|
|
20
22
|
Object.defineProperty(exports, "batchSavePluginInstances", { enumerable: true, get: function () { return plugin_instances_1.batchSavePluginInstances; } });
|
|
21
23
|
var schemas_1 = require("./schemas");
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
//
|
|
9
9
|
// 远端部署链路(B/C)所需的 release 接口先预留类型骨架,待 B/C 落地时启用。
|
|
10
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.LocalReleaseStatus = void 0;
|
|
11
|
+
exports.TosActionType = exports.LocalReleaseStatus = void 0;
|
|
12
12
|
/**
|
|
13
13
|
* localPublish 状态枚举(数值,与服务端 IDL 对齐)。
|
|
14
14
|
* CLI updateLocalRelease 只翻 Finished / Failed 两个终态;其它由后端流转。
|
|
@@ -21,3 +21,6 @@ exports.LocalReleaseStatus = {
|
|
|
21
21
|
Canceled: 4,
|
|
22
22
|
Rollback: 5,
|
|
23
23
|
};
|
|
24
|
+
// ── applyTosDiff(design-html 增量发布;后端应用 TOS diff) ──
|
|
25
|
+
/** 对齐 IDL publish.TosActionType(UNSPECIFIED=0 不用) */
|
|
26
|
+
exports.TosActionType = { CREATE: 1, UPDATE: 2, DELETE: 3 };
|
|
@@ -17,6 +17,7 @@ exports.callbackStatic = callbackStatic;
|
|
|
17
17
|
exports.createRelease = createRelease;
|
|
18
18
|
exports.getReleaseStatus = getReleaseStatus;
|
|
19
19
|
exports.getLastPublishedVersion = getLastPublishedVersion;
|
|
20
|
+
exports.applyTosDiff = applyTosDiff;
|
|
20
21
|
const http_1 = require("../../utils/http");
|
|
21
22
|
const devops_error_1 = require("../../utils/devops-error");
|
|
22
23
|
const DEFAULT_ERR_CODE = 'INTERNAL_DEVOPS_ERROR';
|
|
@@ -76,3 +77,10 @@ async function getLastPublishedVersion(req) {
|
|
|
76
77
|
const url = `/v1/devops/app/${encodeURIComponent(appID)}/last_published_version`;
|
|
77
78
|
return (0, http_1.postInnerApi)(url, {}, envelopeOpts('Failed to get last published version'));
|
|
78
79
|
}
|
|
80
|
+
// ── applyTosDiff ──
|
|
81
|
+
/** POST /v1/devops/app/:appID/apply_tos_diff —— 增量应用 TOS 文件 diff */
|
|
82
|
+
async function applyTosDiff(req) {
|
|
83
|
+
const { appID, ...body } = req;
|
|
84
|
+
const url = `/v1/devops/app/${encodeURIComponent(appID)}/apply_tos_diff`;
|
|
85
|
+
return (0, http_1.postInnerApi)(url, body, envelopeOpts('Failed to apply tos diff'));
|
|
86
|
+
}
|
|
@@ -164,7 +164,7 @@ function registerAppInit(parent) {
|
|
|
164
164
|
.command('init')
|
|
165
165
|
.description('初始化应用代码:抓 template 渲染、同步 upgrade/templates、装 .agent/steering/ skills、写 .spark/meta.json。.spark/meta.json 已存在则直接退出')
|
|
166
166
|
.option('--template <stack>', `技术栈短名(${index_1.SUPPORTED_STACKS.join(' / ')})`)
|
|
167
|
-
.option('--conf
|
|
167
|
+
.option('--conf [json]', 'init 配置 JSON。支持 {"version": "<template 版本>"},默认 latest')
|
|
168
168
|
.option('--skip-install', '跳过依赖安装', false)
|
|
169
169
|
.option('--async-install', '派发后台进程装依赖并立即返回(与 --skip-install 互斥)', false)
|
|
170
170
|
.addOption((0, shared_1.appIdOption)())
|
|
@@ -198,7 +198,7 @@ function registerAppInit(parent) {
|
|
|
198
198
|
异步安装(--async-install)
|
|
199
199
|
跳过同步 npm install,派发一个 detached 后台进程装依赖后立即返回。
|
|
200
200
|
.spark/meta.json 在返回前写出(= 脚手架就绪),install 真实结果由 event marker 表达。
|
|
201
|
-
仅沙箱(
|
|
201
|
+
仅沙箱(MIAODA_DEP_CACHE_DIR 非空)写 marker(presence 定成败,content 给排障):
|
|
202
202
|
成功 → /tmp/event/WORKSPACE_READY
|
|
203
203
|
失败 → /tmp/event/WORKSPACE_FAILED
|
|
204
204
|
安装日志:/tmp/async_install_dep.std.log
|
|
@@ -234,7 +234,9 @@ JSON 输出
|
|
|
234
234
|
}));
|
|
235
235
|
}
|
|
236
236
|
function parseInitConf(raw) {
|
|
237
|
-
|
|
237
|
+
// --conf 为可选值:未传(undefined)、裸 --conf(Commander 给 true)、空/纯空白字符串
|
|
238
|
+
// 一律视为不配置,回退默认(latest)。
|
|
239
|
+
if (raw === undefined || typeof raw === 'boolean' || raw.trim() === '')
|
|
238
240
|
return undefined;
|
|
239
241
|
let parsed;
|
|
240
242
|
try {
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.registerDeployCommandsModern = registerDeployCommandsModern;
|
|
4
4
|
const shared_1 = require("../../../cli/commands/shared");
|
|
5
5
|
const modern_1 = require("../../../cli/handlers/deploy/modern");
|
|
6
|
+
const index_1 = require("../../../cli/handlers/deploy/index");
|
|
6
7
|
/**
|
|
7
8
|
* modern scene (MIAODA_APP_TYPE=7) 专用 deploy 注册。
|
|
8
9
|
* 仅披露顶层 `miaoda deploy`,CLI 表面对齐 openclaw-cli:`--dir / --skip-build`。
|
|
@@ -56,4 +57,33 @@ JSON 输出(stdout)
|
|
|
56
57
|
conf: rawOpts.conf,
|
|
57
58
|
});
|
|
58
59
|
}));
|
|
60
|
+
const patchCmd = deployCmd
|
|
61
|
+
.command('patch')
|
|
62
|
+
.description('design-html 增量发布:按文件 create/update/delete,.html 变化时同步 routes.json')
|
|
63
|
+
.option('--create <relpath>', '新增文件(可重复)', shared_1.collectRepeatedOption, [])
|
|
64
|
+
.option('--update <relpath>', '覆盖已有文件(可重复)', shared_1.collectRepeatedOption, [])
|
|
65
|
+
.option('--delete <relpath>', '删除文件(可重复)', shared_1.collectRepeatedOption, [])
|
|
66
|
+
.addHelpText('after', `
|
|
67
|
+
--dir 为项目目录(与 deploy 同名参数,默认当前目录)。
|
|
68
|
+
仅支持 design-html(design_local_deploy)。路径为工程根相对路径(= 服务端 latest 下 key),
|
|
69
|
+
禁绝对路径与 ".."。--create/--update 的本地文件必须存在。改动集含 .html 时自动重算并随包
|
|
70
|
+
更新 routes.json。
|
|
71
|
+
|
|
72
|
+
JSON 输出
|
|
73
|
+
{"data": {"upsertCount": <n>, "deleteCount": <n>, "actionsSent": <n>, "routesRegenerated": <bool>}}
|
|
74
|
+
|
|
75
|
+
示例
|
|
76
|
+
$ miaoda deploy patch --update index.html
|
|
77
|
+
$ miaoda deploy patch --create blog/post.html --delete blog/old.html
|
|
78
|
+
$ miaoda deploy patch --update assets/app.js --update assets/app.css
|
|
79
|
+
`);
|
|
80
|
+
patchCmd.action((0, shared_1.withHelp)(patchCmd, async (rawOpts) => {
|
|
81
|
+
await (0, index_1.handleDeployPatch)({
|
|
82
|
+
appId: (0, shared_1.resolveAppId)({}),
|
|
83
|
+
dir: deployCmd.opts().dir ?? '.',
|
|
84
|
+
creates: rawOpts.create,
|
|
85
|
+
updates: rawOpts.update,
|
|
86
|
+
deletes: rawOpts.delete,
|
|
87
|
+
});
|
|
88
|
+
}));
|
|
59
89
|
}
|
|
@@ -14,6 +14,7 @@ const index_6 = require("../../cli/commands/skills/index");
|
|
|
14
14
|
// 3 = AppType_APPLICATION(全栈应用,当前仅 nestjs-react-fullstack 一个 stack)
|
|
15
15
|
// 4 = AppType_DESIGN(design-stack,SSR 渲染、无业务逻辑、无数据库)
|
|
16
16
|
// 7 = miaoda-cli 自定义 modern 占位(后端枚举无 7,沙箱目前不传)
|
|
17
|
+
// 8 = AppType_DESIGN_HTML(design-html,buildless 静态 HTML,命令集同 modern)
|
|
17
18
|
// 其它(0/1/2/5/6 / 未设)→ default(命令全开,本地 dev / CI / 兼容回退)
|
|
18
19
|
// stack 维度(nestjs-react-fullstack / vite-react / ...)是正交的,
|
|
19
20
|
// skills sync 内部按 .spark/meta.json.stack 拉对应 coding-steering/steering/<stack>/ 子目录。
|
|
@@ -24,6 +25,8 @@ function resolveScene(appType, _archType) {
|
|
|
24
25
|
return 'application';
|
|
25
26
|
if (appType === '4')
|
|
26
27
|
return 'design';
|
|
28
|
+
if (appType === '8')
|
|
29
|
+
return 'design-html';
|
|
27
30
|
return 'default';
|
|
28
31
|
}
|
|
29
32
|
const SCENE_REGISTRARS = {
|
|
@@ -62,6 +65,13 @@ const SCENE_REGISTRARS = {
|
|
|
62
65
|
(0, index_3.registerObservabilityCommands)(p);
|
|
63
66
|
(0, index_6.registerSkillsCommands)(p);
|
|
64
67
|
},
|
|
68
|
+
// design-html scene(AppType_DESIGN_HTML=8):buildless 静态 HTML,
|
|
69
|
+
// 命令集与 modern 一致(app init/sync + modern 拆分版 deploy + skills),不挂 db/file/observability。
|
|
70
|
+
'design-html': (p) => {
|
|
71
|
+
(0, index_4.registerAppCommands)(p, { includeInit: true });
|
|
72
|
+
(0, modern_1.registerDeployCommandsModern)(p);
|
|
73
|
+
(0, index_6.registerSkillsCommands)(p);
|
|
74
|
+
},
|
|
65
75
|
};
|
|
66
76
|
function readEnv(name) {
|
|
67
77
|
const v = process.env[name]?.trim();
|
|
@@ -11,6 +11,7 @@ const coding_steering_1 = require("../../../utils/coding-steering");
|
|
|
11
11
|
const logger_1 = require("../../../utils/logger");
|
|
12
12
|
const githooks_1 = require("../../../utils/githooks");
|
|
13
13
|
const logs_dir_1 = require("../../../utils/logs-dir");
|
|
14
|
+
const env_1 = require("../../../utils/env");
|
|
14
15
|
const error_1 = require("../../../utils/error");
|
|
15
16
|
const output_1 = require("../../../utils/output");
|
|
16
17
|
/**
|
|
@@ -72,12 +73,12 @@ async function handleAppInit(opts) {
|
|
|
72
73
|
(0, logs_dir_1.ensureLogsDir)(targetDir);
|
|
73
74
|
// skills 同步软失败:拉不到 coding-steering 包不该阻断 writeSparkMeta /
|
|
74
75
|
// activateGitHooks(之前会让 .spark/meta.json 没写,下次 init 半渲染状态又得重跑全套)。
|
|
75
|
-
// 按运行环境(
|
|
76
|
-
// -
|
|
76
|
+
// 按运行环境(isSandboxEnv:MIAODA_DEP_CACHE_DIR 非空)分流 outputLayout,不绑 stack:
|
|
77
|
+
// - 沙箱内 → nested (.agent/skills/steering/<stack>/skills/),
|
|
77
78
|
// 跟沙箱端 update-skills.sh 链路对齐
|
|
78
|
-
// -
|
|
79
|
+
// - 本地 → flat (.agents/skills + .claude/skills 软链),
|
|
79
80
|
// Agent / Claude Code 用同一份;nrf 在本地是主战场,vite-react 等也一样适用
|
|
80
|
-
const outputLayout =
|
|
81
|
+
const outputLayout = (0, env_1.isSandboxEnv)() ? 'nested' : 'flat';
|
|
81
82
|
let steeringResult;
|
|
82
83
|
let steeringError;
|
|
83
84
|
try {
|
|
@@ -14,6 +14,7 @@ const migrate_rule_1 = require("../../../utils/migrate-rule");
|
|
|
14
14
|
const spark_meta_1 = require("../../../utils/spark-meta");
|
|
15
15
|
const error_1 = require("../../../utils/error");
|
|
16
16
|
const output_1 = require("../../../utils/output");
|
|
17
|
+
const env_1 = require("../../../utils/env");
|
|
17
18
|
const logger_1 = require("../../../utils/logger");
|
|
18
19
|
/**
|
|
19
20
|
* miaoda app migrate --to <stack> [--from <stack>] [--dir <path>]
|
|
@@ -138,14 +139,12 @@ async function handleAppMigrate(opts) {
|
|
|
138
139
|
// 跑的 node 进程仍按老逻辑工作(只起 vite,没起 nest),整体没切到 fullstack 模式。
|
|
139
140
|
// 通过 pkill 杀掉 dev.js 主进程,依赖沙箱平台 supervisor 自动重新 exec dev.sh → dev.js,
|
|
140
141
|
// 新进程用新 deps + 新 scripts,正常进入 fullstack 模式。
|
|
141
|
-
// -
|
|
142
|
+
// - 只在沙箱内做(isSandboxEnv;本地环境用户进程混杂,主动 pkill 风险大)
|
|
142
143
|
// - install 挂了不做 —— 新依赖不全, 杀旧 dev 后新 dev 起不来反而更糟,
|
|
143
144
|
// 留着旧进程让用户先处理 installError
|
|
144
145
|
// - 软失败:pkill 无匹配进程退出 1,catch 吞掉
|
|
145
146
|
let devRestarted = false;
|
|
146
|
-
if (installError === undefined &&
|
|
147
|
-
process.env.SANDBOX_ID !== undefined &&
|
|
148
|
-
process.env.SANDBOX_ID !== '') {
|
|
147
|
+
if (installError === undefined && (0, env_1.isSandboxEnv)()) {
|
|
149
148
|
(0, logger_1.log)('migrate', '沙箱环境,重启 dev process(平台 supervisor 会自动拉起)...');
|
|
150
149
|
try {
|
|
151
150
|
(0, node_child_process_1.execFileSync)('pkill', ['-f', 'node.*scripts/dev\\.js'], { stdio: 'ignore' });
|
|
@@ -170,7 +169,7 @@ async function handleAppMigrate(opts) {
|
|
|
170
169
|
followLatestPackages: followLatest,
|
|
171
170
|
installError,
|
|
172
171
|
devRestarted,
|
|
173
|
-
nextActions:
|
|
172
|
+
nextActions: (0, env_1.isSandboxEnv)()
|
|
174
173
|
? [
|
|
175
174
|
'git status / git diff 评估改动并 commit',
|
|
176
175
|
'miaoda skills sync 同步到新 stack 的 agent skills',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_POLL_INTERVAL_MS = exports.waitForPipeline = exports.handleDeployErrorLog = exports.handleDeployHistory = exports.handleDeployGet = exports.handleDeploy = void 0;
|
|
3
|
+
exports.handleDeployPatch = exports.DEFAULT_POLL_INTERVAL_MS = exports.waitForPipeline = exports.handleDeployErrorLog = exports.handleDeployHistory = exports.handleDeployGet = exports.handleDeploy = void 0;
|
|
4
4
|
var deploy_1 = require("./deploy");
|
|
5
5
|
Object.defineProperty(exports, "handleDeploy", { enumerable: true, get: function () { return deploy_1.handleDeploy; } });
|
|
6
6
|
var get_1 = require("./get");
|
|
@@ -12,3 +12,5 @@ Object.defineProperty(exports, "handleDeployErrorLog", { enumerable: true, get:
|
|
|
12
12
|
var polling_1 = require("./polling");
|
|
13
13
|
Object.defineProperty(exports, "waitForPipeline", { enumerable: true, get: function () { return polling_1.waitForPipeline; } });
|
|
14
14
|
Object.defineProperty(exports, "DEFAULT_POLL_INTERVAL_MS", { enumerable: true, get: function () { return polling_1.DEFAULT_POLL_INTERVAL_MS; } });
|
|
15
|
+
var patch_1 = require("./patch");
|
|
16
|
+
Object.defineProperty(exports, "handleDeployPatch", { enumerable: true, get: function () { return patch_1.handleDeployPatch; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handleDeployPatch = handleDeployPatch;
|
|
4
|
+
const index_1 = require("../../../services/deploy/modern/patch/index");
|
|
5
|
+
const output_1 = require("../../../utils/output");
|
|
6
|
+
/** miaoda deploy patch —— design-html 文件级增量发布 */
|
|
7
|
+
async function handleDeployPatch(opts) {
|
|
8
|
+
const result = await (0, index_1.patchDesignDeploy)({
|
|
9
|
+
appId: opts.appId,
|
|
10
|
+
projectDir: opts.dir ?? process.cwd(),
|
|
11
|
+
creates: opts.creates,
|
|
12
|
+
updates: opts.updates,
|
|
13
|
+
deletes: opts.deletes,
|
|
14
|
+
});
|
|
15
|
+
(0, output_1.emit)({ data: result });
|
|
16
|
+
}
|
|
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ASYNC_INSTALL_LOG = void 0;
|
|
7
|
-
exports.isSandboxEnv = isSandboxEnv;
|
|
8
7
|
exports.runAsyncInstallWorker = runAsyncInstallWorker;
|
|
9
8
|
exports.dispatchAsyncInstall = dispatchAsyncInstall;
|
|
10
9
|
const node_child_process_1 = require("node:child_process");
|
|
11
10
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
12
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const env_1 = require("../../../utils/env");
|
|
13
13
|
const install_1 = require("./install");
|
|
14
14
|
/** event marker 目录,写死;写前 mkdir -p。沙箱里 code server 轮询此目录。 */
|
|
15
15
|
const EVENT_DIR = '/tmp/event';
|
|
@@ -19,10 +19,6 @@ const MARKER_READY = 'WORKSPACE_READY';
|
|
|
19
19
|
const MARKER_FAILED = 'WORKSPACE_FAILED';
|
|
20
20
|
/** 后台 worker stdout/stderr 落盘路径 */
|
|
21
21
|
exports.ASYNC_INSTALL_LOG = '/tmp/async_install_dep.std.log';
|
|
22
|
-
/** 沙箱判定:SANDBOX_ID 非空。与 init handler 的 outputLayout 分流口径一致。 */
|
|
23
|
-
function isSandboxEnv() {
|
|
24
|
-
return process.env.SANDBOX_ID !== undefined && process.env.SANDBOX_ID !== '';
|
|
25
|
-
}
|
|
26
22
|
function nowIso() {
|
|
27
23
|
return new Date().toISOString();
|
|
28
24
|
}
|
|
@@ -44,7 +40,7 @@ function writeMarker(eventDir, name, content) {
|
|
|
44
40
|
*/
|
|
45
41
|
function runAsyncInstallWorker(opts) {
|
|
46
42
|
const eventDir = opts.eventDir ?? EVENT_DIR;
|
|
47
|
-
const sandbox = isSandboxEnv();
|
|
43
|
+
const sandbox = (0, env_1.isSandboxEnv)();
|
|
48
44
|
if (sandbox)
|
|
49
45
|
clearStaleMarkers(eventDir);
|
|
50
46
|
const start = Date.now();
|
|
@@ -89,7 +85,7 @@ function runAsyncInstallWorker(opts) {
|
|
|
89
85
|
function dispatchAsyncInstall(opts) {
|
|
90
86
|
const eventDir = opts.eventDir ?? EVENT_DIR;
|
|
91
87
|
const logPath = opts.logPath ?? exports.ASYNC_INSTALL_LOG;
|
|
92
|
-
const sandbox = isSandboxEnv();
|
|
88
|
+
const sandbox = (0, env_1.isSandboxEnv)();
|
|
93
89
|
if (sandbox)
|
|
94
90
|
clearStaleMarkers(eventDir);
|
|
95
91
|
// targetDir 走 argv 传,不拼进代码串(免转义);只把本模块路径 JSON 内联进去。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ASYNC_INSTALL_LOG = exports.
|
|
3
|
+
exports.ASYNC_INSTALL_LOG = exports.runAsyncInstallWorker = exports.dispatchAsyncInstall = exports.resolveNpmInstallRegistry = exports.installDependencies = exports.writeSparkMeta = exports.readSparkMeta = exports.TEMPLATE_PACKAGE_BY_STACK = exports.SUPPORTED_STACKS = exports.renderTemplate = void 0;
|
|
4
4
|
var template_1 = require("./template");
|
|
5
5
|
Object.defineProperty(exports, "renderTemplate", { enumerable: true, get: function () { return template_1.renderTemplate; } });
|
|
6
6
|
Object.defineProperty(exports, "SUPPORTED_STACKS", { enumerable: true, get: function () { return template_1.SUPPORTED_STACKS; } });
|
|
@@ -14,5 +14,4 @@ Object.defineProperty(exports, "resolveNpmInstallRegistry", { enumerable: true,
|
|
|
14
14
|
var async_install_1 = require("./async-install");
|
|
15
15
|
Object.defineProperty(exports, "dispatchAsyncInstall", { enumerable: true, get: function () { return async_install_1.dispatchAsyncInstall; } });
|
|
16
16
|
Object.defineProperty(exports, "runAsyncInstallWorker", { enumerable: true, get: function () { return async_install_1.runAsyncInstallWorker; } });
|
|
17
|
-
Object.defineProperty(exports, "isSandboxEnv", { enumerable: true, get: function () { return async_install_1.isSandboxEnv; } });
|
|
18
17
|
Object.defineProperty(exports, "ASYNC_INSTALL_LOG", { enumerable: true, get: function () { return async_install_1.ASYNC_INSTALL_LOG; } });
|
|
@@ -15,6 +15,7 @@ exports.TEMPLATE_PACKAGE_BY_STACK = {
|
|
|
15
15
|
'vite-react': '@lark-apaas/coding-template-vite-react',
|
|
16
16
|
html: '@lark-apaas/coding-template-html',
|
|
17
17
|
'nestjs-react-fullstack': '@lark-apaas/coding-template-nestjs-react-fullstack',
|
|
18
|
+
'design-html': '@lark-apaas/coding-template-design-html',
|
|
18
19
|
};
|
|
19
20
|
/**
|
|
20
21
|
* 短名 → template 包钉版表。renderTemplate 默认按这张表取版本号,表外 stack 跟 npm latest。
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.buildDesignOutput = buildDesignOutput;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const error_1 = require("../../../../utils/error");
|
|
10
|
+
const logger_1 = require("../../../../utils/logger");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
12
|
+
const source_scan_1 = require("../patch/source-scan");
|
|
13
|
+
const routes_1 = require("../patch/routes");
|
|
14
|
+
/**
|
|
15
|
+
* design-html buildless 闭环 build(替代模板 scripts/build.sh):
|
|
16
|
+
* 1. rm -rf <projectDir>/dist
|
|
17
|
+
* 2. 拷源码 → dist/output(套 EXCLUDES,与 routes 同一份 listSourceFiles)
|
|
18
|
+
* 3. 写 dist/output/routes.json = generateRoutes(projectDir)
|
|
19
|
+
* 不跑 npm run build、不依赖技术栈内 build.sh。
|
|
20
|
+
* fs / scan / routes 任何失败统一包成 AppError('DEPLOY_BUILD_FAILED'),与旧 runDesignBuild 对齐。
|
|
21
|
+
*/
|
|
22
|
+
function buildDesignOutput(opts) {
|
|
23
|
+
(0, logger_1.log)('deploy', 'Building (design, CLI)...');
|
|
24
|
+
try {
|
|
25
|
+
const distDir = node_path_1.default.join(opts.projectDir, constants_1.DIST_DIR);
|
|
26
|
+
const outputDir = node_path_1.default.join(distDir, constants_1.OUTPUT_DIR);
|
|
27
|
+
node_fs_1.default.rmSync(distDir, { recursive: true, force: true });
|
|
28
|
+
node_fs_1.default.mkdirSync(outputDir, { recursive: true });
|
|
29
|
+
for (const rel of (0, source_scan_1.listSourceFiles)(opts.projectDir)) {
|
|
30
|
+
const dest = node_path_1.default.join(outputDir, rel);
|
|
31
|
+
node_fs_1.default.mkdirSync(node_path_1.default.dirname(dest), { recursive: true });
|
|
32
|
+
node_fs_1.default.copyFileSync(node_path_1.default.join(opts.projectDir, rel), dest);
|
|
33
|
+
}
|
|
34
|
+
node_fs_1.default.writeFileSync(node_path_1.default.join(outputDir, 'routes.json'), (0, routes_1.generateRoutes)(opts.projectDir), 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err instanceof error_1.AppError)
|
|
38
|
+
throw err;
|
|
39
|
+
throw new error_1.AppError('DEPLOY_BUILD_FAILED', `design build failed: ${err.message}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.uploadDesignArtifacts = uploadDesignArtifacts;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const error_1 = require("../../../../utils/error");
|
|
10
|
+
const logger_1 = require("../../../../utils/logger");
|
|
11
|
+
const constants_1 = require("../constants");
|
|
12
|
+
const protocol_1 = require("../protocol");
|
|
13
|
+
const tosutil_1 = require("./tosutil");
|
|
14
|
+
/** 递归收集 dir 下相对路径(posix 分隔),与 -flat 上传后远端 key 对齐。 */
|
|
15
|
+
function listLocalRelKeys(dir) {
|
|
16
|
+
const out = new Set();
|
|
17
|
+
const walk = (cur, rel) => {
|
|
18
|
+
for (const entry of node_fs_1.default.readdirSync(cur, { withFileTypes: true })) {
|
|
19
|
+
const childRel = rel ? `${rel}/${entry.name}` : entry.name;
|
|
20
|
+
if (entry.isDirectory())
|
|
21
|
+
walk(node_path_1.default.join(cur, entry.name), childRel);
|
|
22
|
+
else
|
|
23
|
+
out.add(childRel);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
walk(dir, '');
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* design 部署上传(省带宽):
|
|
31
|
+
* 1. 本地 dist/output ──cp(local→tos)──▶ output_backup_path/ (唯一一次上传)
|
|
32
|
+
* 2. output_backup_path ──cp(tos→tos,同凭证同桶)──▶ output_latest_path (服务端复制)
|
|
33
|
+
* 3. ls latest → 跟本地 diff → rm latest 里源端已无的对象 (精确镜像)
|
|
34
|
+
* design-html 只产 dist/output,无 output_resource / output_static / capability。
|
|
35
|
+
*/
|
|
36
|
+
async function uploadDesignArtifacts(opts) {
|
|
37
|
+
await Promise.resolve();
|
|
38
|
+
const tosutilPath = (0, tosutil_1.resolveTosutilPath)();
|
|
39
|
+
const outputDir = node_path_1.default.join(opts.projectDir, constants_1.DIST_DIR, constants_1.OUTPUT_DIR);
|
|
40
|
+
if (!node_fs_1.default.existsSync(outputDir)) {
|
|
41
|
+
throw new error_1.AppError('DEPLOY_NO_BUILD_OUTPUT', `Required directory missing: ${constants_1.DIST_DIR}/${constants_1.OUTPUT_DIR}`);
|
|
42
|
+
}
|
|
43
|
+
// 空产物防呆:本地一个文件都没有时,绝不继续(否则 latest 会被整体 prune 清空)。
|
|
44
|
+
const localKeys = listLocalRelKeys(outputDir);
|
|
45
|
+
if (localKeys.size === 0) {
|
|
46
|
+
throw new error_1.AppError('DEPLOY_UPLOAD_EMPTY', `No files under ${constants_1.DIST_DIR}/${constants_1.OUTPUT_DIR} to upload — check build output.`);
|
|
47
|
+
}
|
|
48
|
+
const cred = (0, protocol_1.parseTosUploadCredential)((0, protocol_1.requireDataKey)(opts.data, protocol_1.DataKey.OUTPUT_ALL_TOS_UPLOAD_CREDENTIAL), protocol_1.DataKey.OUTPUT_ALL_TOS_UPLOAD_CREDENTIAL);
|
|
49
|
+
const backupPath = (0, protocol_1.requireDataKey)(opts.data, protocol_1.DataKey.OUTPUT_BACKUP_PATH);
|
|
50
|
+
const latestPath = (0, protocol_1.requireDataKey)(opts.data, protocol_1.DataKey.OUTPUT_LATEST_PATH);
|
|
51
|
+
const base = (0, tosutil_1.tosutilUploadFromTos)(cred); // 鉴权 + bucket
|
|
52
|
+
// 1. 本地 → backup(version):唯一一次本地上传。
|
|
53
|
+
// -ddo(noDirObjects):不上传文件夹占位对象,避免 latest 残留 `src/` 这类空目录。
|
|
54
|
+
(0, logger_1.log)('deploy', `Uploading ${constants_1.OUTPUT_DIR} → ${backupPath}...`);
|
|
55
|
+
(0, tosutil_1.uploadDirWithCredential)(tosutilPath, outputDir, { ...base, prefix: backupPath }, 'output_backup', true);
|
|
56
|
+
// 2. backup → latest:服务端 tos→tos cp(不占带宽)
|
|
57
|
+
(0, logger_1.log)('deploy', `Server-side copy ${backupPath} → ${latestPath}...`);
|
|
58
|
+
(0, tosutil_1.copyTosToTos)(tosutilPath, base, backupPath, latestPath);
|
|
59
|
+
// 3. latest 精确镜像:删源端已不存在的对象。
|
|
60
|
+
// 安全阀:远端有对象但跟本地零重合时,判定为 key 形态/ls 解析不匹配,跳过 prune——
|
|
61
|
+
// 宁可漏删(latest 残留旧文件)也绝不误删整目录(数据丢失)。design-html 的 build.sh
|
|
62
|
+
// 必产稳定名的 routes.json / *.html,正常重合不会为空,零重合即异常信号。
|
|
63
|
+
const remoteKeys = (0, tosutil_1.listRemoteKeys)(tosutilPath, { ...base, prefix: latestPath });
|
|
64
|
+
const overlap = remoteKeys.filter((k) => localKeys.has(k));
|
|
65
|
+
if (remoteKeys.length > 0 && overlap.length === 0) {
|
|
66
|
+
(0, logger_1.log)('deploy', `⚠ latest 远端 ${String(remoteKeys.length)} 个对象与本地零重合,疑似 key 形态不匹配,跳过 prune(避免误删)`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const staleKeys = remoteKeys.filter((k) => !localKeys.has(k));
|
|
70
|
+
if (staleKeys.length > 0) {
|
|
71
|
+
(0, logger_1.log)('deploy', `Pruning ${String(staleKeys.length)} stale object(s) from latest...`);
|
|
72
|
+
(0, tosutil_1.removeRemoteKeys)(tosutilPath, { ...base, prefix: latestPath }, staleKeys);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
3
|
+
exports.savePluginInstances = exports.LocalReleaseStatus = exports.finalizeLocalRelease = exports.createLocalRelease = exports.uploadArtifacts = exports.uploadDesignArtifacts = exports.buildDesignOutput = exports.runBuild = exports.preRelease = exports.prepareDeployContext = void 0;
|
|
4
4
|
var context_1 = require("./context");
|
|
5
5
|
Object.defineProperty(exports, "prepareDeployContext", { enumerable: true, get: function () { return context_1.prepareDeployContext; } });
|
|
6
6
|
var pre_release_1 = require("./pre-release");
|
|
7
7
|
Object.defineProperty(exports, "preRelease", { enumerable: true, get: function () { return pre_release_1.preRelease; } });
|
|
8
8
|
var build_1 = require("./build");
|
|
9
9
|
Object.defineProperty(exports, "runBuild", { enumerable: true, get: function () { return build_1.runBuild; } });
|
|
10
|
+
var design_build_1 = require("./design-build");
|
|
11
|
+
Object.defineProperty(exports, "buildDesignOutput", { enumerable: true, get: function () { return design_build_1.buildDesignOutput; } });
|
|
12
|
+
var design_upload_1 = require("./design-upload");
|
|
13
|
+
Object.defineProperty(exports, "uploadDesignArtifacts", { enumerable: true, get: function () { return design_upload_1.uploadDesignArtifacts; } });
|
|
10
14
|
var upload_1 = require("./upload");
|
|
11
15
|
Object.defineProperty(exports, "uploadArtifacts", { enumerable: true, get: function () { return upload_1.uploadArtifacts; } });
|
|
12
16
|
var local_release_1 = require("./local-release");
|