summaryrefslogtreecommitdiff
path: root/model
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-06-20 14:53:38 -0700
committerElizabeth Hunt <me@liz.coffee>2025-06-20 14:53:38 -0700
commitd4791f3d357634daf506fb8f91cc5332a794c421 (patch)
tree1bb01d2d4d8fa74d83bb6f99f2c8aa4146ca2d11 /model
parentd7e8d31c94cd713a2f4cf799e20e993acc69e361 (diff)
downloadci-d4791f3d357634daf506fb8f91cc5332a794c421.tar.gz
ci-d4791f3d357634daf506fb8f91cc5332a794c421.zip
Move to nodejs
Diffstat (limited to 'model')
-rw-r--r--model/deno.json5
-rw-r--r--model/index.ts2
-rw-r--r--model/job.ts67
-rw-r--r--model/job/index.ts11
-rw-r--r--model/job/jobs.ts52
-rw-r--r--model/mod.ts2
-rw-r--r--model/package.json27
-rw-r--r--model/pipeline.ts89
-rw-r--r--model/pipeline/builder.ts53
-rw-r--r--model/pipeline/impl.ts20
-rw-r--r--model/pipeline/index.ts19
-rw-r--r--model/tsconfig.json15
12 files changed, 199 insertions, 163 deletions
diff --git a/model/deno.json b/model/deno.json
deleted file mode 100644
index 5f5dacf..0000000
--- a/model/deno.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "name": "@emprespresso/ci_model",
- "version": "0.1.0",
- "exports": "./mod.ts"
-}
diff --git a/model/index.ts b/model/index.ts
new file mode 100644
index 0000000..094c693
--- /dev/null
+++ b/model/index.ts
@@ -0,0 +1,2 @@
+export * from './job';
+export * from './pipeline';
diff --git a/model/job.ts b/model/job.ts
deleted file mode 100644
index 187ed56..0000000
--- a/model/job.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { isObject } from "@emprespresso/pengueno";
-
-export type JobArgT = Record<string, string>;
-export interface Job {
- readonly type: string;
- readonly arguments: JobArgT;
-}
-export const isJob = (j: unknown): j is Job =>
- !!(
- isObject(j) &&
- "arguments" in j &&
- isObject(j.arguments) &&
- "type" in j &&
- typeof j.type === "string" &&
- j
- );
-
-export interface FetchCodeJobProps extends JobArgT {
- readonly remoteUrl: string;
- readonly checkout: string;
- readonly path: string;
-}
-
-export interface FetchCodeJob {
- readonly type: "fetch_code.ts";
- readonly arguments: FetchCodeJobProps;
-}
-
-export interface BuildDockerImageJobProps extends JobArgT {
- readonly registry: string;
- readonly namespace: string;
- readonly repository: string;
- readonly imageTag: string;
-
- readonly context: string;
- readonly dockerfile: string;
- readonly buildTarget: string;
-}
-
-export interface BuildDockerImageJob extends Job {
- readonly type: "build_docker_image.ts";
- readonly arguments: BuildDockerImageJobProps;
-}
-
-export interface AnsiblePlaybookJobProps extends JobArgT {
- readonly path: string;
- readonly playbooks: string;
-}
-
-export interface AnsiblePlaybookJob extends Job {
- readonly type: "ansible_playbook.ts";
- readonly arguments: AnsiblePlaybookJobProps;
-}
-
-export interface CheckoutCiJobProps extends JobArgT {
- readonly remote: string;
- readonly refname: string;
- readonly rev: string;
-
- readonly run: string;
- readonly returnPath: string;
-}
-
-export interface CheckoutCiJob extends Job {
- readonly type: "checkout_ci.ts";
- readonly arguments: CheckoutCiJobProps;
-}
diff --git a/model/job/index.ts b/model/job/index.ts
new file mode 100644
index 0000000..78f69d6
--- /dev/null
+++ b/model/job/index.ts
@@ -0,0 +1,11 @@
+import { isObject } from '@emprespresso/pengueno';
+
+export type JobArgT = Record<string, string>;
+export interface Job {
+ readonly type: string;
+ readonly arguments: JobArgT;
+}
+export const isJob = (j: unknown): j is Job =>
+ !!(isObject(j) && 'arguments' in j && isObject(j.arguments) && 'type' in j && typeof j.type === 'string' && j);
+
+export * from './jobs';
diff --git a/model/job/jobs.ts b/model/job/jobs.ts
new file mode 100644
index 0000000..e201c4d
--- /dev/null
+++ b/model/job/jobs.ts
@@ -0,0 +1,52 @@
+import { Job, JobArgT } from '.';
+
+export interface FetchCodeJobProps extends JobArgT {
+ readonly remoteUrl: string;
+ readonly checkout: string;
+ readonly path: string;
+}
+
+export interface FetchCodeJob {
+ readonly type: 'fetch_code.ts';
+ readonly arguments: FetchCodeJobProps;
+}
+
+export interface BuildDockerImageJobProps extends JobArgT {
+ readonly registry: string;
+ readonly namespace: string;
+ readonly repository: string;
+ readonly imageTag: string;
+
+ readonly context: string;
+ readonly dockerfile: string;
+ readonly buildTarget: string;
+}
+
+export interface BuildDockerImageJob extends Job {
+ readonly type: 'build_docker_image.ts';
+ readonly arguments: BuildDockerImageJobProps;
+}
+
+export interface AnsiblePlaybookJobProps extends JobArgT {
+ readonly path: string;
+ readonly playbooks: string;
+}
+
+export interface AnsiblePlaybookJob extends Job {
+ readonly type: 'ansible_playbook.ts';
+ readonly arguments: AnsiblePlaybookJobProps;
+}
+
+export interface CheckoutCiJobProps extends JobArgT {
+ readonly remote: string;
+ readonly refname: string;
+ readonly rev: string;
+
+ readonly run: string;
+ readonly returnPath: string;
+}
+
+export interface CheckoutCiJob extends Job {
+ readonly type: 'checkout_ci.ts';
+ readonly arguments: CheckoutCiJobProps;
+}
diff --git a/model/mod.ts b/model/mod.ts
deleted file mode 100644
index 944ab7d..0000000
--- a/model/mod.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "./job.ts";
-export * from "./pipeline.ts";
diff --git a/model/package.json b/model/package.json
new file mode 100644
index 0000000..23cfd52
--- /dev/null
+++ b/model/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "@emprespresso/ci_model",
+ "version": "0.1.0",
+ "type": "module",
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "exports": {
+ ".": {
+ "types": "./dist/index.d.ts",
+ "import": "./dist/index.js"
+ }
+ },
+ "scripts": {
+ "build": "tsc",
+ "dev": "tsc --watch",
+ "clean": "rm -rf dist",
+ "type-check": "tsc --noEmit"
+ },
+ "dependencies": {
+ "@emprespresso/pengueno": "*"
+ },
+ "files": [
+ "dist/**/*",
+ "package.json",
+ "README.md"
+ ]
+}
diff --git a/model/pipeline.ts b/model/pipeline.ts
deleted file mode 100644
index edc8337..0000000
--- a/model/pipeline.ts
+++ /dev/null
@@ -1,89 +0,0 @@
-import { Either, type IEither, isObject } from "@emprespresso/pengueno";
-import { type FetchCodeJob, isJob, type Job } from "@emprespresso/ci_model";
-
-export interface PipelineStage {
- readonly parallelJobs: Array<Job>;
-}
-export const isPipelineStage = (t: unknown): t is PipelineStage =>
- isObject(t) &&
- "parallelJobs" in t &&
- Array.isArray(t.parallelJobs) &&
- t.parallelJobs.every((j) => isJob(j));
-
-export interface Pipeline {
- readonly serialJobs: Array<PipelineStage>;
- serialize(): string;
-}
-export const isPipeline = (t: unknown): t is Pipeline =>
- isObject(t) &&
- "serialJobs" in t &&
- Array.isArray(t.serialJobs) &&
- t.serialJobs.every((p) => isPipelineStage(p));
-
-export interface PipelineBuilder {
- addStage(stage: PipelineStage): PipelineBuilder;
- build(): Pipeline;
-}
-
-export class PipelineImpl implements Pipeline {
- constructor(public readonly serialJobs: Array<PipelineStage>) {}
-
- public serialize() {
- return JSON.stringify(this.serialJobs);
- }
-
- public static from(s: string): IEither<Error, Pipeline> {
- return Either.fromFailable<Error, unknown>(() => JSON.parse(s))
- .flatMap<Pipeline>((eitherPipelineJson) =>
- isPipeline(eitherPipelineJson)
- ? Either.right(eitherPipelineJson)
- : Either.left(new Error("oh noes D: its a bad pipewine :((")),
- )
- .mapRight((pipeline) => new PipelineImpl(pipeline.serialJobs));
- }
-}
-
-abstract class BasePipelineBuilder implements PipelineBuilder {
- protected readonly stages: Array<PipelineStage> = [];
-
- public addStage(stage: PipelineStage): PipelineBuilder {
- this.stages.push(stage);
- return this;
- }
-
- public build() {
- return new PipelineImpl(this.stages);
- }
-}
-
-export class DefaultGitHookPipelineBuilder extends BasePipelineBuilder {
- constructor(
- private readonly remoteUrl = Deno.env.get("remote")!,
- rev = Deno.env.get("rev")!,
- private readonly ref = Deno.env.get("ref")!,
- ) {
- super();
-
- this.addStage({
- parallelJobs: [
- <FetchCodeJob>{
- type: "fetch_code",
- arguments: {
- remoteUrl,
- checkout: rev,
- path: this.getSourceDestination(),
- },
- },
- ],
- });
- }
-
- public getSourceDestination() {
- return this.remoteUrl.split("/").at(-1) ?? "src";
- }
-
- public getBranch(): string | undefined {
- const branchRefPrefix = "refs/heads/";
- return this.ref.split(branchRefPrefix).at(1);
- }
-}
diff --git a/model/pipeline/builder.ts b/model/pipeline/builder.ts
new file mode 100644
index 0000000..e95e89c
--- /dev/null
+++ b/model/pipeline/builder.ts
@@ -0,0 +1,53 @@
+import { Pipeline, PipelineStage } from '.';
+import { FetchCodeJob } from '../job';
+import { PipelineImpl } from './impl';
+
+export interface PipelineBuilder {
+ addStage(stage: PipelineStage): PipelineBuilder;
+ build(): Pipeline;
+}
+
+export abstract class BasePipelineBuilder implements PipelineBuilder {
+ protected readonly stages: Array<PipelineStage> = [];
+
+ public addStage(stage: PipelineStage): PipelineBuilder {
+ this.stages.push(stage);
+ return this;
+ }
+
+ public build() {
+ return new PipelineImpl(this.stages);
+ }
+}
+
+export class DefaultGitHookPipelineBuilder extends BasePipelineBuilder {
+ constructor(
+ private readonly remoteUrl = process.env.remote!,
+ rev = process.env.rev!,
+ private readonly ref = process.env.ref!,
+ ) {
+ super();
+
+ this.addStage({
+ parallelJobs: [
+ <FetchCodeJob>{
+ type: 'fetch_code.ts',
+ arguments: {
+ remoteUrl,
+ checkout: rev,
+ path: this.getSourceDestination(),
+ },
+ },
+ ],
+ });
+ }
+
+ public getSourceDestination() {
+ return this.remoteUrl.split('/').at(-1) ?? 'src';
+ }
+
+ public getBranch(): string | undefined {
+ const branchRefPrefix = 'refs/heads/';
+ return this.ref.split(branchRefPrefix).at(1);
+ }
+}
diff --git a/model/pipeline/impl.ts b/model/pipeline/impl.ts
new file mode 100644
index 0000000..2e08d6e
--- /dev/null
+++ b/model/pipeline/impl.ts
@@ -0,0 +1,20 @@
+import { Either, IEither } from '@emprespresso/pengueno';
+import { isPipeline, Pipeline, PipelineStage } from '.';
+
+export class PipelineImpl implements Pipeline {
+ constructor(public readonly serialJobs: Array<PipelineStage>) {}
+
+ public serialize() {
+ return JSON.stringify(this.serialJobs);
+ }
+
+ public static from(s: string): IEither<Error, Pipeline> {
+ return Either.fromFailable<Error, unknown>(() => JSON.parse(s))
+ .flatMap<Pipeline>((eitherPipelineJson) =>
+ isPipeline(eitherPipelineJson)
+ ? Either.right(eitherPipelineJson)
+ : Either.left(new Error('oh noes D: its a bad pipewine :((')),
+ )
+ .mapRight((pipeline) => new PipelineImpl(pipeline.serialJobs));
+ }
+}
diff --git a/model/pipeline/index.ts b/model/pipeline/index.ts
new file mode 100644
index 0000000..adf902b
--- /dev/null
+++ b/model/pipeline/index.ts
@@ -0,0 +1,19 @@
+import { isObject } from '@emprespresso/pengueno';
+import { isJob, Job } from '../job';
+
+export interface PipelineStage {
+ readonly parallelJobs: Array<Job>;
+}
+export const isPipelineStage = (t: unknown): t is PipelineStage =>
+ isObject(t) && 'parallelJobs' in t && Array.isArray(t.parallelJobs) && t.parallelJobs.every((j) => isJob(j));
+
+export const isPipeline = (t: unknown): t is Pipeline =>
+ isObject(t) && 'serialJobs' in t && Array.isArray(t.serialJobs) && t.serialJobs.every((p) => isPipelineStage(p));
+
+export interface Pipeline {
+ readonly serialJobs: Array<PipelineStage>;
+ serialize(): string;
+}
+
+export * from './builder';
+export * from './impl';
diff --git a/model/tsconfig.json b/model/tsconfig.json
new file mode 100644
index 0000000..7ad21ad
--- /dev/null
+++ b/model/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" }]
+}