UNPKG

singularci

Version:

SingularCI is a DSL transpiler used to generate CI/CD configuration files for existing CI platforms

195 lines 8.84 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GitLabConfigGenerator = void 0; const yaml_1 = __importDefault(require("yaml")); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const tasks_1 = require("./tasks"); const typedi_1 = require("typedi"); const DSLParser_1 = __importDefault(require("./../../Parser/DSLParser")); const TaskEnum_1 = require("../../SemanticModel/Tasks/TaskEnum"); let GitLabConfigGenerator = class GitLabConfigGenerator { constructor(parser) { this.generateConfig = () => { if (!this.shouldGenerate()) return; this.pipeline = this.parser.parse(); this.buildSecrets(); this.buildTriggers(); this.buildStages(); this.buildJobs(); this.writeToFile(); }; this.writeToFile = () => { fs_1.default.writeFileSync(path_1.default.join(process.cwd(), ".gitlab-ci.yml"), yaml_1.default.stringify(this.configObject), "utf-8"); }; this.changeSecretsSyntax = (obj) => { if (typeof obj === 'object') { // iterating over the object using for..in for (const key in obj) { //checking if the current value is an object itself if (typeof obj[key] === 'object') { // if so then again calling the same function this.changeSecretsSyntax(obj[key]); } else { // else getting the value and replacing braces with empty spaces if (obj[key] !== undefined && isNaN(obj[key])) { const secrets = obj[key].match(/\$\{(secrets\.)[a-zA-Z][^{}]+\}/gm); if (secrets) { for (let i = 0; i < secrets.length; i++) { const newValue = obj[key].replace(secrets[i], "$" + secrets[i].replace("${secrets.", "").replace("}", "") + ""); obj[key] = newValue; } } } } } } return obj; }; this.buildNeeds = (needs) => { const needsArray = []; for (let k = 0; k < needs.length; k++) { const needsName = needs[k]; const neededStage = this.pipeline.getStages().find(stage => stage.getName() === needsName); if (neededStage) { const jobs = neededStage.getJobs(); const jobAmount = jobs.length; for (let l = 0; l < jobAmount; l++) { const jobName = `${neededStage.getName()}-${this.sanitizeJobName(jobs[l].getName())}`; needsArray.push(jobName); } } } return needsArray; }; this.buildBeforeScript = (tasks) => { const beforeScriptArray = []; for (const task of tasks) { if (task.getType() === TaskEnum_1.TaskType.Checkout) { beforeScriptArray.push(...(0, tasks_1.generateCheckoutTask)(task)); } } return beforeScriptArray; }; this.buildTasks = (stageKey, jobObject, tasks) => { const tasksArray = []; for (const task of tasks) { if (task.getType() === TaskEnum_1.TaskType.BuildDockerImage) { jobObject[stageKey].image = "docker:latest"; jobObject[stageKey].services = (0, tasks_1.dockerSetup)(); tasksArray.push(...(0, tasks_1.generateBuildDockerImageTask)(task)); } if (task.getType() === TaskEnum_1.TaskType.Run) { tasksArray.push(...(0, tasks_1.generateRunTask)(task)); } } return tasksArray; }; this.sanitizeJobName = (name) => { return name.replaceAll(' ', '_'); }; this.parser = parser; this.pipeline = this.parser.parse(); this.configObject = {}; } shouldGenerate() { return this.pipeline != undefined && this.pipeline.getPlatformTargets().getTargets().includes('GitLab'); } buildStages() { const stagesArray = []; for (let i = 0; i < this.pipeline.getStages().length; i++) { const stage = this.pipeline.getStages()[i]; stagesArray.push(stage.getName()); } this.configObject.stages = stagesArray; } buildTriggers() { const isPushSet = this.pipeline.getTrigger().getTypes().includes('push'); const isPullRequestSet = this.pipeline.getTrigger().getTypes().includes('pull_request'); const rulesObject = []; const triggerObject = { workflow: { rules: rulesObject } }; if (isPushSet) { triggerObject.workflow.rules.push({ if: '$CI_PIPELINE_SOURCE == "push"', when: 'always' }); } if (isPullRequestSet) { triggerObject.workflow.rules.push({ if: '$CI_PIPELINE_SOURCE == "merge_request_event"', when: 'always' }); } Object.assign(this.configObject, triggerObject); } buildSecrets() { this.pipeline = this.changeSecretsSyntax(this.pipeline); } buildJobs() { const stages = this.pipeline.getStages(); for (let i = 0; i < stages.length; i++) { const jobs = stages[i].getJobs(); for (let j = 0; j < jobs.length; j++) { const tasks = jobs[j].getTasks(); const needs = stages[i].getNeeds(); const stage = stages[i]; const stageKey = `${stage.getName()}-${this.sanitizeJobName(jobs[j].getName())}`; const tasksArray = []; const needsArray = []; const beforeScriptArray = []; const jobObject = { [stageKey]: { image: this.getSelectedImage(this.pipeline.getStages()[i]), stage: this.pipeline.getStages()[i].getName(), needs: needsArray, before_script: beforeScriptArray, script: tasksArray, } }; beforeScriptArray.push(...this.buildBeforeScript(tasks)); tasksArray.push(...this.buildTasks(stageKey, jobObject, tasks)); needsArray.push(...this.buildNeeds(needs)); Object.assign(this.configObject, jobObject); } } } getSelectedImage(stage) { const runsOn = stage.getRunsOn(); switch (runsOn) { case "ubuntu-latest": return "ubuntu:latest"; case "windows-latest": return "mcr.microsoft.com/windows:20H2"; default: return runsOn; } } }; GitLabConfigGenerator = __decorate([ (0, typedi_1.Service)({ id: "GitLabConfigGenerator" }), __param(0, (0, typedi_1.Inject)("dslparser")), __metadata("design:paramtypes", [DSLParser_1.default]) ], GitLabConfigGenerator); exports.GitLabConfigGenerator = GitLabConfigGenerator; //# sourceMappingURL=index.js.map