esa-cli
Version:
A CLI for operating Alibaba Cloud ESA EdgeRoutine (Edge Functions).
209 lines (208 loc) • 10.4 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import chalk from 'chalk';
import { getProjectConfig, readEdgeRoutineFile } from '../../utils/fileUtils/index.js';
import { Environment, PublishType } from '../../libs/interface.js';
import logger from '../../libs/logger.js';
import { checkDirectory, checkIsLoginSuccess, getRoutineVersionList } from '../utils.js';
import { ApiService } from '../../libs/apiService.js';
import { createAndDeployVersion, displaySelectDeployType, promptSelectVersion, yesNoPromptAndExecute } from './helper.js';
import t from '../../i18n/index.js';
import prodBuild from '../commit/prodBuild.js';
import { exit } from 'process';
import path from 'path';
import { checkRoutineExist } from '../../utils/checkIsRoutineCreated.js';
import moment from 'moment';
const deploy = {
command: 'deploy [entry]',
builder: (yargs) => {
return yargs
.positional('entry', {
describe: t('dev_entry_describe').d('Entry file of the Routine'),
type: 'string',
demandOption: false
})
.option('quick', {
alias: 'q',
describe: t('deploy_quick_describe').d('Quick deploy the routine to production environment'),
type: 'boolean'
})
.option('version', {
alias: 'v',
describe: t('deploy_option_version').d('Version to deploy (skip interactive selection)'),
type: 'string'
})
.option('environment', {
alias: 'e',
describe: t('deploy_option_environment').d('Environment to deploy to: staging or production (skip interactive selection)'),
type: 'string',
choices: ['staging', 'production']
});
},
describe: `🚀 ${t('deploy_describe').d('Deploy your project')}`,
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
yield handleDeploy(argv);
exit();
})
};
export default deploy;
export function quickDeploy(entry, projectConfig) {
return __awaiter(this, void 0, void 0, function* () {
const server = yield ApiService.getInstance();
const entryFile = path.resolve(entry !== null && entry !== void 0 ? entry : '', 'src/index.js');
yield prodBuild(false, entryFile, entry);
const code = readEdgeRoutineFile(entry) || '';
const res = yield server.quickDeployRoutine({
name: projectConfig.name,
code: code
});
if (res) {
logger.success(t('quick_deploy_success').d('Your code has been successfully deployed'));
logger.log(`👉 ${t('quick_deploy_success_guide').d('Run this command to add domains')}: ${chalk.green('esa domain add <DOMAIN>')}`);
}
else {
logger.error(t('quick_deploy_failed').d('Quick deploy failed'));
throw Error(t('quick_deploy_failed').d('Quick deploy failed'));
}
});
}
export function handleDeploy(argv) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
if (!checkDirectory()) {
return;
}
const projectConfig = getProjectConfig();
if (!projectConfig)
return logger.notInProject();
const isSuccess = yield checkIsLoginSuccess();
if (!isSuccess)
return;
const server = yield ApiService.getInstance();
const entry = argv.entry;
yield checkRoutineExist(projectConfig.name, entry);
const req = { Name: projectConfig.name };
const routineDetail = yield server.getRoutine(req, false);
const versionList = yield getRoutineVersionList(projectConfig.name);
const customEntry = argv.entry;
const stagingVersion = (_b = (_a = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _a === void 0 ? void 0 : _a.Envs[1]) === null || _b === void 0 ? void 0 : _b.CodeVersion;
const productionVersion = (_d = (_c = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _c === void 0 ? void 0 : _c.Envs[0]) === null || _d === void 0 ? void 0 : _d.CodeVersion;
if (argv.quick) {
yield quickDeploy(customEntry, projectConfig);
exit(0);
}
if (versionList.length === 0) {
logger.log(t('no_formal_version_found').d('No formal version found, you need to create a version first.'));
yield handleOnlyUnstableVersionFound(projectConfig, customEntry);
}
else {
yield displayVersionList(versionList, stagingVersion, productionVersion);
let selectedVersion;
let selectedType;
// Check if version and environment are provided via command line arguments
if (argv.version && argv.environment) {
// Validate version exists
const versionExists = versionList.some((v) => v.codeVersion === argv.version);
if (!versionExists) {
logger.error(t('deploy_version_not_found').d(`Version '${argv.version}' not found`));
return;
}
selectedVersion = argv.version;
selectedType =
argv.environment === 'staging'
? PublishType.Staging
: PublishType.Production;
logger.log(chalk.bold(`${t('deploy_using_version').d('Using version')}: ${selectedVersion}`));
logger.log(chalk.bold(`${t('deploy_using_environment').d('Using environment')}: ${argv.environment}`));
}
else {
logger.log(chalk.bold(`${t('deploy_version_select').d('Select the version you want to publish')}:`));
selectedVersion = yield promptSelectVersion(versionList);
selectedType = yield displaySelectDeployType();
}
yield deploySelectedCodeVersion(projectConfig.name, selectedType, selectedVersion);
}
});
}
function handleNoVersionsFound(projectConfig, customEntry) {
return __awaiter(this, void 0, void 0, function* () {
logger.log(`😄 ${t('deploy_first_time').d("This is first time to deploy. Let's create a version first!")}`);
const created = yield yesNoPromptAndExecute(`📃 ${t('deploy_create_formal_version_ques').d('Do you want to create an unstable version now?')}`, () => createAndDeployVersion(projectConfig, true));
if (created) {
yield handleOnlyUnstableVersionFound(projectConfig);
}
});
}
function promptAndDeployVersion(projectConfig) {
return __awaiter(this, void 0, void 0, function* () {
const versionList = yield getRoutineVersionList(projectConfig.name);
yield displayVersionList(versionList);
logger.log(`📃 ${t('deploy_select_version').d("Select which version you'd like to deploy")}`);
const selectedVersion = yield promptSelectVersion(versionList);
const selectedType = yield displaySelectDeployType();
yield deploySelectedCodeVersion(projectConfig.name, selectedType, selectedVersion);
});
}
export function handleOnlyUnstableVersionFound(projectConfig, customEntry) {
return __awaiter(this, void 0, void 0, function* () {
const created = yield yesNoPromptAndExecute(`📃 ${t('deploy_create_formal_version_ques').d('Do you want to create a formal version to deploy on production environment?')}`, () => createAndDeployVersion(projectConfig));
if (created) {
yield promptAndDeployVersion(projectConfig);
}
});
}
export function deploySelectedCodeVersion(name, selectedType, version) {
return __awaiter(this, void 0, void 0, function* () {
const server = yield ApiService.getInstance();
const param = {
Name: name,
Env: selectedType === PublishType.Staging
? Environment.Staging
: Environment.Production
};
param.CodeVersion = version;
try {
const res = yield server.publishRoutineCodeVersion(param);
if (res) {
logger.success(t('deploy_success').d('Your code has been successfully deployed'));
logger.log(`👉 ${t('deploy_success_guide').d('Run this command to add domains')}: ${chalk.green('esa domain add <DOMAIN>')}`);
}
}
catch (e) {
console.error(e);
}
});
}
export function displayVersionList(versionList_1) {
return __awaiter(this, arguments, void 0, function* (versionList, stagingVersion = 'unstable', productionVersion = 'unstable') {
var _a;
logger.log(`${chalk.bgYellow('Active')} ${t('deploy_env_staging').d('Staging')}`);
logger.log(`${chalk.bgGreen('Active')} ${t('deploy_env_production').d('Production')}`);
const data = [];
for (let i = 0; i < versionList.length; i++) {
const version = versionList[i];
const createTime = moment(version.createTime).format('YYYY/MM/DD HH:mm:ss');
const tags = [
version.codeVersion === stagingVersion ? chalk.bgYellow('Active') : '',
version.codeVersion === productionVersion ? chalk.bgGreen('Active') : ''
];
data.push([
`${version.codeVersion} ${tags.join(' ')}`,
createTime,
(_a = version.codeDescription) !== null && _a !== void 0 ? _a : ''
]);
}
logger.table([
t('deploy_table_header_version').d('Version'),
t('deploy_table_header_created').d('Created'),
t('deploy_table_header_description').d('Description')
], data, [30, 25, 15]);
});
}