Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"@types/node": "^22.13.10",
"@typescript-eslint/eslint-plugin": "8.57.1",
"@typescript-eslint/parser": "8.57.1",
"eslint": "~8.57.0",
"eslint": "^10.1.0",
"nx": "^22.5.4",
"tsx": "^4.19.3",
"typescript": "^5.8.2",
Expand Down
7 changes: 7 additions & 0 deletions packages/devkit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# @cloud-cli/devkit

## 0.1.0

### Patch Changes

Introduce toobelt package
1 change: 1 addition & 0 deletions packages/devkit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# Devkit
29 changes: 29 additions & 0 deletions packages/devkit/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@cloud-cli/on-devkit",
"version": "0.1.0",
"description": "Toolbelt for workflows",
"type": "module",
"exports": {
".": {
"types": "./src/index.ts",
"default": "./dist/on-devkit.js"
},
"./types": "./src/index.ts"
},
"files": [
"dist",
"src"
],
"engines": {
"node": ">=20"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"license": "MIT",
"repository": {
"url": "https://github.com/cloud-cli/on"
},
"dependencies": {}
}
12 changes: 12 additions & 0 deletions packages/devkit/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "devkit",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/on/src",
"projectType": "library",
"targets": {
"build": {},
"test": {},
"lint": {}
},
"tags": []
}
9 changes: 9 additions & 0 deletions packages/devkit/src/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { test, expect } from "vitest";
import { interpolate } from "./index.js";

test("should interpolate a JS snippet with a context object", async () => {
const context = { foo: true, bar: "world" };
const template = "Hello ${bar}! The value of foo is ${foo}.";
const result = interpolate(template, context);
expect(result).toBe("Hello world! The value of foo is true.");
});
44 changes: 44 additions & 0 deletions packages/devkit/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ChildProcess } from "child_process";

export function interpolate(template: string, context: any): string {
const keys = Object.keys(context);
const f = Function(
"__",
"const { " + keys.join(", ") + " } = __;return `" + template + "`;",
);

return String(f(context) || "");
}

export interface StepOutput {
code: number;
cmd: string;
stdout: string;
stderr: string;
}

export function getStepOutput(
cmd: string,
childProcess: ChildProcess,
): Promise<StepOutput> {
const stdout: Buffer[] = [];
const stderr: Buffer[] = [];

childProcess.stdout!.on("data", (data: Buffer) => stdout.push(data));
childProcess.stderr!.on("data", (data: Buffer) => stderr.push(data));

return new Promise<StepOutput>((resolve, reject) => {
childProcess.once("error", reject);
childProcess.once("exit", (code: number | null) => {
resolve({
code: code ?? 0,
cmd,
stdout: Buffer.concat(stdout).toString("utf-8"),
stderr: Buffer.concat(stderr).toString("utf-8"),
});
});

childProcess.stdin?.write(cmd);
childProcess.stdin?.end();
});
}
8 changes: 8 additions & 0 deletions packages/devkit/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "."
},
"include": ["src/**/*.ts"],
"exclude": ["dist/**/*", "node_modules", "src/**/*.spec.ts"]
}
8 changes: 8 additions & 0 deletions packages/devkit/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./dist/"
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.spec.ts"]
}
2 changes: 2 additions & 0 deletions packages/devkit/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { asLib } from "../../vite.config.base.js";
export default asLib(import.meta.dirname, ["src/index.ts"]);
2 changes: 2 additions & 0 deletions packages/devkit/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import config from "../../vitest.config.base.js";
export default config(import.meta.dirname);
20 changes: 20 additions & 0 deletions packages/on-runner-docker/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@cloud-cli/on-runner-docker",
"version": "0.1.0",
"description": "Docker runner for @cloud-cli/on workflows.",
"type": "module",
"main": "./dist/on-runner-docker.js",
"exports": {
".": "./dist/on-runner-docker.js"
},
"files": [
"dist"
],
"engines": {
"node": ">=20"
},
"license": "MIT",
"repository": {
"url": "https://github.com/cloud-cli/on"
}
}
12 changes: 12 additions & 0 deletions packages/on-runner-docker/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "on-runner-docker",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/on-runner-docker/src",
"projectType": "library",
"targets": {
"build": {},
"test": {},
"lint": {}
},
"tags": []
}
82 changes: 82 additions & 0 deletions packages/on-runner-docker/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { spawn } from "node:child_process";
import { interpolate, getStepOutput } from "@cloud-cli/on-devkit";
import type { StepDefinition, WorkflowContext } from "@cloud-cli/on";

export const defaultWorkspace = "/workspace";

export const defaults = {
image: "dhi.io/alpine-base:3.23-alpine3.23-dev",
volumes: {
".": defaultWorkspace,
},
args: [],
};

export interface DockerStep extends StepDefinition {
image?: string;
volumes?: Record<string, string>;
args?: Array<Record<string, string>>;
}

export function prepareDockerStep(
step: StepDefinition,
context: WorkflowContext,
) {
const workflowDefaults = context.workflow.defaults || {};
return { ...defaults, ...workflowDefaults, ...step } as Required<DockerStep>;
}

export function prepareDockerArgs(
args: Record<string, string>[],
context: WorkflowContext,
): string[] {
return (args || []).flatMap((arg) =>
Object.entries(arg).flatMap(([key, value]) => [
`--${key}`,
interpolate(String(value), context),
]),
);
}

export function prepareDockerVolumes(
volumes: Record<string, string>,
context: WorkflowContext,
): string[] {
volumes["."] ||= defaultWorkspace;
return Object.entries(volumes).flatMap(([hostPath, containerPath]) => [
"-v",
`${hostPath === "." ? context.workingDir : hostPath}:${containerPath}`,
]);
}

function prepareDockerShell(step: StepDefinition, context: WorkflowContext) {
const prepared = prepareDockerStep(step, context);
const { args, image, volumes } = prepared;
const mappedVolumes = prepareDockerVolumes(volumes, context);
const mappedArgs = prepareDockerArgs(args, context);
const workingDir = volumes["."];
const dockerArgs = [
"run",
"-i",
"--rm",
...mappedVolumes,
...mappedArgs,
"-w",
workingDir,
"--entrypoint",
"sh",
image,
] as string[];

return spawn("docker", dockerArgs, {
env: context.env,
});
}

export function run<S extends StepDefinition, W extends WorkflowContext>(
step: S,
context: W,
) {
const shell = prepareDockerShell(step, context);
return getStepOutput(cmd, shell);
}
5 changes: 5 additions & 0 deletions packages/on-runner-docker/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["dist/**/*", "node_modules", "src/**/*.spec.ts"]
}
8 changes: 8 additions & 0 deletions packages/on-runner-docker/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./dist/"
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.spec.ts"]
}
3 changes: 3 additions & 0 deletions packages/on-runner-docker/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { asLib } from "../../vite.config.base.js";

export default asLib(import.meta.dirname);
3 changes: 3 additions & 0 deletions packages/on-runner-docker/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import config from "../../vitest.config.base.js";

export default config(import.meta.dirname);
20 changes: 20 additions & 0 deletions packages/on-runner-shell/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "@cloud-cli/on-runner-shell",
"version": "0.1.0",
"description": "Shell runner for @cloud-cli/on workflows.",
"type": "module",
"main": "./dist/on-runner-shell.js",
"exports": {
".": "./dist/on-runner-shell.js"
},
"files": [
"dist"
],
"engines": {
"node": ">=20"
},
"license": "MIT",
"repository": {
"url": "https://github.com/cloud-cli/on"
}
}
12 changes: 12 additions & 0 deletions packages/on-runner-shell/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "on-runner-shell",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/on-runner-shell/src",
"projectType": "library",
"targets": {
"build": {},
"test": {},
"lint": {}
},
"tags": []
}
17 changes: 17 additions & 0 deletions packages/on-runner-shell/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { spawn } from "node:child_process";
import { getStepOutput } from "@cloud-cli/on-devkit";
import type { StepDefinition, WorkflowContext } from "@cloud-cli/on/types";

const SHELL = process.env.SHELL || "sh";

export function run(step: StepDefinition, context: WorkflowContext) {
const shell = spawn(SHELL, {
shell: true,
env: context.env,
cwd: step.workingDir || context.workingDir || process.cwd(),
});

const cmd = step.run + "\nexit $?;\n";

return getStepOutput(cmd, shell);
}
5 changes: 5 additions & 0 deletions packages/on-runner-shell/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src/**/*.ts"],
"exclude": ["dist/**/*", "node_modules", "src/**/*.spec.ts"]
}
8 changes: 8 additions & 0 deletions packages/on-runner-shell/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./dist/"
},
"include": ["src/**/*.ts"],
"exclude": ["src/**/*.spec.ts"]
}
3 changes: 3 additions & 0 deletions packages/on-runner-shell/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { asLib } from "../../vite.config.base.js";

export default asLib(import.meta.dirname);
3 changes: 3 additions & 0 deletions packages/on-runner-shell/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import config from "../../vitest.config.base.js";

export default config(import.meta.dirname);
5 changes: 5 additions & 0 deletions packages/on/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"on": "./dist/on.js"
},
"main": "./dist/on.js",
"exports": {
".": "./dist/on.js",
"./types": "./dist/types.js"
},
"files": [
"dist"
],
Expand All @@ -22,6 +26,7 @@
"url": "https://github.com/cloud-cli/on"
},
"dependencies": {
"@cloud-cli/on-devkit": "workspace:*",
"ansi_up": "6.0.6",
"yaml": "^2.8.2"
}
Expand Down
Loading
Loading