@cloud-cli/on 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/dashboard.d.ts +1 -1
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/events.d.ts +12 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/on.js +233 -85
- package/dist/parser/yaml-loader.d.ts.map +1 -1
- package/dist/queue.d.ts +4 -3
- package/dist/queue.d.ts.map +1 -1
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/worker.d.ts +3 -2
- package/dist/worker.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -82,6 +82,9 @@ concurrency:
|
|
|
82
82
|
group: release-${inputs.repo}
|
|
83
83
|
cancel-in-progress: true
|
|
84
84
|
|
|
85
|
+
# Every tag must be advertised by the worker that claims this workflow.
|
|
86
|
+
tags: [linux, docker]
|
|
87
|
+
|
|
85
88
|
steps:
|
|
86
89
|
- id: checkout
|
|
87
90
|
name: Checkout Code Repository
|
|
@@ -147,7 +150,7 @@ npx @cloud-cli/on [command] [options]
|
|
|
147
150
|
| Command | Description |
|
|
148
151
|
| ------------------- | ---------------------------------------------------------------------------------------- |
|
|
149
152
|
| **`start-server`** | Runs Webhook Ingress Gateway (the HTTP server receiving webhooks). |
|
|
150
|
-
| **`start-workers`** | Runs
|
|
153
|
+
| **`start-workers`** | Runs the event-driven worker scheduler (Scalable Workers). |
|
|
151
154
|
| **`validate`** | Parses and validates all YAML workflows in your workflows folder without executing jobs. |
|
|
152
155
|
|
|
153
156
|
### CLI and Environment Options
|
|
@@ -159,8 +162,12 @@ npx @cloud-cli/on [command] [options]
|
|
|
159
162
|
| `-d` | `--database` | - | `RUNNER_DATABASE_URL` | SQLite database file path or HTTP URL. |
|
|
160
163
|
| `-w` | `--workflows` | `on/` | `RUNNER_WORKFLOWS` | Directory where workflow YAML files live. |
|
|
161
164
|
| `-p` | `--port` | `11235` | `PORT` | Port for the Ingress HTTP server. |
|
|
162
|
-
| `-k` | `--workers` | `5` | `RUNNER_WORKERS` |
|
|
165
|
+
| `-k` | `--workers` | `5` | `RUNNER_WORKERS` | Maximum concurrent jobs on this node. |
|
|
163
166
|
| | | | `RUNNER_ADMIN_SECRET` | Admin token to refresh secrets via API |
|
|
167
|
+
| | | | `RUNNER_SERVER_URL` | Webhook server URL used by workers. |
|
|
168
|
+
| | | | `RUNNER_TAGS` | Comma-separated worker capability tags. |
|
|
169
|
+
|
|
170
|
+
Set the same non-empty `RUNNER_ADMIN_SECRET` on the server and workers to publish live job-status refresh events. Job availability and the 60-second recovery refresh continue to work without it.
|
|
164
171
|
|
|
165
172
|
### Secrets
|
|
166
173
|
|
|
@@ -177,6 +184,8 @@ import { HtmlReporter, SlackReporter, JsonFileReporter } from '@cloud-cli/on/rep
|
|
|
177
184
|
export default {
|
|
178
185
|
port: 3000,
|
|
179
186
|
workers: 5,
|
|
187
|
+
serverUrl: 'https://runner.example.com/',
|
|
188
|
+
tags: ['linux', 'docker'],
|
|
180
189
|
workflows: '/home/workflows/',
|
|
181
190
|
storagePath: '/tmp/workspaces',
|
|
182
191
|
database: 'https://remote.db.com/',
|
|
@@ -250,6 +259,7 @@ The Ingress Gateway listens for incoming HTTP requests and serves the live web U
|
|
|
250
259
|
| ---------- | ------------------ | -------------------------------------------------------------------------------------- |
|
|
251
260
|
| **`POST`** | `/webhooks/github` | Webhook endpoint for GitHub events. Applies GitHub filters and evaluates `on.github.if`. |
|
|
252
261
|
| **`GET`** | `/runs` | **Dashboard:** Live dark-mode monitoring page listing recent jobs and worker health. |
|
|
262
|
+
| **`GET`** | `/api/jobs?afterId=<id>&beforeId=<id>&limit=<n>` | Dashboard jobs with exclusive lower and upper ID cursors and a limit from 1 to 500 (default 50). |
|
|
253
263
|
| **`GET`** | `/runs/:jobId` | **Job Report:** Interactive HTML trace view with step timings and terminal log output. |
|
|
254
264
|
|
|
255
265
|
### Dashboard Features
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG5D,wBAAsB,UAAU,CAAC,MAAM,KAAA,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAyBrE;AAED,wBAAgB,aAAa,CAAC,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG5D,wBAAsB,UAAU,CAAC,MAAM,KAAA,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAyBrE;AAED,wBAAgB,aAAa,CAAC,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,GAAG,YAAY,CAgB7G;AAED,wBAAgB,SAAS,SAwBxB;AAED,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAwB9F"}
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -7,5 +7,5 @@ export interface DashboardJob {
|
|
|
7
7
|
updatedAt: string;
|
|
8
8
|
}
|
|
9
9
|
export declare function toDashboardJobs(rows: any[]): DashboardJob[];
|
|
10
|
-
export declare function generateDashboardHtml(jobs: DashboardJob[]): string;
|
|
10
|
+
export declare function generateDashboardHtml(jobs: DashboardJob[], hasMore?: boolean): string;
|
|
11
11
|
//# sourceMappingURL=dashboard.d.ts.map
|
package/dist/dashboard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,CAS3D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,YAAY,EAAE,CAS3D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,OAAO,UAAQ,GAAG,MAAM,CAEnF"}
|
package/dist/events.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type http from 'node:http';
|
|
2
|
+
export type RunnerEvent = 'jobs.available' | 'jobs.changed';
|
|
3
|
+
export declare class EventBroker {
|
|
4
|
+
private clients;
|
|
5
|
+
private nextId;
|
|
6
|
+
private readonly maxClients;
|
|
7
|
+
subscribe(req: http.IncomingMessage, res: http.ServerResponse): void;
|
|
8
|
+
publish(event: RunnerEvent, data?: Record<string, unknown>): void;
|
|
9
|
+
close(): void;
|
|
10
|
+
}
|
|
11
|
+
export declare function consumeRunnerEvents(serverUrl: string, signal: AbortSignal, onEvent: (event: RunnerEvent, data: Record<string, unknown>) => void, onOpen?: () => void): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,MAAM,WAAW,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAE5D,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAkD;IACjE,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IAEnC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,GAAG,IAAI;IAuBpE,OAAO,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAUrE,KAAK,IAAI,IAAI;CAOd;AAED,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EACpE,MAAM,CAAC,EAAE,MAAM,IAAI,GAClB,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
|
package/dist/on.js
CHANGED
|
@@ -63,20 +63,22 @@ async function le(e) {
|
|
|
63
63
|
return t(o.workflows) ? (ce(o.database), o) : (console.warn(`⚠️ Warning: Workflows directory '${o.workflows}' not found.`), null);
|
|
64
64
|
}
|
|
65
65
|
function ue(e, t) {
|
|
66
|
-
let n = process.env;
|
|
66
|
+
let n = process.env, r = Number(e.port || t.port || n.PORT || 11235), i = e.tags ?? (n.RUNNER_TAGS ? n.RUNNER_TAGS.split(",") : []);
|
|
67
67
|
return {
|
|
68
|
-
port:
|
|
68
|
+
port: r,
|
|
69
69
|
adminToken: e.adminToken ?? n.RUNNER_ADMIN_SECRET ?? "",
|
|
70
70
|
database: e.database ?? t.database ?? n.RUNNER_DATABASE_URL ?? "",
|
|
71
71
|
workflows: e.workflows ?? t.workflows ?? n.RUNNER_WORKFLOWS ?? "on/",
|
|
72
72
|
workers: Number(e.workers ?? t.workers ?? n.RUNNER_WORKERS ?? 5),
|
|
73
|
+
serverUrl: e.serverUrl ?? n.RUNNER_SERVER_URL ?? `http://127.0.0.1:${r}`,
|
|
74
|
+
tags: i.map((e) => e.trim()).filter(Boolean),
|
|
73
75
|
storagePath: e.storagePath ?? n.RUNNER_TMP ?? "/tmp/workspaces",
|
|
74
76
|
env: e.env ?? {},
|
|
75
77
|
reporters: e.reporters ?? []
|
|
76
78
|
};
|
|
77
79
|
}
|
|
78
80
|
function de() {
|
|
79
|
-
console.log("\n🏃 Runner CLI 🏃\n\nUsage:\n npx -y @cloud-cli/on <command> [options]\n pnpm dlx -y @cloud-cli/on <command> [options]\n\nCommands:\n start Runs both Webhook Ingress Server and Workers (Default)\n start-server Runs Webhook Ingress Server only (API Gateway mode)\n start-workers Runs
|
|
81
|
+
console.log("\n🏃 Runner CLI 🏃\n\nUsage:\n npx -y @cloud-cli/on <command> [options]\n pnpm dlx -y @cloud-cli/on <command> [options]\n\nCommands:\n start Runs both Webhook Ingress Server and Workers (Default)\n start-server Runs Webhook Ingress Server only (API Gateway mode)\n start-workers Runs event-driven workers (Scalable Worker mode)\n validate Parses and validates workflow YAML files without running\n\nOptions:\n -c, --config Path to runner.config.mjs (default: ./runner.config.mjs, env: RUNNER_CONFIG_PATH)\n -d, --database SQLite Database URL (env: RUNNER_DATABASE_URL)\n -w, --workflows Path to where your workflows are defined (default: on/, env: RUNNER_WORKFLOWS_PATH)\n -p, --port Port for Webhook Ingress Server (default: 11235, env: PORT)\n -k, --workers Maximum concurrent jobs (default: 5, env: RUNNER_WORKERS)\n Worker tags (comma-separated env: RUNNER_TAGS)\n Webhook server URL (env: RUNNER_SERVER_URL)\n -h, --help Show this help message\n ");
|
|
80
82
|
}
|
|
81
83
|
async function fe() {
|
|
82
84
|
let { values: e, positionals: t } = l({
|
|
@@ -4462,8 +4464,11 @@ var pi = class {
|
|
|
4462
4464
|
JSON.stringify(t)
|
|
4463
4465
|
]);
|
|
4464
4466
|
}
|
|
4465
|
-
async claimNextJob() {
|
|
4466
|
-
return await S.get("\n UPDATE jobs\n SET\n status = 'running',\n worker_id = ?,\n started_at = CURRENT_TIMESTAMP\n WHERE id = (\n SELECT id FROM jobs\n WHERE status = 'pending'\n ORDER BY created_at ASC\n LIMIT 1\n )\n RETURNING *;\n ", [this.workerId]) || null;
|
|
4467
|
+
async claimNextJob(e = []) {
|
|
4468
|
+
return await S.get("\n UPDATE jobs\n SET\n status = 'running',\n worker_id = ?,\n started_at = CURRENT_TIMESTAMP\n WHERE id = (\n SELECT id FROM jobs\n WHERE status = 'pending'\n AND NOT EXISTS (\n SELECT 1\n FROM json_each(COALESCE(json_extract(jobs.payload, '$.tags'), '[]')) AS required_tag\n WHERE required_tag.value NOT IN (SELECT value FROM json_each(?))\n )\n ORDER BY created_at ASC\n LIMIT 1\n )\n RETURNING *;\n ", [this.workerId, JSON.stringify(e)]) || null;
|
|
4469
|
+
}
|
|
4470
|
+
async releaseJob(e) {
|
|
4471
|
+
await S.run("UPDATE jobs SET status = 'pending', worker_id = NULL, started_at = NULL WHERE id = ? AND status = 'running';", [e]);
|
|
4467
4472
|
}
|
|
4468
4473
|
async finishJob(e, t) {
|
|
4469
4474
|
await S.run("UPDATE jobs SET status = ?, finished_at = CURRENT_TIMESTAMP WHERE id = ?;", [t, e]);
|
|
@@ -4491,8 +4496,11 @@ var pi = class {
|
|
|
4491
4496
|
async getJob(e) {
|
|
4492
4497
|
return S.get("SELECT * FROM jobs WHERE id = ?", [e]);
|
|
4493
4498
|
}
|
|
4494
|
-
async listJobs(e = 50) {
|
|
4495
|
-
|
|
4499
|
+
async listJobs(e = 50, t, n) {
|
|
4500
|
+
let r = [], i = [];
|
|
4501
|
+
t !== void 0 && (r.push("id > ?"), i.push(t)), n !== void 0 && (r.push("id < ?"), i.push(n));
|
|
4502
|
+
let a = r.length ? ` WHERE ${r.join(" AND ")}` : "";
|
|
4503
|
+
return S.all(`SELECT * FROM jobs${a} ORDER BY id DESC LIMIT ?;`, [...i, e]);
|
|
4496
4504
|
}
|
|
4497
4505
|
async saveReport(e, t) {
|
|
4498
4506
|
await S.run("UPDATE jobs SET report = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?", [JSON.stringify(t), e]);
|
|
@@ -8021,7 +8029,8 @@ var Po = "<!DOCTYPE html>\n<html lang=\"en\" class=\"dark\">\n<head>\n <meta ch
|
|
|
8021
8029
|
},
|
|
8022
8030
|
concurrency: t.concurrency,
|
|
8023
8031
|
steps: t.steps,
|
|
8024
|
-
env: t.env
|
|
8032
|
+
env: t.env,
|
|
8033
|
+
tags: Array.isArray(t.tags) ? [...new Set(t.tags.filter((e) => typeof e == "string").map((e) => e.trim()).filter(Boolean))] : void 0
|
|
8025
8034
|
});
|
|
8026
8035
|
}
|
|
8027
8036
|
} catch (t) {
|
|
@@ -8029,7 +8038,7 @@ var Po = "<!DOCTYPE html>\n<html lang=\"en\" class=\"dark\">\n<head>\n <meta ch
|
|
|
8029
8038
|
}
|
|
8030
8039
|
return n;
|
|
8031
8040
|
}
|
|
8032
|
-
}, Ro = "<!DOCTYPE html>\n<html lang=\"en\" class=\"dark\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Workflow Engine Dashboard</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\" } }\n <\/script>\n</head>\n<body class=\"bg-gray-950 text-gray-100 min-h-screen p-4 md:p-6 font-sans\">\n <template app>\n <main class=\"max-w-6xl mx-auto space-y-6\">\n <header class=\"flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-gray-800 pb-4\">\n <div>\n <h1 class=\"text-2xl font-bold text-white\">Runner Engine Status</h1>\n <p class=\"text-xs text-gray-400\">Live Job Queue & Execution Traces</p>\n </div>\n <div class=\"flex items-center gap-3 text-xs font-mono\">\n <span class=\"text-gray-500\">Updated {{ lastUpdated }}</span>\n <span\n class=\"px-3 py-1 rounded-full border\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400.border-emerald-500/20': !refreshError,\n 'bg-rose-500/10.text-rose-400.border-rose-500/20': refreshError\n }\"\n >\n {{ refreshError ? 'Refresh failed' : 'System operational' }}\n </span>\n </div>\n </header>\n\n <section class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden hidden md:block\">\n <table class=\"w-full text-left text-sm\">\n <thead class=\"bg-gray-800/50 text-gray-400 text-xs uppercase font-mono border-b border-gray-800\">\n <tr>\n <th class=\"py-3 px-4\">Job ID</th>\n <th class=\"py-3 px-4\">Workflow</th>\n <th class=\"py-3 px-4\">Status</th>\n <th class=\"py-3 px-4 hidden xl:table-cell\">Worker</th>\n <th class=\"py-3 px-4 hidden lg:table-cell\">Created At</th>\n <th class=\"py-3 px-4 text-right\">Action</th>\n </tr>\n </thead>\n <tbody>\n <template for=\"job of jobs\">\n <tr class=\"border-b border-gray-800 hover:bg-gray-800/40 transition\">\n <td class=\"py-3 px-4 font-mono text-indigo-400\">\n <a attr-href=\"'/runs/' + job.id\" class=\"hover:underline\">#{{ job.id }}</a>\n </td>\n <td class=\"py-3 px-4 font-medium text-white\">{{ job.workflowId }}</td>\n <td class=\"py-3 px-4\">\n <span\n class=\"px-2.5 py-0.5 rounded-full text-xs font-semibold\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400': job.status === 'success',\n 'bg-rose-500/10.text-rose-400': job.status === 'failed',\n 'bg-indigo-500/10.text-indigo-400.animate-pulse': job.status === 'running',\n 'bg-gray-500/10.text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n >\n {{ upper(job.status) }}\n </span>\n </td>\n <td class=\"py-3 px-4 hidden xl:table-cell text-xs font-mono text-gray-400\">{{ job.workerId || '-' }}</td>\n <td class=\"py-3 px-4 hidden lg:table-cell text-xs text-gray-400\">{{ job.createdAt }}</td>\n <td class=\"py-3 px-4 text-right whitespace-nowrap\">\n <a attr-href=\"'/runs/' + job.id\" class=\"text-xs bg-gray-800 hover:bg-gray-700 text-gray-200 px-3 py-1 rounded border border-gray-700\">View Trace</a>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">No jobs recorded yet.</div>\n </template>\n </section>\n\n <section class=\"md:hidden bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800 overflow-hidden\">\n <template for=\"job of jobs\">\n <article class=\"p-4 bg-gray-900/60\">\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <span\n class=\"w-2.5 h-2.5 rounded-full shrink-0\"\n bind-class=\"{\n 'bg-emerald-400': job.status === 'success',\n 'bg-rose-400': job.status === 'failed',\n 'bg-indigo-400.animate-pulse': job.status === 'running',\n 'bg-gray-500': !['success', 'failed', 'running'].includes(job.status)\n }\"\n ></span>\n <h2 class=\"font-medium text-white truncate\">{{ job.workflowId }}</h2>\n </div>\n <p class=\"mt-1 pl-[18px] text-xs font-mono text-gray-400\">#{{ job.id }} · {{ upper(job.status) }}</p>\n </div>\n <a attr-href=\"'/runs/' + job.id\" class=\"shrink-0 text-xs bg-gray-800 hover:bg-gray-700 text-gray-300 px-2.5 py-1 rounded border border-gray-700\">Trace</a>\n </div>\n </article>\n </template>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">No jobs recorded yet.</div>\n </template>\n </section>\n </main>\n\n <script setup>\n import { onDestroy, onInit, ref } from '@li3/web';\n\n export default function setup() {\n const jobs = ref([]);\n const lastUpdated = ref('now');\n const refreshError = ref(false);\n let refreshTimer;\n let refreshing = false;\n\n const upper = (value) => String(value || '').toUpperCase();\n const refreshJobs = async () => {\n if (refreshing) return;\n refreshing = true;\n\n try {\n const
|
|
8041
|
+
}, Ro = "<!DOCTYPE html>\n<html lang=\"en\" class=\"dark\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Workflow Engine Dashboard</title>\n <script type=\"importmap\">\n { \"imports\": { \"@li3/\": \"https://cdn.li3.dev/@li3/\" } }\n <\/script>\n</head>\n<body class=\"bg-gray-950 text-gray-100 min-h-screen p-4 md:p-6 font-sans\">\n <template app>\n <main class=\"max-w-6xl mx-auto space-y-6\">\n <header class=\"flex flex-col sm:flex-row sm:items-center justify-between gap-3 border-b border-gray-800 pb-4\">\n <div>\n <h1 class=\"text-2xl font-bold text-white\">Runner Engine Status</h1>\n <p class=\"text-xs text-gray-400\">Live Job Queue & Execution Traces</p>\n </div>\n <div class=\"flex items-center gap-3 text-xs font-mono\">\n <span class=\"text-gray-500\">Updated {{ lastUpdated }}</span>\n <span\n class=\"px-3 py-1 rounded-full border\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400.border-emerald-500/20': !refreshError,\n 'bg-rose-500/10.text-rose-400.border-rose-500/20': refreshError\n }\"\n >\n {{ refreshError ? 'Refresh failed' : 'System operational' }}\n </span>\n </div>\n </header>\n\n <section class=\"bg-gray-900 border border-gray-800 rounded-xl overflow-hidden hidden md:block\">\n <table class=\"w-full text-left text-sm\">\n <thead class=\"bg-gray-800/50 text-gray-400 text-xs uppercase font-mono border-b border-gray-800\">\n <tr>\n <th class=\"py-3 px-4\">Job ID</th>\n <th class=\"py-3 px-4\">Workflow</th>\n <th class=\"py-3 px-4\">Status</th>\n <th class=\"py-3 px-4 hidden xl:table-cell\">Worker</th>\n <th class=\"py-3 px-4 hidden lg:table-cell\">Created At</th>\n <th class=\"py-3 px-4 text-right\">Action</th>\n </tr>\n </thead>\n <tbody>\n <template for=\"job of jobs\">\n <tr class=\"border-b border-gray-800 hover:bg-gray-800/40 transition\">\n <td class=\"py-3 px-4 font-mono text-indigo-400\">\n <a attr-href=\"'/runs/' + job.id\" class=\"hover:underline\">#{{ job.id }}</a>\n </td>\n <td class=\"py-3 px-4 font-medium text-white\">{{ job.workflowId }}</td>\n <td class=\"py-3 px-4\">\n <span\n class=\"px-2.5 py-0.5 rounded-full text-xs font-semibold\"\n bind-class=\"{\n 'bg-emerald-500/10.text-emerald-400': job.status === 'success',\n 'bg-rose-500/10.text-rose-400': job.status === 'failed',\n 'bg-indigo-500/10.text-indigo-400.animate-pulse': job.status === 'running',\n 'bg-gray-500/10.text-gray-400': !['success', 'failed', 'running'].includes(job.status)\n }\"\n >\n {{ upper(job.status) }}\n </span>\n </td>\n <td class=\"py-3 px-4 hidden xl:table-cell text-xs font-mono text-gray-400\">{{ job.workerId || '-' }}</td>\n <td class=\"py-3 px-4 hidden lg:table-cell text-xs text-gray-400\">{{ job.createdAt }}</td>\n <td class=\"py-3 px-4 text-right whitespace-nowrap\">\n <a attr-href=\"'/runs/' + job.id\" class=\"text-xs bg-gray-800 hover:bg-gray-700 text-gray-200 px-3 py-1 rounded border border-gray-700\">View Trace</a>\n </td>\n </tr>\n </template>\n </tbody>\n </table>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">No jobs recorded yet.</div>\n </template>\n </section>\n\n <section class=\"md:hidden bg-gray-900 border border-gray-800 rounded-xl divide-y divide-gray-800 overflow-hidden\">\n <template for=\"job of jobs\">\n <article class=\"p-4 bg-gray-900/60\">\n <div class=\"flex items-start justify-between gap-3\">\n <div class=\"min-w-0\">\n <div class=\"flex items-center gap-2\">\n <span\n class=\"w-2.5 h-2.5 rounded-full shrink-0\"\n bind-class=\"{\n 'bg-emerald-400': job.status === 'success',\n 'bg-rose-400': job.status === 'failed',\n 'bg-indigo-400.animate-pulse': job.status === 'running',\n 'bg-gray-500': !['success', 'failed', 'running'].includes(job.status)\n }\"\n ></span>\n <h2 class=\"font-medium text-white truncate\">{{ job.workflowId }}</h2>\n </div>\n <p class=\"mt-1 pl-[18px] text-xs font-mono text-gray-400\">#{{ job.id }} · {{ upper(job.status) }}</p>\n </div>\n <a attr-href=\"'/runs/' + job.id\" class=\"shrink-0 text-xs bg-gray-800 hover:bg-gray-700 text-gray-300 px-2.5 py-1 rounded border border-gray-700\">Trace</a>\n </div>\n </article>\n </template>\n <template if=\"!jobs.length\">\n <div class=\"p-8 text-center text-gray-500\">No jobs recorded yet.</div>\n </template>\n </section>\n\n <template if=\"hasMore\">\n <div class=\"flex justify-center\">\n <button\n class=\"px-4 py-2 text-sm text-gray-200 bg-gray-800 hover:bg-gray-700 border border-gray-700 rounded-lg\"\n on-click=\"loadMore()\"\n >\n {{ loadingMore ? 'Loading...' : 'Load more' }}\n </button>\n </div>\n </template>\n </main>\n\n <script setup>\n import { onDestroy, onInit, ref } from '@li3/web';\n\n export default function setup() {\n const jobs = ref([]);\n const lastUpdated = ref('now');\n const refreshError = ref(false);\n const hasMore = ref(false);\n const loadingMore = ref(false);\n let refreshTimer;\n let eventSource;\n let refreshing = false;\n let refreshPending = false;\n\n const upper = (value) => String(value || '').toUpperCase();\n const terminalStatuses = new Set(['success', 'failed', 'cancelled']);\n const refreshJobs = async () => {\n if (refreshing) {\n refreshPending = true;\n return;\n }\n refreshing = true;\n\n try {\n const activeIds = jobs.value\n .filter((job) => !terminalStatuses.has(job.status))\n .map((job) => Number(job.id));\n const knownIds = jobs.value.map((job) => Number(job.id));\n const afterId = activeIds.length\n ? Math.max(0, Math.min(...activeIds) - 1)\n : knownIds.length\n ? Math.max(...knownIds)\n : null;\n const url = afterId === null ? '/api/jobs?limit=500' : `/api/jobs?afterId=${afterId}&limit=500`;\n const response = await fetch(url, { headers: { accept: 'application/json' } });\n if (!response.ok) throw new Error(`Dashboard refresh failed: ${response.status}`);\n\n const data = await response.json();\n const merged = new Map(jobs.value.map((job) => [job.id, job]));\n for (const job of data.jobs) merged.set(job.id, job);\n jobs.value = Array.from(merged.values()).sort((a, b) => Number(b.id) - Number(a.id));\n lastUpdated.value = new Date().toLocaleTimeString();\n refreshError.value = false;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n refreshing = false;\n if (refreshPending) {\n refreshPending = false;\n void refreshJobs();\n }\n }\n };\n\n const loadMore = async () => {\n if (loadingMore.value || !hasMore.value || !jobs.value.length) return;\n loadingMore.value = true;\n\n try {\n const beforeId = Math.min(...jobs.value.map((job) => Number(job.id)));\n const response = await fetch(`/api/jobs?beforeId=${beforeId}`, {\n headers: { accept: 'application/json' },\n });\n if (!response.ok) throw new Error(`Loading older jobs failed: ${response.status}`);\n\n const data = await response.json();\n const merged = new Map(jobs.value.map((job) => [job.id, job]));\n for (const job of data.jobs) merged.set(job.id, job);\n jobs.value = Array.from(merged.values()).sort((a, b) => Number(b.id) - Number(a.id));\n hasMore.value = data.hasMore;\n } catch (error) {\n console.error(error);\n refreshError.value = true;\n } finally {\n loadingMore.value = false;\n }\n };\n\n onInit(() => {\n eventSource = new EventSource('/api/events');\n eventSource.addEventListener('jobs.available', refreshJobs);\n eventSource.addEventListener('jobs.changed', refreshJobs);\n eventSource.onerror = () => {\n refreshError.value = true;\n };\n refreshTimer = setInterval(refreshJobs, 60000);\n });\n onDestroy(() => {\n eventSource?.close();\n clearInterval(refreshTimer);\n });\n\n return { jobs, lastUpdated, refreshError, hasMore, loadingMore, loadMore, upper };\n }\n <\/script>\n <script state>__DASHBOARD_STATE__<\/script>\n </template>\n\n <script type=\"module\">import '@li3/web';<\/script>\n <script src=\"https://cdn.tailwindcss.com\"><\/script>\n</body>\n</html>\n";
|
|
8033
8042
|
//#endregion
|
|
8034
8043
|
//#region src/dashboard.ts
|
|
8035
8044
|
function zo(e) {
|
|
@@ -8042,24 +8051,84 @@ function zo(e) {
|
|
|
8042
8051
|
updatedAt: e.updated_at
|
|
8043
8052
|
}));
|
|
8044
8053
|
}
|
|
8045
|
-
function Bo(e) {
|
|
8046
|
-
return Ro.replace("__DASHBOARD_STATE__", () => No({
|
|
8054
|
+
function Bo(e, t = !1) {
|
|
8055
|
+
return Ro.replace("__DASHBOARD_STATE__", () => No({
|
|
8056
|
+
jobs: e,
|
|
8057
|
+
hasMore: t
|
|
8058
|
+
}));
|
|
8059
|
+
}
|
|
8060
|
+
//#endregion
|
|
8061
|
+
//#region src/events.ts
|
|
8062
|
+
var Vo = class {
|
|
8063
|
+
clients = /* @__PURE__ */ new Map();
|
|
8064
|
+
nextId = 1;
|
|
8065
|
+
maxClients = 1e3;
|
|
8066
|
+
subscribe(e, t) {
|
|
8067
|
+
if (this.clients.size >= this.maxClients) {
|
|
8068
|
+
t.writeHead(503, {
|
|
8069
|
+
"Content-Type": "application/json",
|
|
8070
|
+
"Retry-After": "5"
|
|
8071
|
+
}), t.end(JSON.stringify({ error: "Too many event stream clients" }));
|
|
8072
|
+
return;
|
|
8073
|
+
}
|
|
8074
|
+
t.writeHead(200, {
|
|
8075
|
+
"Cache-Control": "no-cache, no-transform",
|
|
8076
|
+
Connection: "keep-alive",
|
|
8077
|
+
"Content-Type": "text/event-stream",
|
|
8078
|
+
"X-Accel-Buffering": "no"
|
|
8079
|
+
}), t.write("retry: 2000\n\n");
|
|
8080
|
+
let n = setInterval(() => t.write(": heartbeat\n\n"), 3e4);
|
|
8081
|
+
n.unref(), this.clients.set(t, n), e.once("close", () => {
|
|
8082
|
+
clearInterval(n), this.clients.delete(t);
|
|
8083
|
+
});
|
|
8084
|
+
}
|
|
8085
|
+
publish(e, t = {}) {
|
|
8086
|
+
let n = `id: ${this.nextId++}\nevent: ${e}\ndata: ${JSON.stringify(t)}\n\n`;
|
|
8087
|
+
for (let [e, t] of this.clients) e.write(n) || (clearInterval(t), this.clients.delete(e), e.end());
|
|
8088
|
+
}
|
|
8089
|
+
close() {
|
|
8090
|
+
for (let [e, t] of this.clients) clearInterval(t), e.end();
|
|
8091
|
+
this.clients.clear();
|
|
8092
|
+
}
|
|
8093
|
+
};
|
|
8094
|
+
async function Ho(e, t, n, r) {
|
|
8095
|
+
let i = await fetch(new URL("/api/events", e), {
|
|
8096
|
+
headers: { Accept: "text/event-stream" },
|
|
8097
|
+
signal: t
|
|
8098
|
+
});
|
|
8099
|
+
if (!i.ok || !i.body) throw Error(`Event stream failed with HTTP ${i.status}`);
|
|
8100
|
+
r?.();
|
|
8101
|
+
let a = new TextDecoder(), o = "";
|
|
8102
|
+
for await (let e of i.body) {
|
|
8103
|
+
o += a.decode(e, { stream: !0 }).replaceAll("\r\n", "\n");
|
|
8104
|
+
let t = o.indexOf("\n\n");
|
|
8105
|
+
for (; t !== -1;) {
|
|
8106
|
+
let e = o.slice(0, t);
|
|
8107
|
+
o = o.slice(t + 2), t = o.indexOf("\n\n");
|
|
8108
|
+
let r = e.match(/^event: (.+)$/m)?.[1];
|
|
8109
|
+
if (!r) continue;
|
|
8110
|
+
let i = e.match(/^data: (.*)$/m)?.[1];
|
|
8111
|
+
n(r, i ? JSON.parse(i) : {});
|
|
8112
|
+
}
|
|
8113
|
+
}
|
|
8047
8114
|
}
|
|
8048
8115
|
//#endregion
|
|
8049
8116
|
//#region src/server.ts
|
|
8050
|
-
var
|
|
8117
|
+
var Uo = 50, Wo = 500, Go = class e {
|
|
8051
8118
|
server;
|
|
8052
8119
|
preprocessors = /* @__PURE__ */ new Map();
|
|
8053
8120
|
workflows = [];
|
|
8054
8121
|
queue;
|
|
8055
8122
|
secrets;
|
|
8056
8123
|
adminToken;
|
|
8124
|
+
events = new Vo();
|
|
8125
|
+
workflowsLoaded;
|
|
8057
8126
|
static async withPort(t) {
|
|
8058
8127
|
let { port: n, ...r } = t;
|
|
8059
8128
|
return new e(r).listen(n);
|
|
8060
8129
|
}
|
|
8061
8130
|
constructor(e) {
|
|
8062
|
-
this.queue = e.queue, this.secrets = e.secrets, this.adminToken = e.adminToken, Lo.from(e.config.workflows).then((t) => {
|
|
8131
|
+
this.queue = e.queue, this.secrets = e.secrets, this.adminToken = e.adminToken, this.workflowsLoaded = Lo.from(e.config.workflows).then((t) => {
|
|
8063
8132
|
this.workflows = t, console.log(`✅ Loaded ${t.length} workflow(s) from ${e.config.workflows}`);
|
|
8064
8133
|
}), this.registerPreprocessor(new Mo()), this.server = f.createServer((e, t) => this.handleRequest(e, t));
|
|
8065
8134
|
}
|
|
@@ -8069,7 +8138,12 @@ var Vo = class e {
|
|
|
8069
8138
|
async handleRequest(e, t) {
|
|
8070
8139
|
let n = new p(e.url || "/", `${e.headers["x-forwarded-proto"] || "http"}://${e.headers["x-forwarded-host"] || e.headers.host}`);
|
|
8071
8140
|
if (e.method === "GET" && (n.pathname === "/runs" || n.pathname === "/")) return this.renderDashboard(t);
|
|
8072
|
-
if (e.method === "GET" && n.pathname === "/api/jobs")
|
|
8141
|
+
if (e.method === "GET" && n.pathname === "/api/jobs") {
|
|
8142
|
+
let e = n.searchParams.get("afterId"), r = n.searchParams.get("beforeId"), i = n.searchParams.get("limit"), a = e === null ? void 0 : Number(e), o = r === null ? void 0 : Number(r), s = i === null ? Uo : Number(i);
|
|
8143
|
+
return a !== void 0 && (!Number.isSafeInteger(a) || a < 0) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "afterId must be a non-negative integer" }))) : o !== void 0 && (!Number.isSafeInteger(o) || o < 1) ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: "beforeId must be a positive integer" }))) : !Number.isSafeInteger(s) || s < 1 || s > Wo ? (t.writeHead(400, { "Content-Type": "application/json; charset=utf-8" }), t.end(JSON.stringify({ error: `limit must be an integer from 1 to ${Wo}` }))) : this.renderDashboardJobs(t, s, a, o);
|
|
8144
|
+
}
|
|
8145
|
+
if (e.method === "GET" && n.pathname === "/api/events") return this.events.subscribe(e, t);
|
|
8146
|
+
if (e.method === "POST" && n.pathname === "/api/events") return this.handleWorkerEvent(e, t);
|
|
8073
8147
|
if (e.method === "GET" && n.pathname.startsWith("/runs/")) {
|
|
8074
8148
|
let e = n.pathname.replace("/runs/", "");
|
|
8075
8149
|
return this.renderRunDetails(e, t);
|
|
@@ -8094,7 +8168,7 @@ var Vo = class e {
|
|
|
8094
8168
|
n.writeHead(401, { "Content-Type": "application/json" }), n.end(JSON.stringify({ error: "Invalid HMAC signature or authentication failed" }));
|
|
8095
8169
|
return;
|
|
8096
8170
|
}
|
|
8097
|
-
this.matchWorkflows(e, o), n.writeHead(202, { "Content-Type": "application/json" }), n.end(JSON.stringify({ message: "OK" }));
|
|
8171
|
+
await this.workflowsLoaded, await this.matchWorkflows(e, o), n.writeHead(202, { "Content-Type": "application/json" }), n.end(JSON.stringify({ message: "OK" }));
|
|
8098
8172
|
} catch (e) {
|
|
8099
8173
|
console.error("❌ Webhook Ingress Error:", e), n.writeHead(500, { "Content-Type": "application/json" }), n.end(JSON.stringify({
|
|
8100
8174
|
error: "Internal Ingress Error",
|
|
@@ -8160,25 +8234,33 @@ var Vo = class e {
|
|
|
8160
8234
|
workflowId: n.id,
|
|
8161
8235
|
env: n.env,
|
|
8162
8236
|
steps: n.steps,
|
|
8163
|
-
inputs: t
|
|
8237
|
+
inputs: t,
|
|
8238
|
+
tags: n.tags
|
|
8164
8239
|
};
|
|
8165
|
-
await this.queue.enqueue(n.id, a, i);
|
|
8240
|
+
await this.queue.enqueue(n.id, a, i), this.events.publish("jobs.available", { tags: n.tags || [] });
|
|
8166
8241
|
}
|
|
8167
8242
|
}
|
|
8168
8243
|
async handleSecretReload(e, t) {
|
|
8169
8244
|
if (e.headers.authorization !== `Bearer ${this.adminToken}`) return t.writeHead(403, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Unauthorized" }));
|
|
8170
8245
|
this.secrets.reload(), console.log("🔄 SecretStore reloaded successfully without downtime!"), t.writeHead(200, { "Content-Type": "application/json" }), t.end(JSON.stringify({ message: "Secrets reloaded successfully" }));
|
|
8171
8246
|
}
|
|
8247
|
+
async handleWorkerEvent(e, t) {
|
|
8248
|
+
if (!this.adminToken || e.headers.authorization !== `Bearer ${this.adminToken}`) return t.writeHead(403, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Unauthorized" }));
|
|
8249
|
+
this.events.publish("jobs.changed"), t.writeHead(202).end();
|
|
8250
|
+
}
|
|
8172
8251
|
async renderDashboard(e) {
|
|
8173
|
-
let t =
|
|
8174
|
-
e.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), e.end(
|
|
8252
|
+
let t = await this.queue.listJobs(51), n = zo(t.slice(0, Uo)), r = this.secrets.redactText(Bo(n, t.length > Uo));
|
|
8253
|
+
e.writeHead(200, { "Content-Type": "text/html; charset=utf-8" }), e.end(r);
|
|
8175
8254
|
}
|
|
8176
|
-
async renderDashboardJobs(e) {
|
|
8177
|
-
let
|
|
8255
|
+
async renderDashboardJobs(e, t, n, r) {
|
|
8256
|
+
let i = await this.queue.listJobs(t + 1, n, r), a = zo(i.slice(0, t)), o = this.secrets.redactText(JSON.stringify({
|
|
8257
|
+
jobs: a,
|
|
8258
|
+
hasMore: i.length > t
|
|
8259
|
+
}));
|
|
8178
8260
|
e.writeHead(200, {
|
|
8179
8261
|
"Cache-Control": "no-store",
|
|
8180
8262
|
"Content-Type": "application/json; charset=utf-8"
|
|
8181
|
-
}), e.end(
|
|
8263
|
+
}), e.end(o);
|
|
8182
8264
|
}
|
|
8183
8265
|
async renderRunDetails(e, t) {
|
|
8184
8266
|
let n = await this.queue.getJob(e);
|
|
@@ -8222,7 +8304,7 @@ var Vo = class e {
|
|
|
8222
8304
|
async handleRestartJob(e, t) {
|
|
8223
8305
|
let n = await this.queue.restartJob(e);
|
|
8224
8306
|
if (n) {
|
|
8225
|
-
t.writeHead(201, { "Content-Type": "application/json" }), t.end(JSON.stringify({ id: n }));
|
|
8307
|
+
this.events.publish("jobs.available"), t.writeHead(201, { "Content-Type": "application/json" }), t.end(JSON.stringify({ id: n }));
|
|
8226
8308
|
return;
|
|
8227
8309
|
}
|
|
8228
8310
|
t.writeHead(404, { "Content-Type": "application/json" }), t.end(JSON.stringify({ error: "Job not found" }));
|
|
@@ -8235,13 +8317,13 @@ var Vo = class e {
|
|
|
8235
8317
|
});
|
|
8236
8318
|
}
|
|
8237
8319
|
async stop() {
|
|
8238
|
-
return new Promise((e) => {
|
|
8320
|
+
return this.events.close(), new Promise((e) => {
|
|
8239
8321
|
this.server.close(() => {
|
|
8240
8322
|
console.log("🌐 Webhook Ingress Server stopped listening."), e();
|
|
8241
8323
|
});
|
|
8242
8324
|
});
|
|
8243
8325
|
}
|
|
8244
|
-
},
|
|
8326
|
+
}, Ko = d(v), qo = class {
|
|
8245
8327
|
name = "systemd";
|
|
8246
8328
|
async isSupported() {
|
|
8247
8329
|
try {
|
|
@@ -8364,7 +8446,7 @@ var Vo = class e {
|
|
|
8364
8446
|
cancel: async () => {
|
|
8365
8447
|
d = !0;
|
|
8366
8448
|
try {
|
|
8367
|
-
t.image && await
|
|
8449
|
+
t.image && await Ko(`docker stop -t 2 ${o}`).catch(() => {}), await Ko(`systemctl stop ${o}.service`).catch(() => {});
|
|
8368
8450
|
} catch {}
|
|
8369
8451
|
},
|
|
8370
8452
|
logFilePath: i
|
|
@@ -8374,7 +8456,7 @@ var Vo = class e {
|
|
|
8374
8456
|
let t = await g(e, "utf-8"), n = t.includes("Running as unit: ") ? t.indexOf("\n") + 1 : 0, r = t.includes("Finished with result: ") ? t.lastIndexOf("Finished with result: ") : t.length;
|
|
8375
8457
|
return t.slice(n, r);
|
|
8376
8458
|
}
|
|
8377
|
-
},
|
|
8459
|
+
}, Jo = class {
|
|
8378
8460
|
name = "standard-process";
|
|
8379
8461
|
async isSupported() {
|
|
8380
8462
|
return !0;
|
|
@@ -8489,13 +8571,13 @@ var Vo = class e {
|
|
|
8489
8571
|
};
|
|
8490
8572
|
//#endregion
|
|
8491
8573
|
//#region src/drivers/index.ts
|
|
8492
|
-
async function
|
|
8493
|
-
let e = new
|
|
8494
|
-
return await e.isSupported() ? (console.log("⚡ Selected Execution Driver: Systemd (cgroups enabled)"), e) : (console.log("📦 Selected Execution Driver: Standard Process (Fallback)"), new
|
|
8574
|
+
async function Yo() {
|
|
8575
|
+
let e = new qo();
|
|
8576
|
+
return await e.isSupported() ? (console.log("⚡ Selected Execution Driver: Systemd (cgroups enabled)"), e) : (console.log("📦 Selected Execution Driver: Standard Process (Fallback)"), new Jo());
|
|
8495
8577
|
}
|
|
8496
8578
|
//#endregion
|
|
8497
8579
|
//#region src/signals.ts
|
|
8498
|
-
async function
|
|
8580
|
+
async function Xo(e) {
|
|
8499
8581
|
let t = !1;
|
|
8500
8582
|
async function n(n) {
|
|
8501
8583
|
if (!t) {
|
|
@@ -8503,7 +8585,7 @@ async function Ko(e) {
|
|
|
8503
8585
|
console.error("⚠️ Graceful shutdown timed out after 10s. Forcing exit!"), process.exit(1);
|
|
8504
8586
|
}, 1e4).unref();
|
|
8505
8587
|
try {
|
|
8506
|
-
|
|
8588
|
+
ns(), e.length > 0 && (console.log("⚙️ Waiting for active worker jobs to drain..."), await Promise.allSettled(e)), console.log("✨ Engine stopped cleanly. Goodbye!"), process.exit(0);
|
|
8507
8589
|
} catch (e) {
|
|
8508
8590
|
console.error("❌ Error during graceful shutdown:", e.message), process.exit(1);
|
|
8509
8591
|
}
|
|
@@ -8513,34 +8595,99 @@ async function Ko(e) {
|
|
|
8513
8595
|
}
|
|
8514
8596
|
//#endregion
|
|
8515
8597
|
//#region src/worker.ts
|
|
8516
|
-
var
|
|
8517
|
-
function
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8598
|
+
var Zo = !!process.env.DEBUG, Qo = { isStopping: !1 }, $o = /* @__PURE__ */ new Set(), es = null, ts = null;
|
|
8599
|
+
function ns() {
|
|
8600
|
+
Qo.isStopping = !0, es?.abort(), ts?.();
|
|
8601
|
+
}
|
|
8602
|
+
function rs(e, t, n, r) {
|
|
8603
|
+
Qo.isStopping = !1;
|
|
8604
|
+
let i = [is(e, t, n, r)];
|
|
8605
|
+
return Xo(i), i;
|
|
8606
|
+
}
|
|
8607
|
+
async function is(e, t, n, r) {
|
|
8608
|
+
let i = await Yo(), a = /* @__PURE__ */ new Set(), o = 0, s = null, c = () => {
|
|
8609
|
+
o++, s?.();
|
|
8610
|
+
};
|
|
8611
|
+
ts = c, es = new AbortController();
|
|
8612
|
+
let l = as(r, es.signal, c);
|
|
8613
|
+
for (console.log(`🚀 Worker scheduler started. Driver: ${i.name}. Concurrency: ${e}. Tags: ${r.tags.join(", ") || "(none)"}`); !Qo.isStopping;) {
|
|
8614
|
+
let l = o;
|
|
8615
|
+
try {
|
|
8616
|
+
for (; a.size < e && !Qo.isStopping;) {
|
|
8617
|
+
let e = await t.claimNextJob(r.tags);
|
|
8618
|
+
if (!e) break;
|
|
8619
|
+
if (Qo.isStopping) {
|
|
8620
|
+
await t.releaseJob(e.id);
|
|
8621
|
+
break;
|
|
8622
|
+
}
|
|
8623
|
+
let o = `worker-${e.id}`, s;
|
|
8624
|
+
s = (async () => {
|
|
8625
|
+
cs(r), await ls({
|
|
8626
|
+
workerId: o,
|
|
8627
|
+
job: e,
|
|
8628
|
+
queue: t,
|
|
8629
|
+
secrets: n,
|
|
8630
|
+
config: r,
|
|
8631
|
+
driver: i
|
|
8632
|
+
});
|
|
8633
|
+
})().catch((e) => console.error(`[${o}] ⚠️ Worker execution error:`, e)).finally(() => {
|
|
8634
|
+
a.delete(s), cs(r), c();
|
|
8635
|
+
}), a.add(s);
|
|
8636
|
+
}
|
|
8637
|
+
} catch (e) {
|
|
8638
|
+
console.error("⚠️ Worker scheduler claim error:", e), setTimeout(c, 5e3).unref();
|
|
8639
|
+
}
|
|
8640
|
+
!Qo.isStopping && o === l && (await os(l, () => o, (e) => s = e), s = null);
|
|
8641
|
+
}
|
|
8642
|
+
es.abort(), await Promise.allSettled(a), await l, ts = null, console.log("🛑 Worker scheduler stopped cleanly.");
|
|
8643
|
+
}
|
|
8644
|
+
async function as(e, t, n) {
|
|
8645
|
+
let r = 1e3;
|
|
8646
|
+
for (; !t.aborted;) {
|
|
8647
|
+
try {
|
|
8648
|
+
await Ho(e.serverUrl, t, (t, r) => {
|
|
8649
|
+
t === "jobs.available" && (Array.isArray(r.tags) ? r.tags.filter((e) => typeof e == "string") : []).every((t) => e.tags.includes(t)) && n();
|
|
8650
|
+
}, n), r = 1e3;
|
|
8651
|
+
} catch (e) {
|
|
8652
|
+
if (t.aborted || e?.name === "AbortError") break;
|
|
8653
|
+
console.error(`⚠️ Worker event stream disconnected: ${e.message}`);
|
|
8529
8654
|
}
|
|
8530
|
-
await
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8655
|
+
await ss(r, t), r = Math.min(r * 2, 3e4);
|
|
8656
|
+
}
|
|
8657
|
+
}
|
|
8658
|
+
function os(e, t, n) {
|
|
8659
|
+
return new Promise((r) => {
|
|
8660
|
+
if (t() !== e) return r();
|
|
8661
|
+
let i = setTimeout(r, 6e4);
|
|
8662
|
+
n(() => {
|
|
8663
|
+
clearTimeout(i), r();
|
|
8664
|
+
});
|
|
8665
|
+
});
|
|
8666
|
+
}
|
|
8667
|
+
function ss(e, t) {
|
|
8668
|
+
return new Promise((n) => {
|
|
8669
|
+
if (t.aborted) return n();
|
|
8670
|
+
let r = () => {
|
|
8671
|
+
clearTimeout(i), n();
|
|
8672
|
+
}, i = setTimeout(() => {
|
|
8673
|
+
t.removeEventListener("abort", r), n();
|
|
8674
|
+
}, e);
|
|
8675
|
+
t.addEventListener("abort", r, { once: !0 });
|
|
8676
|
+
});
|
|
8677
|
+
}
|
|
8678
|
+
async function cs(e) {
|
|
8679
|
+
if (e.adminToken) try {
|
|
8680
|
+
let t = await fetch(new URL("/api/events", e.serverUrl), {
|
|
8681
|
+
method: "POST",
|
|
8682
|
+
headers: { Authorization: `Bearer ${e.adminToken}` },
|
|
8683
|
+
signal: AbortSignal.timeout(5e3)
|
|
8537
8684
|
});
|
|
8538
|
-
|
|
8539
|
-
|
|
8685
|
+
!t.ok && Zo && console.error(`Failed to publish job status event: HTTP ${t.status}`);
|
|
8686
|
+
} catch (e) {
|
|
8687
|
+
Zo && console.error("Failed to publish job status event:", e);
|
|
8540
8688
|
}
|
|
8541
|
-
console.log(`[${e}] 🛑 Worker loop stopped cleanly.`);
|
|
8542
8689
|
}
|
|
8543
|
-
async function
|
|
8690
|
+
async function ls(e) {
|
|
8544
8691
|
let { workerId: t, job: n, config: r, secrets: i, queue: o } = e;
|
|
8545
8692
|
console.log(`\n[${t}] 📦 Claimed Job #${n.id} (Workflow: ${n.workflow_id})`);
|
|
8546
8693
|
let s = typeof n.payload == "string" ? JSON.parse(n.payload) : n.payload, c = s.steps || [], l = s.inputs || {}, u = Date.now(), d = a.join(r.storagePath, `job-${n.id}`), f = a.join(d, "logs"), p = a.join(d, "wd"), m = {
|
|
@@ -8557,20 +8704,20 @@ async function Zo(e) {
|
|
|
8557
8704
|
durationMs: 0,
|
|
8558
8705
|
outputs: {},
|
|
8559
8706
|
logContent: ""
|
|
8560
|
-
})), g =
|
|
8707
|
+
})), g = gs(n, "running", u, l, m.env, h, s);
|
|
8561
8708
|
await o.saveReport(n.id, g);
|
|
8562
|
-
let { cancelled: _, failed: v } = await
|
|
8709
|
+
let { cancelled: _, failed: v } = await us({
|
|
8563
8710
|
payload: s,
|
|
8564
8711
|
steps: c,
|
|
8565
8712
|
executionContext: m,
|
|
8566
8713
|
...e
|
|
8567
8714
|
}, g), y = _ ? "cancelled" : v ? "failed" : "success";
|
|
8568
|
-
g.status = y, g.durationMs = Date.now() - u, g.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), await o.completeJob(n.id, y, g), console.log(`[${t}] ✅ Job #${n.id} completed as: ${y}`), await
|
|
8715
|
+
g.status = y, g.durationMs = Date.now() - u, g.finishedAt = (/* @__PURE__ */ new Date()).toISOString(), await o.completeJob(n.id, y, g), console.log(`[${t}] ✅ Job #${n.id} completed as: ${y}`), await _s(t, r.reporters, g);
|
|
8569
8716
|
}
|
|
8570
|
-
async function
|
|
8717
|
+
async function us(e, t) {
|
|
8571
8718
|
let { driver: n, workerId: r, queue: i, config: a, job: o, payload: s, steps: c, executionContext: l } = e, u = t.steps, d = !1, f = !1, p = 0;
|
|
8572
8719
|
try {
|
|
8573
|
-
s.env && Object.assign(l.env, await
|
|
8720
|
+
s.env && Object.assign(l.env, await ps(s.env, l));
|
|
8574
8721
|
for (let e = 0; e < c.length; e++) {
|
|
8575
8722
|
let s = c[e], m = (/* @__PURE__ */ new Date()).toISOString();
|
|
8576
8723
|
u[e] = {
|
|
@@ -8584,7 +8731,7 @@ async function Qo(e, t) {
|
|
|
8584
8731
|
startedAt: m,
|
|
8585
8732
|
finishedAt: void 0
|
|
8586
8733
|
}, t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t);
|
|
8587
|
-
let h = await
|
|
8734
|
+
let h = await ds({
|
|
8588
8735
|
workerId: r,
|
|
8589
8736
|
jobId: o.id,
|
|
8590
8737
|
step: s,
|
|
@@ -8624,22 +8771,22 @@ async function Qo(e, t) {
|
|
|
8624
8771
|
} catch (e) {
|
|
8625
8772
|
console.log("🛑 Step failed", e), d = !0;
|
|
8626
8773
|
}
|
|
8627
|
-
return p < c.length && (
|
|
8774
|
+
return p < c.length && (hs(c, p, u), t.durationMs = Date.now() - Date.parse(t.startedAt), await i.saveReport(o.id, t)), {
|
|
8628
8775
|
failed: d,
|
|
8629
8776
|
cancelled: f,
|
|
8630
8777
|
stepReports: u
|
|
8631
8778
|
};
|
|
8632
8779
|
}
|
|
8633
|
-
async function
|
|
8780
|
+
async function ds(e) {
|
|
8634
8781
|
let { step: t, stepIndex: n, executionContext: r } = e;
|
|
8635
|
-
if (t.id ||= `step-${n}`, t.name ||= t.id, t.if && !await ko.evaluateConditions(t.if, r)) return
|
|
8782
|
+
if (t.id ||= `step-${n}`, t.name ||= t.id, t.if && !await ko.evaluateConditions(t.if, r)) return Zo && console.log(`⏩ Skipped step ${t.id} based on condition: ${t.if}`, r), {
|
|
8636
8783
|
failed: !1,
|
|
8637
8784
|
cancelled: !1,
|
|
8638
8785
|
skipped: !0,
|
|
8639
8786
|
report: null
|
|
8640
8787
|
};
|
|
8641
8788
|
try {
|
|
8642
|
-
let n = await
|
|
8789
|
+
let n = await ps(t.env, r), i = {
|
|
8643
8790
|
jobId: String(e.jobId),
|
|
8644
8791
|
step: t,
|
|
8645
8792
|
command: t.run,
|
|
@@ -8653,15 +8800,15 @@ async function $o(e) {
|
|
|
8653
8800
|
WORKING_DIR: r.workingDir
|
|
8654
8801
|
}
|
|
8655
8802
|
};
|
|
8656
|
-
return t.eval ?
|
|
8803
|
+
return t.eval ? fs({
|
|
8657
8804
|
...e,
|
|
8658
8805
|
stepContext: i
|
|
8659
|
-
}) :
|
|
8806
|
+
}) : ms({
|
|
8660
8807
|
...e,
|
|
8661
8808
|
stepContext: i
|
|
8662
8809
|
});
|
|
8663
8810
|
} catch (e) {
|
|
8664
|
-
return
|
|
8811
|
+
return Zo && console.error(`⏩ Failed to run step ${t.id}`, r, e), {
|
|
8665
8812
|
failed: !0,
|
|
8666
8813
|
cancelled: !1,
|
|
8667
8814
|
skipped: !1,
|
|
@@ -8669,7 +8816,7 @@ async function $o(e) {
|
|
|
8669
8816
|
};
|
|
8670
8817
|
}
|
|
8671
8818
|
}
|
|
8672
|
-
async function
|
|
8819
|
+
async function fs(e) {
|
|
8673
8820
|
let { queue: t, stepContext: n, executionContext: r } = e, { jobId: i, step: a } = n, o = Date.now(), s = a.id, c = a.name;
|
|
8674
8821
|
try {
|
|
8675
8822
|
let e = await ko.evaluateExpression(a.eval, r);
|
|
@@ -8715,12 +8862,12 @@ async function es(e) {
|
|
|
8715
8862
|
};
|
|
8716
8863
|
}
|
|
8717
8864
|
}
|
|
8718
|
-
async function
|
|
8865
|
+
async function ps(e, t) {
|
|
8719
8866
|
let n = {};
|
|
8720
8867
|
if (e) for (let [r, i] of Object.entries(e)) n[r] = String(await ko.evaluateValue(i, t));
|
|
8721
8868
|
return n;
|
|
8722
8869
|
}
|
|
8723
|
-
async function
|
|
8870
|
+
async function ms(t) {
|
|
8724
8871
|
let { workerId: n, jobId: r, stepContext: i, executionContext: a, driver: o, queue: s } = t, { step: c } = i, l = c.id, u = c.name, d;
|
|
8725
8872
|
try {
|
|
8726
8873
|
d = o.execute(i);
|
|
@@ -8735,10 +8882,11 @@ async function ns(t) {
|
|
|
8735
8882
|
logFilePath: ""
|
|
8736
8883
|
};
|
|
8737
8884
|
}
|
|
8885
|
+
$o.add(d);
|
|
8738
8886
|
let f = !1, p = setInterval(async () => {
|
|
8739
8887
|
await s.isCancelled(r) && (console.log(`[${n}] 🛑 Job #${r} was cancelled! Halting execution.`), f = !0, clearInterval(p), await d.cancel());
|
|
8740
8888
|
}, 3e3), m = await d.done;
|
|
8741
|
-
if (clearInterval(p), d.logFilePath && e.existsSync(d.logFilePath)) try {
|
|
8889
|
+
if (clearInterval(p), $o.delete(d), d.logFilePath && e.existsSync(d.logFilePath)) try {
|
|
8742
8890
|
let e = await o.readLog(d.logFilePath);
|
|
8743
8891
|
await s.saveStepLog(r, l, e);
|
|
8744
8892
|
} catch (e) {
|
|
@@ -8765,7 +8913,7 @@ async function ns(t) {
|
|
|
8765
8913
|
}
|
|
8766
8914
|
};
|
|
8767
8915
|
}
|
|
8768
|
-
function
|
|
8916
|
+
function hs(e, t, n) {
|
|
8769
8917
|
for (let r = t; r < e.length; r++) {
|
|
8770
8918
|
let t = e[r], i = t.id || `step-${r}`;
|
|
8771
8919
|
n[r] = {
|
|
@@ -8779,7 +8927,7 @@ function rs(e, t, n) {
|
|
|
8779
8927
|
};
|
|
8780
8928
|
}
|
|
8781
8929
|
}
|
|
8782
|
-
function
|
|
8930
|
+
function gs(e, t, n, r, i, a, o) {
|
|
8783
8931
|
return {
|
|
8784
8932
|
jobId: String(e.id),
|
|
8785
8933
|
parentId: String(e.parentId || ""),
|
|
@@ -8798,7 +8946,7 @@ function is(e, t, n, r, i, a, o) {
|
|
|
8798
8946
|
})
|
|
8799
8947
|
};
|
|
8800
8948
|
}
|
|
8801
|
-
async function
|
|
8949
|
+
async function _s(e, t = [], n) {
|
|
8802
8950
|
!Array.isArray(t) || t.length === 0 || (console.log(`[${e}] 📢 Dispatching execution report to ${t.length} reporter(s)...`), await Promise.allSettled(t.map(async (t) => {
|
|
8803
8951
|
try {
|
|
8804
8952
|
await t.report(n);
|
|
@@ -8809,7 +8957,7 @@ async function as(e, t = [], n) {
|
|
|
8809
8957
|
}
|
|
8810
8958
|
//#endregion
|
|
8811
8959
|
//#region src/reporters/json-file.reporter.ts
|
|
8812
|
-
var
|
|
8960
|
+
var vs = class {
|
|
8813
8961
|
name = "json-file";
|
|
8814
8962
|
outputDir;
|
|
8815
8963
|
constructor(e) {
|
|
@@ -8820,7 +8968,7 @@ var os = class {
|
|
|
8820
8968
|
let n = a.join(this.outputDir, `run-${t.jobId}.json`);
|
|
8821
8969
|
e.writeFileSync(n, JSON.stringify(t, null, 2), "utf-8"), console.log(`📊 Execution report saved to: ${n}`);
|
|
8822
8970
|
}
|
|
8823
|
-
},
|
|
8971
|
+
}, ys = class {
|
|
8824
8972
|
name = "slack";
|
|
8825
8973
|
webhookUrl = "";
|
|
8826
8974
|
token = "";
|
|
@@ -8847,7 +8995,7 @@ var os = class {
|
|
|
8847
8995
|
};
|
|
8848
8996
|
//#endregion
|
|
8849
8997
|
//#region src/index.ts
|
|
8850
|
-
function
|
|
8998
|
+
function bs(e) {
|
|
8851
8999
|
console.log("🔍 Validating Workflows in:", e.workflows);
|
|
8852
9000
|
let t = new di(e.workflows), n = r(e.workflows).filter((e) => e.endsWith(".yml") || e.endsWith(".yaml"));
|
|
8853
9001
|
for (let e of n) {
|
|
@@ -8855,13 +9003,13 @@ function cs(e) {
|
|
|
8855
9003
|
console.log(` ✅ ${e} -> Valid! (${n.length} job matrix variant(s) generated)`);
|
|
8856
9004
|
}
|
|
8857
9005
|
}
|
|
8858
|
-
async function
|
|
9006
|
+
async function xs() {
|
|
8859
9007
|
let { config: e, command: t } = await fe();
|
|
8860
|
-
if (e || process.exit(1), t === "validate") return
|
|
9008
|
+
if (e || process.exit(1), t === "validate") return bs(e);
|
|
8861
9009
|
let n = new mi("./.env"), r = new pi(process.env.WORKER_NAME || "cli");
|
|
8862
9010
|
switch (t) {
|
|
8863
9011
|
case "start-server":
|
|
8864
|
-
console.log("🌐 Starting Ingress Gateway..."), await r.init(), await
|
|
9012
|
+
console.log("🌐 Starting Ingress Gateway..."), await r.init(), await Go.withPort({
|
|
8865
9013
|
config: e,
|
|
8866
9014
|
queue: r,
|
|
8867
9015
|
secrets: n,
|
|
@@ -8870,11 +9018,11 @@ async function ls() {
|
|
|
8870
9018
|
});
|
|
8871
9019
|
break;
|
|
8872
9020
|
case "start-workers":
|
|
8873
|
-
console.log(`⚙️ Starting ${e.workers}
|
|
9021
|
+
console.log(`⚙️ Starting worker scheduler with ${e.workers} concurrent slot(s)...`), await r.init(), rs(e.workers, r, n, e);
|
|
8874
9022
|
break;
|
|
8875
9023
|
default: console.error(`❌ Unknown command: '${t}'`), de(), process.exit(1);
|
|
8876
9024
|
}
|
|
8877
9025
|
}
|
|
8878
|
-
|
|
9026
|
+
xs().catch(console.error);
|
|
8879
9027
|
//#endregion
|
|
8880
|
-
export { Io as HtmlReporter,
|
|
9028
|
+
export { Io as HtmlReporter, vs as JsonFileReporter, ys as SlackReporter };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yaml-loader.d.ts","sourceRoot":"","sources":["../../src/parser/yaml-loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,qBAAa,UAAU;WACR,IAAI,CAAC,IAAI,EAAE,MAAM;IAiB9B,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB;
|
|
1
|
+
{"version":3,"file":"yaml-loader.d.ts","sourceRoot":"","sources":["../../src/parser/yaml-loader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjD,qBAAa,UAAU;WACR,IAAI,CAAC,IAAI,EAAE,MAAM;IAiB9B,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,uBAAuB;CAwChE"}
|
package/dist/queue.d.ts
CHANGED
|
@@ -9,10 +9,11 @@ export declare class QueueManager {
|
|
|
9
9
|
*/
|
|
10
10
|
enqueue(workflowId: string, payload: JobPayload, concurrencyKey?: string): Promise<any>;
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Atomically claims the oldest pending job compatible with this worker.
|
|
13
13
|
* Requires SQLite >= 3.35 for the RETURNING clause.
|
|
14
14
|
*/
|
|
15
|
-
claimNextJob(): Promise<JobRecord | null>;
|
|
15
|
+
claimNextJob(workerTags?: string[]): Promise<JobRecord | null>;
|
|
16
|
+
releaseJob(jobId: string | number): Promise<void>;
|
|
16
17
|
/**
|
|
17
18
|
* Marks a job as completed or failed
|
|
18
19
|
*/
|
|
@@ -32,7 +33,7 @@ export declare class QueueManager {
|
|
|
32
33
|
/**
|
|
33
34
|
* List recent jobs for dashboard status monitoring
|
|
34
35
|
*/
|
|
35
|
-
listJobs(limit?: number): Promise<any[]>;
|
|
36
|
+
listJobs(limit?: number, afterId?: number, beforeId?: number): Promise<any[]>;
|
|
36
37
|
/**
|
|
37
38
|
* Save lightweight summary report (NO heavy logs in this JSON!)
|
|
38
39
|
*/
|
package/dist/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAE9B,IAAI;IAKV;;;OAGG;IACG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM;IAkB9E;;;OAGG;IACG,YAAY,
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvF,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAE9B,IAAI;IAKV;;;OAGG;IACG,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,cAAc,CAAC,EAAE,MAAM;IAkB9E;;;OAGG;IACG,YAAY,CAAC,UAAU,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IA6BlE,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvD;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,SAAS;IAInD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAStG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAiBvC;;OAEG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrD,cAAc;IAMd,YAAY;IAoClB;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAIlD;;OAEG;IACG,QAAQ,CAAC,KAAK,SAAK,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAiB/E;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAOxF,2DAA2D;IACrD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU5F;;OAEG;IACG,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAS1E"}
|
package/dist/server.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export declare class WebhookServer {
|
|
|
6
6
|
private queue;
|
|
7
7
|
private secrets;
|
|
8
8
|
private adminToken;
|
|
9
|
+
private events;
|
|
10
|
+
private workflowsLoaded;
|
|
9
11
|
static withPort(options: WebhookServerOptions & {
|
|
10
12
|
port: number;
|
|
11
13
|
}): Promise<WebhookServer>;
|
|
@@ -23,6 +25,7 @@ export declare class WebhookServer {
|
|
|
23
25
|
* Handles Zero-Downtime Secret Reload
|
|
24
26
|
*/
|
|
25
27
|
private handleSecretReload;
|
|
28
|
+
private handleWorkerEvent;
|
|
26
29
|
/**
|
|
27
30
|
* Serves the Server Health & Jobs Dashboard
|
|
28
31
|
*/
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,mBAAmB,EACnB,oBAAoB,EAGrB,MAAM,YAAY,CAAC;AAQpB,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,eAAe,CAAgB;WAE1B,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE;gBAK1D,OAAO,EAAE,oBAAoB;IAczC,oBAAoB,CAAC,YAAY,EAAE,mBAAmB;YAIxC,aAAa;IAkE3B;;OAEG;YACW,aAAa;YA0Bb,WAAW;IAwBzB,OAAO,CAAC,UAAU;YAiBJ,cAAc;IA2C5B;;OAEG;YACW,kBAAkB;YAelB,iBAAiB;IAU/B;;OAEG;YACW,eAAe;YAQf,mBAAmB;IAWjC;;OAEG;YACW,gBAAgB;IAkC9B,OAAO,CAAC,kBAAkB;YA0BZ,gBAAgB;IAc9B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAStC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAS5B"}
|
package/dist/types.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export interface RunnerConfig {
|
|
|
15
15
|
workflows: string;
|
|
16
16
|
/** Number of concurrent worker loops to spawn */
|
|
17
17
|
workers: number;
|
|
18
|
+
/** Webhook server URL used for worker event notifications */
|
|
19
|
+
serverUrl: string;
|
|
20
|
+
/** Capabilities advertised by this worker node */
|
|
21
|
+
tags: string[];
|
|
18
22
|
/** Storage path for job workspaces and step logs */
|
|
19
23
|
storagePath: string;
|
|
20
24
|
/** Global environment variables injected into all step runs */
|
|
@@ -105,6 +109,8 @@ export interface WorkflowDefinition {
|
|
|
105
109
|
};
|
|
106
110
|
steps: WorkflowStep[];
|
|
107
111
|
env?: Record<string, string>;
|
|
112
|
+
/** Worker capabilities required to execute this workflow */
|
|
113
|
+
tags?: string[];
|
|
108
114
|
}
|
|
109
115
|
export interface WebhookServerOptions {
|
|
110
116
|
config: RunnerConfig;
|
|
@@ -129,6 +135,7 @@ export interface JobPayload {
|
|
|
129
135
|
steps: WorkflowStep[];
|
|
130
136
|
inputs: WorkflowInputs;
|
|
131
137
|
env?: Record<string, string>;
|
|
138
|
+
tags?: string[];
|
|
132
139
|
}
|
|
133
140
|
export interface MatrixStrategy {
|
|
134
141
|
matrix?: Record<string, (string | number | boolean)[]>;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/worker.d.ts
CHANGED
|
@@ -8,14 +8,15 @@ export declare const shutdownState: {
|
|
|
8
8
|
* Called by signal handlers in index.ts during graceful shutdown
|
|
9
9
|
*/
|
|
10
10
|
export declare function abortActiveWorkerTask(): Promise<void>;
|
|
11
|
+
export declare function requestWorkerShutdown(): void;
|
|
11
12
|
/**
|
|
12
13
|
* Spawns worker loops as requested by configuration
|
|
13
14
|
*/
|
|
14
15
|
export declare function startWorkers(count: number, queue: QueueManager, secrets: SecretStore, config: RunnerConfig): Promise<void>[];
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
+
* Event-driven worker scheduler with bounded local concurrency.
|
|
17
18
|
*/
|
|
18
|
-
export declare function
|
|
19
|
+
export declare function startWorkerScheduler(concurrency: number, queue: QueueManager, secrets: SecretStore, config: RunnerConfig): Promise<void>;
|
|
19
20
|
/**
|
|
20
21
|
* Processes a single job sequentially
|
|
21
22
|
*/
|
package/dist/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,YAAY,EAOZ,WAAW,EAIZ,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,YAAY,EAOZ,WAAW,EAIZ,MAAM,YAAY,CAAC;AAMpB,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAMF;;GAEG;AACH,wBAAsB,qBAAqB,kBAK1C;AAED,wBAAgB,qBAAqB,SAIpC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,mBAK1G;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,YAAY,iBA4DrB;AA4ED;;GAEG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAAE,WAAW,iBA2D9C"}
|