diff options
Diffstat (limited to 'hooks')
-rw-r--r-- | hooks/Dockerfile | 8 | ||||
-rw-r--r-- | hooks/deno.json | 4 | ||||
-rwxr-xr-x | hooks/main.ts | 12 | ||||
-rwxr-xr-x | hooks/mod.ts | 2 | ||||
-rw-r--r-- | hooks/server/ci.ts | 56 | ||||
-rw-r--r-- | hooks/server/health.ts | 28 | ||||
-rw-r--r-- | hooks/server/job/activity.ts | 110 | ||||
-rw-r--r-- | hooks/server/job/mod.ts | 2 | ||||
-rw-r--r-- | hooks/server/job/queuer.ts | 88 | ||||
-rw-r--r-- | hooks/server/mod.ts | 3 |
10 files changed, 0 insertions, 313 deletions
diff --git a/hooks/Dockerfile b/hooks/Dockerfile deleted file mode 100644 index d1a6cb7..0000000 --- a/hooks/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -# -- <ci-hooks> -- -FROM oci.liz.coffee/emprespresso/ci-base:release AS hooks - -HEALTHCHECK --interval=10s --retries=3 --start-period=3s \ - CMD [ "curl --fail http://localhost:9000/health" ] - -CMD [ "/app/hooks/main.ts" ] -# -- </ci-hooks> -- diff --git a/hooks/deno.json b/hooks/deno.json deleted file mode 100644 index cdaf63f..0000000 --- a/hooks/deno.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "@emprespresso/ci-hooks", - "exports": "./mod.ts" -} diff --git a/hooks/main.ts b/hooks/main.ts deleted file mode 100755 index 21a3f3f..0000000 --- a/hooks/main.ts +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env -S deno run --allow-env --allow-net --allow-run - -import { CiHookServer } from "./server/mod.ts"; - -const server = new CiHookServer(); - -const SERVER_CONFIG = { - host: "0.0.0.0", - port: 9000, -}; - -Deno.serve(SERVER_CONFIG, (request: Request) => server.serve(request)); diff --git a/hooks/mod.ts b/hooks/mod.ts deleted file mode 100755 index cc15112..0000000 --- a/hooks/mod.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./server/mod.ts"; -export * from "./main.ts"; diff --git a/hooks/server/ci.ts b/hooks/server/ci.ts deleted file mode 100644 index 4f0d7ba..0000000 --- a/hooks/server/ci.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { - FourOhFourActivityImpl, - getRequiredEnv, - HealthCheckActivityImpl, - type HealthChecker, - type IFourOhFourActivity, - type IHealthCheckActivity, - type ITraceable, - PenguenoRequest, - type ServerTrace, - TraceUtil, -} from "@emprespresso/pengueno"; -import type { Job } from "@emprespresso/ci-model"; -import { - healthCheck as _healthCheck, - type IJobHookActivity, - type IJobQueuer, - JobHookActivityImpl, - LaminarJobQueuer, -} from "@emprespresso/ci-hooks"; - -export class CiHookServer { - constructor( - healthCheck: HealthChecker = _healthCheck, - jobQueuer: IJobQueuer<ITraceable<Job, ServerTrace>> = new LaminarJobQueuer( - getRequiredEnv("LAMINAR_URL").fold((err, val) => - err ? "https://ci.liz.coffee" : val, - ), - ), - private readonly healthCheckActivity: IHealthCheckActivity = new HealthCheckActivityImpl( - healthCheck, - ), - private readonly jobHookActivity: IJobHookActivity = new JobHookActivityImpl( - jobQueuer, - ), - private readonly fourOhFourActivity: IFourOhFourActivity = new FourOhFourActivityImpl(), - ) {} - - private route(req: ITraceable<PenguenoRequest, ServerTrace>) { - const url = new URL(req.get().url); - if (url.pathname === "/health") { - return this.healthCheckActivity.checkHealth(req); - } - if (url.pathname === "/job") { - return this.jobHookActivity.processHook(req); - } - return this.fourOhFourActivity.fourOhFour(req); - } - - public serve(req: Request): Promise<Response> { - return PenguenoRequest.from(req) - .bimap(TraceUtil.withClassTrace(this)) - .map(this.route) - .get(); - } -} diff --git a/hooks/server/health.ts b/hooks/server/health.ts deleted file mode 100644 index 1acc074..0000000 --- a/hooks/server/health.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { - getRequiredEnv, - getStdout, - type HealthChecker, - type HealthCheckInput, - HealthCheckOutput, - type IEither, - type ITraceable, - type ServerTrace, - TraceUtil, -} from "@emprespresso/pengueno"; - -export const healthCheck: HealthChecker = ( - input: ITraceable<HealthCheckInput, ServerTrace>, -): Promise<IEither<Error, HealthCheckOutput>> => - input - .bimap(TraceUtil.withFunctionTrace(healthCheck)) - .move(getRequiredEnv("LAMINAR_HOST")) - // ensure LAMINAR_HOST is propagated to getStdout for other procedures - .map((e) => e.get().moveRight(["laminarc", "show-jobs"])) - .map((i) => - i - .get() - .mapRight(i.move.apply) - .flatMapAsync(getStdout.apply) - .then((gotJobs) => gotJobs.moveRight(HealthCheckOutput.YAASSSLAYQUEEN)), - ) - .get(); diff --git a/hooks/server/job/activity.ts b/hooks/server/job/activity.ts deleted file mode 100644 index 173cedf..0000000 --- a/hooks/server/job/activity.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - Either, - ErrorSource, - type IActivity, - type IEither, - type ITraceable, - jsonModel, - JsonResponse, - LogLevel, - Metric, - PenguenoError, - type PenguenoRequest, - type ServerTrace, - TraceUtil, - validateExecutionEntries, -} from "@emprespresso/pengueno"; -import { isJob, type Job } from "@emprespresso/ci-model"; -import type { IJobQueuer } from "@emprespresso/ci-hooks"; - -const wellFormedJobMetric = Metric.fromName("Job.WellFormed"); - -const jobJsonTransformer = ( - j: ITraceable<unknown, ServerTrace>, -): IEither<PenguenoError, Job> => - j - .bimap(TraceUtil.withMetricTrace(wellFormedJobMetric)) - .map((tJson) => { - if (!isJob(tJson) || !validateExecutionEntries(tJson)) { - const err = "seems like a pwetty mawfomed job \\(-.-)/"; - tJson.trace.addTrace(LogLevel.WARN).trace(err); - return Either.left<PenguenoError, Job>(new PenguenoError(err, 400)); - } - return Either.right<PenguenoError, Job>(tJson); - }) - .peek((tJob) => - tJob.trace.trace( - tJob - .get() - .fold((err) => - err ? wellFormedJobMetric.failure : wellFormedJobMetric.success, - ), - ), - ) - .get(); - -export interface IJobHookActivity { - processHook: IActivity; -} - -const jobHookRequestMetric = Metric.fromName("JobHook.process"); -export class JobHookActivityImpl implements IJobHookActivity { - constructor( - private readonly queuer: IJobQueuer<ITraceable<Job, ServerTrace>>, - ) {} - - private trace(r: ITraceable<PenguenoRequest, ServerTrace>) { - return r - .bimap(TraceUtil.withClassTrace(this)) - .bimap(TraceUtil.withMetricTrace(jobHookRequestMetric)); - } - - public processHook(r: ITraceable<PenguenoRequest, ServerTrace>) { - return this.trace(r) - .map(jsonModel(jobJsonTransformer)) - .map(async (tEitherJobJson) => { - const eitherJob = await tEitherJobJson.get(); - return eitherJob.flatMapAsync(async (job) => { - const eitherQueued = await tEitherJobJson - .move(job) - .map(this.queuer.queue) - .get(); - return eitherQueued.mapLeft((e) => new PenguenoError(e.message, 500)); - }); - }) - .peek( - TraceUtil.promiseify((tJob) => - tJob - .get() - .fold( - (err: PenguenoError | undefined, _val: string | undefined) => { - if (!err) { - tJob.trace.trace(jobHookRequestMetric.success); - tJob.trace.trace( - `all queued up and weady to go :D !! ${_val}`, - ); - return; - } - tJob.trace.trace( - err.source === ErrorSource.SYSTEM - ? jobHookRequestMetric.failure - : jobHookRequestMetric.warn, - ); - tJob.trace.addTrace(err.source).trace(`${err}`); - }, - ), - ), - ) - .map( - TraceUtil.promiseify( - (tEitherQueuedJob) => - new JsonResponse(r, tEitherQueuedJob.get(), { - status: tEitherQueuedJob - .get() - .fold(({ status }, _val) => (_val ? 200 : status)), - }), - ), - ) - .get(); - } -} diff --git a/hooks/server/job/mod.ts b/hooks/server/job/mod.ts deleted file mode 100644 index 6b4ae85..0000000 --- a/hooks/server/job/mod.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./activity.ts"; -export * from "./queuer.ts"; diff --git a/hooks/server/job/queuer.ts b/hooks/server/job/queuer.ts deleted file mode 100644 index d30de22..0000000 --- a/hooks/server/job/queuer.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { - getStdout, - type IEither, - type ITraceable, - LogLevel, - type Mapper, - memoize, - Metric, - type ServerTrace, - TraceUtil, -} from "@emprespresso/pengueno"; -import type { Job } from "@emprespresso/ci-model"; - -type QueuePosition = string; -export class QueueError extends Error {} -export interface IJobQueuer<TJob> { - queue: Mapper<TJob, Promise<IEither<QueueError, QueuePosition>>>; -} - -export class LaminarJobQueuer - implements IJobQueuer<ITraceable<Job, ServerTrace>> -{ - constructor(private readonly queuePositionPrefix: string) {} - - private static GetJobTypeTrace = (jobType: string) => - `LaminarJobQueue.Queue.${jobType}`; - private static JobTypeMetrics = memoize((jobType: string) => - Metric.fromName(LaminarJobQueuer.GetJobTypeTrace(jobType)), - ); - - public queue(j: ITraceable<Job, ServerTrace>) { - const { type: jobType } = j.get(); - const trace = LaminarJobQueuer.GetJobTypeTrace(jobType); - const metric = LaminarJobQueuer.JobTypeMetrics(trace); - - return j - .bimap(TraceUtil.withTrace(trace)) - .bimap(TraceUtil.withMetricTrace(metric)) - .map((j) => { - const { type: jobType, arguments: args } = j.get(); - const laminarCommand = [ - "laminarc", - "queue", - jobType, - ...Object.entries(args).map(([key, val]) => `"${key}"="${val}"`), - ]; - return laminarCommand; - }) - .peek((c) => - c.trace.trace( - `im so excited to see how this queue job will end!! (>ᴗ<): ${c - .get() - .toString()}`, - ), - ) - .map(getStdout) - .peek( - TraceUtil.promiseify((q) => - q.trace.trace( - q - .get() - .fold((err, _val) => (err ? metric.failure : metric.success)), - ), - ), - ) - .map( - TraceUtil.promiseify((q) => - q - .get() - .mapRight((stdout) => { - q.trace.addTrace(LogLevel.DEBUG).trace(`stdout ${stdout}`); - const [jobName, jobId] = stdout.split(":"); - const jobUrl = `${this.queuePositionPrefix}/jobs/${jobName}/${jobId}`; - - q.trace.trace( - `all queued up and weady to go~ (˘ω˘) => ${jobUrl}`, - ); - return jobUrl; - }) - .mapLeft((err) => { - q.trace.addTrace(LogLevel.ERROR).trace(err.toString()); - return err; - }), - ), - ) - .get(); - } -} diff --git a/hooks/server/mod.ts b/hooks/server/mod.ts deleted file mode 100644 index 0a520f9..0000000 --- a/hooks/server/mod.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./ci.ts"; -export * from "./health.ts"; -export * from "./job/mod.ts"; |