feat: CISandbox v1.0.0 — Interactive CI Pipeline Debugger with Local Env Sync

This commit is contained in:
Bun Bun
2026-06-16 06:24:19 +00:00
commit af0d21c025
45 changed files with 4584 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
import { readFileSync } from 'fs';
import { resolve } from 'path';
import yaml from 'js-yaml';
export function parseWorkflow(filePath) {
const fullPath = resolve(filePath);
const content = readFileSync(fullPath, 'utf-8');
const parsed = yaml.load(content);
if (!parsed || typeof parsed !== 'object') {
throw new Error(`Invalid YAML in ${filePath}: not an object`);
}
if (!parsed.jobs || typeof parsed.jobs !== 'object') {
throw new Error(`Invalid workflow in ${filePath}: missing 'jobs' field`);
}
return parsed;
}
export function listJobs(workflow) {
return Object.entries(workflow.jobs).map(([name, job]) => ({ name, job }));
}
export function pickJob(workflow, jobName) {
const jobs = listJobs(workflow);
if (jobs.length === 0) {
throw new Error('Workflow has no jobs');
}
if (jobName) {
const found = jobs.find(j => j.name === jobName);
if (!found) {
throw new Error(`Job "${jobName}" not found. Available: ${jobs.map(j => j.name).join(', ')}`);
}
return found;
}
// Return first job if only one exists
if (jobs.length === 1) {
return jobs[0];
}
throw new Error(`Multiple jobs found: ${jobs.map(j => j.name).join(', ')}. Use --job to specify one.`);
}
export function normalizeRunsOn(runsOn) {
const mapping = {
'ubuntu-latest': 'node:20-slim',
'ubuntu-24.04': 'node:20-slim',
'ubuntu-22.04': 'node:20-slim',
'ubuntu-20.04': 'node:18-slim',
'node-latest': 'node:22-slim',
'node-20': 'node:20-slim',
'node-18': 'node:18-slim',
};
return mapping[runsOn] ?? runsOn;
}
//# sourceMappingURL=parser.js.map