summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-07-01 12:38:35 -0700
committerElizabeth Hunt <me@liz.coffee>2025-07-01 12:38:35 -0700
commitb2ab472a677a22f8300b5beb061f426ad35e2a6a (patch)
tree1ca4465bf6322b514ad5cf0466b7953dedbcb719
parent684d3768920786440278fd3745c7d6a69cb34a8b (diff)
downloadci-b2ab472a677a22f8300b5beb061f426ad35e2a6a.tar.gz
ci-b2ab472a677a22f8300b5beb061f426ad35e2a6a.zip
Build local ci exec
-rwxr-xr-x.ci/ci.cjs592
-rw-r--r--.ci/ci.ts8
-rw-r--r--.ci/package.json16
-rw-r--r--.ci/tsconfig.json15
-rw-r--r--package-lock.json479
-rw-r--r--server/package.json3
-rwxr-xr-xworker/scripts/checkout_ci.ts15
7 files changed, 1118 insertions, 10 deletions
diff --git a/.ci/ci.cjs b/.ci/ci.cjs
new file mode 100755
index 0000000..0e7ef6d
--- /dev/null
+++ b/.ci/ci.cjs
@@ -0,0 +1,592 @@
+#!/usr/bin/env node
+"use strict";
+
+// ../u/leftpadesque/debug.ts
+var _hasEnv = true;
+var _env = _hasEnv && (process.env.ENVIRONMENT ?? "").toLowerCase().includes("prod") ? "production" : "development";
+var isProd = () => _env === "production";
+var _debug = !isProd() || _hasEnv && ["y", "t"].some((process.env.DEBUG ?? "").toLowerCase().startsWith);
+var isDebug = () => _debug;
+
+// ../u/leftpadesque/memoize.ts
+var memoize = (fn) => {
+ const cache = /* @__PURE__ */ new Map();
+ return (...args) => {
+ const key = JSON.stringify(args);
+ if (cache.has(key)) {
+ return cache.get(key);
+ }
+ const res = fn.apply(args);
+ cache.set(key, res);
+ return res;
+ };
+};
+
+// ../u/trace/itrace.ts
+var TraceableImpl = class _TraceableImpl {
+ constructor(item, trace) {
+ this.item = item;
+ this.trace = trace;
+ }
+ map(mapper) {
+ const result = mapper(this);
+ return new _TraceableImpl(result, this.trace);
+ }
+ coExtend(mapper) {
+ const results = mapper(this);
+ return Array.from(results).map((result) => this.move(result));
+ }
+ flatMap(mapper) {
+ return mapper(this);
+ }
+ flatMapAsync(mapper) {
+ return new _TraceableImpl(
+ mapper(this).then((t) => t.get()),
+ this.trace
+ );
+ }
+ traceScope(mapper) {
+ return new _TraceableImpl(this.get(), this.trace.traceScope(mapper(this)));
+ }
+ peek(peek) {
+ peek(this);
+ return this;
+ }
+ move(t) {
+ return this.map(() => t);
+ }
+ bimap(mapper) {
+ const { item, trace: _trace } = mapper(this);
+ return this.move(item).traceScope(() => _trace);
+ }
+ get() {
+ return this.item;
+ }
+};
+
+// ../u/trace/metric/emittable.ts
+var EmittableMetric = class {
+ constructor(name, unit) {
+ this.name = name;
+ this.unit = unit;
+ }
+ withValue(value) {
+ return {
+ name: this.name,
+ unit: this.unit,
+ emissionTimestamp: Date.now(),
+ value,
+ _tag: MetricValueTag
+ };
+ }
+};
+
+// ../u/trace/metric/metric.ts
+var _Tagged = class {
+ constructor(_tag = IMetricTag) {
+ this._tag = _tag;
+ }
+};
+var Metric = class _Metric extends _Tagged {
+ constructor(name, parent = void 0, count = new EmittableMetric(_Metric.join(name, "count"), "COUNT" /* COUNT */), time = new EmittableMetric(_Metric.join(name, "time"), "MILLISECONDS" /* MILLISECONDS */)) {
+ super();
+ this.name = name;
+ this.parent = parent;
+ this.count = count;
+ this.time = time;
+ }
+ static DELIM = ".";
+ child(_name) {
+ const childName = _Metric.join(this.name, _name);
+ return new _Metric(childName, this);
+ }
+ asResult() {
+ return ResultMetric.from(this);
+ }
+ static join(...name) {
+ return name.join(_Metric.DELIM);
+ }
+ static fromName(name) {
+ return new _Metric(name);
+ }
+};
+var ResultMetric = class _ResultMetric extends Metric {
+ constructor(name, parent = void 0, failure, success, warn) {
+ super(name, parent);
+ this.name = name;
+ this.parent = parent;
+ this.failure = failure;
+ this.success = success;
+ this.warn = warn;
+ }
+ static from(metric) {
+ const failure = metric.child("failure");
+ const success = metric.child("success");
+ const warn = metric.child("warn");
+ return new _ResultMetric(metric.name, metric.parent, failure, success, warn);
+ }
+};
+
+// ../u/trace/metric/trace.ts
+var MetricsTrace = class _MetricsTrace {
+ constructor(metricConsumer, activeTraces = /* @__PURE__ */ new Map(), completedTraces = /* @__PURE__ */ new Set()) {
+ this.metricConsumer = metricConsumer;
+ this.activeTraces = activeTraces;
+ this.completedTraces = completedTraces;
+ }
+ traceScope(trace) {
+ const now = Date.now();
+ const metricsToTrace = (Array.isArray(trace) ? trace : [trace]).filter(isIMetric);
+ const initialTraces = new Map(metricsToTrace.map((metric) => [metric, now]));
+ return new _MetricsTrace(this.metricConsumer, initialTraces);
+ }
+ trace(metrics) {
+ if (!metrics || typeof metrics === "string") {
+ return this;
+ }
+ const now = Date.now();
+ const allMetrics = Array.isArray(metrics) ? metrics : [metrics];
+ const valuesToEmit = allMetrics.filter(isMetricValue);
+ const traceableMetrics = allMetrics.filter(isIMetric);
+ const metricsToStart = traceableMetrics.filter((m) => !this.activeTraces.has(m));
+ const metricsToEnd = traceableMetrics.filter((m) => this.activeTraces.has(m) && !this.completedTraces.has(m));
+ const endedMetricValues = metricsToEnd.flatMap((metric) => [
+ metric.count.withValue(1),
+ metric.time.withValue(now - this.activeTraces.get(metric))
+ ]);
+ const allMetricsToEmit = [...valuesToEmit, ...endedMetricValues];
+ if (allMetricsToEmit.length > 0) {
+ this.metricConsumer(allMetricsToEmit);
+ }
+ const nextActiveTraces = new Map([
+ ...this.activeTraces,
+ ...metricsToStart.map((m) => [m, now])
+ ]);
+ const nextCompletedTraces = /* @__PURE__ */ new Set([...this.completedTraces, ...metricsToEnd]);
+ return new _MetricsTrace(this.metricConsumer, nextActiveTraces, nextCompletedTraces);
+ }
+};
+
+// ../u/trace/metric/index.ts
+var MetricValueTag = "MetricValue";
+var isMetricValue = (t) => isTagged(t, MetricValueTag);
+var IMetricTag = "IMetric";
+var isIMetric = (t) => isTagged(t, IMetricTag);
+
+// ../u/trace/log/ansi.ts
+var ANSI = {
+ RESET: "\x1B[0m",
+ BOLD: "\x1B[1m",
+ DIM: "\x1B[2m",
+ RED: "\x1B[31m",
+ GREEN: "\x1B[32m",
+ YELLOW: "\x1B[33m",
+ BLUE: "\x1B[34m",
+ MAGENTA: "\x1B[35m",
+ CYAN: "\x1B[36m",
+ WHITE: "\x1B[37m",
+ BRIGHT_RED: "\x1B[91m",
+ BRIGHT_YELLOW: "\x1B[93m",
+ GRAY: "\x1B[90m"
+};
+
+// ../u/trace/log/level.ts
+var logLevelOrder = [
+ "DEBUG" /* DEBUG */,
+ "INFO" /* INFO */,
+ "WARN" /* WARN */,
+ "ERROR" /* ERROR */,
+ "SYS" /* SYS */
+];
+var isLogLevel = (l) => typeof l === "string" && logLevelOrder.some((level) => level === l);
+
+// ../u/trace/log/pretty_json_console.ts
+var PrettyJsonConsoleLogger = class {
+ log(level, ...trace) {
+ const message = JSON.stringify(
+ {
+ level,
+ trace
+ },
+ null,
+ 4
+ );
+ const styled = `${this.getStyle(level)}${message}${ANSI.RESET}
+`;
+ this.getStream(level)(styled);
+ }
+ getStream(level) {
+ if (level === "ERROR" /* ERROR */) {
+ return console.error;
+ }
+ return console.log;
+ }
+ getStyle(level) {
+ switch (level) {
+ case "UNKNOWN" /* UNKNOWN */:
+ case "INFO" /* INFO */:
+ return `${ANSI.MAGENTA}`;
+ case "DEBUG" /* DEBUG */:
+ return `${ANSI.CYAN}`;
+ case "WARN" /* WARN */:
+ return `${ANSI.BRIGHT_YELLOW}`;
+ case "ERROR" /* ERROR */:
+ return `${ANSI.BRIGHT_RED}`;
+ case "SYS" /* SYS */:
+ return `${ANSI.DIM}${ANSI.BLUE}`;
+ }
+ }
+};
+
+// ../u/trace/log/trace.ts
+var LogTrace = class _LogTrace {
+ constructor(logger = new PrettyJsonConsoleLogger(), traces = [defaultTrace], defaultLevel = "INFO" /* INFO */, allowedLevels = defaultAllowedLevelsSupplier) {
+ this.logger = logger;
+ this.traces = traces;
+ this.defaultLevel = defaultLevel;
+ this.allowedLevels = allowedLevels;
+ }
+ traceScope(trace) {
+ return new _LogTrace(this.logger, this.traces.concat(trace), this.defaultLevel, this.allowedLevels);
+ }
+ trace(trace) {
+ const { traces, level: _level } = this.foldTraces(this.traces.concat(trace));
+ if (!this.allowedLevels().has(_level)) return;
+ const level = _level === "UNKNOWN" /* UNKNOWN */ ? this.defaultLevel : _level;
+ this.logger.log(level, ...traces);
+ }
+ foldTraces(_traces) {
+ const _logTraces = _traces.map((trace) => typeof trace === "function" ? trace() : trace);
+ const _level = _logTraces.filter((trace) => isLogLevel(trace)).reduce((acc, level2) => Math.max(logLevelOrder.indexOf(level2), acc), -1);
+ const level = logLevelOrder[_level] ?? "UNKNOWN" /* UNKNOWN */;
+ const traces = _logTraces.filter((trace) => !isLogLevel(trace)).map((trace) => {
+ if (typeof trace === "object") {
+ return `TracedException.Name = ${trace.name}, TracedException.Message = ${trace.message}, TracedException.Stack = ${trace.stack}`;
+ }
+ return trace;
+ });
+ return {
+ level,
+ traces
+ };
+ }
+};
+var defaultTrace = () => `TimeStamp = ${(/* @__PURE__ */ new Date()).toISOString()}`;
+var defaultAllowedLevels = memoize(
+ (isDebug2) => /* @__PURE__ */ new Set([
+ "UNKNOWN" /* UNKNOWN */,
+ ...isDebug2 ? ["DEBUG" /* DEBUG */] : [],
+ "INFO" /* INFO */,
+ "WARN" /* WARN */,
+ "ERROR" /* ERROR */,
+ "SYS" /* SYS */
+ ])
+);
+var defaultAllowedLevelsSupplier = () => defaultAllowedLevels(isDebug());
+
+// ../u/trace/trace.ts
+var LogTraceable = class _LogTraceable extends TraceableImpl {
+ static LogTrace = new LogTrace();
+ static of(t) {
+ return new _LogTraceable(t, _LogTraceable.LogTrace);
+ }
+};
+var getEmbeddedMetricConsumer = (logTrace) => (metrics) => {
+ if (metrics.length === 0) return;
+ logTrace.traceScope("SYS" /* SYS */).trace(`Metrics = <metrics>${JSON.stringify(metrics)}</metrics>`);
+};
+var EmbeddedMetricsTraceable = class _EmbeddedMetricsTraceable extends TraceableImpl {
+ static MetricsTrace = new MetricsTrace(getEmbeddedMetricConsumer(LogTraceable.LogTrace));
+ static of(t, metricsTrace = _EmbeddedMetricsTraceable.MetricsTrace) {
+ return new _EmbeddedMetricsTraceable(t, metricsTrace);
+ }
+};
+
+// ../u/process/run.ts
+var import_node_util = require("node:util");
+var import_node_child_process = require("node:child_process");
+var exec = (0, import_node_util.promisify)(import_node_child_process.exec);
+var CmdMetric = Metric.fromName("Exec").asResult();
+
+// ../u/process/signals.ts
+var SigIntMetric = Metric.fromName("SigInt").asResult();
+var SigTermMetric = Metric.fromName("SigTerm").asResult();
+
+// ../u/server/response/pengueno.ts
+var ResponseCodeMetrics = [0, 1, 2, 3, 4, 5].map((x) => Metric.fromName(`response.${x}xx`).asResult());
+
+// ../u/server/activity/health.ts
+var healthCheckMetric = Metric.fromName("Health").asResult();
+
+// ../u/server/filter/json.ts
+var ParseJsonMetric = Metric.fromName("JsonParse").asResult();
+
+// ../u/server/filter/index.ts
+var ErrorSource = ((ErrorSource2) => {
+ ErrorSource2[ErrorSource2["USER"] = "WARN" /* WARN */] = "USER";
+ ErrorSource2[ErrorSource2["SYSTEM"] = "ERROR" /* ERROR */] = "SYSTEM";
+ return ErrorSource2;
+})(ErrorSource || {});
+
+// ../u/types/object.ts
+var isObject = (o) => typeof o === "object" && !Array.isArray(o) && !!o;
+
+// ../u/types/tagged.ts
+var isTagged = (o, tag) => !!(isObject(o) && "_tag" in o && o._tag === tag);
+
+// ../u/types/fn/either.ts
+var IEitherTag = "IEither";
+var ELeftTag = "E.Left";
+var isLeft = (o) => isTagged(o, ELeftTag);
+var ERightTag = "E.Right";
+var isRight = (o) => isTagged(o, ERightTag);
+var _Tagged2 = class {
+ constructor(_tag = IEitherTag) {
+ this._tag = _tag;
+ }
+};
+var Either = class _Either extends _Tagged2 {
+ constructor(self) {
+ super();
+ this.self = self;
+ }
+ moveRight(t) {
+ return this.mapRight(() => t);
+ }
+ mapBoth(errBranch, okBranch) {
+ if (isLeft(this.self)) return _Either.left(errBranch(this.self.err));
+ return _Either.right(okBranch(this.self.ok));
+ }
+ mapRight(mapper) {
+ if (isRight(this.self)) return _Either.right(mapper(this.self.ok));
+ return _Either.left(this.self.err);
+ }
+ mapLeft(mapper) {
+ if (isLeft(this.self)) return _Either.left(mapper(this.self.err));
+ return _Either.right(this.self.ok);
+ }
+ flatMap(mapper) {
+ if (isRight(this.self)) return mapper(this.self.ok);
+ return _Either.left(this.self.err);
+ }
+ async flatMapAsync(mapper) {
+ if (isLeft(this.self)) return Promise.resolve(_Either.left(this.self.err));
+ return await mapper(this.self.ok).catch((err) => _Either.left(err));
+ }
+ fold(leftFolder, rightFolder) {
+ if (isLeft(this.self)) return leftFolder(this.self.err);
+ return rightFolder(this.self.ok);
+ }
+ left() {
+ if (isLeft(this.self)) return Optional.from(this.self.err);
+ return Optional.none();
+ }
+ right() {
+ if (isRight(this.self)) return Optional.from(this.self.ok);
+ return Optional.none();
+ }
+ static left(e) {
+ return new _Either({ err: e, _tag: ELeftTag });
+ }
+ static right(t) {
+ return new _Either({ ok: t, _tag: ERightTag });
+ }
+ static fromFailable(s) {
+ try {
+ return _Either.right(s());
+ } catch (e) {
+ return _Either.left(e);
+ }
+ }
+ static async fromFailableAsync(s) {
+ return await (typeof s === "function" ? s() : s).then((t) => _Either.right(t)).catch((e) => _Either.left(e));
+ }
+};
+
+// ../u/types/fn/optional.ts
+var IOptionalTag = "IOptional";
+var IOptionalEmptyError = class extends Error {
+};
+var OSomeTag = "O.Some";
+var ONoneTag = "O.None";
+var isNone = (o) => isTagged(o, ONoneTag);
+var isSome = (o) => isTagged(o, OSomeTag);
+var _Tagged3 = class {
+ constructor(_tag = IOptionalTag) {
+ this._tag = _tag;
+ }
+};
+var Optional = class _Optional extends _Tagged3 {
+ constructor(self) {
+ super();
+ this.self = self;
+ }
+ move(t) {
+ return this.map(() => t);
+ }
+ orSome(supplier) {
+ if (isNone(this.self)) return _Optional.from(supplier());
+ return this;
+ }
+ get() {
+ if (isNone(this.self)) throw new IOptionalEmptyError("empty value");
+ return this.self.value;
+ }
+ filter(mapper) {
+ if (isNone(this.self) || !mapper(this.self.value)) return _Optional.none();
+ return _Optional.some(this.self.value);
+ }
+ map(mapper) {
+ if (isNone(this.self)) return _Optional.none();
+ return _Optional.from(mapper(this.self.value));
+ }
+ flatMap(mapper) {
+ if (isNone(this.self)) return _Optional.none();
+ return _Optional.from(mapper(this.self.value)).orSome(() => _Optional.none()).get();
+ }
+ present() {
+ return isSome(this.self);
+ }
+ *[Symbol.iterator]() {
+ if (isSome(this.self)) yield this.self.value;
+ }
+ static some(value) {
+ return new _Optional({ value, _tag: OSomeTag });
+ }
+ static _none = new _Optional({ _tag: ONoneTag });
+ static none() {
+ return this._none;
+ }
+ static from(value) {
+ if (value === null || value === void 0) return _Optional.none();
+ return _Optional.some(value);
+ }
+};
+
+// ../model/job/index.ts
+var isJob = (j) => !!(isObject(j) && "arguments" in j && isObject(j.arguments) && "type" in j && typeof j.type === "string" && j);
+
+// ../model/pipeline/builder.ts
+var BasePipelineBuilder = class {
+ stages = [];
+ addStage(stage) {
+ this.stages.push(stage);
+ return this;
+ }
+ build() {
+ return new PipelineImpl(this.stages);
+ }
+};
+var DefaultGitHookPipelineBuilder = class extends BasePipelineBuilder {
+ constructor(remoteUrl = process.env.remote, rev = process.env.rev, ref = process.env.ref) {
+ super();
+ this.remoteUrl = remoteUrl;
+ this.ref = ref;
+ this.addStage({
+ parallelJobs: [
+ {
+ type: "fetch_code",
+ arguments: {
+ remoteUrl,
+ checkout: rev,
+ path: this.getSourceDestination()
+ }
+ }
+ ]
+ });
+ }
+ getSourceDestination() {
+ return this.remoteUrl.split("/").at(-1) ?? "src";
+ }
+ getBranch() {
+ const branchRefPrefix = "refs/heads/";
+ return this.ref.split(branchRefPrefix).at(1);
+ }
+};
+
+// ../model/pipeline/impl.ts
+var PipelineImpl = class _PipelineImpl {
+ constructor(serialJobs) {
+ this.serialJobs = serialJobs;
+ }
+ serialize() {
+ return JSON.stringify(this.serialJobs);
+ }
+ static from(s) {
+ return Either.fromFailable(() => JSON.parse(s)).flatMap(
+ (eitherPipelineJson) => isPipeline(eitherPipelineJson) ? Either.right(eitherPipelineJson) : Either.left(new Error("oh noes D: its a bad pipewine :(("))
+ ).mapRight((pipeline) => new _PipelineImpl(pipeline.serialJobs));
+ }
+};
+
+// ../model/pipeline/index.ts
+var isPipelineStage = (t) => isObject(t) && "parallelJobs" in t && Array.isArray(t.parallelJobs) && t.parallelJobs.every((j) => isJob(j));
+var isPipeline = (t) => isObject(t) && "serialJobs" in t && Array.isArray(t.serialJobs) && t.serialJobs.every((p) => isPipelineStage(p));
+
+// dist/ci.js
+var REGISTRY = "oci.liz.coffee";
+var NAMESPACE = "emprespresso";
+var IMG = "ci";
+var REMOTE = "ssh://src.liz.coffee:2222";
+var getPipeline = () => {
+ const gitHookPipeline = new DefaultGitHookPipelineBuilder();
+ const branch = gitHookPipeline.getBranch();
+ if (!branch)
+ return gitHookPipeline.build();
+ const commonBuildArgs = {
+ registry: REGISTRY,
+ namespace: NAMESPACE,
+ imageTag: branch
+ };
+ const baseCiPackageBuild = {
+ type: "build_docker_image.js",
+ arguments: {
+ ...commonBuildArgs,
+ context: gitHookPipeline.getSourceDestination(),
+ repository: IMG + "_base",
+ buildTarget: IMG + "_base",
+ dockerfile: "Dockerfile"
+ }
+ };
+ gitHookPipeline.addStage({
+ parallelJobs: [baseCiPackageBuild]
+ });
+ const subPackages = ["worker", "hooks"].map((_package) => ({
+ type: "build_docker_image.js",
+ arguments: {
+ ...commonBuildArgs,
+ repository: `${IMG}_${_package}`,
+ buildTarget: _package,
+ dockerfile: `${_package}/Dockerfile`
+ }
+ }));
+ gitHookPipeline.addStage({
+ parallelJobs: subPackages
+ });
+ const isRelease = branch === "release";
+ if (!isRelease) {
+ return gitHookPipeline.build();
+ }
+ const fetchAnsibleCode = {
+ type: "fetch_code",
+ arguments: {
+ remoteUrl: `${REMOTE}/infra`,
+ checkout: "main",
+ path: "infra"
+ }
+ };
+ const thenDeploy = {
+ type: "ansible_playbook.js",
+ arguments: {
+ path: "infra",
+ playbooks: "playbooks/ci.yml"
+ }
+ };
+ [fetchAnsibleCode, thenDeploy].forEach((deploymentStage) => gitHookPipeline.addStage({ parallelJobs: [deploymentStage] }));
+ return gitHookPipeline.build();
+};
+var main = () => {
+ const data = getPipeline().serialize();
+ process.stdout.write(data);
+};
+main();
diff --git a/.ci/ci.ts b/.ci/ci.ts
index 3cc20a0..39844d5 100644
--- a/.ci/ci.ts
+++ b/.ci/ci.ts
@@ -1,4 +1,4 @@
-#!/usr/bin/env ts-node
+#!/usr/bin/env node
import {
AnsiblePlaybookJob,
@@ -77,7 +77,9 @@ const getPipeline = () => {
return gitHookPipeline.build();
};
-if (import.meta.url === `file://${process.argv[1]}`) {
+const main = () => {
const data = getPipeline().serialize();
process.stdout.write(data);
-}
+};
+
+main();
diff --git a/.ci/package.json b/.ci/package.json
new file mode 100644
index 0000000..9d8bfa7
--- /dev/null
+++ b/.ci/package.json
@@ -0,0 +1,16 @@
+{
+ "scripts": {
+ "build": "tsc && esbuild --format=cjs --target=node22 --platform=node --bundle --outfile=ci.cjs dist/ci.js && chmod +x ci.cjs",
+ "clean": "rm -rf dist ci.cjs"
+ },
+ "dependencies": {
+ "@emprespresso/ci_model": "*"
+ },
+ "devDependencies": {
+ "esbuild": "0.25.5"
+ },
+ "files": [
+ "dist/**/*",
+ "package.json"
+ ]
+}
diff --git a/.ci/tsconfig.json b/.ci/tsconfig.json
new file mode 100644
index 0000000..58e9147
--- /dev/null
+++ b/.ci/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "extends": "../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./dist",
+ "rootDir": "./",
+ "composite": true,
+ "declaration": true,
+ "declarationMap": true,
+ "sourceMap": true,
+ "noEmit": false
+ },
+ "include": ["**/*.ts"],
+ "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"],
+ "references": [{ "path": "../u" }, { "path": "../model" }]
+}
diff --git a/package-lock.json b/package-lock.json
index 06ebd92..5f6f6ae 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -29,6 +29,15 @@
"npm": ">=10.0.0"
}
},
+ ".ci": {
+ "name": "ci.ci",
+ "dependencies": {
+ "@emprespresso/ci_model": "*"
+ },
+ "devDependencies": {
+ "esbuild": "0.25.5"
+ }
+ },
"model": {
"name": "@emprespresso/ci_model",
"version": "0.1.0",
@@ -52,6 +61,431 @@
"resolved": "u",
"link": true
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
+ "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
+ "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
+ "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
+ "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
+ "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
+ "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
+ "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
+ "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
+ "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
+ "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
+ "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
+ "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
+ "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
+ "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
+ "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
+ "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
+ "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
+ "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
+ "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
+ "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
+ "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
+ "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
+ "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
@@ -655,6 +1089,10 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/ci.ci": {
+ "resolved": ".ci",
+ "link": true
+ },
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -805,6 +1243,47 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/esbuild": {
+ "version": "0.25.5",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
+ "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.5",
+ "@esbuild/android-arm": "0.25.5",
+ "@esbuild/android-arm64": "0.25.5",
+ "@esbuild/android-x64": "0.25.5",
+ "@esbuild/darwin-arm64": "0.25.5",
+ "@esbuild/darwin-x64": "0.25.5",
+ "@esbuild/freebsd-arm64": "0.25.5",
+ "@esbuild/freebsd-x64": "0.25.5",
+ "@esbuild/linux-arm": "0.25.5",
+ "@esbuild/linux-arm64": "0.25.5",
+ "@esbuild/linux-ia32": "0.25.5",
+ "@esbuild/linux-loong64": "0.25.5",
+ "@esbuild/linux-mips64el": "0.25.5",
+ "@esbuild/linux-ppc64": "0.25.5",
+ "@esbuild/linux-riscv64": "0.25.5",
+ "@esbuild/linux-s390x": "0.25.5",
+ "@esbuild/linux-x64": "0.25.5",
+ "@esbuild/netbsd-arm64": "0.25.5",
+ "@esbuild/netbsd-x64": "0.25.5",
+ "@esbuild/openbsd-arm64": "0.25.5",
+ "@esbuild/openbsd-x64": "0.25.5",
+ "@esbuild/sunos-x64": "0.25.5",
+ "@esbuild/win32-arm64": "0.25.5",
+ "@esbuild/win32-ia32": "0.25.5",
+ "@esbuild/win32-x64": "0.25.5"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
diff --git a/server/package.json b/server/package.json
index 644f267..e5e808e 100644
--- a/server/package.json
+++ b/server/package.json
@@ -27,7 +27,6 @@
},
"files": [
"dist/**/*",
- "package.json",
- "README.md"
+ "package.json"
]
}
diff --git a/worker/scripts/checkout_ci.ts b/worker/scripts/checkout_ci.ts
index 0c6d92c..f2c87a0 100755
--- a/worker/scripts/checkout_ci.ts
+++ b/worker/scripts/checkout_ci.ts
@@ -62,7 +62,14 @@ await LogMetricTraceable.ofLogTraceable(_logJob)
mkdir(wd, { recursive: true })
.then(() => process.chdir(wd))
.then(() => tEitherJob.move(fetchPackageJob).map(executeJob).get())
- .then((e) => e.fold(err => { throw err; }, () => ciJob)),
+ .then((e) =>
+ e.fold(
+ (err) => {
+ throw err;
+ },
+ () => ciJob,
+ ),
+ ),
);
}),
)
@@ -136,13 +143,11 @@ function getSrcDirectoryForCiJob(job: CheckoutCiJob) {
return `${job.arguments.returnPath}/${job.arguments.run}/src`;
}
-const _runFlags = ('--rm --network none --cap-drop ALL' + '--security-opt no-new-privileges').split(' ');
-const _image = 'oci.liz.coffee/img/ci-worker:release';
function getPipelineGenerationCommand(
job: CheckoutCiJob,
pipelineGeneratorPath: string,
- image = _image,
- runFlags = _runFlags,
+ image = 'oci.liz.coffee/img/ci-worker:release',
+ runFlags = ('--rm --network none --cap-drop ALL --security-opt no-new-privileges').split(' '),
): Command {
return [
'docker',