@kici-dev/orchestrator 0.4.0 → 0.6.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/dist/__test-helpers__/fake-scaler-state-store.d.ts +24 -0
- package/dist/__test-helpers__/mock-db-query.d.ts +130 -0
- package/dist/__test-helpers__/mock-db.d.ts +27 -0
- package/dist/agent/agent-version.d.ts +34 -0
- package/dist/agent/dispatcher.d.ts +151 -13
- package/dist/agent/host-roster.d.ts +37 -5
- package/dist/agent/registry.d.ts +2 -0
- package/dist/app.d.ts +56 -7
- package/dist/approvals/apply-decision.d.ts +67 -19
- package/dist/approvals/held-run-release-wiring.d.ts +45 -0
- package/dist/approvals/independent-wiring.d.ts +55 -0
- package/dist/approvals/resume-router.d.ts +9 -0
- package/dist/approvals/triggerer-subject.d.ts +37 -0
- package/dist/cache/dep-cache.d.ts +54 -10
- package/dist/cache/global-eval-round-cache.d.ts +95 -0
- package/dist/cache/index.d.ts +3 -0
- package/dist/cache/pending-global-evals.d.ts +42 -0
- package/dist/cache/pending-inits.d.ts +10 -0
- package/dist/cli/api-client.d.ts +18 -0
- package/dist/cli/commands/cluster-settings.d.ts +52 -3
- package/dist/cli/commands/diagnose.d.ts +6 -0
- package/dist/cli/commands/held-run.d.ts +58 -0
- package/dist/cli/commands/runs.d.ts +1 -0
- package/dist/cli/commands/trust-policy.d.ts +117 -12
- package/dist/cli/kici-admin.d.ts +10 -0
- package/dist/cli.js +2770 -938
- package/dist/cluster/cluster-identity.d.ts +3 -3
- package/dist/cluster/cluster-settings-reader.d.ts +59 -1
- package/dist/cluster/coordinator.d.ts +44 -0
- package/dist/cluster/index.d.ts +4 -0
- package/dist/cluster/peer-handler.d.ts +19 -0
- package/dist/cluster/peer-registry.d.ts +17 -0
- package/dist/cluster/plan-headroom-store.d.ts +26 -0
- package/dist/cluster/worker-eviction.d.ts +69 -0
- package/dist/cold-store/load-event-log-range.d.ts +10 -3
- package/dist/cold-store/load-secret-audit-log-range.d.ts +4 -3
- package/dist/cold-store/tables/secret-audit-log.d.ts +4 -3
- package/dist/config.d.ts +48 -21
- package/dist/content-requirements-cache.d.ts +55 -0
- package/dist/contexts/held-runs.d.ts +123 -16
- package/dist/contexts/protection/aggregate.d.ts +3 -2
- package/dist/contexts/protection/branch-gate.d.ts +15 -0
- package/dist/contexts/protection/concurrency-gate.d.ts +8 -2
- package/dist/contexts/protection/pipeline.d.ts +18 -0
- package/dist/contexts/release-queued-holds.d.ts +35 -0
- package/dist/dashboard/attestation-filters.d.ts +8 -0
- package/dist/dashboard/handler.d.ts +6 -24
- package/dist/db/migrations/109_cluster_settings_cache_knobs.d.ts +4 -0
- package/dist/db/migrations/110_cluster_settings_global_eval_knobs.d.ts +4 -0
- package/dist/db/migrations/111_cluster_settings_global_eval_wait.d.ts +4 -0
- package/dist/db/migrations/112_execution_runs_workflow_repo.d.ts +4 -0
- package/dist/db/migrations/113_execution_runs_workflow_repo_index.d.ts +30 -0
- package/dist/db/migrations/114_ingest_queue_claim.d.ts +4 -0
- package/dist/db/migrations/115_global_workflows_cluster_switch.d.ts +9 -0
- package/dist/db/migrations/116_org_plan_headroom.d.ts +4 -0
- package/dist/db/migrations/117_invoke_gate_proxy_jobs.d.ts +4 -0
- package/dist/db/migrations/118_invoke_gate_scheduling.d.ts +4 -0
- package/dist/db/migrations/119_scaler_ha_ownership.d.ts +4 -0
- package/dist/db/migrations/120_cluster_settings_scaler_reaper.d.ts +4 -0
- package/dist/db/migrations/121_org_settings_allow_untrusted_dockerfile_builds.d.ts +19 -0
- package/dist/db/migrations/122_host_roster_scaler_managed.d.ts +25 -0
- package/dist/db/migrations/123_workflow_registrations_default_branch.d.ts +24 -0
- package/dist/db/migrations/124_cluster_settings_provision_backoff.d.ts +4 -0
- package/dist/db/migrations/125_org_trust_directory.d.ts +30 -0
- package/dist/db/migrations/126_held_runs_posted_pending_check.d.ts +28 -0
- package/dist/db/migrations/127_org_trust_policy_approval_expiry_seconds.d.ts +26 -0
- package/dist/db/migrations/128_execution_runs_global_eval_round.d.ts +23 -0
- package/dist/db/migrations/129_execution_runs_dispatch_routing_key.d.ts +24 -0
- package/dist/db/migrations/130_scaler_provision_outcomes.d.ts +32 -0
- package/dist/db/types.d.ts +428 -12
- package/dist/entry-helpers.d.ts +28 -0
- package/dist/events/event-emitter.d.ts +22 -0
- package/dist/events/event-router.d.ts +87 -1
- package/dist/events/types.d.ts +2 -23
- package/dist/git/credential-broker.d.ts +94 -0
- package/dist/git/inherited-secret.d.ts +24 -0
- package/dist/git/installation-token.d.ts +38 -0
- package/dist/git/job-context.d.ts +13 -0
- package/dist/index.js +324 -84
- package/dist/metrics/agent-metrics-aggregator.d.ts +4 -4
- package/dist/metrics/prometheus.d.ts +170 -3
- package/dist/oidc/oidc-mint-registration.d.ts +7 -3
- package/dist/orchestrator-core.d.ts +91 -24
- package/dist/pipeline/content-filter.d.ts +71 -0
- package/dist/pipeline/direct-ingress-deps.d.ts +100 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +521 -11
- package/dist/pipeline/global-eval-round.d.ts +307 -0
- package/dist/pipeline/internal-event-pipeline.d.ts +140 -0
- package/dist/pipeline/invoke-gate.d.ts +164 -0
- package/dist/pipeline/job-contexts.d.ts +16 -17
- package/dist/pipeline/needs-scheduler.d.ts +13 -0
- package/dist/pipeline/process-webhook.d.ts +126 -31
- package/dist/pipeline/processor.d.ts +282 -23
- package/dist/pipeline/rerun.d.ts +21 -0
- package/dist/pipeline/resume-workflow.d.ts +40 -7
- package/dist/pipeline/route-or-dispatch-jobs.d.ts +15 -0
- package/dist/pipeline/security-hold-check.d.ts +217 -0
- package/dist/pipeline/test-pipeline.d.ts +12 -0
- package/dist/pipeline/undispatched-hold-checks.d.ts +23 -0
- package/dist/pipeline/webhook-payload-store.d.ts +20 -0
- package/dist/policy/dashboard-write-policy-listener.d.ts +62 -0
- package/dist/policy/dashboard-write-policy.d.ts +14 -0
- package/dist/provenance/backfill-run.d.ts +10 -1
- package/dist/provider-registry.d.ts +47 -4
- package/dist/providers/github/check-status-poster.d.ts +33 -3
- package/dist/providers/github/commit-message.d.ts +20 -0
- package/dist/providers/github/file-contents.d.ts +40 -0
- package/dist/providers/github/index.d.ts +2 -2
- package/dist/providers/github/normalizer.d.ts +3 -2
- package/dist/providers/local/normalizer.d.ts +3 -5
- package/dist/providers/universal-git/config.d.ts +2 -0
- package/dist/providers/universal-git/index.d.ts +11 -2
- package/dist/providers/universal-git/normalizer.d.ts +10 -0
- package/dist/queue/cleanup.d.ts +7 -1
- package/dist/queue/job-queue.d.ts +112 -7
- package/dist/queue/terminalize-unroutable.d.ts +13 -0
- package/dist/registration/extractor.d.ts +3 -3
- package/dist/registration/registration-index.d.ts +7 -0
- package/dist/registration/registration-run-match.d.ts +47 -0
- package/dist/registration/registration-store.d.ts +22 -0
- package/dist/reporting/check-run-reporter.d.ts +146 -2
- package/dist/reporting/check-run-summary.d.ts +25 -1
- package/dist/reporting/execution-tracker.d.ts +324 -9
- package/dist/reporting/log-chunk-sink.d.ts +8 -5
- package/dist/reporting/run-aggregator.d.ts +4 -14
- package/dist/reporting/step-display-order.d.ts +43 -0
- package/dist/routes/admin-held-runs.d.ts +142 -0
- package/dist/routes/admin-org-settings.d.ts +5 -0
- package/dist/routes/admin-trust-policy.d.ts +34 -6
- package/dist/routes/admin.d.ts +15 -0
- package/dist/scaler/backend-factory.d.ts +55 -0
- package/dist/scaler/bare-metal-backend.d.ts +43 -5
- package/dist/scaler/claim-store.d.ts +119 -0
- package/dist/scaler/config.d.ts +4 -0
- package/dist/scaler/container-backend.d.ts +18 -4
- package/dist/scaler/container-routing.d.ts +23 -0
- package/dist/scaler/container-spawn.d.ts +28 -0
- package/dist/scaler/event-backend.d.ts +124 -0
- package/dist/scaler/event-provision-reaper.d.ts +350 -0
- package/dist/scaler/failure-tracker.d.ts +1 -1
- package/dist/scaler/firecracker-backend.d.ts +33 -6
- package/dist/scaler/index.d.ts +11 -1
- package/dist/scaler/label-matcher.d.ts +4 -3
- package/dist/scaler/manager.d.ts +905 -76
- package/dist/scaler/resolve-container-auth.d.ts +45 -0
- package/dist/scaler/scaler-events.d.ts +11 -0
- package/dist/scaler/scaler-state-store.d.ts +294 -10
- package/dist/scaler/types.d.ts +131 -13
- package/dist/scaler/warm-pool.d.ts +132 -29
- package/dist/security/comment-handler.d.ts +50 -11
- package/dist/security/global-workflow-policy.d.ts +52 -12
- package/dist/security/identity-link.d.ts +60 -0
- package/dist/security/lock-source.d.ts +11 -13
- package/dist/security/reduced-privilege-note.d.ts +59 -0
- package/dist/security/trust-directory-store.d.ts +233 -0
- package/dist/security/trust-policy-gate.d.ts +94 -59
- package/dist/security/trust-policy-store.d.ts +3 -0
- package/dist/security/trust-resolver.d.ts +14 -98
- package/dist/server.d.ts +11 -1
- package/dist/server.js +56329 -42234
- package/dist/stale-detector/gate-deadline-detector.d.ts +52 -0
- package/dist/stale-detector/stale-run-detector.d.ts +61 -3
- package/dist/standalone.js +37619 -23570
- package/dist/webhook/ingest-accept.d.ts +70 -0
- package/dist/webhook/ingest-overflow-buffer.d.ts +35 -4
- package/dist/webhook/ingest-overflow-replayer.d.ts +50 -6
- package/dist/worker/in-memory-job-queue.d.ts +1 -1
- package/dist/ws/agent-handler.d.ts +31 -4
- package/dist/ws/dashboard-context-handler.d.ts +28 -4
- package/dist/ws/dashboard-global-workflows-handler.d.ts +36 -9
- package/dist/ws/execution-status-frame.d.ts +32 -0
- package/dist/ws/failure-messages.d.ts +2 -0
- package/dist/ws/git-credential-relay.d.ts +39 -0
- package/dist/ws/oidc-token-relay.d.ts +6 -11
- package/dist/ws/platform-client.d.ts +68 -9
- package/dist/ws/test-relay-handlers.d.ts +35 -10
- package/installer-image-digests.json +3 -3
- package/package.json +24 -19
- package/sbom.spdx.json +868 -821
- package/dist/approvals/team-membership-lookup.d.ts +0 -13
- package/dist/pipeline/inline-eval.d.ts +0 -44
- package/dist/providers/github/contributor-resolver.d.ts +0 -30
- package/dist/security/contributor-cache.d.ts +0 -83
|
@@ -72,6 +72,7 @@ export declare const UniversalGitPayloadPathsSchema: z.ZodObject<{
|
|
|
72
72
|
commitsAdded: z.ZodString;
|
|
73
73
|
commitsModified: z.ZodString;
|
|
74
74
|
commitsRemoved: z.ZodString;
|
|
75
|
+
commitMessage: z.ZodOptional<z.ZodString>;
|
|
75
76
|
}, z.core.$strip>;
|
|
76
77
|
export type UniversalGitPayloadPaths = z.infer<typeof UniversalGitPayloadPathsSchema>;
|
|
77
78
|
/**
|
|
@@ -129,6 +130,7 @@ export declare const UniversalGitConfigSchema: z.ZodObject<{
|
|
|
129
130
|
commitsAdded: z.ZodString;
|
|
130
131
|
commitsModified: z.ZodString;
|
|
131
132
|
commitsRemoved: z.ZodString;
|
|
133
|
+
commitMessage: z.ZodOptional<z.ZodString>;
|
|
132
134
|
}, z.core.$strip>>;
|
|
133
135
|
eventMapping: z.ZodOptional<z.ZodObject<{
|
|
134
136
|
push: z.ZodArray<z.ZodString>;
|
|
@@ -18,8 +18,17 @@
|
|
|
18
18
|
* - `UniversalGitRepoUrlBuilder` — substitutes `{owner}`/`{name}`/`{repo}`
|
|
19
19
|
* in the source's `gitUrlTemplate`.
|
|
20
20
|
*
|
|
21
|
-
* No `
|
|
22
|
-
*
|
|
21
|
+
* No `CheckStatusPoster` is wired for v1 — forge API support for it is uneven
|
|
22
|
+
* and adding it is a separate phase.
|
|
23
|
+
*
|
|
24
|
+
* The bundle also leaves `hasForkModel` unset. The normalizer does report an
|
|
25
|
+
* `isForkPR`, but it compares two repo names that `extractRepoFullName` reads
|
|
26
|
+
* from fixed keys (`repo.full_name`, then `full_name`) on the payload's `head`
|
|
27
|
+
* and `base` — keys many forges' PR payloads do not carry, and which no
|
|
28
|
+
* `payloadPaths` entry can redirect. It yields `false` whenever either is
|
|
29
|
+
* absent, so it fails toward trust. A pull-request event here therefore
|
|
30
|
+
* resolves no trust tier: it reads the base branch's lock file and writes an
|
|
31
|
+
* isolated cache scope, and the org fork policy never gates it.
|
|
23
32
|
*/
|
|
24
33
|
import type { ProviderBundle } from '../../provider-registry.js';
|
|
25
34
|
import type { GenericWebhookSource } from '../../db/types.js';
|
|
@@ -84,6 +84,16 @@ export declare class UniversalGitWebhookNormalizer implements WebhookNormalizer
|
|
|
84
84
|
* is safe to ship ahead of the interface change in Phase 3.
|
|
85
85
|
*/
|
|
86
86
|
extractDefaultBranch(payload: unknown): string | null;
|
|
87
|
+
/**
|
|
88
|
+
* Text a `commitMessage` trigger filter is tested against.
|
|
89
|
+
*
|
|
90
|
+
* Push/tag reads the configured JSONPath, because forges genuinely differ on
|
|
91
|
+
* where the head commit lives. The PR read is STRUCTURAL rather than
|
|
92
|
+
* configured, matching how this normalizer already resolves base/head refs —
|
|
93
|
+
* `pull_request` on Gitea-family forges, `object_attributes` on GitLab, whose
|
|
94
|
+
* body field is spelled `description`.
|
|
95
|
+
*/
|
|
96
|
+
private extractCommitMessage;
|
|
87
97
|
/** Classify the raw event header against the source's eventMapping. */
|
|
88
98
|
private classifyEvent;
|
|
89
99
|
}
|
package/dist/queue/cleanup.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { CheckRunTrackingStore } from '../reporting/check-run-tracking-stor
|
|
|
6
6
|
import type { ClusterSettingsReader } from '../cluster/cluster-settings-reader.js';
|
|
7
7
|
import type { LogStorage } from '../reporting/log-storage.js';
|
|
8
8
|
import { JobQueue } from './job-queue.js';
|
|
9
|
-
import { type CanRouteLabels } from './terminalize-unroutable.js';
|
|
9
|
+
import { type CanRouteLabels, type TerminalizeDeps } from './terminalize-unroutable.js';
|
|
10
10
|
/**
|
|
11
11
|
* Optional cleanup dependencies + retention knobs. Present in platform/hybrid
|
|
12
12
|
* mode (the only wiring site, `orchestrator-core`, always supplies them); the
|
|
@@ -67,6 +67,12 @@ export interface CleanupExtras {
|
|
|
67
67
|
* safety: the job is terminal either way and the run fails either way.
|
|
68
68
|
*/
|
|
69
69
|
canRouteLabels?: CanRouteLabels;
|
|
70
|
+
/**
|
|
71
|
+
* The Tier-2 global-eval tracker, forwarded to
|
|
72
|
+
* {@link terminalizeUnroutableJob} so a round job this sweep settles also
|
|
73
|
+
* settles the webhook request awaiting its verdict.
|
|
74
|
+
*/
|
|
75
|
+
pendingGlobalEvals?: TerminalizeDeps['pendingGlobalEvals'];
|
|
70
76
|
}
|
|
71
77
|
/**
|
|
72
78
|
* Run a single cleanup pass: remove expired dedup_cache entries and
|
|
@@ -180,6 +180,23 @@ export interface QueuedJob {
|
|
|
180
180
|
/** For a runsOnAll host-fanout child: the agent this job is pinned to. */
|
|
181
181
|
pinnedAgentId?: string;
|
|
182
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* The resource shape a job declares, read from the one location that always
|
|
185
|
+
* carries it.
|
|
186
|
+
*
|
|
187
|
+
* `jobConfig.resources` is where the declaration is stored and transported: it
|
|
188
|
+
* is what `job_config` holds across the DB round trip and what a worker
|
|
189
|
+
* receives over the wire. The typed `resources` field on {@link QueuedJobInput}
|
|
190
|
+
* and {@link QueuedJob} is a convenience mirror, and it is optional — several
|
|
191
|
+
* dispatch paths build their input without it (the worker's reroute handler and
|
|
192
|
+
* the webhook dispatch path among them). So a consumer that reads only the
|
|
193
|
+
* mirror sees a job that declares nothing, and a shape-sensitive decision made
|
|
194
|
+
* on that reading is wrong rather than merely unaware.
|
|
195
|
+
*
|
|
196
|
+
* Callers that hold a mirror still prefer it — it is the same value — and fall
|
|
197
|
+
* back here.
|
|
198
|
+
*/
|
|
199
|
+
export declare function resourcesFromJobConfig(jobConfig: Record<string, unknown> | undefined): ResourceRequest | undefined;
|
|
183
200
|
/**
|
|
184
201
|
* DB-backed FIFO job dispatch queue using Kysely (PostgreSQL only).
|
|
185
202
|
* Uses SQL-based JSONB containment queries (@> operator) for label matching.
|
|
@@ -236,21 +253,69 @@ export declare class JobQueue {
|
|
|
236
253
|
* @param agentLabels Labels the agent provides.
|
|
237
254
|
* @param agentMandatoryLabels Mandatory labels the spawning scaler declared
|
|
238
255
|
* (empty for static / non-scaler agents).
|
|
256
|
+
* @param canServe Optional extra predicate applied to every candidate row
|
|
257
|
+
* before it is claimed. Labels cannot express whether a pre-spawned agent's
|
|
258
|
+
* fixed cpu / memory / image fit a job, so a caller that has to answer that
|
|
259
|
+
* supplies it here — the row must never be claimed and put back, because a
|
|
260
|
+
* claim-then-release both strands it as Dispatched for a window and burns a
|
|
261
|
+
* dispatch attempt. Supplying it opts out of the single-statement fast
|
|
262
|
+
* path, so pass it only for an agent that actually needs the check.
|
|
239
263
|
* @returns The matching job, or null if none found.
|
|
240
264
|
*/
|
|
241
|
-
dequeueForLabels(agentLabels: string[], agentMandatoryLabels?: string[], agentId?: string): Promise<QueuedJob | null>;
|
|
265
|
+
dequeueForLabels(agentLabels: string[], agentMandatoryLabels?: string[], agentId?: string, canServe?: (job: QueuedJob) => boolean): Promise<QueuedJob | null>;
|
|
266
|
+
/**
|
|
267
|
+
* The column writes that constitute a claim. Identical to what
|
|
268
|
+
* {@link markDispatched} sets, so a claim and the caller's follow-up
|
|
269
|
+
* markDispatched are the same transition applied twice rather than two
|
|
270
|
+
* different half-transitions — and a row is never observable as Dispatched
|
|
271
|
+
* with no owner.
|
|
272
|
+
*
|
|
273
|
+
* `agentId` is optional only because `dequeueForLabels` accepts it optionally;
|
|
274
|
+
* every production caller supplies it.
|
|
275
|
+
*/
|
|
276
|
+
private claimTransition;
|
|
277
|
+
/**
|
|
278
|
+
* Conditionally claim one row by id: flip Pending -> Dispatched, returning
|
|
279
|
+
* whether this caller won. The `status = Pending` guard is the arbiter — a
|
|
280
|
+
* loser updates zero rows and must treat that as "someone else took it",
|
|
281
|
+
* never as an error.
|
|
282
|
+
*
|
|
283
|
+
* Used by every claim path that has to run a JS post-filter before claiming
|
|
284
|
+
* (the regex matchers), since that filter runs after the SELECT's
|
|
285
|
+
* per-statement lock window has already closed.
|
|
286
|
+
*/
|
|
287
|
+
private claimRowById;
|
|
242
288
|
/**
|
|
243
289
|
* Build the shared drain WHERE chain (status / expiry / exact-label @> /
|
|
244
290
|
* exclude-label / pin / mandatory-label gate) common to both drain passes.
|
|
245
291
|
* The pattern columns are NOT filtered here — each pass adds its own
|
|
246
292
|
* pattern-free / pattern-bearing guard on top.
|
|
293
|
+
*
|
|
294
|
+
* No projection is attached: the pattern-free pass selects `id` alone (it
|
|
295
|
+
* embeds this as the sub-select of its claiming UPDATE), while the pattern
|
|
296
|
+
* pass selects every column so it can run the JS matcher post-filter.
|
|
247
297
|
*/
|
|
248
298
|
private drainBaseQuery;
|
|
249
299
|
/**
|
|
250
300
|
* Fast path: claim the oldest pending pattern-free row. The
|
|
251
301
|
* `runs_on_patterns = '[]' AND exclude_patterns = '[]'` guard restricts this
|
|
252
|
-
* pass to rows that need no JS post-filter,
|
|
253
|
-
*
|
|
302
|
+
* pass to rows that need no JS post-filter, which is what lets the whole
|
|
303
|
+
* claim be ONE statement.
|
|
304
|
+
*
|
|
305
|
+
* Selecting a row and transitioning it in two statements is not a claim.
|
|
306
|
+
* Outside an explicit transaction the `FOR UPDATE` lock lives only for the
|
|
307
|
+
* duration of its own SELECT, so a second agent arriving between the SELECT
|
|
308
|
+
* and the UPDATE reads the row still Pending, skips nothing, and dispatches
|
|
309
|
+
* the same job — which is one job executing twice on two agents, side effects
|
|
310
|
+
* and all.
|
|
311
|
+
*
|
|
312
|
+
* So the sub-select is embedded in the claiming UPDATE: its `FOR UPDATE SKIP
|
|
313
|
+
* LOCKED` row lock is now taken inside the UPDATE's own transaction and held
|
|
314
|
+
* until commit. That buys both halves at once — exactly one claimant can win
|
|
315
|
+
* a given row, and a concurrent claimant SKIPs the locked row and takes the
|
|
316
|
+
* *next* one instead of coming back empty-handed, which a select-then-claim
|
|
317
|
+
* retry loop would not preserve. The redundant outer `status = Pending` is
|
|
318
|
+
* belt-and-braces on the arbiter.
|
|
254
319
|
*/
|
|
255
320
|
private claimPatternFree;
|
|
256
321
|
/**
|
|
@@ -263,8 +328,29 @@ export declare class JobQueue {
|
|
|
263
328
|
* Pending` makes exactly one of them win. The claim transitions the row to
|
|
264
329
|
* Dispatched, matching the value the caller-side markDispatched would set
|
|
265
330
|
* (which then re-sets it idempotently).
|
|
331
|
+
*
|
|
332
|
+
* Losing the claim continues to the next candidate rather than returning
|
|
333
|
+
* null, so a lost race costs this agent a candidate and not a whole drain.
|
|
266
334
|
*/
|
|
267
335
|
private claimWithPatterns;
|
|
336
|
+
/**
|
|
337
|
+
* Both drain passes at once, with an extra JS predicate between the SELECT
|
|
338
|
+
* and the claim.
|
|
339
|
+
*
|
|
340
|
+
* Same shape as {@link claimWithPatterns} and for the same reason: the filter
|
|
341
|
+
* has to run BEFORE the row transitions, so the claim is a conditional
|
|
342
|
+
* `status = Pending` UPDATE by id rather than the embedded sub-select the
|
|
343
|
+
* fast path uses. Claiming first and releasing on a rejection is not an
|
|
344
|
+
* option — it strands the row as Dispatched for the width of the round trip
|
|
345
|
+
* and spends one of the job's bounded dispatch attempts every time an
|
|
346
|
+
* unsuitable agent polls.
|
|
347
|
+
*
|
|
348
|
+
* It covers pattern-free rows too, which the fast path would otherwise take
|
|
349
|
+
* first, so the predicate is applied to every candidate rather than to the
|
|
350
|
+
* pattern-bearing minority. Losing a claim continues to the next candidate,
|
|
351
|
+
* exactly as the pattern pass does.
|
|
352
|
+
*/
|
|
353
|
+
private claimWithPostFilter;
|
|
268
354
|
/**
|
|
269
355
|
* Atomically claim the oldest pending job pinned to a specific agent. Used by
|
|
270
356
|
* the eager pin drain when the pinned agent (re)registers or frees a slot —
|
|
@@ -276,6 +362,13 @@ export declare class JobQueue {
|
|
|
276
362
|
* `runsOn`/`exclude` patterns no longer match the agent's current labels must
|
|
277
363
|
* not be claimed. The single matching authority is the engine's
|
|
278
364
|
* `matcherSatisfiedBy` (never a Postgres `~`).
|
|
365
|
+
*
|
|
366
|
+
* The claim is the conditional UPDATE, not the SELECT: the JS post-filter has
|
|
367
|
+
* to run first (claiming and then releasing a pattern-rejected row would
|
|
368
|
+
* strand it as Dispatched), which puts the filter outside the SELECT's
|
|
369
|
+
* per-statement lock window. Losing that claim returns null, and
|
|
370
|
+
* `onAgentAvailable` then falls through to the generic label drain — which
|
|
371
|
+
* also matches jobs pinned to this agent — so a lost race is not a stall.
|
|
279
372
|
*/
|
|
280
373
|
dequeueByPinnedAgent(agentId: string, agentLabels?: string[]): Promise<QueuedJob | null>;
|
|
281
374
|
/**
|
|
@@ -292,10 +385,22 @@ export declare class JobQueue {
|
|
|
292
385
|
* spawned the agent and was reassigned to a different queued job).
|
|
293
386
|
*
|
|
294
387
|
* Returns null if the job is gone, no longer pending, expired, its label
|
|
295
|
-
* requirements are no longer satisfied by the agent,
|
|
296
|
-
*
|
|
297
|
-
|
|
298
|
-
|
|
388
|
+
* requirements are no longer satisfied by the agent, the agent's gate is not
|
|
389
|
+
* satisfied by the job's `runsOn`, or another claimant won the row first.
|
|
390
|
+
*
|
|
391
|
+
* That last case is the one this shares with every other claim path: the
|
|
392
|
+
* eager bound claim and the generic drain can target the same row moments
|
|
393
|
+
* apart, and a SELECT that returns the row still Pending lets both dispatch
|
|
394
|
+
* it. The conditional UPDATE below is the arbiter, and it runs after the JS
|
|
395
|
+
* post-filter so a pattern-rejected row is never claimed and stranded. A
|
|
396
|
+
* loser returns null, and `dispatchBoundJob` then falls back to the generic
|
|
397
|
+
* `onAgentAvailable` drain exactly as it does for an already-gone job.
|
|
398
|
+
*
|
|
399
|
+
* @param claimingAgentId Recorded as the row's durable owner as part of the
|
|
400
|
+
* claim. Optional so existing 3-arg callers keep working; the caller's
|
|
401
|
+
* markDispatched sets the same column immediately afterwards either way.
|
|
402
|
+
*/
|
|
403
|
+
dequeueById(jobId: string, agentLabels: string[], agentMandatoryLabels?: string[], claimingAgentId?: string): Promise<QueuedJob | null>;
|
|
299
404
|
/**
|
|
300
405
|
* Insert a job directly with status='dispatched' (bypasses the queue).
|
|
301
406
|
* Used when an agent is immediately available and the job doesn't need to wait.
|
|
@@ -3,6 +3,7 @@ import { ExecutionJobStatus, type LabelMatcher } from '@kici-dev/engine';
|
|
|
3
3
|
import type { Database } from '../db/types.js';
|
|
4
4
|
import type { ExecutionTracker } from '../reporting/execution-tracker.js';
|
|
5
5
|
import type { CheckRunReporter } from '../reporting/check-run-reporter.js';
|
|
6
|
+
import type { PendingGlobalEvalTracker } from '../cache/pending-global-evals.js';
|
|
6
7
|
import type { ExpiredJobInfo } from './job-queue.js';
|
|
7
8
|
/**
|
|
8
9
|
* Whether ANYTHING could ever run a job with these selectors — a registered
|
|
@@ -23,6 +24,18 @@ export interface TerminalizeDeps {
|
|
|
23
24
|
executionTracker: ExecutionTracker;
|
|
24
25
|
checkRunReporter?: Pick<CheckRunReporter, 'updateJobStatus'>;
|
|
25
26
|
canRouteLabels?: CanRouteLabels;
|
|
27
|
+
/**
|
|
28
|
+
* The Tier-2 global-eval tracker, so a round job settled here also settles
|
|
29
|
+
* the webhook request awaiting its verdict.
|
|
30
|
+
*
|
|
31
|
+
* A round job is the one queue entry with an in-process awaiter and no
|
|
32
|
+
* `execution_runs` row — the round decides whether any run exists at all —
|
|
33
|
+
* so the rest of this function skips it entirely and the awaiter would
|
|
34
|
+
* otherwise wait out its full ceiling for a job the queue has already
|
|
35
|
+
* declared dead. With the shipped defaults that is a 120s definitive
|
|
36
|
+
* fast-fail followed by a 240s wait, twice.
|
|
37
|
+
*/
|
|
38
|
+
pendingGlobalEvals?: Pick<PendingGlobalEvalTracker, 'reject'>;
|
|
26
39
|
}
|
|
27
40
|
export declare function unroutableMessage(job: JobRoutingFacts): string;
|
|
28
41
|
/**
|
|
@@ -29,9 +29,9 @@ export declare function extractGlobalWorkflows(lockFile: LockFile): LockWorkflow
|
|
|
29
29
|
* Extract workflows that have at least one registerable trigger, OR that
|
|
30
30
|
* have repo patterns (global workflows).
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
32
|
+
* Git-provider triggers (push, pr, tag, …) are ALSO registerable, so
|
|
33
|
+
* cross-source dispatch can resolve them via the registration index when a
|
|
34
|
+
* generic webhook targets an externally-hosted repo. The
|
|
35
35
|
* per-event lock file pipeline remains the primary matching path for
|
|
36
36
|
* same-source git events; registration is an additive index.
|
|
37
37
|
*
|
|
@@ -21,6 +21,13 @@ export interface RegisteredWorkflow {
|
|
|
21
21
|
*/
|
|
22
22
|
customerId: string;
|
|
23
23
|
commitSha: string | null;
|
|
24
|
+
/**
|
|
25
|
+
* The repository's default branch at last registration. A `__schedule_fire`
|
|
26
|
+
* run executes this branch's lock file, so it is the branch such a run
|
|
27
|
+
* presents to a context's branch restrictions. `null` until the repo's next
|
|
28
|
+
* default-branch push populates it.
|
|
29
|
+
*/
|
|
30
|
+
defaultBranch: string | null;
|
|
24
31
|
sourceFile: string | null;
|
|
25
32
|
}
|
|
26
33
|
/**
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ExpressionBuilder, ExpressionWrapper, SqlBool } from 'kysely';
|
|
2
|
+
import type { Database } from '../db/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Match `execution_runs` rows to the registrations that define their workflow.
|
|
5
|
+
*
|
|
6
|
+
* A registration always names the repository the workflow is DEFINED in. A run
|
|
7
|
+
* names two repositories: `repo_identifier` is the one it acted on and whose
|
|
8
|
+
* code its jobs checked out, and `workflow_repo_identifier` is the one that
|
|
9
|
+
* defines the workflow — recorded only when the two differ, which is exactly an
|
|
10
|
+
* organization-wide workflow dispatched against another repository.
|
|
11
|
+
*
|
|
12
|
+
* So the repository a registration must be matched on is
|
|
13
|
+
* `workflow_repo_identifier ?? repo_identifier`. Matching on `repo_identifier`
|
|
14
|
+
* alone is wrong in both directions at once: a global registration matches none
|
|
15
|
+
* of its own runs, and a same-named registration in the acted-on repository
|
|
16
|
+
* matches all of them.
|
|
17
|
+
*
|
|
18
|
+
* Both consumers — the "last triggered" enrichment and the delete path's
|
|
19
|
+
* in-flight cancellation — share this one predicate deliberately. Fixing one
|
|
20
|
+
* and not the other would leave the dashboard showing a global workflow as
|
|
21
|
+
* triggered while deleting it still cancelled nothing.
|
|
22
|
+
*
|
|
23
|
+
* A NULL marker is evidence of a per-repository run only because every
|
|
24
|
+
* recording site states which repository defines the workflow it is recording,
|
|
25
|
+
* and the sites narrow that to NULL exactly when it is the repository the run
|
|
26
|
+
* acted on. The predicate never infers the answer, and the recording sites do
|
|
27
|
+
* not leave it to a default: `recordInitFailureRun`, `recordRunHeld` and
|
|
28
|
+
* `recordGlobalEvalRoundFailureRun` take the defining repository as a required
|
|
29
|
+
* argument, and `WorkflowDispatchContext` carries it as a required field, so a
|
|
30
|
+
* dispatch path that does not state it does not compile. The one run-start
|
|
31
|
+
* recorder that takes it as a trailing positional, `onExecutionStarted`, is
|
|
32
|
+
* supplied by the global dispatch path — the only path where the two
|
|
33
|
+
* repositories differ.
|
|
34
|
+
*/
|
|
35
|
+
export declare function runsDefinedByRepos(eb: ExpressionBuilder<Database, 'execution_runs'>, repoIdentifiers: readonly string[]): ExpressionWrapper<Database, 'execution_runs', SqlBool>;
|
|
36
|
+
/**
|
|
37
|
+
* The repository that defines the workflow a run executed — the read-side
|
|
38
|
+
* counterpart of {@link runsDefinedByRepos}, applied to a row the query
|
|
39
|
+
* returned. Selecting `workflow_repo_identifier` alongside `repo_identifier`
|
|
40
|
+
* and folding here keeps the grouping key the same expression the predicate
|
|
41
|
+
* filters on.
|
|
42
|
+
*/
|
|
43
|
+
export declare function definingRepoOfRun(row: {
|
|
44
|
+
repo_identifier: string;
|
|
45
|
+
workflow_repo_identifier: string | null;
|
|
46
|
+
}): string;
|
|
47
|
+
//# sourceMappingURL=registration-run-match.d.ts.map
|
|
@@ -24,6 +24,16 @@ export interface RegistrationRow {
|
|
|
24
24
|
*/
|
|
25
25
|
customerId: string;
|
|
26
26
|
commitSha: string | null;
|
|
27
|
+
/**
|
|
28
|
+
* The repository's default branch, captured from the push that last updated
|
|
29
|
+
* this registration. A `__schedule_fire` run executes this branch's lock
|
|
30
|
+
* file, so this is the branch such a run presents to a context's branch
|
|
31
|
+
* restrictions.
|
|
32
|
+
*
|
|
33
|
+
* `null` when the registration predates the column or the payload named no
|
|
34
|
+
* default branch — the run then presents no branch and the gate rejects.
|
|
35
|
+
*/
|
|
36
|
+
defaultBranch: string | null;
|
|
27
37
|
sourceFile: string | null;
|
|
28
38
|
created_at: Date;
|
|
29
39
|
updated_at: Date;
|
|
@@ -40,6 +50,18 @@ interface ReplaceAllOptions {
|
|
|
40
50
|
*/
|
|
41
51
|
customerId: string;
|
|
42
52
|
commitSha?: string;
|
|
53
|
+
/**
|
|
54
|
+
* The repository's default branch, read off the registering push's payload.
|
|
55
|
+
* Persisted so a `__schedule_fire` run can present it as its own branch.
|
|
56
|
+
*
|
|
57
|
+
* Three states, and the difference between the last two is load-bearing on an
|
|
58
|
+
* UPDATE: a string is written; `null` means the caller LOOKED and the payload
|
|
59
|
+
* named none, so the stored value is cleared; **omitting the field** means the
|
|
60
|
+
* caller does not know, and an already-captured branch is preserved. Only a
|
|
61
|
+
* default-branch push knows a repository's default branch, so a caller that
|
|
62
|
+
* is not one (the manual registration route) must not erase what one proved.
|
|
63
|
+
*/
|
|
64
|
+
defaultBranch?: string | null;
|
|
43
65
|
sourceFile?: string;
|
|
44
66
|
/** Set of workflow names that should be marked as global */
|
|
45
67
|
globalWorkflowNames?: Set<string>;
|
|
@@ -30,7 +30,7 @@ import type { ProviderRegistry } from '../provider-registry.js';
|
|
|
30
30
|
import type { StepLogBuffer } from './step-log-buffer.js';
|
|
31
31
|
import { type SourceLocationData } from './check-run-summary.js';
|
|
32
32
|
import type { CheckRunTrackingStore } from './check-run-tracking-store.js';
|
|
33
|
-
import { type TerminalJobStatus } from '@kici-dev/engine';
|
|
33
|
+
import { CheckRunConclusion, type TerminalJobStatus } from '@kici-dev/engine';
|
|
34
34
|
/**
|
|
35
35
|
* Dependencies for the CheckRunReporter.
|
|
36
36
|
*/
|
|
@@ -87,6 +87,15 @@ interface SetPendingOptions {
|
|
|
87
87
|
repo: string;
|
|
88
88
|
sha: string;
|
|
89
89
|
workflowName: string;
|
|
90
|
+
/**
|
|
91
|
+
* The repository that DEFINES the workflow, when that is not the repository
|
|
92
|
+
* the run acted on — an organization-wide workflow dispatched against
|
|
93
|
+
* another repository. Qualifies the check-run name so the run cannot share a
|
|
94
|
+
* check run with a same-named workflow of the acted-on repository; see
|
|
95
|
+
* `workflowLabel`. Passing the acted-on repository here is a no-op, so a
|
|
96
|
+
* caller cannot change a per-repository run's name by accident.
|
|
97
|
+
*/
|
|
98
|
+
workflowRepoIdentifier?: string;
|
|
90
99
|
jobNames: string[];
|
|
91
100
|
installationId?: number;
|
|
92
101
|
/** Routing key for per-app credential lookup (e.g., "github:12345"). */
|
|
@@ -105,6 +114,8 @@ interface SetBuildPendingOptions {
|
|
|
105
114
|
repo: string;
|
|
106
115
|
sha: string;
|
|
107
116
|
workflowName: string;
|
|
117
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
118
|
+
workflowRepoIdentifier?: string;
|
|
108
119
|
installationId?: number;
|
|
109
120
|
/** Routing key for per-app credential lookup (e.g., "github:12345"). */
|
|
110
121
|
routingKey?: string;
|
|
@@ -122,6 +133,8 @@ interface SetBuildCompleteOptions {
|
|
|
122
133
|
repo: string;
|
|
123
134
|
sha: string;
|
|
124
135
|
workflowName: string;
|
|
136
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
137
|
+
workflowRepoIdentifier?: string;
|
|
125
138
|
status: TerminalJobStatus;
|
|
126
139
|
installationId?: number;
|
|
127
140
|
/** Routing key for per-app credential lookup (e.g., "github:12345"). */
|
|
@@ -141,6 +154,8 @@ interface UpdateJobStatusOptions {
|
|
|
141
154
|
repo: string;
|
|
142
155
|
sha: string;
|
|
143
156
|
workflowName: string;
|
|
157
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
158
|
+
workflowRepoIdentifier?: string;
|
|
144
159
|
jobName: string;
|
|
145
160
|
state: TerminalJobStatus;
|
|
146
161
|
installationId?: number;
|
|
@@ -157,6 +172,15 @@ interface UpdateJobStatusOptions {
|
|
|
157
172
|
runIdForLogs?: string;
|
|
158
173
|
/** Job ID for StepLogBuffer lookup. */
|
|
159
174
|
jobId?: string;
|
|
175
|
+
/**
|
|
176
|
+
* The run's resolved trust tier and lock-file branch. When the tier is
|
|
177
|
+
* anything other than `trusted`, the completion summary leads with the
|
|
178
|
+
* reduced-privilege note so a contributor reading a failed job on a fork pull
|
|
179
|
+
* request can see which parts of the build environment the run did not have.
|
|
180
|
+
* Both absent for a run whose trust never resolved.
|
|
181
|
+
*/
|
|
182
|
+
trustTier?: string;
|
|
183
|
+
lockFileSource?: string;
|
|
160
184
|
}
|
|
161
185
|
/**
|
|
162
186
|
* Options for updateWorkflowStatus.
|
|
@@ -167,6 +191,8 @@ interface UpdateWorkflowStatusOptions {
|
|
|
167
191
|
repo: string;
|
|
168
192
|
sha: string;
|
|
169
193
|
workflowName: string;
|
|
194
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
195
|
+
workflowRepoIdentifier?: string;
|
|
170
196
|
overallStatus: TerminalJobStatus;
|
|
171
197
|
installationId?: number;
|
|
172
198
|
/** Routing key for per-app credential lookup (e.g., "github:12345"). */
|
|
@@ -176,6 +202,43 @@ interface UpdateWorkflowStatusOptions {
|
|
|
176
202
|
requestId?: string;
|
|
177
203
|
/** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
|
|
178
204
|
runId?: string;
|
|
205
|
+
/**
|
|
206
|
+
* The run's resolved trust tier and lock-file branch, same contract as
|
|
207
|
+
* {@link UpdateJobStatusOptions}. The roll-up check carries the note too: a
|
|
208
|
+
* contributor who reads only `kici/<workflow>` — the one branch protection
|
|
209
|
+
* usually requires — would otherwise see a run fail with no explanation.
|
|
210
|
+
*/
|
|
211
|
+
trustTier?: string;
|
|
212
|
+
lockFileSource?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Options for completeUndispatchedCheckRuns.
|
|
216
|
+
*/
|
|
217
|
+
export interface CompleteUndispatchedCheckRunsOptions {
|
|
218
|
+
provider: string;
|
|
219
|
+
owner: string;
|
|
220
|
+
repo: string;
|
|
221
|
+
sha: string;
|
|
222
|
+
workflowName: string;
|
|
223
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
224
|
+
workflowRepoIdentifier?: string;
|
|
225
|
+
/**
|
|
226
|
+
* The job names `setPending` / `setPendingAwait` created a check run for.
|
|
227
|
+
* Pass the same list that call used, or the names will not match the check
|
|
228
|
+
* runs on the commit.
|
|
229
|
+
*/
|
|
230
|
+
jobNames: string[];
|
|
231
|
+
installationId?: number;
|
|
232
|
+
/** Routing key for per-app credential lookup (e.g., "github:12345"). */
|
|
233
|
+
routingKey?: string;
|
|
234
|
+
/** Explicit requestId for trace context (falls back to AsyncLocalStorage context). */
|
|
235
|
+
requestId?: string;
|
|
236
|
+
/** Explicit runId for trace context (falls back to AsyncLocalStorage context). */
|
|
237
|
+
runId?: string;
|
|
238
|
+
/** The conclusion to complete each check run with. */
|
|
239
|
+
conclusion: CheckRunConclusion;
|
|
240
|
+
/** The check-run output body. The title stays the standard `KiCI: <label>` form. */
|
|
241
|
+
summary: string;
|
|
179
242
|
}
|
|
180
243
|
/**
|
|
181
244
|
* Options for updateStepProgress.
|
|
@@ -186,6 +249,8 @@ interface UpdateStepProgressOptions {
|
|
|
186
249
|
repo: string;
|
|
187
250
|
sha: string;
|
|
188
251
|
workflowName: string;
|
|
252
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
253
|
+
workflowRepoIdentifier?: string;
|
|
189
254
|
jobName: string;
|
|
190
255
|
stepIndex: number;
|
|
191
256
|
stepName: string;
|
|
@@ -257,7 +322,26 @@ export declare class CheckRunReporter {
|
|
|
257
322
|
* still find every key for a runId at cleanup time.
|
|
258
323
|
*/
|
|
259
324
|
private readonly runIdToKeys;
|
|
325
|
+
/**
|
|
326
|
+
* Per-key serialization of GitHub check-run PATCHes. Two updates for one
|
|
327
|
+
* check run must never be in flight at GitHub simultaneously: the terminal
|
|
328
|
+
* `completed` write and an earlier `in_progress` write race last-write-wins,
|
|
329
|
+
* and if the `in_progress` PATCH lands second it reopens the check run to the
|
|
330
|
+
* permanently-unresolved `{ status: in_progress, conclusion: <terminal> }`
|
|
331
|
+
* state. The `terminalSent` re-check inside `updateCheckRun` cannot help once
|
|
332
|
+
* an `in_progress` PATCH has passed it and is awaiting the network — it is a
|
|
333
|
+
* check-then-await. Chaining every PATCH for a key through this map makes the
|
|
334
|
+
* re-check and the PATCH atomic relative to the completion write.
|
|
335
|
+
*/
|
|
336
|
+
private readonly updateLocks;
|
|
260
337
|
constructor(deps: CheckRunReporterDeps);
|
|
338
|
+
/**
|
|
339
|
+
* Run `fn` after every previously-queued check-run PATCH for `key` has
|
|
340
|
+
* settled, so all updates to one check run execute strictly in order. The
|
|
341
|
+
* chain swallows prior errors (each is surfaced to its own caller) so one
|
|
342
|
+
* failed PATCH does not wedge the key.
|
|
343
|
+
*/
|
|
344
|
+
private runUpdateExclusive;
|
|
261
345
|
/**
|
|
262
346
|
* Update the provider registry used for per-routing-key credential lookup.
|
|
263
347
|
* Called after config reload when the provider registry is rebuilt.
|
|
@@ -301,6 +385,33 @@ export declare class CheckRunReporter {
|
|
|
301
385
|
* Fire-and-forget: errors are logged but don't block the pipeline.
|
|
302
386
|
*/
|
|
303
387
|
updateWorkflowStatus(opts: UpdateWorkflowStatusOptions): void;
|
|
388
|
+
/**
|
|
389
|
+
* Complete the queued check runs of a workflow that never dispatched a job.
|
|
390
|
+
*
|
|
391
|
+
* `setPendingAwait` creates `kici/<workflow>` and one
|
|
392
|
+
* `kici/<workflow>/job/<name>` per static job before the pipeline knows
|
|
393
|
+
* whether the workflow will run. When the workflow then ends without
|
|
394
|
+
* dispatching one — a hold rejected or expired, or any pre-dispatch init
|
|
395
|
+
* failure — none of these names ever reaches a job or run record, so
|
|
396
|
+
* `updateJobStatus` and `updateWorkflowStatus` are never called for them, and
|
|
397
|
+
* `doCleanupStaleCheckRuns` skips them because that sweep only updates check
|
|
398
|
+
* runs whose status is `in_progress`. They stay `queued` on the commit, which
|
|
399
|
+
* on a pull request reads as a check that never finishes and blocks branch
|
|
400
|
+
* protection.
|
|
401
|
+
*
|
|
402
|
+
* Completes only the check runs this reporter can resolve an id for (L1 cache
|
|
403
|
+
* or the `check_run_tracking` row), and skips a key already latched terminal.
|
|
404
|
+
*
|
|
405
|
+
* The build check `kici/<workflow>/setup` is deliberately not in the set,
|
|
406
|
+
* because that latch does not reliably cover it. `setBuildComplete` stamps
|
|
407
|
+
* `terminal_sent_at` on the row but adds nothing to the in-process
|
|
408
|
+
* `terminalSent` set, and `resolveCheckRunId` returns on an L1 hit without
|
|
409
|
+
* reading the row — so a build check this process completed a moment ago
|
|
410
|
+
* resolves with no latch, and completing it again would overwrite a real
|
|
411
|
+
* build conclusion. An unreadable row is the harmless direction: it yields
|
|
412
|
+
* no id and the name is skipped.
|
|
413
|
+
*/
|
|
414
|
+
completeUndispatchedCheckRuns(opts: CompleteUndispatchedCheckRunsOptions): Promise<void>;
|
|
304
415
|
/**
|
|
305
416
|
* Clean up stale check runs left by a dead orchestrator.
|
|
306
417
|
*
|
|
@@ -321,6 +432,8 @@ export declare class CheckRunReporter {
|
|
|
321
432
|
repo: string;
|
|
322
433
|
sha: string;
|
|
323
434
|
workflowName: string;
|
|
435
|
+
/** See {@link SetPendingOptions.workflowRepoIdentifier}. */
|
|
436
|
+
workflowRepoIdentifier?: string;
|
|
324
437
|
jobNames: string[];
|
|
325
438
|
}): void;
|
|
326
439
|
/**
|
|
@@ -337,7 +450,8 @@ export declare class CheckRunReporter {
|
|
|
337
450
|
* Separate from execution check runs so users see build progress independently.
|
|
338
451
|
* Fire-and-forget: errors are logged but don't block the pipeline.
|
|
339
452
|
*
|
|
340
|
-
* Check run name format: kici/{workflowName}/setup
|
|
453
|
+
* Check run name format: kici/{workflowName}/setup — prefixed with the
|
|
454
|
+
* defining repository for a cross-repository global run, see `workflowLabel`.
|
|
341
455
|
*/
|
|
342
456
|
setBuildPending(opts: SetBuildPendingOptions): void;
|
|
343
457
|
/**
|
|
@@ -390,6 +504,13 @@ export declare class CheckRunReporter {
|
|
|
390
504
|
* Read-through helper: look up a check-run ID. Checks L1 first, falls
|
|
391
505
|
* through to the store on miss, caches the result on hit. Returns
|
|
392
506
|
* undefined when neither layer has the ID — the caller logs + skips.
|
|
507
|
+
*
|
|
508
|
+
* The same row also rehydrates the `terminalSent` latch. Both L1 entries are
|
|
509
|
+
* dropped together by `cleanupRun`, and only one of them used to come back:
|
|
510
|
+
* the id reloaded from here while the latch did not, which is exactly the
|
|
511
|
+
* pair that lets a late step-progress update resolve a check run and PATCH
|
|
512
|
+
* `status: in_progress` over its completion. Reading `terminal_sent_at` off
|
|
513
|
+
* the row this query already selects costs nothing and closes that gap.
|
|
393
514
|
*/
|
|
394
515
|
private resolveCheckRunId;
|
|
395
516
|
/**
|
|
@@ -425,6 +546,28 @@ export declare class CheckRunReporter {
|
|
|
425
546
|
*/
|
|
426
547
|
private appendTraceIds;
|
|
427
548
|
private checkRunKey;
|
|
549
|
+
/**
|
|
550
|
+
* The workflow label every check-run name and title is built from.
|
|
551
|
+
*
|
|
552
|
+
* A check run's identity is `(owner, repo, sha, check name)` — on the
|
|
553
|
+
* provider, in `check_run_tracking`'s primary key, and in this class's L1
|
|
554
|
+
* keys. There is no run id anywhere in it. Two per-repository runs cannot
|
|
555
|
+
* collide on that identity, because one lock file cannot define a workflow
|
|
556
|
+
* name twice. An organization-wide workflow can: it is defined in ANOTHER
|
|
557
|
+
* repository, so its name is free to equal a workflow name of the repository
|
|
558
|
+
* it was dispatched against, and on the same commit the two runs then resolve
|
|
559
|
+
* to one check run. The global run's conclusion would complete the acted-on
|
|
560
|
+
* repository's check — the signal branch protection reads — and point its
|
|
561
|
+
* `details_url` at the wrong run, while `cleanupRun` would evict the other
|
|
562
|
+
* run's check-run id and terminal latch on prune.
|
|
563
|
+
*
|
|
564
|
+
* Qualifying the label with the defining repository keeps them apart. The
|
|
565
|
+
* "differs from the acted-on repository" narrowing lives here rather than at
|
|
566
|
+
* the call sites, so a per-repository run's name — which is customer-visible
|
|
567
|
+
* and may sit in a branch-protection required-check list — cannot move
|
|
568
|
+
* because a caller passed the field where it did not apply.
|
|
569
|
+
*/
|
|
570
|
+
private workflowLabel;
|
|
428
571
|
/**
|
|
429
572
|
* Build the `details_url` for a check run pointing at the dashboard's
|
|
430
573
|
* public-alias resolver (`/r/orgs/<oal_xxx>/runs/<runId>`). Returns
|
|
@@ -468,6 +611,7 @@ export declare class CheckRunReporter {
|
|
|
468
611
|
* Supports both 'completed' and 'in_progress' statuses.
|
|
469
612
|
*/
|
|
470
613
|
private updateCheckRun;
|
|
614
|
+
private updateCheckRunLocked;
|
|
471
615
|
}
|
|
472
616
|
/**
|
|
473
617
|
* Build a meaningful failure description from agent job status data.
|