summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth <me@liz.coffee>2025-06-02 11:14:52 -0700
committerElizabeth <me@liz.coffee>2025-06-02 11:14:52 -0700
commit373d9ec700c0097a22cf665a8e33cf48998d1dc2 (patch)
tree71297ac69177037929e1bfb00b8c71038058acd5
parent646c5eb11d3b9240f8434163d103a117d30c88c7 (diff)
downloadci-373d9ec700c0097a22cf665a8e33cf48998d1dc2.tar.gz
ci-373d9ec700c0097a22cf665a8e33cf48998d1dc2.zip
Minor things
-rw-r--r--.ci/ci.ts2
-rw-r--r--.zed/settings.json4
-rw-r--r--Dockerfile4
-rw-r--r--deno.json3
-rw-r--r--hooks/Dockerfile8
-rw-r--r--hooks/deno.json4
-rwxr-xr-xhooks/main.ts12
-rwxr-xr-xhooks/mod.ts2
-rw-r--r--hooks/server/job/mod.ts2
-rw-r--r--hooks/server/job/queuer.ts88
-rw-r--r--hooks/server/mod.ts3
-rwxr-xr-xmod.ts31
-rw-r--r--model/deno.json2
-rw-r--r--model/pipeline.ts2
-rw-r--r--server/Dockerfile8
-rw-r--r--server/ci.ts (renamed from hooks/server/ci.ts)8
-rw-r--r--server/deno.json4
-rw-r--r--server/health.ts (renamed from hooks/server/health.ts)0
-rw-r--r--server/job.ts (renamed from hooks/server/job/activity.ts)89
-rw-r--r--server/mod.ts16
-rw-r--r--u/deno.json3
-rw-r--r--u/fn/either.ts2
-rw-r--r--u/process/argv.ts65
-rw-r--r--u/process/mod.ts1
-rw-r--r--u/server/activity/fourohfour.ts12
-rw-r--r--u/server/request.ts9
-rw-r--r--worker/Dockerfile10
-rw-r--r--worker/deno.json2
-rw-r--r--worker/executor.ts (renamed from worker/executor/pipeline.ts)51
-rw-r--r--worker/executor/job.ts42
-rw-r--r--worker/executor/mod.ts2
-rw-r--r--worker/jobs/ci_pipeline.run8
-rw-r--r--worker/mod.ts4
-rwxr-xr-xworker/scripts/ansible_playbook4
-rwxr-xr-xworker/scripts/build_docker_image10
-rw-r--r--worker/secret.ts (renamed from worker/secret/bitwarden.ts)28
-rw-r--r--worker/secret/ivault.ts24
-rw-r--r--worker/secret/mod.ts2
38 files changed, 327 insertions, 244 deletions
diff --git a/.ci/ci.ts b/.ci/ci.ts
index 0b8e124..d6f0bfa 100644
--- a/.ci/ci.ts
+++ b/.ci/ci.ts
@@ -5,7 +5,7 @@ import {
BuildDockerImageJob,
DefaultGitHookPipelineBuilder,
FetchCodeJob,
-} from "@emprespresso/ci-model";
+} from "@emprespresso/ci_model";
const REGISTRY = "oci.liz.coffee";
const NAMESPACE = "emprespresso";
diff --git a/.zed/settings.json b/.zed/settings.json
index 5d2dc7a..cf1756f 100644
--- a/.zed/settings.json
+++ b/.zed/settings.json
@@ -10,11 +10,11 @@
},
"languages": {
"TypeScript": {
- "language_servers": ["deno"],
+ "language_servers": ["deno", "!typescript-language-server"],
"formatter": "prettier"
},
"TSX": {
- "language_servers": ["deno"],
+ "language_servers": ["deno", "!typescript-language-server"],
"formatter": "prettier"
}
}
diff --git a/Dockerfile b/Dockerfile
index 9c1ba66..6aa29f2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# -- <laminar_bin> --
-FROM debian:stable-slim AS laminar-bin
+FROM debian:stable-slim AS laminar_bin
ENV DEBIAN_FRONTEND=noninteractive
RUN useradd --system --home-dir /var/lib/laminar --no-user-group --groups users --uid 100 laminar
RUN rm -rf /etc/cron.d/e2scrub_all
@@ -26,7 +26,7 @@ RUN cmake -B /opt/laminar/build -S /opt/laminar/src -G Ninja \
# -- </laminar_bin> --
# -- <ci_base> --
-FROM denoland/deno:debian AS ci-base
+FROM denoland/deno:debian AS ci_base
RUN apt-get update -yqq && apt-get install -yqq libcapnp-0.9.2 \
libsqlite3-0 zlib1g curl bash
diff --git a/deno.json b/deno.json
index 50ebd48..adeae7b 100644
--- a/deno.json
+++ b/deno.json
@@ -1,3 +1,4 @@
{
- "workspace": ["./model", "./u", "./worker", "./hooks"]
+ "package": "@emprespresso/ci",
+ "workspace": ["./*"]
}
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/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";
diff --git a/mod.ts b/mod.ts
new file mode 100755
index 0000000..81a2bc2
--- /dev/null
+++ b/mod.ts
@@ -0,0 +1,31 @@
+#!/usr/bin/env -S deno run --allow-env --allow-net
+
+import { argv } from "@emprespresso/pengueno";
+import { runServer } from "@emprespresso/ci_server";
+
+const main = (_argv = Deno.args) => {
+ const defaults = {
+ "--port": "9000",
+ "--host": "0.0.0.0",
+ };
+ const _args = argv(["--run-server", "--port", "--host"], defaults, _argv);
+ const args = _args.fold((err, args) => {
+ if (!args || err) throw err;
+ return {
+ server_mode: "--run-server" in args,
+ port: parseInt(args["--port"]),
+ host: args["--host"],
+ };
+ });
+
+ const promises: Array<Promise<void>> = [];
+ if (args.server_mode) {
+ promises.push(runServer(args.port, args.host));
+ }
+
+ return Promise.all(promises);
+};
+
+if (import.meta.main) {
+ await main();
+}
diff --git a/model/deno.json b/model/deno.json
index afd9f22..5f5dacf 100644
--- a/model/deno.json
+++ b/model/deno.json
@@ -1,5 +1,5 @@
{
- "name": "@emprespresso/ci-model",
+ "name": "@emprespresso/ci_model",
"version": "0.1.0",
"exports": "./mod.ts"
}
diff --git a/model/pipeline.ts b/model/pipeline.ts
index d7b6435..edc8337 100644
--- a/model/pipeline.ts
+++ b/model/pipeline.ts
@@ -1,5 +1,5 @@
import { Either, type IEither, isObject } from "@emprespresso/pengueno";
-import { type FetchCodeJob, isJob, type Job } from "@emprespresso/ci-model";
+import { type FetchCodeJob, isJob, type Job } from "@emprespresso/ci_model";
export interface PipelineStage {
readonly parallelJobs: Array<Job>;
diff --git a/server/Dockerfile b/server/Dockerfile
new file mode 100644
index 0000000..c66e1b1
--- /dev/null
+++ b/server/Dockerfile
@@ -0,0 +1,8 @@
+# -- <ci_server> --
+FROM oci.liz.coffee/emprespresso/ci_base:release AS server
+
+HEALTHCHECK --interval=10s --retries=3 --start-period=3s \
+ CMD [ "curl --fail http://localhost:9000/health" ]
+
+CMD [ "/app/mod.ts --server --port 9000" ]
+# -- </ci_server> --
diff --git a/hooks/server/ci.ts b/server/ci.ts
index 4f0d7ba..e1a9ca7 100644
--- a/hooks/server/ci.ts
+++ b/server/ci.ts
@@ -10,21 +10,21 @@ import {
type ServerTrace,
TraceUtil,
} from "@emprespresso/pengueno";
-import type { Job } from "@emprespresso/ci-model";
+import type { Job } from "@emprespresso/ci_model";
import {
healthCheck as _healthCheck,
type IJobHookActivity,
type IJobQueuer,
JobHookActivityImpl,
LaminarJobQueuer,
-} from "@emprespresso/ci-hooks";
+} from "@emprespresso/ci_server";
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,
+ err ? "https://ci.liz.coffee" : val!,
),
),
private readonly healthCheckActivity: IHealthCheckActivity = new HealthCheckActivityImpl(
@@ -50,7 +50,7 @@ export class CiHookServer {
public serve(req: Request): Promise<Response> {
return PenguenoRequest.from(req)
.bimap(TraceUtil.withClassTrace(this))
- .map(this.route)
+ .map((req) => this.route(req))
.get();
}
}
diff --git a/server/deno.json b/server/deno.json
new file mode 100644
index 0000000..c86c9a7
--- /dev/null
+++ b/server/deno.json
@@ -0,0 +1,4 @@
+{
+ "name": "@emprespresso/ci_server",
+ "exports": "./mod.ts"
+}
diff --git a/hooks/server/health.ts b/server/health.ts
index 1acc074..1acc074 100644
--- a/hooks/server/health.ts
+++ b/server/health.ts
diff --git a/hooks/server/job/activity.ts b/server/job.ts
index 173cedf..62582d6 100644
--- a/hooks/server/job/activity.ts
+++ b/server/job.ts
@@ -1,4 +1,7 @@
import {
+ getStdout,
+ type Mapper,
+ memoize,
Either,
ErrorSource,
type IActivity,
@@ -14,9 +17,9 @@ import {
TraceUtil,
validateExecutionEntries,
} from "@emprespresso/pengueno";
-import { isJob, type Job } from "@emprespresso/ci-model";
-import type { IJobQueuer } from "@emprespresso/ci-hooks";
+import { isJob, type Job } from "@emprespresso/ci_model";
+// -- <job.hook> --
const wellFormedJobMetric = Metric.fromName("Job.WellFormed");
const jobJsonTransformer = (
@@ -101,10 +104,90 @@ export class JobHookActivityImpl implements IJobHookActivity {
new JsonResponse(r, tEitherQueuedJob.get(), {
status: tEitherQueuedJob
.get()
- .fold(({ status }, _val) => (_val ? 200 : status)),
+ .fold((err, _val) => (_val ? 200 : err?.status ?? 500)),
}),
),
)
.get();
}
}
+
+// -- </job.hook> --
+
+// -- <job.queuer> --
+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();
+ }
+}
+// -- </job.queuer> --
diff --git a/server/mod.ts b/server/mod.ts
new file mode 100644
index 0000000..9dc57aa
--- /dev/null
+++ b/server/mod.ts
@@ -0,0 +1,16 @@
+#!/usr/bin/env -S deno run --allow-env --allow-net --allow-run
+
+export * from "./ci.ts";
+export * from "./health.ts";
+export * from "./job.ts";
+
+import { CiHookServer } from "./mod.ts";
+const server = new CiHookServer();
+
+export const runServer = (port: number, host: string) => {
+ const serverConfig = {
+ host,
+ port,
+ };
+ return Deno.serve(serverConfig, (req) => server.serve(req)).finished;
+};
diff --git a/u/deno.json b/u/deno.json
index 26b08bf..b277873 100644
--- a/u/deno.json
+++ b/u/deno.json
@@ -1,6 +1,5 @@
{
"name": "@emprespresso/pengueno",
"version": "0.1.0",
- "exports": "./mod.ts",
- "workspace": ["./*"]
+ "exports": "./mod.ts"
}
diff --git a/u/fn/either.ts b/u/fn/either.ts
index 8b233bf..b228af2 100644
--- a/u/fn/either.ts
+++ b/u/fn/either.ts
@@ -10,7 +10,7 @@ export interface IEither<E, T> {
errBranch: Mapper<E, Ee>,
okBranch: Mapper<T, Tt>,
) => IEither<Ee, Tt>;
- fold: <Tt>(folder: BiMapper<E | undefined, T | undefined, Tt>) => Tt;
+ fold: <Tt>(folder: (err: E | undefined, val: T | undefined) => Tt) => Tt; //BiMapper<E | undefined, T | undefined, Tt>) => Tt;;
moveRight: <Tt>(t: Tt) => IEither<E, Tt>;
mapRight: <Tt>(mapper: Mapper<T, Tt>) => IEither<E, Tt>;
mapLeft: <Ee>(mapper: Mapper<E, Ee>) => IEither<Ee, T>;
diff --git a/u/process/argv.ts b/u/process/argv.ts
new file mode 100644
index 0000000..657c9a7
--- /dev/null
+++ b/u/process/argv.ts
@@ -0,0 +1,65 @@
+import { Either, type IEither } from "@emprespresso/pengueno";
+
+export const isArgKey = <K extends string>(k: string): k is K =>
+ k.startsWith("--");
+
+export const getArg = <K extends string, V extends string>(
+ arg: K,
+ args: Array<K>,
+): IEither<Error, V> => {
+ const result = args.findIndex((_arg) => _arg.startsWith(arg));
+ if (result < 0) return Either.left(new Error("no argument found for " + arg));
+ const [resultArg, next]: Array<string | undefined> = [
+ args[result],
+ args.at(result + 1),
+ ];
+ if (resultArg && resultArg.includes("=")) {
+ return Either.right(resultArg.split("=")[1] as V);
+ }
+ if (typeof next === "undefined")
+ return Either.left(new Error("no value specified for " + arg));
+ if (isArgKey(next))
+ return Either.left(
+ new Error("next value for arg " + arg + " is another arg " + next),
+ );
+ return Either.right(next as V);
+};
+
+type ObjectFromList<T extends ReadonlyArray<string>, V = string> = {
+ [K in T extends ReadonlyArray<infer U> ? U : never]: V;
+};
+export const argv = <K extends string, V extends string>(
+ args: ReadonlyArray<K>,
+ defaultArgs?: Partial<Record<K, V>>,
+ argv = Deno.args,
+) => {
+ return args
+ .map((arg) => [arg, getArg(arg, argv)] as [K, IEither<Error, V>])
+ .map(([arg, specified]): [K, IEither<Error, V>] => [
+ arg,
+ specified.fold((e, val) => {
+ const hasDefaultVal = e && defaultArgs && arg in defaultArgs;
+ if (hasDefaultVal) {
+ return Either.right<Error, V>(defaultArgs[arg]!);
+ } else if (!val || e) {
+ return Either.left<Error, V>(e ?? new Error("unknown"));
+ }
+ return Either.right<Error, V>(val);
+ }),
+ ])
+ .reduce(
+ (
+ acc: IEither<Error, ObjectFromList<typeof args, V>>,
+ x: [K, IEither<Error, V>],
+ ): IEither<Error, ObjectFromList<typeof args, V>> => {
+ const [arg, eitherVal] = x;
+ return acc.flatMap((args) => {
+ return eitherVal.mapRight((envValue) => ({
+ ...args,
+ [arg]: envValue,
+ }));
+ });
+ },
+ Either.right({} as ObjectFromList<typeof args, V>),
+ );
+};
diff --git a/u/process/mod.ts b/u/process/mod.ts
index 3f02d46..211e9a7 100644
--- a/u/process/mod.ts
+++ b/u/process/mod.ts
@@ -1,3 +1,4 @@
export * from "./env.ts";
export * from "./run.ts";
export * from "./validate_identifier.ts";
+export * from "./argv.ts";
diff --git a/u/server/activity/fourohfour.ts b/u/server/activity/fourohfour.ts
index c09aef6..ed8c7eb 100644
--- a/u/server/activity/fourohfour.ts
+++ b/u/server/activity/fourohfour.ts
@@ -7,14 +7,10 @@ import {
} from "@emprespresso/pengueno";
const messages = [
- "(≧ω≦)ゞ Oopsie! This endpoint has gone a-404-dable!",
- "。゚(。ノωヽ。)゚。 Meow-t found! Your API call ran away!",
- "404-bidden! But like...in a cute way (・`ω´・) !",
- "(=①ω①=) This endpoint is hiss-terically missing!",
- "┐(´∀`)┌ Whoopsie fluff! No API here!",
- "(つ≧▽≦)つ Your data went on a paw-sible vacation!",
- "(ꈍᴗꈍ) Uwu~ not found, but found our hearts instead!",
- "ヽ(;▽;)ノ Eep! This route has ghosted you~",
+ "D: Meow-t found! Your API call ran away!",
+ "404-bidden! But like...in a cute way >:3 !",
+ ":o Your data went on a paw-sible vacation!",
+ "uwu~ not found, but found our hearts instead!",
];
const randomFourOhFour = () => messages[Math.random() * messages.length];
diff --git a/u/server/request.ts b/u/server/request.ts
index 480ee69..c857f88 100644
--- a/u/server/request.ts
+++ b/u/server/request.ts
@@ -2,11 +2,10 @@ import { LogMetricTraceable } from "@emprespresso/pengueno";
const greetings = [
"hewwo :D",
- "hiya cutie (✿◠‿◠)",
- "boop! ૮・ᴥ・ა",
- "sending virtual hugs! (づ。◕‿‿◕。)づ",
- "stay pawsitive ₍^..^₎⟆",
- "⋆。‧˚❆🐧❆˚‧。⋆",
+ "hiya cutie",
+ "boop!",
+ "sending virtual hugs!",
+ "stay pawsitive",
];
const penguenoGreeting = () =>
greetings[Math.floor(Math.random() * greetings.length)];
diff --git a/worker/Dockerfile b/worker/Dockerfile
index d87d67f..24193be 100644
--- a/worker/Dockerfile
+++ b/worker/Dockerfile
@@ -1,4 +1,4 @@
-# -- <worker_dependencies> --
+# -- <worker.dependencies> --
FROM debian:stable-slim AS worker-dependencies
# Define versions as build arguments to improve caching
@@ -11,10 +11,10 @@ RUN unzip /bw-linux.zip -d / \
RUN curl -L "https://get.docker.com/builds/$(uname -s)/$(uname -m)/docker-latest.tgz" > /docker.tgz
RUN tar -xvzf /docker.tgz
-# -- </worker_dependencies> --
+# -- </worker.dependencies> --
-# -- <ci_worker> --
-FROM oci.liz.coffee/emprespresso/ci-base:release AS worker
+# -- <ci.worker> --
+FROM oci.liz.coffee/emprespresso/ci.base:release AS worker
RUN apt-get update && apt-get install -yqq git jq
RUN groupadd docker
@@ -36,4 +36,4 @@ HEALTHCHECK --interval=10s --retries=3 --start-period=3s \
CMD [ "/usr/bin/laminarc show-jobs" ]
CMD [ "/usr/sbin/laminard" ]
-# -- </ci_worker> --
+# -- </ci.worker> --
diff --git a/worker/deno.json b/worker/deno.json
index 90f50c9..c908330 100644
--- a/worker/deno.json
+++ b/worker/deno.json
@@ -1,4 +1,4 @@
{
- "name": "@emprespresso/ci-worker",
+ "name": "@emprespresso/ci_worker",
"exports": "./mod.ts"
}
diff --git a/worker/executor/pipeline.ts b/worker/executor.ts
index c8423b1..faa40a6 100644
--- a/worker/executor/pipeline.ts
+++ b/worker/executor.ts
@@ -1,14 +1,51 @@
import {
- Either,
- type IEither,
+ getStdout,
type ITraceable,
+ LogLevel,
type LogMetricTraceSupplier,
+ memoize,
Metric,
TraceUtil,
+ validateExecutionEntries,
+ Either,
+ type IEither,
} from "@emprespresso/pengueno";
-import type { Job, JobArgT, Pipeline } from "@emprespresso/ci-model";
-import { executeJob } from "./mod.ts";
+import type { Job, JobArgT, Pipeline } from "@emprespresso/ci_model";
+
+// -- <job.exectuor> --
+const jobTypeMetric = memoize((type: string) => Metric.fromName(`run.${type}`));
+export const executeJob = (tJob: ITraceable<Job, LogMetricTraceSupplier>) =>
+ tJob
+ .bimap(TraceUtil.withMetricTrace(jobTypeMetric(tJob.get().type)))
+ .peek((tJob) =>
+ tJob.trace.trace(`let's do this little job ok!! ${tJob.get()}`),
+ )
+ .map((tJob) =>
+ validateExecutionEntries(tJob.get().arguments)
+ .mapLeft((badEntries) => {
+ tJob.trace.addTrace(LogLevel.ERROR).trace(badEntries.toString());
+ return new Error("invalid job arguments");
+ })
+ .flatMapAsync((args) =>
+ getStdout(tJob.move(tJob.get().type), { env: args }),
+ ),
+ )
+ .peek(
+ TraceUtil.promiseify((q) =>
+ q.trace.trace(
+ q
+ .get()
+ .fold(
+ (err, _val) =>
+ jobTypeMetric(tJob.get().type)[err ? "failure" : "success"],
+ ),
+ ),
+ ),
+ )
+ .get();
+// -- </job.exectuor> --
+// -- <pipeline.executor> --
const pipelinesMetric = Metric.fromName("pipelines");
export const executePipeline = (
tPipeline: ITraceable<Pipeline, LogMetricTraceSupplier>,
@@ -30,7 +67,10 @@ export const executePipeline = (
(tJob) =>
<Job>{
...tJob.get(),
- arguments: { ...baseEnv, ...tJob.get().arguments },
+ arguments: {
+ ...baseEnv,
+ ...tJob.get().arguments,
+ },
},
)
.map(executeJob)
@@ -56,3 +96,4 @@ export const executePipeline = (
return Either.right(undefined);
})
.get();
+// -- </pipeline.executor> --
diff --git a/worker/executor/job.ts b/worker/executor/job.ts
deleted file mode 100644
index ca7feed..0000000
--- a/worker/executor/job.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {
- getStdout,
- type ITraceable,
- LogLevel,
- type LogMetricTraceSupplier,
- memoize,
- Metric,
- TraceUtil,
- validateExecutionEntries,
-} from "@emprespresso/pengueno";
-import type { Job } from "@emprespresso/ci-model";
-
-const jobTypeMetric = memoize((type: string) => Metric.fromName(`run.${type}`));
-export const executeJob = (tJob: ITraceable<Job, LogMetricTraceSupplier>) =>
- tJob
- .bimap(TraceUtil.withMetricTrace(jobTypeMetric(tJob.get().type)))
- .peek((tJob) =>
- tJob.trace.trace(`let's do this little job ok!! ${tJob.get()}`),
- )
- .map((tJob) =>
- validateExecutionEntries(tJob.get().arguments)
- .mapLeft((badEntries) => {
- tJob.trace.addTrace(LogLevel.ERROR).trace(badEntries.toString());
- return new Error("invalid job arguments");
- })
- .flatMapAsync((args) =>
- getStdout(tJob.move(tJob.get().type), { env: args }),
- ),
- )
- .peek(
- TraceUtil.promiseify((q) =>
- q.trace.trace(
- q
- .get()
- .fold(
- (err, _val) =>
- jobTypeMetric(tJob.get().type)[err ? "failure" : "success"],
- ),
- ),
- ),
- )
- .get();
diff --git a/worker/executor/mod.ts b/worker/executor/mod.ts
deleted file mode 100644
index 944ab7d..0000000
--- a/worker/executor/mod.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "./job.ts";
-export * from "./pipeline.ts";
diff --git a/worker/jobs/ci_pipeline.run b/worker/jobs/ci_pipeline.run
index 337bd53..434850c 100644
--- a/worker/jobs/ci_pipeline.run
+++ b/worker/jobs/ci_pipeline.run
@@ -1,3 +1,5 @@
+#!/usr/bin/env -S deno run --allow-all
+
import {
type Command,
Either,
@@ -13,8 +15,8 @@ import {
type CheckoutCiJob,
type FetchCodeJob,
PipelineImpl,
-} from "@emprespresso/ci-model";
-import { executeJob, executePipeline } from "@emprespresso/ci-worker";
+} from "@emprespresso/ci_model";
+import { executeJob, executePipeline } from "@emprespresso/ci_worker";
const run = Date.now().toString();
const eitherJob = getRequiredEnvVars(["remote", "refname", "rev"])
@@ -122,7 +124,7 @@ await LogMetricTraceable.from(eitherJob).bimap(TraceUtil.withTrace(trace))
.get()
.then((e) =>
e.flatMap(() => eitherJob).fold((err, val) => {
- if (err) throw err;
+ if (!val || err) throw err;
return Deno.remove(getWorkingDirectoryForCiJob(val), { recursive: true });
})
);
diff --git a/worker/mod.ts b/worker/mod.ts
index affcb2c..97980a8 100644
--- a/worker/mod.ts
+++ b/worker/mod.ts
@@ -1,2 +1,2 @@
-export * from "./secret/mod.ts";
-export * from "./executor/mod.ts";
+export * from "./secret.ts";
+export * from "./executor.ts";
diff --git a/worker/scripts/ansible_playbook b/worker/scripts/ansible_playbook
index e9e967c..f2cd4b9 100755
--- a/worker/scripts/ansible_playbook
+++ b/worker/scripts/ansible_playbook
@@ -10,8 +10,8 @@ import {
prependWith,
TraceUtil,
} from "@emprespresso/pengueno";
-import type { AnsiblePlaybookJob } from "@emprespresso/ci-model";
-import { Bitwarden, type SecureNote } from "@emprespresso/ci-worker";
+import type { AnsiblePlaybookJob } from "@emprespresso/ci_model";
+import { Bitwarden, type SecureNote } from "@emprespresso/ci_worker";
const eitherJob = getRequiredEnvVars([
"path",
diff --git a/worker/scripts/build_docker_image b/worker/scripts/build_docker_image
index 1dd0c3d..dc0e961 100755
--- a/worker/scripts/build_docker_image
+++ b/worker/scripts/build_docker_image
@@ -11,8 +11,8 @@ import {
import type {
BuildDockerImageJob,
BuildDockerImageJobProps,
-} from "@emprespresso/ci-model";
-import { Bitwarden, type LoginItem } from "@emprespresso/ci-worker";
+} from "@emprespresso/ci_model";
+import { Bitwarden, type LoginItem } from "@emprespresso/ci_worker";
const eitherJob = getRequiredEnvVars([
"registry",
@@ -38,7 +38,7 @@ await LogMetricTraceable.from(eitherJob)
.bimap(
(tEitherJob) => {
const trace = "build_docker_image." +
- tEitherJob.get().fold((_, v) => v?.buildTarget ?? "");
+ tEitherJob.get().fold((_, v) => v?.arguments.buildTarget ?? "");
return [tEitherJob.get(), trace];
},
)
@@ -116,13 +116,13 @@ await LogMetricTraceable.from(eitherJob)
tEitherWithBuiltImage.trace.trace(
buildImageMetric[err ? "failure" : "success"],
);
- if (err) {
+ if (!val || err) {
tEitherWithBuiltImage.trace.addTrace(LogLevel.ERROR).trace(
`oh nyoo we couldn't buiwd the img :(( ${err}`,
);
return;
}
- tEitherWithBuiltImage.trace.addTrace("buildOutput").trace(val);
+ tEitherWithBuiltImage.trace.addTrace("buildOutput").trace(val.buildOutput);
});
})
.map(async (tEitherWithBuiltImage) => {
diff --git a/worker/secret/bitwarden.ts b/worker/secret.ts
index 7145f49..e0a4c5d 100644
--- a/worker/secret/bitwarden.ts
+++ b/worker/secret.ts
@@ -8,8 +8,33 @@ import {
Metric,
TraceUtil,
} from "@emprespresso/pengueno";
-import type { IVault, SecretItem } from "./mod.ts";
+// -- <ISecret> --
+export interface LoginItem {
+ login: {
+ username: string;
+ password: string;
+ };
+}
+
+export interface SecureNote {
+ notes: string;
+}
+
+export type SecretItem = LoginItem | SecureNote;
+export interface IVault<TClient, TKey, TItemId> {
+ unlock: (client: TClient) => Promise<IEither<Error, TKey>>;
+ lock: (client: TClient, key: TKey) => Promise<IEither<Error, TKey>>;
+
+ fetchSecret: <T extends SecretItem>(
+ client: TClient,
+ key: TKey,
+ item: TItemId,
+ ) => Promise<IEither<Error, T>>;
+}
+// -- </ISecret> --
+
+// -- <IVault> --
type TClient = ITraceable<unknown, LogMetricTraceSupplier>;
type TKey = string;
type TItemId = string;
@@ -165,3 +190,4 @@ export interface BitwardenConfig {
secret: string;
clientId: string;
}
+// -- </IVault> --
diff --git a/worker/secret/ivault.ts b/worker/secret/ivault.ts
deleted file mode 100644
index e101e56..0000000
--- a/worker/secret/ivault.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import type { IEither } from "@emprespresso/pengueno";
-
-export interface LoginItem {
- login: {
- username: string;
- password: string;
- };
-}
-
-export interface SecureNote {
- notes: string;
-}
-
-export type SecretItem = LoginItem | SecureNote;
-export interface IVault<TClient, TKey, TItemId> {
- unlock: (client: TClient) => Promise<IEither<Error, TKey>>;
- lock: (client: TClient, key: TKey) => Promise<IEither<Error, TKey>>;
-
- fetchSecret: <T extends SecretItem>(
- client: TClient,
- key: TKey,
- item: TItemId,
- ) => Promise<IEither<Error, T>>;
-}
diff --git a/worker/secret/mod.ts b/worker/secret/mod.ts
deleted file mode 100644
index 70a1ea9..0000000
--- a/worker/secret/mod.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "./ivault.ts";
-export * from "./bitwarden.ts";