@kie/act-js
Version:
nodejs wrapper for nektos/act
136 lines (135 loc) • 6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StepMocker = void 0;
const step_mocker_types_1 = require("../step-mocker/step-mocker.types");
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const yaml_1 = require("yaml");
class StepMocker {
constructor(workflowFile, cwd) {
this.workflowFile = workflowFile;
this.cwd = cwd;
}
async mock(mockSteps) {
const filePath = this.getWorkflowPath();
const workflow = await this.readWorkflowFile(filePath);
for (const jobId of Object.keys(mockSteps)) {
const stepsToAdd = [];
for (const mockStep of mockSteps[jobId]) {
const { step, stepIndex } = this.locateStep(workflow, jobId, mockStep);
if (step) {
if ((0, step_mocker_types_1.isStepIdentifierUsingBeforeOrAfter)(mockStep)) {
// need to adjust the step index if there were elements added previously
const adjustIndex = stepsToAdd.filter(s => s.stepIndex < stepIndex).length;
// we will only actually add the steps at the end so as to avoid indexing errors in subsequent add steps
stepsToAdd.push({ jobId, stepIndex: stepIndex + adjustIndex, mockStep });
}
else {
this.updateStep(workflow, jobId, stepIndex, mockStep);
}
}
else {
const { mockWith: _, ...stepQuery } = mockStep;
throw new Error(`Could not find step ${JSON.stringify(stepQuery)} in job ${jobId}\nin ${filePath}`);
}
}
stepsToAdd.forEach(s => this.addStep(workflow, s.jobId, s.stepIndex, s.mockStep));
}
return this.writeWorkflowFile(filePath, workflow);
}
addStep(workflow, jobId, stepIndex, mockStep) {
if (workflow.jobs[jobId]) {
let indexToInsertAt = stepIndex;
if ((0, step_mocker_types_1.isStepIdentifierUsingBefore)(mockStep)) {
indexToInsertAt = stepIndex <= 0 ? 0 : indexToInsertAt - 1;
}
else {
indexToInsertAt =
stepIndex >= workflow.jobs[jobId].steps.length - 1
? workflow.jobs[jobId].steps.length
: indexToInsertAt + 1;
}
workflow.jobs[jobId].steps.splice(indexToInsertAt, 0, { ...mockStep.mockWith });
}
}
updateStep(workflow, jobId, stepIndex, mockStep) {
if (workflow.jobs[jobId]) {
const oldStep = workflow.jobs[jobId].steps[stepIndex];
const newStep = typeof mockStep.mockWith === "string"
? {
...oldStep,
run: mockStep.mockWith,
uses: undefined,
}
: mockStep.mockWith;
const updatedStep = { ...oldStep, ...newStep };
for (const key of Object.keys(oldStep)) {
if (key === "env" || key === "with") {
updatedStep[key] = {
...oldStep[key],
...(newStep[key] ?? {}),
};
}
}
workflow.jobs[jobId].steps[stepIndex] = updatedStep;
}
}
locateStep(workflow, jobId, step) {
const index = workflow.jobs[jobId]?.steps.findIndex((s, index) => {
if ((0, step_mocker_types_1.isStepIdentifierUsingId)(step)) {
return step.id === s.id;
}
if ((0, step_mocker_types_1.isStepIdentifierUsingName)(step)) {
return step.name === s.name;
}
if ((0, step_mocker_types_1.isStepIdentifierUsingUses)(step)) {
return step.uses === s.uses;
}
if ((0, step_mocker_types_1.isStepIdentifierUsingRun)(step)) {
return step.run === s.run;
}
if ((0, step_mocker_types_1.isStepIdentifierUsingIndex)(step)) {
return step.index === index;
}
if ((0, step_mocker_types_1.isStepIdentifierUsingBefore)(step)) {
return typeof step.before === "string"
? [s.id, s.name, s.uses, s.run].includes(step.before)
: step.before === index;
}
if ((0, step_mocker_types_1.isStepIdentifierUsingAfter)(step)) {
return typeof step.after === "string"
? [s.id, s.name, s.uses, s.run].includes(step.after)
: step.after === index;
}
return false;
});
return {
stepIndex: index,
step: index > -1 ? workflow.jobs[jobId]?.steps[index] : undefined,
};
}
getWorkflowPath() {
if ((0, fs_1.existsSync)(path_1.default.join(this.cwd, this.workflowFile))) {
return path_1.default.join(this.cwd, this.workflowFile);
}
if (this.cwd.endsWith(".github")) {
return path_1.default.join(this.cwd, "workflows", this.workflowFile);
}
else if ((0, fs_1.existsSync)(path_1.default.join(this.cwd, ".github", "workflows", this.workflowFile))) {
return path_1.default.join(this.cwd, ".github", "workflows", this.workflowFile);
}
else {
throw new Error(`Could not locate ${this.workflowFile}`);
}
}
async readWorkflowFile(location) {
return (0, yaml_1.parse)((0, fs_1.readFileSync)(location, "utf8"));
}
async writeWorkflowFile(location, data) {
return (0, fs_1.writeFileSync)(location, (0, yaml_1.stringify)(data), "utf8");
}
}
exports.StepMocker = StepMocker;