@intra-mart/accel 0.3.0-dev.202606150745 → 0.3.0-dev.202606220428
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.md +11 -0
- package/dist/commands/deploy.d.ts +4 -1
- package/dist/commands/deploy.js +130 -2
- package/dist/core/types.d.ts +22 -0
- package/dist/deploy/api-client.d.ts +4 -2
- package/dist/deploy/api-client.js +23 -1
- package/dist/i18n/en.js +12 -0
- package/dist/i18n/ja.js +12 -0
- package/dist/i18n/zh_CN.js +12 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -192,6 +192,16 @@ accel deploy
|
|
|
192
192
|
- ただし、除外した結果 0 件になった場合(`.accel/settings.json` の `artifactId` と実ファイル名の artifactId が乖離しているケースなど)は、除外せず `./target/` 配下の全 zip を選択候補とします。
|
|
193
193
|
- いずれの場合もデプロイ実行前に最終確認を行います。
|
|
194
194
|
- 送信時、zip は imm 形式としてアップロードされます(送信時のファイル名のみ `.imm` に変更され、ディスク上のファイルはそのままです)。
|
|
195
|
+
- デプロイ成功後、レスポンスにショートカットURL(`shortcutUrl`)が含まれる場合は結果と共に表示します(ステージング詳細画面への自動ログイン付きURL、有効期限60分)。
|
|
196
|
+
- デプロイ成功後、レスポンスにテナント環境セットアップ設定(`setupConfigs`)が含まれる場合は、対話的にテナント環境セットアップの実行を提案します:
|
|
197
|
+
1. セットアップ設定の情報(moduleId / configNumber / sections)を表示
|
|
198
|
+
2. 「テナント環境セットアップを実行しますか?」を確認(No → スキップ)
|
|
199
|
+
3. 「全て実行しますか?」を確認
|
|
200
|
+
- Yes → 全設定ファイルを一括実行
|
|
201
|
+
- No → 実行する設定ファイルを複数選択し、順次実行
|
|
202
|
+
4. 実行結果を一覧表示
|
|
203
|
+
- **注意**: セットアップの実行はステージング分離されず、実テナントのデータベースに反映されます
|
|
204
|
+
- セットアップの成否はデプロイの終了コードに影響しません(デプロイ成功 = 正常終了)
|
|
195
205
|
|
|
196
206
|
#### 非対話モード
|
|
197
207
|
|
|
@@ -213,6 +223,7 @@ ACCEL_API_KEY=*** accel deploy \
|
|
|
213
223
|
- `--file` を指定した場合はそのパス(`./target/` 配下に限定しません)を使います。ファイルが存在しなければエラー終了します。
|
|
214
224
|
- `--file` 未指定の場合は対話モードと同じ自動特定(`<artifactId>-<projectVersion>.zip` 完全一致)を試みます。**自動特定できない場合**(settings 無し/完全一致無し/複数候補)は `--file` 指定が必要な旨を表示してエラー終了します。`./target/` に zip が 1 件も無い場合は、ビルド未実行の旨(`mvn package` 等の実行を促す)を表示してエラー終了します。
|
|
215
225
|
- `--description` は任意です。最終確認プロンプトは出さず、即デプロイします。
|
|
226
|
+
- **テナント環境セットアップは実行しません**(対話が必要なため)。`shortcutUrl` はデプロイ結果に含めて表示します。
|
|
216
227
|
- フラグ/環境変数で渡した接続情報は **`.accel/credentials.json` に保存しません**(CIランナーにシークレット情報を残さないため)。
|
|
217
228
|
|
|
218
229
|
#### オプション一覧
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AccelCredentials, StagingResponse } from "../core/types.js";
|
|
1
|
+
import type { AccelCredentials, SetupConfigResponse, StagingResponse } from "../core/types.js";
|
|
2
2
|
import { type ApiClient } from "../deploy/api-client.js";
|
|
3
3
|
export declare const toImmFileName: (zipPath: string) => string;
|
|
4
4
|
type ConfirmInfo = {
|
|
@@ -12,6 +12,9 @@ export type DeployPrompts = {
|
|
|
12
12
|
selectZip: (zips: string[], locale: string) => Promise<string>;
|
|
13
13
|
description: (locale: string) => Promise<string>;
|
|
14
14
|
confirm: (info: ConfirmInfo, locale: string) => Promise<boolean>;
|
|
15
|
+
confirmSetup: (configs: SetupConfigResponse[], locale: string) => Promise<boolean>;
|
|
16
|
+
confirmSetupAll: (locale: string) => Promise<boolean>;
|
|
17
|
+
selectSetupConfigs: (configs: SetupConfigResponse[], locale: string) => Promise<number[]>;
|
|
15
18
|
};
|
|
16
19
|
export type RunDeployDeps = {
|
|
17
20
|
projectDir: string;
|
package/dist/commands/deploy.js
CHANGED
|
@@ -66,6 +66,40 @@ const defaultPrompts = {
|
|
|
66
66
|
process.exit(0);
|
|
67
67
|
return res;
|
|
68
68
|
},
|
|
69
|
+
confirmSetup: async (configs, locale) => {
|
|
70
|
+
p.note(configs
|
|
71
|
+
.map((c) => `#${c.configNumber} ${c.moduleId} [${c.sections.join(", ")}]`)
|
|
72
|
+
.join("\n"), getMessage("deploy.setup.heading", locale));
|
|
73
|
+
const res = await p.confirm({
|
|
74
|
+
message: getMessage("deploy.setup.confirm", locale),
|
|
75
|
+
initialValue: true,
|
|
76
|
+
});
|
|
77
|
+
if (p.isCancel(res))
|
|
78
|
+
process.exit(0);
|
|
79
|
+
return res;
|
|
80
|
+
},
|
|
81
|
+
confirmSetupAll: async (locale) => {
|
|
82
|
+
const res = await p.confirm({
|
|
83
|
+
message: getMessage("deploy.setup.confirmAll", locale),
|
|
84
|
+
initialValue: true,
|
|
85
|
+
});
|
|
86
|
+
if (p.isCancel(res))
|
|
87
|
+
process.exit(0);
|
|
88
|
+
return res;
|
|
89
|
+
},
|
|
90
|
+
selectSetupConfigs: async (configs, locale) => {
|
|
91
|
+
const res = await p.multiselect({
|
|
92
|
+
message: getMessage("deploy.setup.selectConfigs", locale),
|
|
93
|
+
options: configs.map((c) => ({
|
|
94
|
+
value: c.configNumber,
|
|
95
|
+
label: `#${c.configNumber} ${c.moduleId} [${c.sections.join(", ")}]`,
|
|
96
|
+
})),
|
|
97
|
+
required: true,
|
|
98
|
+
});
|
|
99
|
+
if (p.isCancel(res))
|
|
100
|
+
process.exit(0);
|
|
101
|
+
return res;
|
|
102
|
+
},
|
|
69
103
|
};
|
|
70
104
|
const resolveLocale = async (projectDir) => {
|
|
71
105
|
try {
|
|
@@ -225,14 +259,108 @@ export const runDeploy = async (deps) => {
|
|
|
225
259
|
throw logAndRethrow(err, locale);
|
|
226
260
|
}
|
|
227
261
|
spin.stop(getMessage("deploy.progress.deploying", locale));
|
|
228
|
-
|
|
262
|
+
const resultLines = [
|
|
229
263
|
`${getMessage("deploy.result.deployId", locale)}: ${result.deployId}`,
|
|
230
264
|
`${getMessage("deploy.result.stagingId", locale)}: ${result.stagingId}`,
|
|
231
265
|
`${getMessage("deploy.result.status", locale)}: ${result.status}`,
|
|
232
266
|
`${getMessage("deploy.result.createDate", locale)}: ${formatEpochMillis(result.createDate, locale)}`,
|
|
233
|
-
]
|
|
267
|
+
];
|
|
268
|
+
p.note(resultLines.join("\n"));
|
|
269
|
+
if (!nonInteractive && result.setupConfigs && result.setupConfigs.length > 0) {
|
|
270
|
+
try {
|
|
271
|
+
await runSetup(api, stagingId, result.setupConfigs, locale, prompts, spin);
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
const msg = isDeployError(err)
|
|
275
|
+
? formatDeployError(err, locale)
|
|
276
|
+
: err instanceof Error
|
|
277
|
+
? err.message
|
|
278
|
+
: String(err);
|
|
279
|
+
p.log.error(getMessage("deploy.setup.error", locale, { message: msg }));
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (result.shortcutUrl) {
|
|
283
|
+
p.log.info(`${getMessage("deploy.result.shortcutUrl", locale)}: ${result.shortcutUrl}`);
|
|
284
|
+
}
|
|
234
285
|
p.outro(getMessage("deploy.success", locale));
|
|
235
286
|
};
|
|
287
|
+
const runSetup = async (api, stagingId, configs, locale, prompts, spin) => {
|
|
288
|
+
const doSetup = await prompts.confirmSetup(configs, locale);
|
|
289
|
+
if (!doSetup)
|
|
290
|
+
return;
|
|
291
|
+
const doAll = await prompts.confirmSetupAll(locale);
|
|
292
|
+
let setupResult;
|
|
293
|
+
if (doAll) {
|
|
294
|
+
spin.start(getMessage("deploy.setup.executing", locale, { config: "all" }));
|
|
295
|
+
try {
|
|
296
|
+
setupResult = await api.executeSetup(stagingId);
|
|
297
|
+
}
|
|
298
|
+
finally {
|
|
299
|
+
spin.stop(getMessage("deploy.setup.executing", locale, { config: "all" }));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
const selected = await prompts.selectSetupConfigs(configs, locale);
|
|
304
|
+
const allResults = [];
|
|
305
|
+
let allSuccess = true;
|
|
306
|
+
for (const configNumber of selected.sort((a, b) => a - b)) {
|
|
307
|
+
const config = configs.find((c) => c.configNumber === configNumber);
|
|
308
|
+
const label = config
|
|
309
|
+
? `#${config.configNumber} ${config.moduleId}`
|
|
310
|
+
: `#${configNumber}`;
|
|
311
|
+
spin.start(getMessage("deploy.setup.executing", locale, { config: label }));
|
|
312
|
+
let partial;
|
|
313
|
+
try {
|
|
314
|
+
partial = await api.executeSetupConfig(stagingId, configNumber);
|
|
315
|
+
}
|
|
316
|
+
finally {
|
|
317
|
+
spin.stop(getMessage("deploy.setup.executing", locale, { config: label }));
|
|
318
|
+
}
|
|
319
|
+
allResults.push(...partial.results);
|
|
320
|
+
if (!partial.success)
|
|
321
|
+
allSuccess = false;
|
|
322
|
+
}
|
|
323
|
+
setupResult = {
|
|
324
|
+
success: allSuccess,
|
|
325
|
+
totalCount: allResults.length,
|
|
326
|
+
results: allResults,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
showSetupResults(setupResult, locale);
|
|
330
|
+
};
|
|
331
|
+
const showSetupResults = (result, locale) => {
|
|
332
|
+
if (result.results.length === 0)
|
|
333
|
+
return;
|
|
334
|
+
const sectionHeader = getMessage("deploy.setup.resultHeader.section", locale);
|
|
335
|
+
const targetHeader = getMessage("deploy.setup.resultHeader.target", locale);
|
|
336
|
+
const resultHeader = getMessage("deploy.setup.resultHeader.result", locale);
|
|
337
|
+
const rows = result.results.map((r) => {
|
|
338
|
+
const status = r.success ? "OK" : "NG";
|
|
339
|
+
const detail = r.message ? ` (${r.message})` : "";
|
|
340
|
+
return [r.label, r.target, `${status}${detail}`];
|
|
341
|
+
});
|
|
342
|
+
const displayWidth = (s) => {
|
|
343
|
+
let w = 0;
|
|
344
|
+
for (const ch of s) {
|
|
345
|
+
const cp = ch.codePointAt(0) ?? 0;
|
|
346
|
+
w += cp > 0x7f ? 2 : 1;
|
|
347
|
+
}
|
|
348
|
+
return w;
|
|
349
|
+
};
|
|
350
|
+
const colWidths = [sectionHeader, targetHeader, resultHeader].map((h, i) => Math.max(displayWidth(h), ...rows.map((r) => displayWidth(r[i]))));
|
|
351
|
+
const pad = (s, w) => s + " ".repeat(Math.max(0, w - displayWidth(s)));
|
|
352
|
+
const formatRow = (cols) => cols.map((c, i) => pad(c, colWidths[i])).join(" | ");
|
|
353
|
+
const header = formatRow([sectionHeader, targetHeader, resultHeader]);
|
|
354
|
+
const separator = colWidths.map((w) => "-".repeat(w)).join("-+-");
|
|
355
|
+
const lines = rows.map((r) => formatRow(r));
|
|
356
|
+
p.note([header, separator, ...lines].join("\n"));
|
|
357
|
+
if (result.success) {
|
|
358
|
+
p.log.success(getMessage("deploy.setup.resultSuccess", locale));
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
p.log.warn(getMessage("deploy.setup.resultPartialFailure", locale));
|
|
362
|
+
}
|
|
363
|
+
};
|
|
236
364
|
const logAndRethrow = (err, locale) => {
|
|
237
365
|
if (isDeployError(err)) {
|
|
238
366
|
p.log.error(formatDeployError(err, locale));
|
package/dist/core/types.d.ts
CHANGED
|
@@ -163,6 +163,28 @@ export type DeploymentResponse = {
|
|
|
163
163
|
createUserCd: string;
|
|
164
164
|
createDate: number;
|
|
165
165
|
};
|
|
166
|
+
export type SetupConfigResponse = {
|
|
167
|
+
moduleId: string;
|
|
168
|
+
configNumber: number;
|
|
169
|
+
sections: string[];
|
|
170
|
+
};
|
|
171
|
+
export type DeploymentCreateResponse = DeploymentResponse & {
|
|
172
|
+
shortcutUrl?: string | null;
|
|
173
|
+
setupConfigs?: SetupConfigResponse[] | null;
|
|
174
|
+
};
|
|
175
|
+
export type SetupExecuteResultResponse = {
|
|
176
|
+
configNumber: number;
|
|
177
|
+
section: string;
|
|
178
|
+
label: string;
|
|
179
|
+
target: string;
|
|
180
|
+
success: boolean;
|
|
181
|
+
message?: string | null;
|
|
182
|
+
};
|
|
183
|
+
export type SetupExecuteResponse = {
|
|
184
|
+
success: boolean;
|
|
185
|
+
totalCount: number;
|
|
186
|
+
results: SetupExecuteResultResponse[];
|
|
187
|
+
};
|
|
166
188
|
export type ApiSuccess<T> = {
|
|
167
189
|
error: false;
|
|
168
190
|
data: T;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { StagingResponse,
|
|
1
|
+
import type { StagingResponse, DeploymentCreateResponse, DeployError, SetupExecuteResponse } from "../core/types.js";
|
|
2
2
|
type FetchFn = typeof globalThis.fetch;
|
|
3
3
|
export declare const makeDeployError: (kind: DeployError["kind"], extra?: {
|
|
4
4
|
status?: number;
|
|
@@ -8,7 +8,9 @@ export declare const isDeployError: (e: unknown) => e is DeployError;
|
|
|
8
8
|
export type ApiClient = {
|
|
9
9
|
verifyToken: () => Promise<void>;
|
|
10
10
|
listStagings: () => Promise<StagingResponse[]>;
|
|
11
|
-
createDeployment: (stagingId: string, bytes: Uint8Array, immFileName: string, description?: string) => Promise<
|
|
11
|
+
createDeployment: (stagingId: string, bytes: Uint8Array, immFileName: string, description?: string) => Promise<DeploymentCreateResponse>;
|
|
12
|
+
executeSetup: (stagingId: string) => Promise<SetupExecuteResponse>;
|
|
13
|
+
executeSetupConfig: (stagingId: string, configNumber: number) => Promise<SetupExecuteResponse>;
|
|
12
14
|
};
|
|
13
15
|
export declare const createApiClient: (endpoint: string, apiKey: string, deps?: {
|
|
14
16
|
fetch?: FetchFn;
|
|
@@ -101,5 +101,27 @@ export const createApiClient = (endpoint, apiKey, deps = {}) => {
|
|
|
101
101
|
body: form,
|
|
102
102
|
});
|
|
103
103
|
};
|
|
104
|
-
|
|
104
|
+
const executeSetup = async (stagingId) => {
|
|
105
|
+
const url = `${endpoint}${STAGING_PATH}/${encodeURIComponent(stagingId)}/setup/execute`;
|
|
106
|
+
return request(url, {
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: { ...baseHeaders, "Content-Type": "application/json" },
|
|
109
|
+
body: JSON.stringify({}),
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
const executeSetupConfig = async (stagingId, configNumber) => {
|
|
113
|
+
const url = `${endpoint}${STAGING_PATH}/${encodeURIComponent(stagingId)}/setup/configs/${configNumber}/execute`;
|
|
114
|
+
return request(url, {
|
|
115
|
+
method: "POST",
|
|
116
|
+
headers: { ...baseHeaders, "Content-Type": "application/json" },
|
|
117
|
+
body: JSON.stringify({}),
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
verifyToken,
|
|
122
|
+
listStagings,
|
|
123
|
+
createDeployment,
|
|
124
|
+
executeSetup,
|
|
125
|
+
executeSetupConfig,
|
|
126
|
+
};
|
|
105
127
|
};
|
package/dist/i18n/en.js
CHANGED
|
@@ -138,4 +138,16 @@ export const messages = {
|
|
|
138
138
|
"deploy.error.unexpectedResponse": "Received an unexpected response (HTTP {status}).",
|
|
139
139
|
"deploy.reauth.notFound": "The endpoint could not be reached (404). Check that the endpoint URL is correct.",
|
|
140
140
|
"deploy.reauth.notice": "Please re-enter your connection information.",
|
|
141
|
+
"deploy.result.shortcutUrl": "Shortcut URL",
|
|
142
|
+
"deploy.setup.heading": "Tenant Environment Setup Configs",
|
|
143
|
+
"deploy.setup.confirm": "Run tenant environment setup?",
|
|
144
|
+
"deploy.setup.confirmAll": "Execute all?",
|
|
145
|
+
"deploy.setup.selectConfigs": "Select the configs to execute",
|
|
146
|
+
"deploy.setup.executing": "Running tenant environment setup... ({config})",
|
|
147
|
+
"deploy.setup.resultSuccess": "Tenant environment setup completed.",
|
|
148
|
+
"deploy.setup.resultPartialFailure": "Tenant environment setup partially failed.",
|
|
149
|
+
"deploy.setup.error": "An error occurred during tenant environment setup: {message}",
|
|
150
|
+
"deploy.setup.resultHeader.section": "Section",
|
|
151
|
+
"deploy.setup.resultHeader.target": "Target",
|
|
152
|
+
"deploy.setup.resultHeader.result": "Result",
|
|
141
153
|
};
|
package/dist/i18n/ja.js
CHANGED
|
@@ -138,4 +138,16 @@ export const messages = {
|
|
|
138
138
|
"deploy.error.unexpectedResponse": "想定外のレスポンスを受信しました(HTTP {status})。",
|
|
139
139
|
"deploy.reauth.notFound": "指定されたエンドポイントにアクセスできません(404)。エンドポイントの URL が正しいか確認してください。",
|
|
140
140
|
"deploy.reauth.notice": "接続情報を再入力してください。",
|
|
141
|
+
"deploy.result.shortcutUrl": "ショートカットURL",
|
|
142
|
+
"deploy.setup.heading": "テナント環境セットアップ設定",
|
|
143
|
+
"deploy.setup.confirm": "テナント環境セットアップを実行しますか?",
|
|
144
|
+
"deploy.setup.confirmAll": "全て実行しますか?",
|
|
145
|
+
"deploy.setup.selectConfigs": "実行する設定を選択してください",
|
|
146
|
+
"deploy.setup.executing": "テナント環境セットアップを実行しています... ({config})",
|
|
147
|
+
"deploy.setup.resultSuccess": "テナント環境セットアップが完了しました。",
|
|
148
|
+
"deploy.setup.resultPartialFailure": "テナント環境セットアップが一部失敗しました。",
|
|
149
|
+
"deploy.setup.error": "テナント環境セットアップの実行中にエラーが発生しました: {message}",
|
|
150
|
+
"deploy.setup.resultHeader.section": "セクション",
|
|
151
|
+
"deploy.setup.resultHeader.target": "対象",
|
|
152
|
+
"deploy.setup.resultHeader.result": "結果",
|
|
141
153
|
};
|
package/dist/i18n/zh_CN.js
CHANGED
|
@@ -138,4 +138,16 @@ export const messages = {
|
|
|
138
138
|
"deploy.error.unexpectedResponse": "收到意外的响应(HTTP {status})。",
|
|
139
139
|
"deploy.reauth.notFound": "无法访问指定的端点(404)。请确认端点 URL 是否正确。",
|
|
140
140
|
"deploy.reauth.notice": "请重新输入连接信息。",
|
|
141
|
+
"deploy.result.shortcutUrl": "快捷链接",
|
|
142
|
+
"deploy.setup.heading": "租户环境配置设置",
|
|
143
|
+
"deploy.setup.confirm": "是否执行租户环境配置?",
|
|
144
|
+
"deploy.setup.confirmAll": "是否全部执行?",
|
|
145
|
+
"deploy.setup.selectConfigs": "请选择要执行的配置",
|
|
146
|
+
"deploy.setup.executing": "正在执行租户环境配置... ({config})",
|
|
147
|
+
"deploy.setup.resultSuccess": "租户环境配置已完成。",
|
|
148
|
+
"deploy.setup.resultPartialFailure": "租户环境配置部分失败。",
|
|
149
|
+
"deploy.setup.error": "执行租户环境配置时发生错误: {message}",
|
|
150
|
+
"deploy.setup.resultHeader.section": "部分",
|
|
151
|
+
"deploy.setup.resultHeader.target": "对象",
|
|
152
|
+
"deploy.setup.resultHeader.result": "结果",
|
|
141
153
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intra-mart/accel",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.202606220428",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI tool for intra-mart Accel Platform development",
|
|
6
6
|
"author": "NTT DATA INTRAMART",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@clack/prompts": "^1.4.0",
|
|
42
|
-
"@intra-mart/catalog": "
|
|
42
|
+
"@intra-mart/catalog": "0.1.0-dev.202606160846",
|
|
43
43
|
"citty": "^0.1.6",
|
|
44
44
|
"fast-xml-parser": "^5.2.0",
|
|
45
45
|
"remark": "^15.0.1",
|