esa-cli 1.0.3 → 1.0.4-beta.0
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/commands/commit/index.js +11 -1
- package/dist/commands/common/utils.js +10 -5
- package/dist/commands/deploy/index.js +5 -1
- package/dist/commands/utils.js +58 -0
- package/dist/docs/Commands_en.md +6 -0
- package/dist/docs/Commands_zh_CN.md +6 -0
- package/dist/i18n/locales.json +12 -0
- package/dist/libs/api.js +1 -1
- package/dist/libs/apiService.js +1 -1
- package/package.json +1 -1
|
@@ -13,6 +13,7 @@ import chalk from 'chalk';
|
|
|
13
13
|
import t from '../../i18n/index.js';
|
|
14
14
|
import logger from '../../libs/logger.js';
|
|
15
15
|
import promptParameter from '../../utils/prompt.js';
|
|
16
|
+
import { checkAndCleanupVersions } from '../utils.js';
|
|
16
17
|
import { validateAndInitializeProject, generateCodeVersion } from '../common/utils.js';
|
|
17
18
|
const commit = {
|
|
18
19
|
command: 'commit [entry]',
|
|
@@ -44,6 +45,10 @@ const commit = {
|
|
|
44
45
|
describe: 'Bundle with esbuild (use --no-bundle to skip)',
|
|
45
46
|
type: 'boolean',
|
|
46
47
|
default: true
|
|
48
|
+
})
|
|
49
|
+
.option('version-limit', {
|
|
50
|
+
describe: t('commit_option_version_limit').d('Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.'),
|
|
51
|
+
type: 'number'
|
|
47
52
|
});
|
|
48
53
|
},
|
|
49
54
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -59,7 +64,12 @@ export function handleCommit(argv) {
|
|
|
59
64
|
const projectInfo = yield validateAndInitializeProject(argv === null || argv === void 0 ? void 0 : argv.name);
|
|
60
65
|
if (!projectInfo)
|
|
61
66
|
return;
|
|
62
|
-
const { projectName } = projectInfo;
|
|
67
|
+
const { projectName, projectConfig } = projectInfo;
|
|
68
|
+
// Cleanup old versions if limit is specified
|
|
69
|
+
const limit = argv['version-limit'] || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.versionLimit);
|
|
70
|
+
if (limit) {
|
|
71
|
+
yield checkAndCleanupVersions(projectName, limit, true);
|
|
72
|
+
}
|
|
63
73
|
let description;
|
|
64
74
|
if (argv.description) {
|
|
65
75
|
description = argv.description;
|
|
@@ -15,7 +15,7 @@ import { ensureRoutineExists } from '../../utils/checkIsRoutineCreated.js';
|
|
|
15
15
|
import compress from '../../utils/compress.js';
|
|
16
16
|
import { getProjectConfig } from '../../utils/fileUtils/index.js';
|
|
17
17
|
import sleep from '../../utils/sleep.js';
|
|
18
|
-
import { checkIsLoginSuccess } from '../utils.js';
|
|
18
|
+
import { checkAndCleanupVersions, checkIsLoginSuccess } from '../utils.js';
|
|
19
19
|
function normalizeNotFoundStrategy(value) {
|
|
20
20
|
if (!value)
|
|
21
21
|
return undefined;
|
|
@@ -260,21 +260,26 @@ export function deployToEnvironments(name, codeVersion, env) {
|
|
|
260
260
|
* 结合了压缩、提交和部署的完整流程
|
|
261
261
|
*/
|
|
262
262
|
export function commitAndDeployVersion(projectName_1, scriptEntry_1, assets_1) {
|
|
263
|
-
return __awaiter(this, arguments, void 0, function* (projectName, scriptEntry, assets, description = '', projectPath, env = 'production', minify = false, version, noBundle = false) {
|
|
263
|
+
return __awaiter(this, arguments, void 0, function* (projectName, scriptEntry, assets, description = '', projectPath, env = 'production', minify = false, version, noBundle = false, versionLimit) {
|
|
264
264
|
var _a, _b, _c;
|
|
265
265
|
const projectInfo = yield validateAndInitializeProject(projectName, projectPath);
|
|
266
266
|
if (!projectInfo) {
|
|
267
267
|
return false;
|
|
268
268
|
}
|
|
269
|
-
const { projectConfig } = projectInfo;
|
|
269
|
+
const { projectConfig, projectName: resolvedProjectName } = projectInfo;
|
|
270
|
+
// Cleanup old versions if limit is specified
|
|
271
|
+
const limit = versionLimit || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.versionLimit);
|
|
272
|
+
if (limit) {
|
|
273
|
+
yield checkAndCleanupVersions(resolvedProjectName, limit, !version);
|
|
274
|
+
}
|
|
270
275
|
// 2) Use existing version or generate a new one
|
|
271
276
|
if (version) {
|
|
272
277
|
logger.startSubStep(`Using existing version ${version}`);
|
|
273
|
-
const deployed = yield deployToEnvironments(
|
|
278
|
+
const deployed = yield deployToEnvironments(resolvedProjectName, version, env);
|
|
274
279
|
logger.endSubStep(deployed ? 'Deploy finished' : 'Deploy failed');
|
|
275
280
|
return deployed;
|
|
276
281
|
}
|
|
277
|
-
const res = yield generateCodeVersion(
|
|
282
|
+
const res = yield generateCodeVersion(resolvedProjectName, description, scriptEntry || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.entry), assets || ((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.assets) === null || _a === void 0 ? void 0 : _a.directory), minify || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.minify), projectPath, noBundle);
|
|
278
283
|
const isCommitSuccess = res === null || res === void 0 ? void 0 : res.isSuccess;
|
|
279
284
|
if (!isCommitSuccess) {
|
|
280
285
|
logger.endSubStep('Generate version failed');
|
|
@@ -61,6 +61,10 @@ const deploy = {
|
|
|
61
61
|
.option('versions', {
|
|
62
62
|
describe: 'Deploy two versions with percentages, format: v1:80,v2:20 or repeat --versions v1:80 --versions v2:20',
|
|
63
63
|
type: 'array'
|
|
64
|
+
})
|
|
65
|
+
.option('version-limit', {
|
|
66
|
+
describe: t('deploy_option_version_limit').d('Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.'),
|
|
67
|
+
type: 'number'
|
|
64
68
|
});
|
|
65
69
|
},
|
|
66
70
|
describe: `🚀 ${t('deploy_describe').d('Deploy your project')}`,
|
|
@@ -82,7 +86,7 @@ export function handleDeploy(argv) {
|
|
|
82
86
|
outro(ok ? 'Deploy finished' : 'Deploy failed');
|
|
83
87
|
exit(ok ? 0 : 1);
|
|
84
88
|
}
|
|
85
|
-
const success = yield commitAndDeployVersion(argv.name || undefined, entry, assets, argv.description || '', getRoot(), argv.environment || 'all', argv.minify, argv.version, (argv.bundle === false));
|
|
89
|
+
const success = yield commitAndDeployVersion(argv.name || undefined, entry, assets, argv.description || '', getRoot(), argv.environment || 'all', argv.minify, argv.version, (argv.bundle === false), argv['version-limit']);
|
|
86
90
|
outro(success ? 'Deploy finished' : 'Deploy failed');
|
|
87
91
|
if (success) {
|
|
88
92
|
const projectConfig = getProjectConfig(getRoot());
|
package/dist/commands/utils.js
CHANGED
|
@@ -153,3 +153,61 @@ export const getRoutineCodeVersions = (projectName) => __awaiter(void 0, void 0,
|
|
|
153
153
|
const productionVersions = ((_m = (_l = (_k = (_j = (_h = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _h === void 0 ? void 0 : _h.Envs) === null || _j === void 0 ? void 0 : _j.find((item) => item.Env === 'production')) === null || _k === void 0 ? void 0 : _k.CodeDeploy) === null || _l === void 0 ? void 0 : _l.CodeVersions) === null || _m === void 0 ? void 0 : _m.map((item) => item.CodeVersion)) || [];
|
|
154
154
|
return { allVersions, stagingVersions, productionVersions };
|
|
155
155
|
});
|
|
156
|
+
/**
|
|
157
|
+
* Check the total number of versions and delete the oldest unreleased ones if they exceed the limit.
|
|
158
|
+
* @param projectName Name of the project
|
|
159
|
+
* @param limit The maximum number of versions to keep
|
|
160
|
+
* @param isCreatingNewVersion Whether a new version will be created after cleanup
|
|
161
|
+
*/
|
|
162
|
+
export function checkAndCleanupVersions(projectName_1, limit_1) {
|
|
163
|
+
return __awaiter(this, arguments, void 0, function* (projectName, limit, isCreatingNewVersion = true) {
|
|
164
|
+
if (limit <= 0)
|
|
165
|
+
return;
|
|
166
|
+
const { allVersions, stagingVersions, productionVersions } = yield getRoutineCodeVersions(projectName);
|
|
167
|
+
const currentCount = allVersions.length;
|
|
168
|
+
const targetCount = isCreatingNewVersion ? limit - 1 : limit;
|
|
169
|
+
if (currentCount <= targetCount) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const deployedVersions = new Set([...stagingVersions, ...productionVersions]);
|
|
173
|
+
// Filter versions that are not currently deployed
|
|
174
|
+
const undeployedVersions = allVersions.filter((v) => v.codeVersion && !deployedVersions.has(v.codeVersion));
|
|
175
|
+
// Sort by createTime (oldest first)
|
|
176
|
+
undeployedVersions.sort((a, b) => {
|
|
177
|
+
const timeA = a.createTime ? new Date(a.createTime).getTime() : 0;
|
|
178
|
+
const timeB = b.createTime ? new Date(b.createTime).getTime() : 0;
|
|
179
|
+
return timeA - timeB;
|
|
180
|
+
});
|
|
181
|
+
const numToDelete = currentCount - targetCount;
|
|
182
|
+
const toDelete = undeployedVersions.slice(0, numToDelete);
|
|
183
|
+
if (toDelete.length > 0) {
|
|
184
|
+
logger.info(t('cleanup_versions_start', {
|
|
185
|
+
count: toDelete.length.toString(),
|
|
186
|
+
limit: limit.toString()
|
|
187
|
+
}).d(`Cleaning up ${toDelete.length} oldest unreleased versions (limit: ${limit})...`));
|
|
188
|
+
const server = yield ApiService.getInstance();
|
|
189
|
+
for (const version of toDelete) {
|
|
190
|
+
if (!version.codeVersion)
|
|
191
|
+
continue;
|
|
192
|
+
try {
|
|
193
|
+
const res = yield server.deleteRoutineCodeVersion({
|
|
194
|
+
Name: projectName,
|
|
195
|
+
CodeVersion: version.codeVersion
|
|
196
|
+
});
|
|
197
|
+
if ((res === null || res === void 0 ? void 0 : res.Status) === 'OK') {
|
|
198
|
+
logger.success(t('deployments_delete_success').d('Delete success') +
|
|
199
|
+
`: ${version.codeVersion}`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
logger.warn(t('deployments_delete_failed').d('Delete failed') +
|
|
203
|
+
`: ${version.codeVersion}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
logger.warn(t('deployments_delete_failed').d('Delete failed') +
|
|
208
|
+
`: ${version.codeVersion}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
package/dist/docs/Commands_en.md
CHANGED
|
@@ -143,6 +143,9 @@ Description for Functions & Pages/version (skip interactive input)
|
|
|
143
143
|
**--name, -n** _optional_
|
|
144
144
|
Functions & Pages name
|
|
145
145
|
|
|
146
|
+
**--version-limit** _optional_
|
|
147
|
+
Maximum number of versions to keep. Oldest unreleased versions (not in staging or production) will be deleted if exceeded.
|
|
148
|
+
|
|
146
149
|
---
|
|
147
150
|
|
|
148
151
|
## deploy
|
|
@@ -174,6 +177,9 @@ Description of the version
|
|
|
174
177
|
**--minify, -m** _optional_
|
|
175
178
|
Whether to minify the code
|
|
176
179
|
|
|
180
|
+
**--version-limit** _optional_
|
|
181
|
+
Maximum number of versions to keep. Oldest unreleased versions (not in staging or production) will be deleted if exceeded.
|
|
182
|
+
|
|
177
183
|
---
|
|
178
184
|
|
|
179
185
|
## deployments
|
|
@@ -155,6 +155,9 @@ esa-cli commit [<ENTRY>] [OPTIONS]
|
|
|
155
155
|
**--name, -n** _可选_
|
|
156
156
|
**函数和Pages名称**
|
|
157
157
|
|
|
158
|
+
**--version-limit** _可选_
|
|
159
|
+
**保持的最大版本数量。如果超过此限制,将删除最旧的未发布版本(不处于仿真环境或线上环境的版本)。**
|
|
160
|
+
|
|
158
161
|
---
|
|
159
162
|
|
|
160
163
|
## deploy
|
|
@@ -186,6 +189,9 @@ esa-cli deploy [<ENTRY>] [OPTIONS]
|
|
|
186
189
|
**--minify, -m** _可选_
|
|
187
190
|
**是否压缩代码**
|
|
188
191
|
|
|
192
|
+
**--version-limit** _可选_
|
|
193
|
+
**保持的最大版本数量。如果超过此限制,将删除最旧的未发布版本(不处于仿真环境或线上环境的版本)。**
|
|
194
|
+
|
|
189
195
|
---
|
|
190
196
|
|
|
191
197
|
## deployments
|
package/dist/i18n/locales.json
CHANGED
|
@@ -1322,5 +1322,17 @@
|
|
|
1322
1322
|
"login_get_credentials_from_environment_variables": {
|
|
1323
1323
|
"en": "Get credentials from environment variables",
|
|
1324
1324
|
"zh_CN": ""
|
|
1325
|
+
},
|
|
1326
|
+
"commit_option_version_limit": {
|
|
1327
|
+
"en": "Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.",
|
|
1328
|
+
"zh_CN": "保留的最大版本数量。如果超过此限制,最旧的未发布版本将被删除。"
|
|
1329
|
+
},
|
|
1330
|
+
"deploy_option_version_limit": {
|
|
1331
|
+
"en": "Maximum number of versions to keep. Oldest unreleased versions will be deleted if exceeded.",
|
|
1332
|
+
"zh_CN": "保留的最大版本数量。如果超过此限制,最旧的未发布版本将被删除。"
|
|
1333
|
+
},
|
|
1334
|
+
"cleanup_versions_start": {
|
|
1335
|
+
"en": "Cleaning up ${toDelete.length} oldest unreleased versions (limit: ${limit})...",
|
|
1336
|
+
"zh_CN": "正在清理 ${count} 个最旧的未发布版本(限制数量:${limit})..."
|
|
1325
1337
|
}
|
|
1326
1338
|
}
|
package/dist/libs/api.js
CHANGED
|
@@ -11,8 +11,8 @@ import ESA, * as $ESA from '@alicloud/esa20240910';
|
|
|
11
11
|
import * as $OpenApi from '@alicloud/openapi-client';
|
|
12
12
|
import * as $Util from '@alicloud/tea-util';
|
|
13
13
|
import { getApiConfig } from '../utils/fileUtils/index.js';
|
|
14
|
-
import logger from './logger.js';
|
|
15
14
|
import { CLI_USER_AGENT } from './constants.js';
|
|
15
|
+
import logger from './logger.js';
|
|
16
16
|
class Client {
|
|
17
17
|
constructor() {
|
|
18
18
|
this.callApi = (action, request) => __awaiter(this, void 0, void 0, function* () {
|
package/dist/libs/apiService.js
CHANGED
|
@@ -12,8 +12,8 @@ import FormData from 'form-data';
|
|
|
12
12
|
import fetch from 'node-fetch';
|
|
13
13
|
import t from '../i18n/index.js';
|
|
14
14
|
import { getApiConfig } from '../utils/fileUtils/index.js';
|
|
15
|
-
import { Environment } from './interface.js';
|
|
16
15
|
import { CLI_USER_AGENT } from './constants.js';
|
|
16
|
+
import { Environment } from './interface.js';
|
|
17
17
|
export class ApiService {
|
|
18
18
|
constructor(cliConfig) {
|
|
19
19
|
var _a, _b;
|