@cto.ai/ops-rc
Version:
💻 CTO.ai Ops - The CLI built for Teams 🚀
131 lines (130 loc) • 5.56 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const base_1 = tslib_1.__importStar(require("./../base"));
const CustomErrors_1 = require("./../errors/CustomErrors");
const env_1 = require("./../constants/env");
const utils_1 = require("./../utils");
class Start extends base_1.default {
constructor() {
super(...arguments);
this.customParse = (options, argv) => {
const { args, flags } = require('@oclif/parser').parse(argv, Object.assign(Object.assign({}, options), { context: this }));
if (!args.nameOrPath && !flags.help) {
throw new CustomErrors_1.MissingRequiredArgument('ops run');
}
if (!args.nameOrPath)
this._help();
return { args, flags, opParams: argv.slice(1) };
};
this.sendAnalytics = (parsedArgs, config) => {
this.services.analytics.track('Ops CLI Start', {
username: config.user.username,
email: config.user.email,
team: config.team.name,
image: `${env_1.OPS_REGISTRY_HOST}/${parsedArgs.args.nameOrPath}`,
runtime: 'CLI',
cliVersion: this.config.version,
}, config);
};
this.getPublishedOps = async (config) => {
try {
const { data: opResults } = await this.services.api.find(`/private/teams/${config.team.name}/ops`, {
headers: {
Authorization: this.accessToken,
},
});
return opResults;
}
catch (err) {
this.debug('%0', err);
throw new CustomErrors_1.APIError(err);
}
};
this.isOpAvailable = (name, version, ops) => {
return ops.some(op => {
return version
? name === op.name && version === op.version
: name === op.name;
});
};
this.startRemoteOp = async (name, config) => {
try {
// TODO: This will ALWAYS start the latest version
const { data: runDetails } = await this.services.api.create(`/private/workflows/trigger`, {
teamID: config.team.id,
userID: config.user.id,
workflowName: name,
}, {
headers: {
Authorization: this.accessToken,
},
});
// We will only have a non-null serviceUrl if we've started a service
if (runDetails.serviceUrl) {
let startMessage = `Success, service ${name} has been started.\nView the logs here: ${env_1.OPS_API_HOST}logs/${runDetails.runId}\nAccess your service at ${runDetails.serviceUrl}`;
if (runDetails.usageWarning) {
startMessage = startMessage + `\n\n${runDetails.usageWarning}`;
}
this.log(this.ux.colors.whiteBright(startMessage));
}
else {
this.log(this.ux.colors.whiteBright(`Success, pipeline ${name} has been started.\nView the logs here: ${env_1.OPS_API_HOST}logs/${runDetails.runId}`));
}
}
catch (err) {
this.debug('%0', err);
let userErrMsg = `❗ Sorry, we encountered an error trying to start the pipeline ${name}.`;
// 403 - Tier limits reached, display error message
if (err.error[0].code === 403) {
userErrMsg = `❗ Sorry, we encountered an error trying to start the pipeline ${name}: ${err.error[0].message}`;
}
this.log(this.ux.colors.whiteBright(userErrMsg));
throw new CustomErrors_1.APIError(err);
}
};
}
async run() {
const config = await this.isLoggedIn();
try {
const parsedArgs = this.customParse(Start, this.argv);
const { name, version } = utils_1.splitNameAndVersion(parsedArgs.args.nameOrPath);
const ops = await this.getPublishedOps(config);
if (!ops || ops.length < 1) {
this.log(this.ux.colors.whiteBright('❗ Sorry, It appears you have no Ops Or Pipelines published'));
process.exit(1);
}
if (!this.isOpAvailable(name, version, ops)) {
this.log(this.ux.colors.whiteBright(`❗ Sorry, we cannot find the pipeline: ${parsedArgs.args.nameOrPath}. Please publish the pipeline before attempting to start it.`));
process.exit(1);
}
await this.startRemoteOp(name, config);
this.sendAnalytics(parsedArgs, config);
}
catch (err) {
this.debug('%O', err);
this.config.runHook('error', {
err,
accessToken: config.tokens.accessToken,
});
}
}
}
exports.default = Start;
Start.description = 'Run a Pipeline remotely in the Ops Cloud.';
Start.flags = {
help: base_1.flags.boolean({
char: 'h',
description: 'show CLI help',
}),
};
Start.strict = false;
Start.args = [
{
name: 'nameOrPath',
description: 'Name or path of the Op you want to run.',
parse: (input) => {
return input.toLowerCase();
},
},
];