@coze-arch/cli 0.0.36-alpha.8cf839 → 0.0.36-alpha.a7a716
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/lib/__templates__/phaser/scripts/dev.sh +3 -5
- package/lib/__templates__/phaser/scripts/spawn-detached.cjs +29 -0
- package/lib/__templates__/phaser/scripts/start.sh +3 -5
- package/lib/cli.js +164 -152
- package/lib/deploy/package-project.js +6 -0
- package/lib/deploy/package-project.py +3 -0
- package/package.json +1 -1
|
@@ -61,12 +61,11 @@ PID_FILE="${LOG_DIR}/phaser-dev.pid"
|
|
|
61
61
|
mkdir -p "${LOG_DIR}"
|
|
62
62
|
|
|
63
63
|
echo "Starting Phaser dev server on port ${DEPLOY_RUN_PORT}..."
|
|
64
|
-
COZE_PHASER_GAME_ENV=DEV
|
|
64
|
+
server_pid="$(COZE_PHASER_GAME_ENV=DEV node scripts/spawn-detached.cjs \
|
|
65
|
+
"${LOG_FILE}" pnpm vite \
|
|
65
66
|
--port "${DEPLOY_RUN_PORT}" \
|
|
66
67
|
--host 127.0.0.1 \
|
|
67
|
-
--strictPort
|
|
68
|
-
> "${LOG_FILE}" 2>&1 < /dev/null &
|
|
69
|
-
server_pid=$!
|
|
68
|
+
--strictPort)"
|
|
70
69
|
echo "${server_pid}" > "${PID_FILE}"
|
|
71
70
|
|
|
72
71
|
sleep 1
|
|
@@ -77,7 +76,6 @@ if ! kill -0 "${server_pid}" 2>/dev/null; then
|
|
|
77
76
|
exit 1
|
|
78
77
|
fi
|
|
79
78
|
|
|
80
|
-
disown "${server_pid}" 2>/dev/null || true
|
|
81
79
|
echo "Phaser dev server started (PID: ${server_pid})."
|
|
82
80
|
echo "Log file: ${LOG_FILE}"
|
|
83
81
|
echo "PID file: ${PID_FILE}"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const fs = require('node:fs');
|
|
2
|
+
const { spawn } = require('node:child_process');
|
|
3
|
+
|
|
4
|
+
const [logFile, command, ...args] = process.argv.slice(2);
|
|
5
|
+
|
|
6
|
+
if (!logFile || !command) {
|
|
7
|
+
process.stderr.write(
|
|
8
|
+
'Usage: node scripts/spawn-detached.cjs <log-file> <command> [...args]\n',
|
|
9
|
+
);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const logFd = fs.openSync(logFile, 'a');
|
|
14
|
+
const child = spawn(command, args, {
|
|
15
|
+
cwd: process.cwd(),
|
|
16
|
+
detached: process.platform !== 'win32',
|
|
17
|
+
env: process.env,
|
|
18
|
+
stdio: ['ignore', logFd, logFd],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
fs.closeSync(logFd);
|
|
22
|
+
child.unref();
|
|
23
|
+
|
|
24
|
+
if (!child.pid) {
|
|
25
|
+
process.stderr.write('Failed to start detached process.\n');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
process.stdout.write(String(child.pid));
|
|
@@ -61,12 +61,11 @@ PID_FILE="${LOG_DIR}/phaser-start.pid"
|
|
|
61
61
|
mkdir -p "${LOG_DIR}"
|
|
62
62
|
|
|
63
63
|
echo "Starting Phaser production server on port ${DEPLOY_RUN_PORT}..."
|
|
64
|
-
COZE_PHASER_GAME_ENV=PROD
|
|
64
|
+
server_pid="$(COZE_PHASER_GAME_ENV=PROD node scripts/spawn-detached.cjs \
|
|
65
|
+
"${LOG_FILE}" pnpm vite preview \
|
|
65
66
|
--port "${DEPLOY_RUN_PORT}" \
|
|
66
67
|
--host 127.0.0.1 \
|
|
67
|
-
--strictPort
|
|
68
|
-
> "${LOG_FILE}" 2>&1 < /dev/null &
|
|
69
|
-
server_pid=$!
|
|
68
|
+
--strictPort)"
|
|
70
69
|
echo "${server_pid}" > "${PID_FILE}"
|
|
71
70
|
|
|
72
71
|
sleep 1
|
|
@@ -77,7 +76,6 @@ if ! kill -0 "${server_pid}" 2>/dev/null; then
|
|
|
77
76
|
exit 1
|
|
78
77
|
fi
|
|
79
78
|
|
|
80
|
-
disown "${server_pid}" 2>/dev/null || true
|
|
81
79
|
echo "Phaser production server started (PID: ${server_pid})."
|
|
82
80
|
echo "Log file: ${LOG_FILE}"
|
|
83
81
|
echo "PID file: ${PID_FILE}"
|
package/lib/cli.js
CHANGED
|
@@ -2113,7 +2113,7 @@ const EventBuilder = {
|
|
|
2113
2113
|
};
|
|
2114
2114
|
|
|
2115
2115
|
var name = "@coze-arch/cli";
|
|
2116
|
-
var version = "0.0.36-alpha.
|
|
2116
|
+
var version = "0.0.36-alpha.a7a716";
|
|
2117
2117
|
var description = "coze coding devtools cli";
|
|
2118
2118
|
var license = "MIT";
|
|
2119
2119
|
var author = "fanwenjie.fe@bytedance.com";
|
|
@@ -11516,6 +11516,7 @@ const resolveDeployHistoryId = (
|
|
|
11516
11516
|
function _optionalChain$6(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
11517
11517
|
|
|
11518
11518
|
const SOURCE_SNAPSHOT_BYTES = 20;
|
|
11519
|
+
const PROJECT_METADATA_FILE_MODE = 0o644;
|
|
11519
11520
|
|
|
11520
11521
|
const isId = (value) =>
|
|
11521
11522
|
typeof value === 'string' && /^\d+$/u.test(value);
|
|
@@ -11636,7 +11637,11 @@ const writeProjectBinding = async (
|
|
|
11636
11637
|
}
|
|
11637
11638
|
const tempPath = node_path.join(node_path.dirname(path), `.coze-${node_crypto.randomUUID()}.tmp`);
|
|
11638
11639
|
try {
|
|
11639
|
-
await promises.writeFile(tempPath, content, {
|
|
11640
|
+
await promises.writeFile(tempPath, content, {
|
|
11641
|
+
encoding: 'utf8',
|
|
11642
|
+
mode: PROJECT_METADATA_FILE_MODE,
|
|
11643
|
+
});
|
|
11644
|
+
await promises.chmod(tempPath, PROJECT_METADATA_FILE_MODE);
|
|
11640
11645
|
await promises.rename(tempPath, path);
|
|
11641
11646
|
} finally {
|
|
11642
11647
|
await promises.rm(tempPath, { force: true });
|
|
@@ -11660,8 +11665,9 @@ const ensureProjectMetadata = async (
|
|
|
11660
11665
|
await promises.writeFile(
|
|
11661
11666
|
node_path.join(sourceRoot, '.coze'),
|
|
11662
11667
|
`[project]\nname = ${JSON.stringify(name)}\nproject_type = ${JSON.stringify(projectType)}\n`,
|
|
11663
|
-
{ encoding: 'utf8', mode:
|
|
11668
|
+
{ encoding: 'utf8', mode: PROJECT_METADATA_FILE_MODE },
|
|
11664
11669
|
);
|
|
11670
|
+
await promises.chmod(node_path.join(sourceRoot, '.coze'), PROJECT_METADATA_FILE_MODE);
|
|
11665
11671
|
return readProjectMetadata(sourceRoot);
|
|
11666
11672
|
};
|
|
11667
11673
|
|
|
@@ -11743,7 +11749,157 @@ const readDeployLocalContext = async (
|
|
|
11743
11749
|
return { ...sourceSnapshot, metadata, isPagesDeployment };
|
|
11744
11750
|
};
|
|
11745
11751
|
|
|
11752
|
+
// 服务端 deploy_app/list 的 page_size 上限,超了会被判参数错误。
|
|
11753
|
+
// 客户端先拦一道,是为了把错误说在本地(带上上限值),而不是回一句服务端的通用参数错误。
|
|
11754
|
+
const APP_LIST_MAX_PAGE_SIZE = 100;
|
|
11755
|
+
|
|
11756
|
+
// page_token 是**页码的十进制字符串**(服务端口径,与 deploy_history/list 一致),不是不透明游标。
|
|
11757
|
+
// 所以这里能、也应该在本地校验:`--page-token abc` 早报错,比发出去再被拒强。
|
|
11758
|
+
const parsePositiveInt = (
|
|
11759
|
+
raw,
|
|
11760
|
+
option,
|
|
11761
|
+
code,
|
|
11762
|
+
max,
|
|
11763
|
+
) => {
|
|
11764
|
+
const value = Number(raw);
|
|
11765
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
11766
|
+
throw new CliError(`${option} must be a positive integer.`, code, { [option]: raw });
|
|
11767
|
+
}
|
|
11768
|
+
if (max !== undefined && value > max) {
|
|
11769
|
+
throw new CliError(`${option} must not exceed ${String(max)}.`, code, { [option]: raw });
|
|
11770
|
+
}
|
|
11771
|
+
return value;
|
|
11772
|
+
};
|
|
11773
|
+
|
|
11774
|
+
// ⛔ 别再用 `Number(options.pageSize || 20)`:`--page-size abc` 会算出 NaN,
|
|
11775
|
+
// JSON.stringify 把它写成 null 发给服务端,最后表现为「参数没生效」而不是「参数写错了」。
|
|
11776
|
+
const parsePageSize = (
|
|
11777
|
+
raw,
|
|
11778
|
+
fallback,
|
|
11779
|
+
max,
|
|
11780
|
+
) => {
|
|
11781
|
+
if (raw === undefined || raw === '') {
|
|
11782
|
+
return fallback;
|
|
11783
|
+
}
|
|
11784
|
+
return parsePositiveInt(raw, '--page-size', 'INVALID_PAGE_SIZE', max);
|
|
11785
|
+
};
|
|
11786
|
+
|
|
11787
|
+
const parsePageToken = (raw) => {
|
|
11788
|
+
if (raw === undefined || raw === '') {
|
|
11789
|
+
return undefined;
|
|
11790
|
+
}
|
|
11791
|
+
parsePositiveInt(raw, '--page-token', 'INVALID_PAGE_TOKEN');
|
|
11792
|
+
return raw;
|
|
11793
|
+
};
|
|
11794
|
+
|
|
11795
|
+
|
|
11796
|
+
|
|
11797
|
+
|
|
11798
|
+
|
|
11799
|
+
|
|
11800
|
+
|
|
11801
|
+
// collectAllPages 顺着 next_page_token 把所有页取回来。
|
|
11802
|
+
//
|
|
11803
|
+
// 服务端从「全量单页」改成真分页之后,`app list` 一次只回一页;想要「我的全部应用」就得翻页。
|
|
11804
|
+
// 与其让每个调用方各写一遍循环,不如给一个 --all。
|
|
11805
|
+
//
|
|
11806
|
+
// ⚠️ 不设页数上限截断:静默截断正是这次要修掉的毛病。只防死循环——服务端如果一直回同一个
|
|
11807
|
+
// token(或说 has_more 却不给 token),直接报错,而不是无限翻。
|
|
11808
|
+
const collectAllPages = async (
|
|
11809
|
+
fetchPage,
|
|
11810
|
+
) => {
|
|
11811
|
+
const items = [];
|
|
11812
|
+
const seen = new Set();
|
|
11813
|
+
let pageToken;
|
|
11814
|
+
let pages = 0;
|
|
11815
|
+
for (;;) {
|
|
11816
|
+
const page = await fetchPage(pageToken);
|
|
11817
|
+
items.push(...(page.items || []));
|
|
11818
|
+
pages += 1;
|
|
11819
|
+
if (!page.has_more) {
|
|
11820
|
+
return { items, pages };
|
|
11821
|
+
}
|
|
11822
|
+
const next = page.next_page_token;
|
|
11823
|
+
if (!next || seen.has(next)) {
|
|
11824
|
+
throw new CliError(
|
|
11825
|
+
'The server reported more pages but returned no usable next_page_token.',
|
|
11826
|
+
'INVALID_PAGE_TOKEN',
|
|
11827
|
+
{ next_page_token: next, pages },
|
|
11828
|
+
);
|
|
11829
|
+
}
|
|
11830
|
+
seen.add(next);
|
|
11831
|
+
pageToken = next;
|
|
11832
|
+
}
|
|
11833
|
+
};
|
|
11834
|
+
|
|
11835
|
+
async function _asyncOptionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = await fn(value); } else if (op === 'call' || op === 'optionalCall') { value = await fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
11836
|
+
|
|
11746
11837
|
const registerDeployReadCommands = (deploy) => {
|
|
11838
|
+
deploy
|
|
11839
|
+
.command('status')
|
|
11840
|
+
.option('--app-id <appId>', 'Application ID')
|
|
11841
|
+
.option('--deploy-id <deployId>', 'Deployment history ID')
|
|
11842
|
+
.action(async (options, command) => {
|
|
11843
|
+
const runtime = await getRuntime(command);
|
|
11844
|
+
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
11845
|
+
let deployHistoryId = options.deployId;
|
|
11846
|
+
if (!deployHistoryId) {
|
|
11847
|
+
deployHistoryId = await _asyncOptionalChain([(
|
|
11848
|
+
await runtime.client.listDeployHistory({ app_id: appId, page_size: 1 })
|
|
11849
|
+
), 'access', async _ => _.deploy_history_list, 'optionalAccess', async _2 => _2[0], 'optionalAccess', async _3 => _3.deploy_history_id]);
|
|
11850
|
+
}
|
|
11851
|
+
if (!deployHistoryId) {
|
|
11852
|
+
throw new CliError('No deployment history found.', 'DEPLOYMENT_NOT_FOUND');
|
|
11853
|
+
}
|
|
11854
|
+
const history = await runtime.client.getDeployHistory({
|
|
11855
|
+
app_id: appId,
|
|
11856
|
+
deploy_history_id: deployHistoryId,
|
|
11857
|
+
});
|
|
11858
|
+
runtime.output.print({
|
|
11859
|
+
app_id: appId,
|
|
11860
|
+
deploy_history_id: deployHistoryId,
|
|
11861
|
+
status: getDeployStatusText(history.status),
|
|
11862
|
+
commit_hash: history.commit_hash,
|
|
11863
|
+
domains: history.domain_list || [],
|
|
11864
|
+
error_analysis: history.error_analysis,
|
|
11865
|
+
deploy_detail: formatDeployDetails(history),
|
|
11866
|
+
connector_data_list: history.connector_data_list || [],
|
|
11867
|
+
mobile_artifact_list: history.mobile_artifact_list || [],
|
|
11868
|
+
});
|
|
11869
|
+
});
|
|
11870
|
+
|
|
11871
|
+
deploy
|
|
11872
|
+
.command('list')
|
|
11873
|
+
.option('--app-id <appId>', 'Application ID')
|
|
11874
|
+
.option('--page-size <pageSize>', 'Page size', '10')
|
|
11875
|
+
.option('--page-token <pageToken>', 'Page token (page number)')
|
|
11876
|
+
.action(async (options, command) => {
|
|
11877
|
+
// 先在本地校验:`--page-size abc` 以前算出 NaN 发出去,表现成「参数没生效」。
|
|
11878
|
+
const pageSize = parsePageSize(options.pageSize, 10);
|
|
11879
|
+
const pageToken = parsePageToken(options.pageToken);
|
|
11880
|
+
const runtime = await getRuntime(command);
|
|
11881
|
+
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
11882
|
+
const data = await runtime.client.listDeployHistory({
|
|
11883
|
+
app_id: appId,
|
|
11884
|
+
page_size: pageSize,
|
|
11885
|
+
page_token: pageToken,
|
|
11886
|
+
});
|
|
11887
|
+
runtime.output.print({
|
|
11888
|
+
items: (data.deploy_history_list || []).map(item => ({
|
|
11889
|
+
deploy_history_id: item.deploy_history_id,
|
|
11890
|
+
status: getDeployStatusText(item.status),
|
|
11891
|
+
commit_hash: item.commit_hash_short || item.commit_hash,
|
|
11892
|
+
created_at: item.created_at,
|
|
11893
|
+
can_rollback: item.can_rollback,
|
|
11894
|
+
deploy_detail: formatDeployDetails(item),
|
|
11895
|
+
connector_data_list: item.connector_data_list || [],
|
|
11896
|
+
mobile_artifact_list: item.mobile_artifact_list || [],
|
|
11897
|
+
})),
|
|
11898
|
+
next_page_token: data.next_page_token,
|
|
11899
|
+
has_more: data.has_more,
|
|
11900
|
+
});
|
|
11901
|
+
});
|
|
11902
|
+
|
|
11747
11903
|
deploy
|
|
11748
11904
|
.command('online')
|
|
11749
11905
|
.description('Show the current online deployment')
|
|
@@ -11761,6 +11917,7 @@ const registerDeployReadCommands = (deploy) => {
|
|
|
11761
11917
|
created_at: item.created_at,
|
|
11762
11918
|
deploy_detail: formatDeployDetails(item),
|
|
11763
11919
|
domains: item.domain_list || [],
|
|
11920
|
+
mobile_artifact_list: item.mobile_artifact_list || [],
|
|
11764
11921
|
})),
|
|
11765
11922
|
});
|
|
11766
11923
|
});
|
|
@@ -11957,89 +12114,6 @@ const registerMiniProgram = (code) => {
|
|
|
11957
12114
|
});
|
|
11958
12115
|
};
|
|
11959
12116
|
|
|
11960
|
-
// 服务端 deploy_app/list 的 page_size 上限,超了会被判参数错误。
|
|
11961
|
-
// 客户端先拦一道,是为了把错误说在本地(带上上限值),而不是回一句服务端的通用参数错误。
|
|
11962
|
-
const APP_LIST_MAX_PAGE_SIZE = 100;
|
|
11963
|
-
|
|
11964
|
-
// page_token 是**页码的十进制字符串**(服务端口径,与 deploy_history/list 一致),不是不透明游标。
|
|
11965
|
-
// 所以这里能、也应该在本地校验:`--page-token abc` 早报错,比发出去再被拒强。
|
|
11966
|
-
const parsePositiveInt = (
|
|
11967
|
-
raw,
|
|
11968
|
-
option,
|
|
11969
|
-
code,
|
|
11970
|
-
max,
|
|
11971
|
-
) => {
|
|
11972
|
-
const value = Number(raw);
|
|
11973
|
-
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
11974
|
-
throw new CliError(`${option} must be a positive integer.`, code, { [option]: raw });
|
|
11975
|
-
}
|
|
11976
|
-
if (max !== undefined && value > max) {
|
|
11977
|
-
throw new CliError(`${option} must not exceed ${String(max)}.`, code, { [option]: raw });
|
|
11978
|
-
}
|
|
11979
|
-
return value;
|
|
11980
|
-
};
|
|
11981
|
-
|
|
11982
|
-
// ⛔ 别再用 `Number(options.pageSize || 20)`:`--page-size abc` 会算出 NaN,
|
|
11983
|
-
// JSON.stringify 把它写成 null 发给服务端,最后表现为「参数没生效」而不是「参数写错了」。
|
|
11984
|
-
const parsePageSize = (
|
|
11985
|
-
raw,
|
|
11986
|
-
fallback,
|
|
11987
|
-
max,
|
|
11988
|
-
) => {
|
|
11989
|
-
if (raw === undefined || raw === '') {
|
|
11990
|
-
return fallback;
|
|
11991
|
-
}
|
|
11992
|
-
return parsePositiveInt(raw, '--page-size', 'INVALID_PAGE_SIZE', max);
|
|
11993
|
-
};
|
|
11994
|
-
|
|
11995
|
-
const parsePageToken = (raw) => {
|
|
11996
|
-
if (raw === undefined || raw === '') {
|
|
11997
|
-
return undefined;
|
|
11998
|
-
}
|
|
11999
|
-
parsePositiveInt(raw, '--page-token', 'INVALID_PAGE_TOKEN');
|
|
12000
|
-
return raw;
|
|
12001
|
-
};
|
|
12002
|
-
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
// collectAllPages 顺着 next_page_token 把所有页取回来。
|
|
12010
|
-
//
|
|
12011
|
-
// 服务端从「全量单页」改成真分页之后,`app list` 一次只回一页;想要「我的全部应用」就得翻页。
|
|
12012
|
-
// 与其让每个调用方各写一遍循环,不如给一个 --all。
|
|
12013
|
-
//
|
|
12014
|
-
// ⚠️ 不设页数上限截断:静默截断正是这次要修掉的毛病。只防死循环——服务端如果一直回同一个
|
|
12015
|
-
// token(或说 has_more 却不给 token),直接报错,而不是无限翻。
|
|
12016
|
-
const collectAllPages = async (
|
|
12017
|
-
fetchPage,
|
|
12018
|
-
) => {
|
|
12019
|
-
const items = [];
|
|
12020
|
-
const seen = new Set();
|
|
12021
|
-
let pageToken;
|
|
12022
|
-
let pages = 0;
|
|
12023
|
-
for (;;) {
|
|
12024
|
-
const page = await fetchPage(pageToken);
|
|
12025
|
-
items.push(...(page.items || []));
|
|
12026
|
-
pages += 1;
|
|
12027
|
-
if (!page.has_more) {
|
|
12028
|
-
return { items, pages };
|
|
12029
|
-
}
|
|
12030
|
-
const next = page.next_page_token;
|
|
12031
|
-
if (!next || seen.has(next)) {
|
|
12032
|
-
throw new CliError(
|
|
12033
|
-
'The server reported more pages but returned no usable next_page_token.',
|
|
12034
|
-
'INVALID_PAGE_TOKEN',
|
|
12035
|
-
{ next_page_token: next, pages },
|
|
12036
|
-
);
|
|
12037
|
-
}
|
|
12038
|
-
seen.add(next);
|
|
12039
|
-
pageToken = next;
|
|
12040
|
-
}
|
|
12041
|
-
};
|
|
12042
|
-
|
|
12043
12117
|
function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
12044
12118
|
|
|
12045
12119
|
const POLL_INTERVAL_MS = 3000;
|
|
@@ -12753,7 +12827,7 @@ const createDeploymentWithSourcePackage = async (
|
|
|
12753
12827
|
return { uploadMode: 'direct' , result };
|
|
12754
12828
|
};
|
|
12755
12829
|
|
|
12756
|
-
function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
12830
|
+
function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
12757
12831
|
const SUPPORTED_MINIPROGRAM_CONNECTOR_IDS = new Set(['10000127', '10000126']);
|
|
12758
12832
|
const collectConnectorId = (value, previous) => [
|
|
12759
12833
|
...previous,
|
|
@@ -12996,69 +13070,7 @@ const registerDeploy = (code) => {
|
|
|
12996
13070
|
source_package_size_bytes: sourcePackage.sizeBytes,
|
|
12997
13071
|
upload_mode: deployment.uploadMode,
|
|
12998
13072
|
local_link: appId && !projectCreated ? 'unchanged' : 'written',
|
|
12999
|
-
|
|
13000
|
-
});
|
|
13001
|
-
|
|
13002
|
-
deploy
|
|
13003
|
-
.command('status')
|
|
13004
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13005
|
-
.option('--deploy-id <deployId>', 'Deployment history ID')
|
|
13006
|
-
.action(async (options, command) => {
|
|
13007
|
-
const runtime = await getRuntime(command);
|
|
13008
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13009
|
-
let deployHistoryId = options.deployId;
|
|
13010
|
-
if (!deployHistoryId) {
|
|
13011
|
-
deployHistoryId = await _asyncOptionalChain([(
|
|
13012
|
-
await runtime.client.listDeployHistory({ app_id: appId, page_size: 1 })
|
|
13013
|
-
), 'access', async _3 => _3.deploy_history_list, 'optionalAccess', async _4 => _4[0], 'optionalAccess', async _5 => _5.deploy_history_id]);
|
|
13014
|
-
}
|
|
13015
|
-
if (!deployHistoryId) {
|
|
13016
|
-
throw new CliError('No deployment history found.', 'DEPLOYMENT_NOT_FOUND');
|
|
13017
|
-
}
|
|
13018
|
-
const history = await runtime.client.getDeployHistory({
|
|
13019
|
-
app_id: appId,
|
|
13020
|
-
deploy_history_id: deployHistoryId,
|
|
13021
|
-
});
|
|
13022
|
-
runtime.output.print({
|
|
13023
|
-
app_id: appId,
|
|
13024
|
-
deploy_history_id: deployHistoryId,
|
|
13025
|
-
status: getDeployStatusText(history.status),
|
|
13026
|
-
commit_hash: history.commit_hash,
|
|
13027
|
-
domains: history.domain_list || [],
|
|
13028
|
-
error_analysis: history.error_analysis,
|
|
13029
|
-
deploy_detail: formatDeployDetails(history),
|
|
13030
|
-
connector_data_list: history.connector_data_list || [],
|
|
13031
|
-
});
|
|
13032
|
-
});
|
|
13033
|
-
|
|
13034
|
-
deploy
|
|
13035
|
-
.command('list')
|
|
13036
|
-
.option('--app-id <appId>', 'Application ID')
|
|
13037
|
-
.option('--page-size <pageSize>', 'Page size', '10')
|
|
13038
|
-
.option('--page-token <pageToken>', 'Page token (page number)')
|
|
13039
|
-
.action(async (options, command) => {
|
|
13040
|
-
// 先在本地校验:`--page-size abc` 以前算出 NaN 发出去,表现成「参数没生效」。
|
|
13041
|
-
const pageSize = parsePageSize(options.pageSize, 10);
|
|
13042
|
-
const pageToken = parsePageToken(options.pageToken);
|
|
13043
|
-
const runtime = await getRuntime(command);
|
|
13044
|
-
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13045
|
-
const data = await runtime.client.listDeployHistory({
|
|
13046
|
-
app_id: appId,
|
|
13047
|
-
page_size: pageSize,
|
|
13048
|
-
page_token: pageToken,
|
|
13049
|
-
});
|
|
13050
|
-
runtime.output.print({
|
|
13051
|
-
items: (data.deploy_history_list || []).map(item => ({
|
|
13052
|
-
deploy_history_id: item.deploy_history_id,
|
|
13053
|
-
status: getDeployStatusText(item.status),
|
|
13054
|
-
commit_hash: item.commit_hash_short || item.commit_hash,
|
|
13055
|
-
created_at: item.created_at,
|
|
13056
|
-
can_rollback: item.can_rollback,
|
|
13057
|
-
deploy_detail: formatDeployDetails(item),
|
|
13058
|
-
connector_data_list: item.connector_data_list || [],
|
|
13059
|
-
})),
|
|
13060
|
-
next_page_token: data.next_page_token,
|
|
13061
|
-
has_more: data.has_more,
|
|
13073
|
+
mobile_artifact_list: _optionalChain([history, 'optionalAccess', _3 => _3.mobile_artifact_list]) || [],
|
|
13062
13074
|
});
|
|
13063
13075
|
});
|
|
13064
13076
|
|
|
@@ -13161,7 +13173,7 @@ const registerDeploy = (code) => {
|
|
|
13161
13173
|
.action(async (options, command) => {
|
|
13162
13174
|
const runtime = await getRuntime(command);
|
|
13163
13175
|
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13164
|
-
let key = _optionalChain([options, 'access',
|
|
13176
|
+
let key = _optionalChain([options, 'access', _4 => _4.key, 'optionalAccess', _5 => _5.trim, 'call', _6 => _6()]);
|
|
13165
13177
|
if (!key) {
|
|
13166
13178
|
const history = await runtime.client.getDeployHistory({
|
|
13167
13179
|
app_id: appId,
|
|
@@ -13203,7 +13215,7 @@ const registerDeploy = (code) => {
|
|
|
13203
13215
|
const runtime = await getRuntime(command);
|
|
13204
13216
|
const appId = await requireAppId(runtime.cwd, getDeployAppIdOption(options, command));
|
|
13205
13217
|
const application = await runtime.client.getApplication(appId);
|
|
13206
|
-
const commitHash = options.commitId || _optionalChain([application, 'access',
|
|
13218
|
+
const commitHash = options.commitId || _optionalChain([application, 'access', _7 => _7.latest_deployment, 'optionalAccess', _8 => _8.commit_hash]);
|
|
13207
13219
|
if (!commitHash) {
|
|
13208
13220
|
throw new CliError('No deployment commit is available.', 'DEPLOYMENT_NOT_FOUND');
|
|
13209
13221
|
}
|
|
@@ -36,6 +36,7 @@ const LOCAL_METADATA_FILES = new Set([
|
|
|
36
36
|
]);
|
|
37
37
|
const UPLOAD_SESSION_TEMP_PREFIX = '.coze-deploy-upload-';
|
|
38
38
|
const REPRODUCIBLE_ARCHIVE_MTIME = new Date(0);
|
|
39
|
+
const PROJECT_METADATA_FILE_MODE = 0o644;
|
|
39
40
|
|
|
40
41
|
const parseArguments = argv => {
|
|
41
42
|
const positional = [];
|
|
@@ -193,6 +194,11 @@ const createTarGzWithoutRoot = async (sourceDir, outputPath, excludeCozeFile = f
|
|
|
193
194
|
filter: archivePath => shouldInclude(archivePath, excludeCozeFile),
|
|
194
195
|
gzip: true,
|
|
195
196
|
mtime: REPRODUCIBLE_ARCHIVE_MTIME,
|
|
197
|
+
onWriteEntry: entry => {
|
|
198
|
+
if (entry.path === '.coze' && entry.stat?.isFile()) {
|
|
199
|
+
entry.stat.mode = PROJECT_METADATA_FILE_MODE;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
196
202
|
portable: true,
|
|
197
203
|
},
|
|
198
204
|
entries,
|
|
@@ -30,6 +30,7 @@ EXCLUDED_PARTS = {
|
|
|
30
30
|
UPLOAD_SESSION_FILENAME = ".coze-deploy-upload.json"
|
|
31
31
|
UPLOAD_SESSION_TEMP_PREFIX = ".coze-deploy-upload-"
|
|
32
32
|
HOST_LINK_FILENAME = ".host.json"
|
|
33
|
+
PROJECT_METADATA_FILE_MODE = 0o644
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
def build_command_env():
|
|
@@ -116,6 +117,8 @@ def should_exclude(tar_info: tarfile.TarInfo, exclude_coze_file=False):
|
|
|
116
117
|
return None
|
|
117
118
|
if any(part in EXCLUDED_PARTS for part in parts):
|
|
118
119
|
return None
|
|
120
|
+
if parts == (".coze",) and tar_info.isfile():
|
|
121
|
+
tar_info.mode = PROJECT_METADATA_FILE_MODE
|
|
119
122
|
return tar_info
|
|
120
123
|
|
|
121
124
|
|