@kici-dev/orchestrator 0.1.5 → 0.1.7
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/dist/app.d.ts +9 -3
- package/dist/cli.js +30 -1
- package/dist/cluster/coordinator.d.ts +3 -3
- package/dist/config.d.ts +2 -0
- package/dist/db/types.d.ts +1 -1
- package/dist/orchestrator-core.d.ts +9 -2
- package/dist/pipeline/processor.d.ts +2 -2
- package/dist/pipeline/rerun.d.ts +2 -2
- package/dist/pipeline/test-pipeline.d.ts +2 -2
- package/dist/reporting/{commit-status.d.ts → check-run-reporter.d.ts} +7 -7
- package/dist/reporting/check-run-tracking-store.d.ts +2 -2
- package/dist/routes/admin-sources.d.ts +15 -0
- package/dist/routes/admin.d.ts +14 -0
- package/dist/server.js +527 -352
- package/dist/sources/build-platform-sources.d.ts +26 -0
- package/dist/sources/source-manager.d.ts +14 -0
- package/dist/stale-detector/stale-run-detector.d.ts +3 -3
- package/dist/standalone.js +146 -75
- package/dist/webhook/generic-sources-listener.d.ts +15 -0
- package/dist/ws/platform-client.d.ts +27 -1
- package/package.json +3 -3
- package/sbom.spdx.json +36 -36
package/dist/standalone.js
CHANGED
|
@@ -134,6 +134,15 @@ var init_config$5 = __esmMin((() => {
|
|
|
134
134
|
* behavior). Trailing slash optional.
|
|
135
135
|
*/
|
|
136
136
|
dashboardUrl: z.string().optional(),
|
|
137
|
+
/**
|
|
138
|
+
* Public base URL at which this orchestrator's own webhook ingress is
|
|
139
|
+
* reachable (independent/hybrid self-serve generic webhooks:
|
|
140
|
+
* `<base>/webhook/<customerId>/generic/<sourceId>`). Used by
|
|
141
|
+
* `kici-admin source add` to print a generic source's webhook URL. GitHub-App
|
|
142
|
+
* ingress is Platform-relayed, so GitHub URLs come from the Platform's
|
|
143
|
+
* `source.register.ack`, not this value. Trailing slash optional.
|
|
144
|
+
*/
|
|
145
|
+
webhookPublicUrl: z.string().optional(),
|
|
137
146
|
databaseUrl: z.string().default(""),
|
|
138
147
|
lockfileCacheMax: z.coerce.number().default(500),
|
|
139
148
|
lockfileCacheTtlMs: z.coerce.number().default(36e5),
|
|
@@ -326,6 +335,7 @@ var init_config$5 = __esmMin((() => {
|
|
|
326
335
|
platformUrl: "KICI_PLATFORM_URL",
|
|
327
336
|
platformToken: "KICI_PLATFORM_TOKEN",
|
|
328
337
|
dashboardUrl: "KICI_DASHBOARD_URL",
|
|
338
|
+
webhookPublicUrl: "KICI_WEBHOOK_PUBLIC_URL",
|
|
329
339
|
databaseUrl: "KICI_DATABASE_URL",
|
|
330
340
|
cacheStorageType: "KICI_STORAGE_TYPE",
|
|
331
341
|
cacheStoragePath: "KICI_STORAGE_PATH",
|
|
@@ -1028,7 +1038,7 @@ var init_peer_client = __esmMin((() => {
|
|
|
1028
1038
|
init_peer_crypto();
|
|
1029
1039
|
init_peer_credentials();
|
|
1030
1040
|
logger$85 = createLogger({ prefix: "peer-client" });
|
|
1031
|
-
SOFTWARE_VERSION$1 = "0.1.
|
|
1041
|
+
SOFTWARE_VERSION$1 = "0.1.7";
|
|
1032
1042
|
PeerClient$1 = class {
|
|
1033
1043
|
ws = null;
|
|
1034
1044
|
_state = "disconnected";
|
|
@@ -2491,7 +2501,7 @@ var init_peer_handler = __esmMin((() => {
|
|
|
2491
2501
|
init_peer_crypto();
|
|
2492
2502
|
init_join_token();
|
|
2493
2503
|
logger$84 = createLogger({ prefix: "peer-handler" });
|
|
2494
|
-
SOFTWARE_VERSION = "0.1.
|
|
2504
|
+
SOFTWARE_VERSION = "0.1.7";
|
|
2495
2505
|
RATE_LIMIT_MAX = 5;
|
|
2496
2506
|
RATE_LIMIT_WINDOW_MS = 6e4;
|
|
2497
2507
|
}));
|
|
@@ -3125,7 +3135,7 @@ var init_coordinator = __esmMin((() => {
|
|
|
3125
3135
|
peerRegistry;
|
|
3126
3136
|
dispatcher;
|
|
3127
3137
|
executionTracker;
|
|
3128
|
-
|
|
3138
|
+
checkRunReporter;
|
|
3129
3139
|
getPeerClient;
|
|
3130
3140
|
sendAndWaitAckViaHandler;
|
|
3131
3141
|
sendToPeerViaHandler;
|
|
@@ -3147,7 +3157,7 @@ var init_coordinator = __esmMin((() => {
|
|
|
3147
3157
|
this.peerRegistry = deps.peerRegistry;
|
|
3148
3158
|
this.dispatcher = deps.dispatcher;
|
|
3149
3159
|
this.executionTracker = deps.executionTracker;
|
|
3150
|
-
this.
|
|
3160
|
+
this.checkRunReporter = deps.checkRunReporter;
|
|
3151
3161
|
this.getPeerClient = deps.getPeerClient;
|
|
3152
3162
|
this.sendAndWaitAckViaHandler = deps.sendAndWaitAckViaHandler;
|
|
3153
3163
|
this.sendToPeerViaHandler = deps.sendToPeerViaHandler;
|
|
@@ -3270,10 +3280,10 @@ var init_coordinator = __esmMin((() => {
|
|
|
3270
3280
|
const repoIdentifier = (msg.repoUrl ?? "").replace(/\.git$/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/^[^/]+@[^:]+:/, "") || "";
|
|
3271
3281
|
const providerContext = msg.providerContext ?? {};
|
|
3272
3282
|
const installationId = typeof providerContext.installationId === "number" ? providerContext.installationId : void 0;
|
|
3273
|
-
if (this.
|
|
3283
|
+
if (this.checkRunReporter && repoIdentifier && msg.sha) {
|
|
3274
3284
|
const [owner, repo] = repoIdentifier.split("/");
|
|
3275
3285
|
if (owner && repo) try {
|
|
3276
|
-
await this.
|
|
3286
|
+
await this.checkRunReporter.setPendingAwait({
|
|
3277
3287
|
provider: msg.provider ?? "",
|
|
3278
3288
|
owner,
|
|
3279
3289
|
repo,
|
|
@@ -9760,7 +9770,7 @@ var init_check_run_summary = __esmMin((() => {
|
|
|
9760
9770
|
];
|
|
9761
9771
|
}));
|
|
9762
9772
|
//#endregion
|
|
9763
|
-
//#region src/reporting/
|
|
9773
|
+
//#region src/reporting/check-run-reporter.ts
|
|
9764
9774
|
/**
|
|
9765
9775
|
* GitHub check run integration module.
|
|
9766
9776
|
*
|
|
@@ -9775,7 +9785,7 @@ var init_check_run_summary = __esmMin((() => {
|
|
|
9775
9785
|
* Check run IDs are tracked in-memory after creation so that subsequent
|
|
9776
9786
|
* updates (job complete, workflow complete) can reference them via checks.update().
|
|
9777
9787
|
*
|
|
9778
|
-
* Enriched output
|
|
9788
|
+
* Enriched output:
|
|
9779
9789
|
* - Live step progress with checklist-style updates (debounced at 5s)
|
|
9780
9790
|
* - Failed check runs include step names, error messages, exit codes, and log context
|
|
9781
9791
|
* - Check run annotations link failures to step source locations in workflow files (.kici/workflows/*.ts)
|
|
@@ -9785,7 +9795,7 @@ var init_check_run_summary = __esmMin((() => {
|
|
|
9785
9795
|
* Note: The engine-level CheckStatusPoster interface (packages/engine/src/provider/check-status-poster.ts)
|
|
9786
9796
|
* provides a provider-agnostic API for posting security-related check statuses (holds, approvals,
|
|
9787
9797
|
* workflow modifications). The GitHub implementation is at packages/orchestrator/src/providers/github/check-status-poster.ts.
|
|
9788
|
-
* This
|
|
9798
|
+
* This CheckRunReporter handles execution lifecycle checks (queued, in_progress, completed per job/workflow).
|
|
9789
9799
|
* Future cleanup may unify both under CheckStatusPoster, but they serve different purposes today.
|
|
9790
9800
|
*/
|
|
9791
9801
|
/**
|
|
@@ -9807,14 +9817,14 @@ function buildJobFailureDescription(data) {
|
|
|
9807
9817
|
if (data.error) return `Job error: ${data.error}`;
|
|
9808
9818
|
return "Job failed";
|
|
9809
9819
|
}
|
|
9810
|
-
var logger$70, PROGRESS_DEBOUNCE_MS,
|
|
9811
|
-
var
|
|
9820
|
+
var logger$70, PROGRESS_DEBOUNCE_MS, CheckRunReporter;
|
|
9821
|
+
var init_check_run_reporter = __esmMin((() => {
|
|
9812
9822
|
init_auth();
|
|
9813
9823
|
init_prometheus();
|
|
9814
9824
|
init_check_run_summary();
|
|
9815
|
-
logger$70 = createLogger({ prefix: "
|
|
9825
|
+
logger$70 = createLogger({ prefix: "check-run-reporter" });
|
|
9816
9826
|
PROGRESS_DEBOUNCE_MS = 5e3;
|
|
9817
|
-
|
|
9827
|
+
CheckRunReporter = class {
|
|
9818
9828
|
/**
|
|
9819
9829
|
* L1 cache: composite key → check run ID.
|
|
9820
9830
|
*
|
|
@@ -10069,7 +10079,7 @@ var init_commit_status = __esmMin((() => {
|
|
|
10069
10079
|
*/
|
|
10070
10080
|
async recoverState() {
|
|
10071
10081
|
if (!this.deps.trackingStore) return;
|
|
10072
|
-
logger$70.info("
|
|
10082
|
+
logger$70.info("CheckRunReporter recovered (DB-backed state lookups enabled)");
|
|
10073
10083
|
}
|
|
10074
10084
|
/** Track a check run key associated with a runId for later cleanup. */
|
|
10075
10085
|
trackRunKey(runId, key) {
|
|
@@ -13358,10 +13368,29 @@ function createSourceRoutes(deps) {
|
|
|
13358
13368
|
privateKey,
|
|
13359
13369
|
webhookSecret
|
|
13360
13370
|
});
|
|
13371
|
+
let webhookUrl = null;
|
|
13372
|
+
let webhookNote;
|
|
13373
|
+
if (deps.resolveSourceWebhookUrl) try {
|
|
13374
|
+
const resolved = await deps.resolveSourceWebhookUrl({
|
|
13375
|
+
routingKey: source.routing_key,
|
|
13376
|
+
provider,
|
|
13377
|
+
sourceId: source.id
|
|
13378
|
+
});
|
|
13379
|
+
webhookUrl = resolved.webhookUrl;
|
|
13380
|
+
webhookNote = resolved.webhookNote;
|
|
13381
|
+
} catch (err) {
|
|
13382
|
+
logger$63.warn("Failed to resolve webhook URL for added source", {
|
|
13383
|
+
routingKey: source.routing_key,
|
|
13384
|
+
error: toErrorMessage(err)
|
|
13385
|
+
});
|
|
13386
|
+
webhookNote = "resolve-failed";
|
|
13387
|
+
}
|
|
13361
13388
|
return c.json({
|
|
13362
13389
|
routingKey: source.routing_key,
|
|
13363
13390
|
id: source.id,
|
|
13364
|
-
name: source.name
|
|
13391
|
+
name: source.name,
|
|
13392
|
+
webhookUrl,
|
|
13393
|
+
...webhookNote && { webhookNote }
|
|
13365
13394
|
}, 201);
|
|
13366
13395
|
} catch (err) {
|
|
13367
13396
|
logger$63.error("Failed to add source", { error: toErrorMessage(err) });
|
|
@@ -17742,7 +17771,10 @@ function createAdminRoutes(deps) {
|
|
|
17742
17771
|
return handleError$3(c, err);
|
|
17743
17772
|
}
|
|
17744
17773
|
});
|
|
17745
|
-
if (deps.sourceStore) app.route("/api/v1/admin", createSourceRoutes({
|
|
17774
|
+
if (deps.sourceStore) app.route("/api/v1/admin", createSourceRoutes({
|
|
17775
|
+
sourceStore: deps.sourceStore,
|
|
17776
|
+
resolveSourceWebhookUrl: deps.resolveSourceWebhookUrl
|
|
17777
|
+
}));
|
|
17746
17778
|
if (deps.db && deps.pool) app.route("/api/v1/admin", createDbRoutes({
|
|
17747
17779
|
db: deps.db,
|
|
17748
17780
|
pool: deps.pool
|
|
@@ -21504,14 +21536,14 @@ var init_admin_config = __esmMin((() => {
|
|
|
21504
21536
|
function createHealthRoutes$1(deps = {}) {
|
|
21505
21537
|
return createHealthRoutes({
|
|
21506
21538
|
livenessInfo: () => ({
|
|
21507
|
-
version: "0.1.
|
|
21508
|
-
buildDate: "2026-05-
|
|
21509
|
-
buildCommit: "
|
|
21510
|
-
sdkVersion: "0.1.
|
|
21539
|
+
version: "0.1.7",
|
|
21540
|
+
buildDate: "2026-05-26T13:18:35.789Z",
|
|
21541
|
+
buildCommit: "4c0abe030",
|
|
21542
|
+
sdkVersion: "0.1.7",
|
|
21511
21543
|
sdkBundleHash: "675aafe4de03e677785ef2794d8f34951b14e2bd1e6f0ea825953d6c2abfe128",
|
|
21512
|
-
sharedVersion: "0.1.
|
|
21513
|
-
sharedBundleHash: "
|
|
21514
|
-
engineVersion: "0.1.
|
|
21544
|
+
sharedVersion: "0.1.7",
|
|
21545
|
+
sharedBundleHash: "36a23a454fd75ec35f258d39f254543ec0451c6b543fe3618ce427e6e6369aae",
|
|
21546
|
+
engineVersion: "0.1.7",
|
|
21515
21547
|
engineBundleHash: "b704538612ec796a5668765bd55e0eaeaf1bad8a2afa508f9e20ad7b9eb61d21"
|
|
21516
21548
|
}),
|
|
21517
21549
|
readinessCheck: deps.db ? async () => {
|
|
@@ -21546,7 +21578,7 @@ function createCapabilitiesRoutes() {
|
|
|
21546
21578
|
const app = new Hono();
|
|
21547
21579
|
app.get("/api/v1/capabilities", (c) => {
|
|
21548
21580
|
const manifest = {
|
|
21549
|
-
orchestratorVersion: "0.1.
|
|
21581
|
+
orchestratorVersion: "0.1.7",
|
|
21550
21582
|
protocolVersion: PROTOCOL_VERSION,
|
|
21551
21583
|
minProtocolVersion: MIN_PROTOCOL_VERSION
|
|
21552
21584
|
};
|
|
@@ -23036,7 +23068,7 @@ async function mintCloneTokenForReroute(args) {
|
|
|
23036
23068
|
/**
|
|
23037
23069
|
* Build the wrapped dispatcher, overlay info with effective routing/provider,
|
|
23038
23070
|
* persist the webhook payload, fire source-location callbacks, and post the
|
|
23039
|
-
* pending
|
|
23071
|
+
* pending check-run check. Pure side-effects + a typed result bag for
|
|
23040
23072
|
* downstream phases.
|
|
23041
23073
|
*/
|
|
23042
23074
|
async function setupDispatchContext(ctx) {
|
|
@@ -23087,10 +23119,10 @@ async function setupDispatchContext(ctx) {
|
|
|
23087
23119
|
const locs = job.steps.map((s) => s.sourceLocation);
|
|
23088
23120
|
if (locs.some((l) => l !== void 0)) deps.onSourceLocationsExtracted(workflow.name, job.name, locs);
|
|
23089
23121
|
}
|
|
23090
|
-
if (deps.
|
|
23122
|
+
if (deps.checkRunReporter) {
|
|
23091
23123
|
const [owner, repo] = repoIdentifier.split("/");
|
|
23092
23124
|
const jobNames = workflow.jobs.filter(isLockStaticJob).map((j) => j.name);
|
|
23093
|
-
await deps.
|
|
23125
|
+
await deps.checkRunReporter.setPendingAwait({
|
|
23094
23126
|
provider: info.provider,
|
|
23095
23127
|
owner,
|
|
23096
23128
|
repo,
|
|
@@ -23242,9 +23274,9 @@ async function runBuildJob(args) {
|
|
|
23242
23274
|
let rejected = false;
|
|
23243
23275
|
let error;
|
|
23244
23276
|
const coalescingKey = `${contentHash || "none"}:${lockfileHash || "none"}`;
|
|
23245
|
-
if (deps.
|
|
23277
|
+
if (deps.checkRunReporter) {
|
|
23246
23278
|
const [owner, repo] = repoIdentifier.split("/");
|
|
23247
|
-
deps.
|
|
23279
|
+
deps.checkRunReporter.setBuildPending({
|
|
23248
23280
|
provider: setup.info.provider,
|
|
23249
23281
|
owner,
|
|
23250
23282
|
repo,
|
|
@@ -23313,9 +23345,9 @@ async function runBuildJob(args) {
|
|
|
23313
23345
|
async function recordBuildFailure(args) {
|
|
23314
23346
|
const { ctx, setup, buildJobTrackedEarly, err, buildJobId } = args;
|
|
23315
23347
|
const { deps, workflow, repoIdentifier, credentials, event, ref, runId } = ctx;
|
|
23316
|
-
if (deps.
|
|
23348
|
+
if (deps.checkRunReporter) {
|
|
23317
23349
|
const [owner, repo] = repoIdentifier.split("/");
|
|
23318
|
-
deps.
|
|
23350
|
+
deps.checkRunReporter.setBuildComplete({
|
|
23319
23351
|
provider: setup.info.provider,
|
|
23320
23352
|
owner,
|
|
23321
23353
|
repo,
|
|
@@ -23355,9 +23387,9 @@ async function recordBuildFailure(args) {
|
|
|
23355
23387
|
async function readPostBuildCacheUrls(args) {
|
|
23356
23388
|
const { ctx, setup, contentHash, lockfileHash, targetPlatform, targetArch } = args;
|
|
23357
23389
|
const { deps, workflow, repoIdentifier, credentials, ref, runId } = ctx;
|
|
23358
|
-
if (deps.
|
|
23390
|
+
if (deps.checkRunReporter) {
|
|
23359
23391
|
const [owner, repo] = repoIdentifier.split("/");
|
|
23360
|
-
deps.
|
|
23392
|
+
deps.checkRunReporter.setBuildComplete({
|
|
23361
23393
|
provider: setup.info.provider,
|
|
23362
23394
|
owner,
|
|
23363
23395
|
repo,
|
|
@@ -27317,7 +27349,7 @@ function createApp(deps) {
|
|
|
27317
27349
|
sourceCache: deps.sourceCache,
|
|
27318
27350
|
depCache: deps.depCache,
|
|
27319
27351
|
cacheStorage: deps.cacheStorage,
|
|
27320
|
-
onJobStatus: deps.platformClient || deps.executionTracker || deps.
|
|
27352
|
+
onJobStatus: deps.platformClient || deps.executionTracker || deps.checkRunReporter || deps.pendingBuilds || deps.pendingInits ? (_agentId, msg) => {
|
|
27321
27353
|
if (deps.pendingBuilds && deps.pendingBuilds.has(msg.jobId)) {
|
|
27322
27354
|
if (msg.state === ExecutionJobStatus.enum.success && msg.data?.buildComplete) deps.pendingBuilds.resolve(msg.jobId);
|
|
27323
27355
|
else if (msg.state === ExecutionJobStatus.enum.failed || msg.state === ExecutionJobStatus.enum.cancelled) deps.pendingBuilds.reject(msg.jobId, new Error(msg.data?.error ?? `Build ${msg.state}`));
|
|
@@ -27349,13 +27381,13 @@ function createApp(deps) {
|
|
|
27349
27381
|
},
|
|
27350
27382
|
timestamp: msg.timestamp
|
|
27351
27383
|
});
|
|
27352
|
-
if (deps.
|
|
27384
|
+
if (deps.checkRunReporter && deps.executionTracker && (msg.state === ExecutionJobStatus.enum.success || msg.state === ExecutionJobStatus.enum.failed || msg.state === ExecutionJobStatus.enum.cancelled)) {
|
|
27353
27385
|
const execContext = deps.executionTracker.getExecutionContext(msg.runId);
|
|
27354
27386
|
if (execContext) {
|
|
27355
27387
|
const [owner, repo] = execContext.repoIdentifier.split("/");
|
|
27356
27388
|
let description;
|
|
27357
27389
|
if (msg.state === ExecutionJobStatus.enum.failed && msg.data) description = buildJobFailureDescription(msg.data);
|
|
27358
|
-
deps.
|
|
27390
|
+
deps.checkRunReporter.updateJobStatus({
|
|
27359
27391
|
provider: execContext.provider,
|
|
27360
27392
|
owner,
|
|
27361
27393
|
repo,
|
|
@@ -27406,11 +27438,11 @@ function createApp(deps) {
|
|
|
27406
27438
|
} : msg.data;
|
|
27407
27439
|
deps.executionTracker.onStepStatus(msg.runId, msg.jobId, msg.stepIndex, msg.stepName, msg.state, msg.timestamp, data, msg.logBytesStreamed);
|
|
27408
27440
|
}
|
|
27409
|
-
if (deps.
|
|
27441
|
+
if (deps.checkRunReporter && deps.executionTracker) {
|
|
27410
27442
|
const execContext = deps.executionTracker.getExecutionContext(msg.runId);
|
|
27411
27443
|
if (execContext) {
|
|
27412
27444
|
const [owner, repo] = execContext.repoIdentifier.split("/");
|
|
27413
|
-
deps.
|
|
27445
|
+
deps.checkRunReporter.updateStepProgress({
|
|
27414
27446
|
provider: execContext.provider,
|
|
27415
27447
|
owner,
|
|
27416
27448
|
repo,
|
|
@@ -27704,7 +27736,7 @@ function createApp(deps) {
|
|
|
27704
27736
|
pendingBuilds: deps.pendingBuilds,
|
|
27705
27737
|
pendingInits: deps.pendingInits,
|
|
27706
27738
|
pendingDynamics: deps.pendingDynamics,
|
|
27707
|
-
|
|
27739
|
+
checkRunReporter: deps.checkRunReporter,
|
|
27708
27740
|
executionTracker: deps.executionTracker,
|
|
27709
27741
|
onSourceLocationsExtracted,
|
|
27710
27742
|
eventRouter: deps.eventRouter,
|
|
@@ -27745,7 +27777,8 @@ function createApp(deps) {
|
|
|
27745
27777
|
}));
|
|
27746
27778
|
if (deps.adminDeps) app.route("", createAdminRoutes({
|
|
27747
27779
|
...deps.adminDeps,
|
|
27748
|
-
accessLog: deps.accessLogWriter
|
|
27780
|
+
accessLog: deps.accessLogWriter,
|
|
27781
|
+
resolveSourceWebhookUrl: deps.resolveSourceWebhookUrl
|
|
27749
27782
|
}));
|
|
27750
27783
|
if (deps.genericSourceManager && deps.trustStore && deps.adminDeps) app.route("", createAdminEventRoutes({
|
|
27751
27784
|
sourceManager: deps.genericSourceManager,
|
|
@@ -27802,7 +27835,7 @@ function createApp(deps) {
|
|
|
27802
27835
|
lockFileCache: deps.lockFileCache,
|
|
27803
27836
|
dispatcher: deps.dispatcher,
|
|
27804
27837
|
executionTracker: deps.executionTracker,
|
|
27805
|
-
|
|
27838
|
+
checkRunReporter: deps.checkRunReporter,
|
|
27806
27839
|
sourceCache: deps.sourceCache,
|
|
27807
27840
|
buildCoordinator: deps.buildCoordinator,
|
|
27808
27841
|
depCache: deps.depCache,
|
|
@@ -27959,7 +27992,7 @@ var init_app = __esmMin((() => {
|
|
|
27959
27992
|
init_blob_routes();
|
|
27960
27993
|
init_agent_api_registry();
|
|
27961
27994
|
init_server_options();
|
|
27962
|
-
|
|
27995
|
+
init_check_run_reporter();
|
|
27963
27996
|
init_agent_handler();
|
|
27964
27997
|
init_observer_handler();
|
|
27965
27998
|
init_test_trigger();
|
|
@@ -35170,7 +35203,7 @@ var init_stale_run_detector = __esmMin((() => {
|
|
|
35170
35203
|
StaleRunDetector = class {
|
|
35171
35204
|
db;
|
|
35172
35205
|
executionTracker;
|
|
35173
|
-
|
|
35206
|
+
checkRunReporter;
|
|
35174
35207
|
scalerManager;
|
|
35175
35208
|
dispatcher;
|
|
35176
35209
|
registry;
|
|
@@ -35181,7 +35214,7 @@ var init_stale_run_detector = __esmMin((() => {
|
|
|
35181
35214
|
constructor(deps) {
|
|
35182
35215
|
this.db = deps.db;
|
|
35183
35216
|
this.executionTracker = deps.executionTracker;
|
|
35184
|
-
this.
|
|
35217
|
+
this.checkRunReporter = deps.checkRunReporter;
|
|
35185
35218
|
this.scalerManager = deps.scalerManager;
|
|
35186
35219
|
this.dispatcher = deps.dispatcher;
|
|
35187
35220
|
this.registry = deps.registry;
|
|
@@ -35403,11 +35436,11 @@ var init_stale_run_detector = __esmMin((() => {
|
|
|
35403
35436
|
});
|
|
35404
35437
|
markedCount++;
|
|
35405
35438
|
staleRunsDetectedTotal.add(1);
|
|
35406
|
-
if (this.
|
|
35439
|
+
if (this.checkRunReporter) {
|
|
35407
35440
|
const [owner, repo] = entry.repo_identifier.split("/");
|
|
35408
35441
|
const providerCtx = typeof entry.provider_context === "string" ? JSON.parse(entry.provider_context) : entry.provider_context ?? {};
|
|
35409
35442
|
const installationId = typeof providerCtx.installationId === "number" ? providerCtx.installationId : void 0;
|
|
35410
|
-
this.
|
|
35443
|
+
this.checkRunReporter.updateJobStatus({
|
|
35411
35444
|
provider: entry.provider,
|
|
35412
35445
|
owner,
|
|
35413
35446
|
repo,
|
|
@@ -35465,11 +35498,11 @@ var init_stale_run_detector = __esmMin((() => {
|
|
|
35465
35498
|
});
|
|
35466
35499
|
await this.executionTracker.cancelStepsForJob(job.run_id, job.job_id, errorMessage);
|
|
35467
35500
|
affectedRunIds.add(job.run_id);
|
|
35468
|
-
if (this.
|
|
35501
|
+
if (this.checkRunReporter) {
|
|
35469
35502
|
const [owner, repo] = job.repo_identifier.split("/");
|
|
35470
35503
|
const providerCtx = typeof job.provider_context === "string" ? JSON.parse(job.provider_context) : job.provider_context ?? {};
|
|
35471
35504
|
const installationId = typeof providerCtx.installationId === "number" ? providerCtx.installationId : void 0;
|
|
35472
|
-
this.
|
|
35505
|
+
this.checkRunReporter.updateJobStatus({
|
|
35473
35506
|
provider: job.provider,
|
|
35474
35507
|
owner,
|
|
35475
35508
|
repo,
|
|
@@ -36559,10 +36592,27 @@ var init_source_manager = __esmMin((() => {
|
|
|
36559
36592
|
currentSources = [];
|
|
36560
36593
|
debounceTimer = null;
|
|
36561
36594
|
debounceMs;
|
|
36595
|
+
/**
|
|
36596
|
+
* Change callback. Stored in a mutable field (not read off `opts`) so a
|
|
36597
|
+
* mode-specific hook can rewire it after construction — the platform-mode
|
|
36598
|
+
* boot wires it to push the full source list to the Platform via
|
|
36599
|
+
* `platformClient.updateSources()`. Defaults to the (possibly no-op) value
|
|
36600
|
+
* passed at construction.
|
|
36601
|
+
*/
|
|
36602
|
+
onSourcesChanged;
|
|
36562
36603
|
constructor(opts) {
|
|
36563
36604
|
this.opts = opts;
|
|
36564
36605
|
this.registry = new ProviderRegistry();
|
|
36565
36606
|
this.debounceMs = opts.debounceMs ?? 200;
|
|
36607
|
+
this.onSourcesChanged = opts.onSourcesChanged;
|
|
36608
|
+
}
|
|
36609
|
+
/**
|
|
36610
|
+
* Replace the change callback after construction. The SourceManager is built
|
|
36611
|
+
* early (before the Platform client exists); the platform-mode boot calls
|
|
36612
|
+
* this once the client is ready so live source changes propagate upstream.
|
|
36613
|
+
*/
|
|
36614
|
+
setOnSourcesChanged(cb) {
|
|
36615
|
+
this.onSourcesChanged = cb;
|
|
36566
36616
|
}
|
|
36567
36617
|
/** Get current ProviderRegistry (rebuilt on each reload). */
|
|
36568
36618
|
getRegistry() {
|
|
@@ -36637,7 +36687,7 @@ var init_source_manager = __esmMin((() => {
|
|
|
36637
36687
|
added: diff.added.length,
|
|
36638
36688
|
removed: diff.removed.length
|
|
36639
36689
|
});
|
|
36640
|
-
if (diff.added.length > 0 || diff.removed.length > 0) this.
|
|
36690
|
+
if (diff.added.length > 0 || diff.removed.length > 0) this.onSourcesChanged(diff);
|
|
36641
36691
|
}
|
|
36642
36692
|
/**
|
|
36643
36693
|
* Build a ProviderBundle for a source with decrypted secrets.
|
|
@@ -39537,9 +39587,19 @@ var init_generic_sources_listener = __esmMin((() => {
|
|
|
39537
39587
|
pending = /* @__PURE__ */ new Set();
|
|
39538
39588
|
debounceTimer = null;
|
|
39539
39589
|
debounceMs;
|
|
39590
|
+
/**
|
|
39591
|
+
* Drain-applied-change callback. Mutable so the platform-mode boot can wire
|
|
39592
|
+
* it after the Platform client exists (this listener is constructed before).
|
|
39593
|
+
*/
|
|
39594
|
+
onChange;
|
|
39540
39595
|
constructor(opts) {
|
|
39541
39596
|
this.opts = opts;
|
|
39542
39597
|
this.debounceMs = opts.debounceMs ?? 200;
|
|
39598
|
+
this.onChange = opts.onChange;
|
|
39599
|
+
}
|
|
39600
|
+
/** Replace the drain-applied-change callback after construction. */
|
|
39601
|
+
setOnChange(cb) {
|
|
39602
|
+
this.onChange = cb;
|
|
39543
39603
|
}
|
|
39544
39604
|
/** Open the dedicated client and subscribe. Cold-boot bundle
|
|
39545
39605
|
* registration is handled by the orchestrator-core startup loop
|
|
@@ -39585,6 +39645,7 @@ var init_generic_sources_listener = __esmMin((() => {
|
|
|
39585
39645
|
async drain() {
|
|
39586
39646
|
const keys = Array.from(this.pending);
|
|
39587
39647
|
this.pending.clear();
|
|
39648
|
+
let appliedChange = false;
|
|
39588
39649
|
for (const routingKey of keys) try {
|
|
39589
39650
|
const row = await this.opts.sourceManager.getByRoutingKey(routingKey);
|
|
39590
39651
|
if (!row) {
|
|
@@ -39593,6 +39654,7 @@ var init_generic_sources_listener = __esmMin((() => {
|
|
|
39593
39654
|
routingKey,
|
|
39594
39655
|
removed
|
|
39595
39656
|
});
|
|
39657
|
+
appliedChange = true;
|
|
39596
39658
|
continue;
|
|
39597
39659
|
}
|
|
39598
39660
|
this.opts.providerRegistry.unregister(routingKey);
|
|
@@ -39601,12 +39663,14 @@ var init_generic_sources_listener = __esmMin((() => {
|
|
|
39601
39663
|
config: this.opts.config,
|
|
39602
39664
|
secretResolver: this.opts.secretResolver
|
|
39603
39665
|
});
|
|
39666
|
+
appliedChange = true;
|
|
39604
39667
|
} catch (err) {
|
|
39605
39668
|
logger$8.error("Failed to apply generic-source change", {
|
|
39606
39669
|
routingKey,
|
|
39607
39670
|
error: toErrorMessage(err)
|
|
39608
39671
|
});
|
|
39609
39672
|
}
|
|
39673
|
+
if (appliedChange) this.onChange?.();
|
|
39610
39674
|
}
|
|
39611
39675
|
};
|
|
39612
39676
|
}));
|
|
@@ -41353,7 +41417,7 @@ function buildOnEventMatched(dispatcherRef, executionTracker, providerRegistryRe
|
|
|
41353
41417
|
}
|
|
41354
41418
|
};
|
|
41355
41419
|
}
|
|
41356
|
-
function initializeCluster(config, db, agentRegistry, dispatcher, executionTracker,
|
|
41420
|
+
function initializeCluster(config, db, agentRegistry, dispatcher, executionTracker, checkRunReporter, cacheStorage, scalerManager, registrationIndex, cronScheduler, configReloaderRef, localConfigVersionRef, stepLogBuffer, eventRetryScannerRef) {
|
|
41357
41421
|
const peerClients = /* @__PURE__ */ new Map();
|
|
41358
41422
|
const getLocalInventory = () => ({
|
|
41359
41423
|
instanceId: config.instanceId,
|
|
@@ -41457,7 +41521,7 @@ function initializeCluster(config, db, agentRegistry, dispatcher, executionTrack
|
|
|
41457
41521
|
peerRegistry,
|
|
41458
41522
|
dispatcher,
|
|
41459
41523
|
executionTracker,
|
|
41460
|
-
|
|
41524
|
+
checkRunReporter,
|
|
41461
41525
|
getPeerClient: (instanceId) => peerClients.get(instanceId),
|
|
41462
41526
|
sendAndWaitAckViaHandler: (targetId, msg, timeoutMs) => peerHandlerObj?.sendAndWaitAck(targetId, msg, timeoutMs) ?? Promise.resolve(false),
|
|
41463
41527
|
sendToPeerViaHandler: (targetId, msg) => peerHandlerObj?.sendToPeer(targetId, msg) ?? false
|
|
@@ -41667,7 +41731,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
41667
41731
|
const stepLogBuffer = new StepLogBuffer();
|
|
41668
41732
|
const sourceLocationStore = new SourceLocationStore();
|
|
41669
41733
|
const checkRunTrackingStore = new CheckRunTrackingStore(db);
|
|
41670
|
-
const
|
|
41734
|
+
const checkRunReporter = new CheckRunReporter({
|
|
41671
41735
|
providerRegistry,
|
|
41672
41736
|
stepLogBuffer,
|
|
41673
41737
|
trackingStore: checkRunTrackingStore,
|
|
@@ -41714,7 +41778,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
41714
41778
|
});
|
|
41715
41779
|
});
|
|
41716
41780
|
const [owner, repo] = context.repoIdentifier.split("/");
|
|
41717
|
-
|
|
41781
|
+
checkRunReporter.updateWorkflowStatus({
|
|
41718
41782
|
provider: context.provider,
|
|
41719
41783
|
owner,
|
|
41720
41784
|
repo,
|
|
@@ -41764,7 +41828,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
41764
41828
|
orgId: trackerExtras?.orgId,
|
|
41765
41829
|
onRunPruned: (runId) => {
|
|
41766
41830
|
stepLogBuffer.cleanup(runId);
|
|
41767
|
-
|
|
41831
|
+
checkRunReporter.cleanupRun(runId);
|
|
41768
41832
|
},
|
|
41769
41833
|
onWorkflowComplete: (data) => {
|
|
41770
41834
|
if (!eventEmitter) return;
|
|
@@ -41870,7 +41934,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
41870
41934
|
if (pgSecretStore) {
|
|
41871
41935
|
providerRegistry = await sourceManager.start();
|
|
41872
41936
|
providerRegistryRef.current = providerRegistry;
|
|
41873
|
-
|
|
41937
|
+
checkRunReporter.updateRegistry(providerRegistry);
|
|
41874
41938
|
const registeredKeys = providerRegistry.getRoutingKeys();
|
|
41875
41939
|
if (registeredKeys.length > 0) logger$2.info("Provider registry built from sources", { routingKeys: registeredKeys });
|
|
41876
41940
|
else logger$2.info("No sources configured yet (orchestrator can start with zero sources)");
|
|
@@ -42017,7 +42081,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
42017
42081
|
ttl: config.lockfileCacheTtlMs
|
|
42018
42082
|
});
|
|
42019
42083
|
const configReloaderRef = { current: null };
|
|
42020
|
-
const cluster = initializeCluster(config, db, agentRegistry, dispatcher, executionTracker,
|
|
42084
|
+
const cluster = initializeCluster(config, db, agentRegistry, dispatcher, executionTracker, checkRunReporter, cacheStorage, scalerManager, registrationIndex, cronScheduler, configReloaderRef, localConfigVersionRef, stepLogBuffer, eventRetryScannerRef);
|
|
42021
42085
|
coordinatorRef.current = cluster.coordinator;
|
|
42022
42086
|
if (adminDeps) adminDeps.broadcastAgentTokenRevoke = cluster.broadcastAgentTokenRevoke;
|
|
42023
42087
|
let masterKeyForStore = null;
|
|
@@ -42056,7 +42120,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
42056
42120
|
pendingBuilds,
|
|
42057
42121
|
pendingInits,
|
|
42058
42122
|
pendingDynamics,
|
|
42059
|
-
|
|
42123
|
+
checkRunReporter,
|
|
42060
42124
|
stepLogBuffer,
|
|
42061
42125
|
sourceLocationStore,
|
|
42062
42126
|
logStorage,
|
|
@@ -42092,6 +42156,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
42092
42156
|
localConfigVersion: localConfigVersionRef.value,
|
|
42093
42157
|
sourceStore,
|
|
42094
42158
|
sourceManager,
|
|
42159
|
+
genericSourcesChangeListener,
|
|
42095
42160
|
eventLogWriter,
|
|
42096
42161
|
accessLogWriter,
|
|
42097
42162
|
coldStore: coldStoreSingleton,
|
|
@@ -42143,7 +42208,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
42143
42208
|
await sourceManager.reload();
|
|
42144
42209
|
providerRegistry = sourceManager.getRegistry();
|
|
42145
42210
|
providerRegistryRef.current = providerRegistry;
|
|
42146
|
-
|
|
42211
|
+
checkRunReporter.updateRegistry(providerRegistry);
|
|
42147
42212
|
logger$2.info("Provider registry reloaded from sources", { routingKeys: providerRegistry.getRoutingKeys() });
|
|
42148
42213
|
}),
|
|
42149
42214
|
onScalerReload: scalerManager ? async () => {
|
|
@@ -42244,7 +42309,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
42244
42309
|
pendingBuilds,
|
|
42245
42310
|
pendingInits,
|
|
42246
42311
|
pendingDynamics,
|
|
42247
|
-
|
|
42312
|
+
checkRunReporter,
|
|
42248
42313
|
executionTracker,
|
|
42249
42314
|
logWriter,
|
|
42250
42315
|
stepLogBuffer,
|
|
@@ -42298,7 +42363,7 @@ async function bootstrapOrchestrator$1(config, hooks, options) {
|
|
|
42298
42363
|
const staleRunDetector = new StaleRunDetector({
|
|
42299
42364
|
db,
|
|
42300
42365
|
executionTracker,
|
|
42301
|
-
|
|
42366
|
+
checkRunReporter,
|
|
42302
42367
|
scalerManager: scalerManager ?? void 0,
|
|
42303
42368
|
dispatcher,
|
|
42304
42369
|
registry: agentRegistry,
|
|
@@ -42505,7 +42570,7 @@ var init_orchestrator_core = __esmMin((() => {
|
|
|
42505
42570
|
init_scaler();
|
|
42506
42571
|
init_storage();
|
|
42507
42572
|
init_cache();
|
|
42508
|
-
|
|
42573
|
+
init_check_run_reporter();
|
|
42509
42574
|
init_check_run_tracking_store();
|
|
42510
42575
|
init_scaler_state_store();
|
|
42511
42576
|
init_processor();
|
|
@@ -43640,13 +43705,13 @@ var init_worker_core = __esmMin((() => {
|
|
|
43640
43705
|
init_agent_handler();
|
|
43641
43706
|
init_worker_status();
|
|
43642
43707
|
init_agent_heartbeat();
|
|
43643
|
-
ORCHESTRATOR_VERSION$1 = "0.1.
|
|
43644
|
-
WORKER_BUILD_COMMIT = "
|
|
43645
|
-
WORKER_SDK_VERSION = "0.1.
|
|
43708
|
+
ORCHESTRATOR_VERSION$1 = "0.1.7";
|
|
43709
|
+
WORKER_BUILD_COMMIT = "4c0abe030";
|
|
43710
|
+
WORKER_SDK_VERSION = "0.1.7";
|
|
43646
43711
|
WORKER_SDK_BUNDLE_HASH = "675aafe4de03e677785ef2794d8f34951b14e2bd1e6f0ea825953d6c2abfe128";
|
|
43647
|
-
WORKER_SHARED_VERSION = "0.1.
|
|
43648
|
-
WORKER_SHARED_BUNDLE_HASH = "
|
|
43649
|
-
WORKER_ENGINE_VERSION = "0.1.
|
|
43712
|
+
WORKER_SHARED_VERSION = "0.1.7";
|
|
43713
|
+
WORKER_SHARED_BUNDLE_HASH = "36a23a454fd75ec35f258d39f254543ec0451c6b543fe3618ce427e6e6369aae";
|
|
43714
|
+
WORKER_ENGINE_VERSION = "0.1.7";
|
|
43650
43715
|
WORKER_ENGINE_BUNDLE_HASH = "b704538612ec796a5668765bd55e0eaeaf1bad8a2afa508f9e20ad7b9eb61d21";
|
|
43651
43716
|
logger$1 = createLogger({ prefix: "worker" });
|
|
43652
43717
|
DRAIN_TIMEOUT_MS = 3e5;
|
|
@@ -43671,13 +43736,13 @@ var init_worker_core = __esmMin((() => {
|
|
|
43671
43736
|
* Graceful shutdown:
|
|
43672
43737
|
* agent WS -> heartbeat -> HTTP -> DB
|
|
43673
43738
|
*/
|
|
43674
|
-
const ORCHESTRATOR_VERSION = "0.1.
|
|
43675
|
-
const BUILD_COMMIT = "
|
|
43676
|
-
const SDK_VERSION = "0.1.
|
|
43739
|
+
const ORCHESTRATOR_VERSION = "0.1.7";
|
|
43740
|
+
const BUILD_COMMIT = "4c0abe030";
|
|
43741
|
+
const SDK_VERSION = "0.1.7";
|
|
43677
43742
|
const SDK_BUNDLE_HASH = "675aafe4de03e677785ef2794d8f34951b14e2bd1e6f0ea825953d6c2abfe128";
|
|
43678
|
-
const SHARED_VERSION = "0.1.
|
|
43679
|
-
const SHARED_BUNDLE_HASH = "
|
|
43680
|
-
const ENGINE_VERSION = "0.1.
|
|
43743
|
+
const SHARED_VERSION = "0.1.7";
|
|
43744
|
+
const SHARED_BUNDLE_HASH = "36a23a454fd75ec35f258d39f254543ec0451c6b543fe3618ce427e6e6369aae";
|
|
43745
|
+
const ENGINE_VERSION = "0.1.7";
|
|
43681
43746
|
const ENGINE_BUNDLE_HASH = "b704538612ec796a5668765bd55e0eaeaf1bad8a2afa508f9e20ad7b9eb61d21";
|
|
43682
43747
|
const otelSdk = initTelemetry({
|
|
43683
43748
|
serviceName: "kici-orchestrator",
|
|
@@ -43807,12 +43872,18 @@ await guardStartup(logger, async () => {
|
|
|
43807
43872
|
client.connect();
|
|
43808
43873
|
}
|
|
43809
43874
|
return {
|
|
43810
|
-
appDepsExtras: {
|
|
43875
|
+
appDepsExtras: { resolveSourceWebhookUrl: async (params) => params.provider === "github" ? {
|
|
43876
|
+
webhookUrl: null,
|
|
43877
|
+
webhookNote: "github-ingress-platform-only"
|
|
43878
|
+
} : {
|
|
43879
|
+
webhookUrl: null,
|
|
43880
|
+
webhookNote: "unsupported-provider"
|
|
43881
|
+
} },
|
|
43811
43882
|
configReloaderExtras: { onProviderChange: async (_newConfig, _oldConfig, s) => {
|
|
43812
43883
|
await s.sourceManager.reload();
|
|
43813
43884
|
const newRegistry = s.sourceManager.getRegistry();
|
|
43814
43885
|
s.providerRegistry = newRegistry;
|
|
43815
|
-
s.
|
|
43886
|
+
s.checkRunReporter.updateRegistry(newRegistry);
|
|
43816
43887
|
logger.info("Provider registry reloaded from sources (standalone)", { routingKeys: newRegistry.getRoutingKeys() });
|
|
43817
43888
|
} },
|
|
43818
43889
|
shutdownExtras: [],
|
|
@@ -53,6 +53,14 @@ export interface GenericSourcesChangeListenerOptions {
|
|
|
53
53
|
secretResolver: SecretResolver | null;
|
|
54
54
|
/** Coalesce window for rapid NOTIFYs against the same row. Default 200 ms. */
|
|
55
55
|
debounceMs?: number;
|
|
56
|
+
/**
|
|
57
|
+
* Invoked once per drain pass that applied at least one change. The
|
|
58
|
+
* platform-mode boot wires this to re-push the full source list to the
|
|
59
|
+
* Platform (`platformClient.updateSources()`) so a generic source added /
|
|
60
|
+
* removed at runtime reaches the Platform's `webhook_sources` immediately,
|
|
61
|
+
* not just the local registry.
|
|
62
|
+
*/
|
|
63
|
+
onChange?: () => void;
|
|
56
64
|
}
|
|
57
65
|
export declare class GenericSourcesChangeListener {
|
|
58
66
|
private readonly opts;
|
|
@@ -60,7 +68,14 @@ export declare class GenericSourcesChangeListener {
|
|
|
60
68
|
private readonly pending;
|
|
61
69
|
private debounceTimer;
|
|
62
70
|
private readonly debounceMs;
|
|
71
|
+
/**
|
|
72
|
+
* Drain-applied-change callback. Mutable so the platform-mode boot can wire
|
|
73
|
+
* it after the Platform client exists (this listener is constructed before).
|
|
74
|
+
*/
|
|
75
|
+
private onChange?;
|
|
63
76
|
constructor(opts: GenericSourcesChangeListenerOptions);
|
|
77
|
+
/** Replace the drain-applied-change callback after construction. */
|
|
78
|
+
setOnChange(cb: () => void): void;
|
|
64
79
|
/** Open the dedicated client and subscribe. Cold-boot bundle
|
|
65
80
|
* registration is handled by the orchestrator-core startup loop
|
|
66
81
|
* via the same helper; this listener only services warm-path
|