gitlab-ci-local
Version:
Tired of pushing to test your .gitlab-ci.yml?
107 lines • 19.5 kB
JavaScript
import * as yaml from "js-yaml";
import chalk from "chalk";
import path from "path";
import fs from "fs-extra";
import yargs from "yargs";
import { Commander } from "./commander.js";
import { Parser } from "./parser.js";
import * as state from "./state.js";
import prettyHrtime from "pretty-hrtime";
import { cleanupJobResources } from "./job.js";
import { Utils } from "./utils.js";
import { Argv } from "./argv.js";
import assert from "assert";
const generateGitIgnore = (cwd, stateDir) => {
const gitIgnoreFilePath = `${cwd}/${stateDir}/.gitignore`;
const gitIgnoreContent = "*\n!.gitignore\n";
if (!fs.existsSync(gitIgnoreFilePath)) {
fs.outputFileSync(gitIgnoreFilePath, gitIgnoreContent);
}
};
export async function handler(args, writeStreams, jobs = [], childPipelineDepth = 0) {
assert(childPipelineDepth <= 2, "Parent and child pipelines have a maximum depth of two levels of child pipelines.");
const argv = await Argv.build({ ...args, childPipelineDepth: childPipelineDepth }, writeStreams);
const cwd = argv.cwd;
const stateDir = argv.stateDir;
const file = argv.file;
let parser = null;
if (argv.completion) {
yargs(process.argv.slice(2)).showCompletionScript();
return [];
}
assert(fs.existsSync(`${cwd}/${file}`), `${path.resolve(cwd)}/${file} could not be found`);
if (argv.preview) {
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs, false);
const gitlabData = parser.gitlabData;
for (const jobName of Object.keys(gitlabData)) {
if (jobName === "stages") {
continue;
}
if (jobName.startsWith(".") || ["include", "after_script", "before_script", "default"].includes(jobName)) {
// Remove since these are redundant info which are already "extended" in the jobs
delete gitlabData[jobName];
}
}
writeStreams.stdout(`---\n${yaml.dump(gitlabData, { lineWidth: 160 })}`);
}
else if (argv.list || argv.listAll) {
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
Commander.runList(parser, writeStreams, argv.listAll);
}
else if (argv.validateDependencyChain) {
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
Commander.validateDependencyChain(parser);
writeStreams.stdout(chalk `{green ✓ All job dependencies are valid}\n`);
}
else if (argv.listJson) {
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
Commander.runJson(parser, writeStreams);
}
else if (argv.listCsv || argv.listCsvAll) {
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
Commander.runCsv(parser, writeStreams, argv.listCsvAll);
}
else if (argv.job.length > 0) {
assert(argv.stage === null, "You cannot use --stage when starting individual jobs");
generateGitIgnore(cwd, stateDir);
const time = process.hrtime();
if (argv.needs || argv.onlyNeeds) {
await state.incrementPipelineIid(cwd, stateDir);
}
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Commander.runJobs(argv, parser, writeStreams);
if (argv.needs || argv.onlyNeeds) {
writeStreams.stderr(chalk `{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
}
}
else if (argv.stage) {
generateGitIgnore(cwd, stateDir);
const time = process.hrtime();
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Commander.runJobsInStage(argv, parser, writeStreams);
writeStreams.stderr(chalk `{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
}
else {
generateGitIgnore(cwd, stateDir);
const time = process.hrtime();
await state.incrementPipelineIid(cwd, stateDir);
const pipelineIid = await state.getPipelineIid(cwd, stateDir);
parser = await Parser.create(argv, writeStreams, pipelineIid, jobs);
await Utils.rsyncTrackedFiles(cwd, stateDir, ".docker");
await Commander.runPipeline(argv, parser, writeStreams);
if (childPipelineDepth == 0)
writeStreams.stderr(chalk `{grey pipeline finished} in {grey ${prettyHrtime(process.hrtime(time))}}\n`);
}
writeStreams.flush();
return cleanupJobResources(jobs);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLElBQUksTUFBTSxTQUFTLENBQUM7QUFDaEMsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUN4QixPQUFPLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDMUIsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sYUFBYSxDQUFDO0FBQ25DLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sWUFBWSxNQUFNLGVBQWUsQ0FBQztBQUV6QyxPQUFPLEVBQUMsbUJBQW1CLEVBQU0sTUFBTSxVQUFVLENBQUM7QUFDbEQsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLFlBQVksQ0FBQztBQUNqQyxPQUFPLEVBQUMsSUFBSSxFQUFDLE1BQU0sV0FBVyxDQUFDO0FBQy9CLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUU1QixNQUFNLGlCQUFpQixHQUFHLENBQUMsR0FBVyxFQUFFLFFBQWdCLEVBQUUsRUFBRTtJQUN4RCxNQUFNLGlCQUFpQixHQUFHLEdBQUcsR0FBRyxJQUFJLFFBQVEsYUFBYSxDQUFDO0lBQzFELE1BQU0sZ0JBQWdCLEdBQUcsa0JBQWtCLENBQUM7SUFDNUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO1FBQ3BDLEVBQUUsQ0FBQyxjQUFjLENBQUMsaUJBQWlCLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztJQUMzRCxDQUFDO0FBQ0wsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLEtBQUssVUFBVSxPQUFPLENBQUUsSUFBUyxFQUFFLFlBQTBCLEVBQUUs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cy15YW1sXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGZzIGZyb20gXCJmcy1leHRyYVwiO1xuaW1wb3J0IHlhcmdzIGZyb20gXCJ5YXJnc1wiO1xuaW1wb3J0IHtDb21tYW5kZXJ9IGZyb20gXCIuL2NvbW1hbmRlci5qc1wiO1xuaW1wb3J0IHtQYXJzZXJ9IGZyb20gXCIuL3BhcnNlci5qc1wiO1xuaW1wb3J0ICogYXMgc3RhdGUgZnJvbSBcIi4vc3RhdGUuanNcIjtcbmltcG9ydCBwcmV0dHlIcnRpbWUgZnJvbSBcInByZXR0eS1ocnRpbWVcIjtcbmltcG9ydCB7V3JpdGVTdHJlYW1zfSBmcm9tIFwiLi93cml0ZS1zdHJlYW1zLmpzXCI7XG5pbXBvcnQge2NsZWFudXBKb2JSZXNvdXJjZXMsIEpvYn0gZnJvbSBcIi4vam9iLmpzXCI7XG5pbXBvcnQge1V0aWxzfSBmcm9tIFwiLi91dGlscy5qc1wiO1xuaW1wb3J0IHtBcmd2fSBmcm9tIFwiLi9hcmd2LmpzXCI7XG5pbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcblxuY29uc3QgZ2VuZXJhdGVHaXRJZ25vcmUgPSAoY3dkOiBzdHJpbmcsIHN0YXRlRGlyOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCBnaXRJZ25vcmVGaWxlUGF0aCA9IGAke2N3ZH0vJHtzdGF0ZURpcn0vLmdpdGlnbm9yZWA7XG4gICAgY29uc3QgZ2l0SWdub3JlQ29udGVudCA9IFwiKlxcbiEuZ2l0aWdub3JlXFxuXCI7XG4gICAgaWYgKCFmcy5leGlzdHNTeW5jKGdpdElnbm9yZUZpbGVQYXRoKSkge1xuICAgICAgICBmcy5vdXRwdXRGaWxlU3luYyhnaXRJZ25vcmVGaWxlUGF0aCwgZ2l0SWdub3JlQ29udGVudCk7XG4gICAgfVxufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIgKGFyZ3M6IGFueSwgd3JpdGVTdHJlYW1zOiBXcml0ZVN0cmVhbXMsIGpvYnM6IEpvYltdID0gW10sIGNoaWxkUGlwZWxpbmVEZXB0aCA9IDApIHtcbiAgICBhc3NlcnQoY2hpbGRQaXBlbGluZURlcHRoIDw9IDIsIFwiUGFyZW50IGFuZCBjaGlsZCBwaXBlbGluZXMgaGF2ZSBhIG1heGltdW0gZGVwdGggb2YgdHdvIGxldmVscyBvZiBjaGlsZCBwaXBlbGluZXMuXCIpO1xuICAgIGNvbnN0IGFyZ3YgPSBhd2FpdCBBcmd2LmJ1aWxkKHsuLi5hcmdzLCBjaGlsZFBpcGVsaW5lRGVwdGg6IGNoaWxkUGlwZWxpbmVEZXB0aH0sIHdyaXRlU3RyZWFtcyk7XG4gICAgY29uc3QgY3dkID0gYXJndi5jd2Q7XG4gICAgY29uc3Qgc3RhdGVEaXIgPSBhcmd2LnN0YXRlRGlyO1xuICAgIGNvbnN0IGZpbGUgPSBhcmd2LmZpbGU7XG4gICAgbGV0IHBhcnNlcjogUGFyc2VyIHwgbnVsbCA9IG51bGw7XG5cbiAgICBpZiAoYXJndi5jb21wbGV0aW9uKSB7XG4gICAgICAgIHlhcmdzKHByb2Nlc3MuYXJndi5zbGljZSgyKSkuc2hvd0NvbXBsZXRpb25TY3JpcHQoKTtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGFzc2VydChmcy5leGlzdHNTeW5jKGAke2N3ZH0vJHtmaWxlfWApLCBgJHtwYXRoLnJlc29sdmUoY3dkKX0vJHtmaWxlfSBjb3VsZCBub3QgYmUgZm91bmRgKTtcblxuICAgIGlmIChhcmd2LnByZXZpZXcpIHtcbiAgICAgICAgY29uc3QgcGlwZWxpbmVJaWQgPSBhd2FpdCBzdGF0ZS5nZXRQaXBlbGluZUlpZChjd2QsIHN0YXRlRGlyKTtcbiAgICAgICAgcGFyc2VyID0gYXdhaXQgUGFyc2VyLmNyZWF0ZShhcmd2LCB3cml0ZVN0cmVhbXMsIHBpcGVsaW5lSWlkLCBqb2JzLCBmYWxzZSk7XG4gICAgICAgIGNvbnN0IGdpdGxhYkRhdGEgPSBwYXJzZXIuZ2l0bGFiRGF0YTtcbiAgICAgICAgZm9yIChjb25zdCBqb2JOYW1lIG9mIE9iamVjdC5rZXlzKGdpdGxhYkRhdGEpKSB7XG4gICAgICAgICAgICBpZiAoam9iTmFtZSA9PT0gXCJzdGFnZXNcIikge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGpvYk5hbWUuc3RhcnRzV2l0aChcIi5cIikgfHwgW1wiaW5jbHVkZVwiLCBcImFmdGVyX3NjcmlwdFwiLCBcImJlZm9yZV9zY3JpcHRcIiwgXCJkZWZhdWx0XCJdLmluY2x1ZGVzKGpvYk5hbWUpKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIHNpbmNlIHRoZXNlIGFyZSByZWR1bmRhbnQgaW5mbyB3aGljaCBhcmUgYWxyZWFkeSBcImV4dGVuZGVkXCIgaW4gdGhlIGpvYnNcbiAgICAgICAgICAgICAgICBkZWxldGUgZ2l0bGFiRGF0YVtqb2JOYW1lXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB3cml0ZVN0cmVhbXMuc3Rkb3V0KGAtLS1cXG4ke3lhbWwuZHVtcChnaXRsYWJEYXRhLCB7bGluZVdpZHRoOiAxNjB9KX1gKTtcbiAgICB9IGVsc2UgaWYgKGFyZ3YubGlzdCB8fCBhcmd2Lmxpc3RBbGwpIHtcbiAgICAgICAgY29uc3QgcGlwZWxpbmVJaWQgPSBhd2FpdCBzdGF0ZS5nZXRQaXBlbGluZUlpZChjd2QsIHN0YXRlRGlyKTtcbiAgICAgICAgcGFyc2VyID0gYXdhaXQgUGFyc2VyLmNyZWF0ZShhcmd2LCB3cml0ZVN0cmVhbXMsIHBpcGVsaW5lSWlkLCBqb2JzKTtcbiAgICAgICAgQ29tbWFuZGVyLnJ1bkxpc3QocGFyc2VyLCB3cml0ZVN0cmVhbXMsIGFyZ3YubGlzdEFsbCk7XG4gICAgfSBlbHNlIGlmIChhcmd2LnZhbGlkYXRlRGVwZW5kZW5jeUNoYWluKSB7XG4gICAgICAgIGNvbnN0IHBpcGVsaW5lSWlkID0gYXdhaXQgc3RhdGUuZ2V0UGlwZWxpbmVJaWQoY3dkLCBzdGF0ZURpcik7XG4gICAgICAgIHBhcnNlciA9IGF3YWl0IFBhcnNlci5jcmVhdGUoYXJndiwgd3JpdGVTdHJlYW1zLCBwaXBlbGluZUlpZCwgam9icyk7XG4gICAgICAgIENvbW1hbmRlci52YWxpZGF0ZURlcGVuZGVuY3lDaGFpbihwYXJzZXIpO1xuICAgICAgICB3cml0ZVN0cmVhbXMuc3Rkb3V0KGNoYWxrYHtncmVlbiDinJMgQWxsIGpvYiBkZXBlbmRlbmNpZXMgYXJlIHZhbGlkfVxcbmApO1xuICAgIH0gZWxzZSBpZiAoYXJndi5saXN0SnNvbikge1xuICAgICAgICBjb25zdCBwaXBlbGluZUlpZCA9IGF3YWl0IHN0YXRlLmdldFBpcGVsaW5lSWlkKGN3ZCwgc3RhdGVEaXIpO1xuICAgICAgICBwYXJzZXIgPSBhd2FpdCBQYXJzZXIuY3JlYXRlKGFyZ3YsIHdyaXRlU3RyZWFtcywgcGlwZWxpbmVJaWQsIGpvYnMpO1xuICAgICAgICBDb21tYW5kZXIucnVuSnNvbihwYXJzZXIsIHdyaXRlU3RyZWFtcyk7XG4gICAgfSBlbHNlIGlmIChhcmd2Lmxpc3RDc3YgfHwgYXJndi5saXN0Q3N2QWxsKSB7XG4gICAgICAgIGNvbnN0IHBpcGVsaW5lSWlkID0gYXdhaXQgc3RhdGUuZ2V0UGlwZWxpbmVJaWQoY3dkLCBzdGF0ZURpcik7XG4gICAgICAgIHBhcnNlciA9IGF3YWl0IFBhcnNlci5jcmVhdGUoYXJndiwgd3JpdGVTdHJlYW1zLCBwaXBlbGluZUlpZCwgam9icyk7XG4gICAgICAgIENvbW1hbmRlci5ydW5Dc3YocGFyc2VyLCB3cml0ZVN0cmVhbXMsIGFyZ3YubGlzdENzdkFsbCk7XG4gICAgfSBlbHNlIGlmIChhcmd2LmpvYi5sZW5ndGggPiAwKSB7XG4gICAgICAgIGFzc2VydChhcmd2LnN0YWdlID09PSBudWxsLCBcIllvdSBjYW5ub3QgdXNlIC0tc3RhZ2Ugd2hlbiBzdGFydGluZyBpbmRpdmlkdWFsIGpvYnNcIik7XG4gICAgICAgIGdlbmVyYXRlR2l0SWdub3JlKGN3ZCwgc3RhdGVEaXIpO1xuICAgICAgICBjb25zdCB0aW1lID0gcHJvY2Vzcy5ocnRpbWUoKTtcbiAgICAgICAgaWYgKGFyZ3YubmVlZHMgfHwgYXJndi5vbmx5TmVlZHMpIHtcbiAgICAgICAgICAgIGF3YWl0IHN0YXRlLmluY3JlbWVudFBpcGVsaW5lSWlkKGN3ZCwgc3RhdGVEaXIpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBpcGVsaW5lSWlkID0gYXdhaXQgc3RhdGUuZ2V0UGlwZWxpbmVJaWQoY3dkLCBzdGF0ZURpcik7XG4gICAgICAgIHBhcnNlciA9IGF3YWl0IFBhcnNlci5jcmVhdGUoYXJndiwgd3JpdGVTdHJlYW1zLCBwaXBlbGluZUlpZCwgam9icyk7XG4gICAgICAgIGF3YWl0IFV0aWxzLnJzeW5jVHJhY2tlZEZpbGVzKGN3ZCwgc3RhdGVEaXIsIFwiLmRvY2tlclwiKTtcbiAgICAgICAgYXdhaXQgQ29tbWFuZGVyLnJ1bkpvYnMoYXJndiwgcGFyc2VyLCB3cml0ZVN0cmVhbXMpO1xuICAgICAgICBpZiAoYXJndi5uZWVkcyB8fCBhcmd2Lm9ubHlOZWVkcykge1xuICAgICAgICAgICAgd3JpdGVTdHJlYW1zLnN0ZGVycihjaGFsa2B7Z3JleSBwaXBlbGluZSBmaW5pc2hlZH0gaW4ge2dyZXkgJHtwcmV0dHlIcnRpbWUocHJvY2Vzcy5ocnRpbWUodGltZSkpfX1cXG5gKTtcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYXJndi5zdGFnZSkge1xuICAgICAgICBnZW5lcmF0ZUdpdElnbm9yZShjd2QsIHN0YXRlRGlyKTtcbiAgICAgICAgY29uc3QgdGltZSA9IHByb2Nlc3MuaHJ0aW1lKCk7XG4gICAgICAgIGNvbnN0IHBpcGVsaW5lSWlkID0gYXdhaXQgc3RhdGUuZ2V0UGlwZWxpbmVJaWQoY3dkLCBzdGF0ZURpcik7XG4gICAgICAgIHBhcnNlciA9IGF3YWl0IFBhcnNlci5jcmVhdGUoYXJndiwgd3JpdGVTdHJlYW1zLCBwaXBlbGluZUlpZCwgam9icyk7XG4gICAgICAgIGF3YWl0IFV0aWxzLnJzeW5jVHJhY2tlZEZpbGVzKGN3ZCwgc3RhdGVEaXIsIFwiLmRvY2tlclwiKTtcbiAgICAgICAgYXdhaXQgQ29tbWFuZGVyLnJ1bkpvYnNJblN0YWdlKGFyZ3YsIHBhcnNlciwgd3JpdGVTdHJlYW1zKTtcbiAgICAgICAgd3JpdGVTdHJlYW1zLnN0ZGVycihjaGFsa2B7Z3JleSBwaXBlbGluZSBmaW5pc2hlZH0gaW4ge2dyZXkgJHtwcmV0dHlIcnRpbWUocHJvY2Vzcy5ocnRpbWUodGltZSkpfX1cXG5gKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICBnZW5lcmF0ZUdpdElnbm9yZShjd2QsIHN0YXRlRGlyKTtcbiAgICAgICAgY29uc3QgdGltZSA9IHByb2Nlc3MuaHJ0aW1lKCk7XG4gICAgICAgIGF3YWl0IHN0YXRlLmluY3JlbWVudFBpcGVsaW5lSWlkKGN3ZCwgc3RhdGVEaXIpO1xuICAgICAgICBjb25zdCBwaXBlbGluZUlpZCA9IGF3YWl0IHN0YXRlLmdldFBpcGVsaW5lSWlkKGN3ZCwgc3RhdGVEaXIpO1xuICAgICAgICBwYXJzZXIgPSBhd2FpdCBQYXJzZXIuY3JlYXRlKGFyZ3YsIHdyaXRlU3RyZWFtcywgcGlwZWxpbmVJaWQsIGpvYnMpO1xuICAgICAgICBhd2FpdCBVdGlscy5yc3luY1RyYWNrZWRGaWxlcyhjd2QsIHN0YXRlRGlyLCBcIi5kb2NrZXJcIik7XG4gICAgICAgIGF3YWl0IENvbW1hbmRlci5ydW5QaXBlbGluZShhcmd2LCBwYXJzZXIsIHdyaXRlU3RyZWFtcyk7XG4gICAgICAgIGlmIChjaGlsZFBpcGVsaW5lRGVwdGggPT0gMCkgd3JpdGVTdHJlYW1zLnN0ZGVycihjaGFsa2B7Z3JleSBwaXBlbGluZSBmaW5pc2hlZH0gaW4ge2dyZXkgJHtwcmV0dHlIcnRpbWUocHJvY2Vzcy5ocnRpbWUodGltZSkpfX1cXG5gKTtcbiAgICB9XG4gICAgd3JpdGVTdHJlYW1zLmZsdXNoKCk7XG5cbiAgICByZXR1cm4gY2xlYW51cEpvYlJlc291cmNlcyhqb2JzKTtcbn1cbiJdfQ==