@cto.ai/ops
Version:
š» CTO.ai - The CLI built for Teams š
124 lines (123 loc) ⢠6.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Publish = void 0;
const tslib_1 = require("tslib");
const cli_sdk_1 = require("@cto.ai/cli-sdk");
const debug_1 = tslib_1.__importDefault(require("debug"));
const json = tslib_1.__importStar(require("JSONStream"));
const through = tslib_1.__importStar(require("through2"));
const CustomErrors_1 = require("../errors/CustomErrors");
const get_docker_1 = tslib_1.__importDefault(require("../utils/get-docker"));
const opConfig_1 = require("./../constants/opConfig");
const env_1 = require("./../constants/env");
const debug = (0, debug_1.default)('ops:PublishService');
class Publish {
constructor() {
this.publishOpToAPI = async (op, platformVersion, teamName, accessToken, api) => {
try {
const res = await api.create(`/private/teams/${teamName}/ops`, Object.assign(Object.assign({}, op), { platformVersion, isGlueCode: false, isPublic: op.isPublic }), {
headers: {
Authorization: accessToken,
},
});
return res;
}
catch (err) {
debug('%O', err);
if (err.error[0].message === 'version is taken') {
throw new CustomErrors_1.VersionIsTaken();
}
throw new CustomErrors_1.CouldNotCreateOp(err.message);
}
};
this.publishOpToRegistry = async (apiOp, registryAuth, teamName, accessToken, api) => {
const imageUniqueId = `${registryAuth.projectFullName}/${apiOp.id.toLowerCase()}:${apiOp.version}`;
const imageName = `${registryAuth.projectFullName}/${apiOp.name}:${apiOp.version}`;
const self = this;
const docker = await (0, get_docker_1.default)(self, 'publish');
try {
if (!docker) {
throw new Error('Could not initialize Docker.');
}
// getImage always returns an image. Must listImages
const image = docker.getImage(imageName);
if (!image) {
throw new CustomErrors_1.DockerPublishNoImageFound(apiOp.name, teamName);
}
console.log(`š Creating release ${cli_sdk_1.ux.colors.callOutCyan(imageUniqueId)}... \n`);
const all = [];
const errors = [];
const seenChunks = {};
const parser = through.obj(function (chunk, _enc, cb) {
this.push(chunk.status);
if (chunk.errorDetail) {
debug(chunk.errorDetail);
errors.push(chunk.errorDetail.message);
}
else if (chunk.aux) {
console.log(`\nš ${cli_sdk_1.ux.colors.white('Publishing...')}\n`);
console.log(`${cli_sdk_1.ux.colors.green('>')} Tag: ${cli_sdk_1.ux.colors.multiBlue(chunk.aux.Tag)}`);
console.log(`${cli_sdk_1.ux.colors.green('>')} Size: ${cli_sdk_1.ux.colors.multiBlue(chunk.aux.Size)}`);
console.log(`${cli_sdk_1.ux.colors.green('>')} Digest: ${cli_sdk_1.ux.colors.multiBlue(chunk.aux.Digest)}\n`);
}
else if (chunk.id) {
const chunkString = `${chunk.status}: ${cli_sdk_1.ux.colors.white(chunk.id)}`;
if (!seenChunks[chunkString]) {
console.log(`${chunk.status}: ${cli_sdk_1.ux.colors.white(chunk.id)}`);
seenChunks[chunkString] = true;
}
}
cb();
});
const _pipe = parser.pipe;
parser.pipe = function (dest) {
return _pipe(dest);
};
await image.tag({ repo: imageUniqueId }).catch(err => {
throw new CustomErrors_1.ImageTagError(err);
});
const taggedImage = docker.getImage(imageUniqueId);
const stream = await taggedImage
.push({
tag: apiOp.version,
authconfig: registryAuth.authconfig,
})
.catch(err => {
throw new CustomErrors_1.ImageTagError(err);
});
if (stream) {
await new Promise(async function (resolve, reject) {
stream
.pipe(json.parse(null))
.pipe(parser)
.on('data', (d) => {
all.push(d);
})
.on('end', async () => {
if (errors.length) {
return reject(new CustomErrors_1.ImagePushError(errors[0]));
}
console.log(`\nš ${cli_sdk_1.ux.colors.callOutCyan(imageUniqueId)} has been published!`);
console.log(`š„ Visit your registry page here: ${cli_sdk_1.ux.url(`${env_1.OPS_API_HOST}registry/${teamName}/${apiOp.name}`, `<${env_1.OPS_API_HOST}registry/${teamName}/${apiOp.name}>`)}\n`);
resolve(undefined);
});
});
}
}
catch (err) {
// this api service call will always return an error because it tries to
// remove the record from the api database and the harbor registry but
// no record in the harbor registry will exist
await api
.remove(`/private/${(0, opConfig_1.getEndpointFromOpType)(apiOp.type)}`, apiOp.id, {
headers: { Authorization: accessToken },
})
.catch(error => {
debug('%O', error);
});
throw err;
}
};
}
}
exports.Publish = Publish;