UNPKG

@starship-ci/generator

Version:

Kubernetes manifest generator for Starship deployments

83 lines (82 loc) 3.63 kB
import * as fs from 'fs'; import * as yaml from 'js-yaml'; import * as path from 'path'; import { applyDefaults } from '../defaults'; import { ChainBuilder } from './chains'; import { ExplorerBuilder } from './explorer'; import { FrontendBuilder } from './frontend'; import { IngressBuilder } from './ingress'; import { MonitoringBuilder } from './monitoring'; import { RegistryBuilder } from './registry'; import { RelayerBuilder } from './relayers'; export class BuilderManager { config; constructor(config) { this.config = applyDefaults(config); } getManifestOutputPath(manifest, baseDir) { const labels = manifest.metadata?.labels || {}; const component = labels['app.kubernetes.io/component']; const partOf = labels['app.kubernetes.io/part-of']; const role = labels['app.kubernetes.io/role']; const kind = manifest.kind.toLowerCase(); const name = manifest.metadata.name; if (component === 'chain') { // Chain-specific resources: outputs/<chain-name>/<role>-<kind>.yaml // For StatefulSets, use the special chain-name label, otherwise use app.kubernetes.io/name const chainName = labels['starship.io/chain-name'] || labels['app.kubernetes.io/name']; const roleType = role || 'default'; // genesis, validator, setup-scripts, genesis-patch, ics-proposal return path.join(baseDir, chainName, `${roleType}-${kind}.yaml`); } else if (partOf === 'global') { // Global configmaps: outputs/configmaps/<clean-name>.yaml (remove redundant suffixes) const cleanName = name.replace(/-?configmap$/, ''); // Remove -configmap or configmap suffix return path.join(baseDir, 'configmaps', `${cleanName}.yaml`); } else if (component) { // Component resources: outputs/<component>/<clean-kind>.yaml (remove redundant prefixes) const cleanName = name.replace(new RegExp(`^${component}-?`), ''); // Remove component prefix const fileName = cleanName ? `${cleanName}-${kind}.yaml` : `${kind}.yaml`; return path.join(baseDir, component, fileName); } else { // Fallback: outputs/<name>-<kind>.yaml return path.join(baseDir, `${name}-${kind}.yaml`); } } writeManifestToPath(manifest, filePath) { // Ensure directory exists const dir = path.dirname(filePath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } // Write YAML file fs.writeFileSync(filePath, yaml.dump(manifest)); } writeManifests(manifests, outputDir) { if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } manifests.forEach((manifest) => { const outputPath = this.getManifestOutputPath(manifest, outputDir); this.writeManifestToPath(manifest, outputPath); }); } build(outputDir) { const builders = [ new ChainBuilder(this.config), new RegistryBuilder(this.config), new ExplorerBuilder(this.config), new FrontendBuilder(this.config), new RelayerBuilder(this.config), new IngressBuilder(this.config), new MonitoringBuilder(this.config) ]; let allManifests = []; builders.forEach((builder) => { allManifests = allManifests.concat(builder.generate()); }); this.writeManifests(allManifests, outputDir); return allManifests; } }