This commit is contained in:
Morten Olsen
2024-01-12 12:43:51 +01:00
commit 6d8e5bf955
109 changed files with 9246 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
import { EventEmitter } from 'eventemitter3';
import { run } from '@morten-olsen/mini-loader-runner';
import { Repos } from '../repos/repos.js';
import { LoggerEvent } from '../../../mini-loader/dist/esm/logger/logger.js';
import { ArtifactCreateEvent } from '../../../mini-loader/dist/esm/artifacts/artifacts.js';
import { Config } from '../config/config.js';
import { resolve } from 'path';
import { readFile } from 'fs/promises';
type RunnerInstanceEvents = {
completed: (args: { id: string }) => void;
};
type RunnerInstanceOptions = {
id: string;
loadId: string;
repos: Repos;
config: Config;
};
class RunnerInstance extends EventEmitter<RunnerInstanceEvents> {
#options: RunnerInstanceOptions;
constructor(options: RunnerInstanceOptions) {
super();
this.#options = options;
}
#addLog = async (event: LoggerEvent['payload']) => {
const { repos, id, loadId } = this.#options;
const { logs } = repos;
await logs.add({
runId: id,
loadId,
severity: event.severity,
message: event.message,
data: event.data,
});
};
#addArtifact = async (event: ArtifactCreateEvent['payload']) => {
const { repos, id, loadId } = this.#options;
const { artifacts } = repos;
await artifacts.add({
name: event.name,
runId: id,
loadId,
data: event.data,
});
};
public start = async () => {
const { repos, id, config } = this.#options;
const { runs, secrets } = repos;
try {
const { script: scriptHash, input } = await runs.getById(id);
const scriptLocation = resolve(config.files.location, 'script', `${scriptHash}.js`);
const script = await readFile(scriptLocation, 'utf-8');
const allSecrets = await secrets.getAll();
await runs.started(id);
const { promise, emitter } = await run({
script,
secrets: allSecrets,
input,
});
emitter.on('message', (message) => {
switch (message.type) {
case 'log': {
this.#addLog(message.payload);
break;
}
case 'artifact:create': {
this.#addArtifact(message.payload);
break;
}
}
});
await promise;
await runs.finished(id, { status: 'succeeded' });
} catch (error) {
let errorMessage = 'Unknown error';
if (error instanceof Error) {
errorMessage = error.message;
}
await runs.finished(id, { status: 'failed', error: errorMessage });
} finally {
this.emit('completed', { id });
}
};
}
export { RunnerInstance };

View File

@@ -0,0 +1,41 @@
import { Config } from '../config/config.js';
import { Repos } from '../repos/repos.js';
import { RunnerInstance } from './runner.instance.js';
type RunnerOptions = {
repos: Repos;
config: Config;
};
class Runner {
#options: RunnerOptions;
#instances: Map<string, RunnerInstance> = new Map();
constructor(options: RunnerOptions) {
this.#options = options;
const { repos } = options;
repos.runs.on('created', this.#start);
}
#start = async (args: { id: string; loadId: string }) => {
const { repos, config } = this.#options;
if (this.#instances.has(args.id)) {
return;
}
const instance = new RunnerInstance({
id: args.id,
loadId: args.loadId,
repos,
config,
});
instance.on('completed', () => {
this.#instances.delete(args.id);
});
this.#instances.set(args.id, instance);
await instance.start();
};
}
export { Runner };