terrac
Version:
A minimal private module registry for Terraform and OpenTofu
97 lines (96 loc) • 3.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const node_os_1 = require("node:os");
const fs_extra_1 = require("fs-extra");
const zip_a_folder_1 = require("zip-a-folder");
const Joi = require("joi");
const utils_1 = require("../utils");
const factory_1 = require("../backends/factory");
const errors_1 = require("../errors");
const requiredConfigSchema = Joi.object({
backend: utils_1.backendConfigSchema.required(),
module: utils_1.moduleConfigSchema.required(),
});
class Publish extends core_1.Command {
async run() {
const { flags } = await this.parse(Publish);
const workDir = flags['work-directory'];
const config = await (0, utils_1.loadConfig)(workDir, (0, utils_1.parseConfigOverwrites)(flags['overwrite-config']));
const module = config.module;
await (0, utils_1.validateConfig)(requiredConfigSchema, config);
const zipPath = `${(0, node_os_1.tmpdir)()}/${module.name}-${module.version}.zip`;
await (0, zip_a_folder_1.zip)(workDir, zipPath);
const backend = factory_1.BackendFactory.create(config.backend);
const name = module.name;
const version = module.version;
if ((await backend.exists(name, version)) && !flags.overwrite) {
throw new errors_1.ModuleAlreadyExistsError(name, version);
}
// always update latest
const versions = ['latest'];
if ((0, utils_1.isSemver)(version)) {
versions.push(...(0, utils_1.expandSemver)(version));
}
else {
versions.push(version);
}
for (const value of versions) {
// Do NOT assume the backend can support concurrent write
// eslint-disable-next-line no-await-in-loop
await backend.upload(name, value, zipPath);
}
const meta = await backend.getMeta(name);
const existingRelease = meta.releases.find(release => release.version === version);
const updatedTime = Date.now();
meta.updated = updatedTime;
if (flags.overwrite && existingRelease) {
existingRelease.updated = updatedTime;
}
else {
meta.version = version;
meta.releases.push({
version,
updated: updatedTime,
});
}
await backend.saveMeta(meta);
await (0, fs_extra_1.unlink)(zipPath);
const data = await Promise.all(versions.map(async (v) => {
return {
version: v,
url: await backend.getSourceUrl(name, v),
};
}));
this.log(`A new release (${version}) is published successfully. Here is a list of updated releases:` + node_os_1.EOL);
core_1.ux.table(data, {
version: {
header: 'Version',
},
url: {
header: 'Source URL',
},
});
}
}
exports.default = Publish;
Publish.description = 'Publish a terraform module.';
Publish.examples = [
'<%= config.bin %> <%= command.id %>',
'<%= config.bin %> <%= command.id %> --overwrite',
];
Publish.flags = {
overwrite: core_1.Flags.boolean({
summary: 'Overwrite a published version with a new package',
default: false,
}),
'overwrite-config': core_1.Flags.string({
summary: 'Overwrite terrac configuration',
multiple: true,
hidden: true,
}),
'work-directory': core_1.Flags.string({
summary: 'Root directory of the module project',
default: '.',
}),
};