@kici-dev/orchestrator 0.20.1 → 0.21.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/cli/api-client.d.ts +2 -0
- package/dist/cli/commands/runs.d.ts +3 -1
- package/dist/cli/commands/shared/run-ref.d.ts +4 -0
- package/dist/cli/commands/source.d.ts +1 -1
- package/dist/cli.js +113 -27
- package/dist/db/types.d.ts +3 -3
- package/dist/index.js +1 -0
- package/dist/pipeline/dispatch-matched-workflow.d.ts +6 -4
- package/dist/pipeline/test-pipeline.d.ts +21 -1
- package/dist/reporting/check-run-reporter.d.ts +2 -0
- package/dist/reporting/check-run-summary.d.ts +12 -0
- package/dist/reporting/execution-tracker.d.ts +14 -3
- package/dist/reporting/run-workflow-names.d.ts +2 -2
- package/dist/reporting/step-display-order.d.ts +9 -5
- package/dist/server.js +258 -91
- package/dist/standalone.js +238 -89
- package/dist/ws/test-relay-handlers.d.ts +8 -0
- package/installer-image-digests.json +3 -3
- package/package.json +4 -4
- package/sbom.spdx.json +53 -53
package/dist/server.js
CHANGED
|
@@ -5,7 +5,7 @@ __cjs_dirname(__filename);
|
|
|
5
5
|
import "node:module";
|
|
6
6
|
import "@kici-dev/shared/load-service-env-file";
|
|
7
7
|
import { AgentDeliveryMode, AgentPlatform, BaseColdStore, ChunkLru, ChunkRequestWaiter, CommandError, PgTableAdapterBase, RingBuffer, addLogsToArchive, applyProxyKeepAliveTimeouts, chunkBuffer, closeDatabase, computeBackoffDelay, computeMigrationsHash, createDb, createHealthRoutes, createLogger, createMeter, createMetricsRoutes, createPool, createS3Client, decrypt, decryptJson, depCacheKeyOf, deriveKey, encodeKeySegment, encrypt, enrichRequestContext, formatDuration, getPrometheusExporter, getReconnectDelay, getRequestContext, guardStartup, initTelemetry, isPgUniqueViolation, logger, parseDatabaseUrl, redactConfig, requestContext, retryOnBrokenConnection, serializeError, setServiceName, setupGracefulShutdown, shQuote, sha256, stderrTail, stopHttpServer, storeMigrationContentHash, toCommandError, toErrorMessage, trackOpenSockets, validateRequiredTools } from "@kici-dev/shared";
|
|
8
|
-
import { ACTOR_AGENT_SUFFIX, AGENT_API_REQUEST_TIMEOUT_MS, AGENT_FEATURE_LABELS, ALLOWED_SYSTEM_VARS, ARTIFACT_NAME_MAX_LENGTH, AccessLogAction, AccessLogOutcome, AccessLogSource, AccessLogTargetType, ActorType, AgentFailureCategory, ApprovalDecision, ArtifactCompleteAckOutcome, ArtifactDownloadOutcome, ArtifactUploadOutcome, AttestationOrigin, BREAKING_FLOOR, CANONICAL_STATUSES, CLUSTER_MEMBERSHIP_MAX_WORKERS, CONTAINER_BUILD_RUNTIME_LABEL, CacheRefScope, CheckMode, CheckRunConclusion, CheckStepOutcome, CiTrustLevel, ConcurrencyStrategy, ContextDeleteErrorCode, ContextGateRejectReason, ContextType, DASHBOARD_REQUEST_TYPE_SET, DEFAULT_APPROVAL_EXPIRY_SECONDS, DEFAULT_CONCURRENCY_STRATEGY, DEFAULT_HOLD_EXPIRY_SECONDS, DEFERRED_PATHS_SUMMARY_SUFFIX, DashboardResponseErrorCode, DeploymentContainerRuntimeSchema, DeploymentModeSchema, EVENT_LOG_PAYLOAD_CHUNK_BYTES, EventLogPayloadStreamError, EventLogSource, EventLogStatus, ExecutionJobStatus, ExecutionRunStatus, ExecutionStepStatus, FanoutCause, FanoutError, FleetHostWriteRefusal, ForkPolicy, GLOBAL_EVAL_SKIPS_RESULT_AWARE_LABEL, HeldRunQueueType, HeldRunStatus, HoldScope, HoldType, ID_TOKEN_CLAIM_NAMES, INIT_LABEL, INIT_RUNNER_ROLE_LABEL, INSTALL_JOB_ID_PREFIX, INVALID_JOIN_REQUEST_MESSAGE, InitFailureCategory, InventorySelectorSchema, JOB_IMAGE_RUNTIME_LABEL, JOIN_PROTOCOL_UPGRADE_TOKEN, JOIN_PROTOCOL_V1_REMOVED_MESSAGE, JobRejectReason, JoinErrorCode, JoinRequestKind, KICI_AGENT_ENV_PREFIX, KICI_EVENT_NAME_PREFIX, KNOWN_ROLES, LabelMatcher, LockFileParseError, LogStream, MAX_APPROVAL_EXPIRY_SECONDS, MIN_APPROVAL_EXPIRY_SECONDS, MIN_PROTOCOL_VERSION, MinimumTrustSchema, NackCode, ORCH_AGENT_CAPABILITIES, ORCH_CAPABILITIES, OWN_INGRESS_MODES, OrchLogPhase, OrchRole, OrchestratorMode, PEER_MUTUAL_AUTH_REQUIRED_REASON, PLATFORM_CONNECTED_MODES, PLATFORM_TO_ORCH_RECOGNIZED_TYPES, PRIVILEGED_ROOT_LABEL, PROTOCOL_VERSION, PayloadOmittedReason, PeerAuthMode, PeerAuthScheme, PeerForgetOutcome, RELAY_INGRESS_MODES, RegisterableTriggerType, RunFailureClass, RuntimeFact, SCALER_EVENT_NAMES, SCHEMA_VERSION, SECURITY_HOLD_JOB_IDS, SSH_TRANSPORT_CAPABILITY, ScaleDownReason, ScaleDownReason as ScaleDownReason$1, ScalerBackendType, ScalerEventType, ScalerEventType as ScalerEventType$1, ScalerOrphansAction, ScalerReloadOutcome, ScalerScaleDownPayload, ScalerScaleUpPayload, ScalerVmStatus, ScalerVmStopOutcome, ScalerVmTracker, SetupStepType, SourceOrigin, SourceSubtype, TERMINAL_JOB_STATES, TERMINAL_RUN_STATES, TEST_RUN_LOG_CURSOR_START, TRIGGER_EVENT_TYPES, TimeoutReason, TraceCheck, TriggerSource, TrustTierSchema, UnavailablePathsTrace, VariantKind, WEBHOOK_RELAY_MAX_BODY_BYTES, WS_CLOSE_AGENT_AUTH_FAILED, WS_CLOSE_AUTH_TIMEOUT, WS_CLOSE_DISPATCH_ACK_TIMEOUT, WS_CLOSE_GOING_AWAY, WS_CLOSE_HEARTBEAT_TIMEOUT, WS_CLOSE_INTERNAL_ERROR, WS_CLOSE_INVALID_MESSAGE, WS_CLOSE_PLAN_LIMIT, WS_CLOSE_PROTOCOL_ERROR, WS_CLOSE_SUPERSEDED_BY_RECONNECT, WS_CLOSE_UNAUTHORIZED, WS_MAX_PAYLOAD_BYTES, WebhookRelayResult, WsRateLimiter, accessLogWarmSqlCase, agentAuthRequestSchema, agentLabelOf, agentToOrchestratorMessageSchema, agentTypeLabel, appendChecks, approvalTimeoutSecondsSchema, artifactInvalidNameError, assertValidScopeName, assertValidSecretKey, attestationVerifyStatusSchema, buildEventClaims, buildIdTokenSubject, buildJoinRefusal, buildTrustedPassthroughEnv, buildUnsupportedMessageNack, canonicalizeCapability, canonicalizeLabel, canonicalizeLabelSet, canonicalizeLabels, canonicalizeMatcher, checkArtifactName, clampInitFailure, clampStatusFreeText, classifyJoinRequest, coerceDispatchInputs, collectDiscriminatorTypes, createContentRequirementsTraceEntry, createDispatchFailureTraceEntry, createGlobalFilterTraceEntry, createWorkflowDecision, dashboardArtifactsListResponseSchema, dashboardAttestationGetResponseSchema, dashboardAttestationsListAllResponseSchema, dashboardAttestationsListResponseSchema, dashboardRunDetailApiResponseSchema, dashboardStepLogsApiResponseSchema, deriveOsArchLabels, diffRangeKindSchema, executionStatusSchema, fanoutEnvelopeFields, flattenActor, formatLabelMatcher, getAccessLogColdDays, getRepoGlobMatcher, getSecretAuditLogColdDays, githubIngressPath, githubWebhookPath, globalEvalRoundResultSchema, hostLabel, hostSatisfiesTarget, hostToScalerPlatform, installGateJobId, invalidFramePaths, isFailureStatus, isJoinRequestFrame, isKnownCapability, isLockDynamicJobFn, isLockParallelStep, isLockStaticJob, isPullRequestFamilyTriggerEvent, isSecurityHoldJobId, isSelfReportedLabel, jobStatusForwardSchema, joinRequestSchema, logPullPlatformToOrchSchema, matchAllWorkflows, matchScopePattern, matchWorkflowsForEvent, matcherSatisfiedBy, materializeFanout, materializeResolvedHosts, materializeResolvedMatrix, matrixEnvelopeFields, mergeOrderedMaps, minAccessLogWarmDays, minSecretAuditLogWarmDays, partitionMatchers, peerAuthRequestSchema, peerFromPeerMessageSchema, peerHelloResponseSchema, peerHelloSchema, platformToOrchestratorMessageSchema, platformToOsArchLabels, platformToTaints, reservedEventNamePrefix, resolveDiffRange, resolveRoleLabels, resolveScheduleInputs, resolveSecretsWithProvenance, resourceRequestNestedSchema, runtimeLabel, scalerAgentLabels, scalerLabel, scalerPlatformSchema, scheduleTriggerKey, secretAuditLogWarmSqlCase, shouldRecordAccess, shouldRecordSecretResolve, sleep, stateReplaySchema, stepStatusForwardSchema, stringifyActor, testRelayTriggerRequestSchema, testRelayUploadsInitRequestSchema, toIsoString, truncateDecisionsToByteBudget, truncateReasonText, trustPolicyUpdateSchema, trustedContributorHoldReason, validateScopeName, validateSecretKey, wrapUntrusted } from "@kici-dev/engine";
|
|
8
|
+
import { ACTOR_AGENT_SUFFIX, AGENT_API_REQUEST_TIMEOUT_MS, AGENT_FEATURE_LABELS, ALLOWED_SYSTEM_VARS, ARTIFACT_NAME_MAX_LENGTH, AccessLogAction, AccessLogOutcome, AccessLogSource, AccessLogTargetType, ActorType, AgentFailureCategory, ApprovalDecision, ArtifactCompleteAckOutcome, ArtifactDownloadOutcome, ArtifactUploadOutcome, AttestationOrigin, BREAKING_FLOOR, CANONICAL_STATUSES, CLUSTER_MEMBERSHIP_MAX_WORKERS, CONTAINER_BUILD_RUNTIME_LABEL, CacheRefScope, CheckMode, CheckRunConclusion, CheckStepOutcome, CiTrustLevel, ConcurrencyStrategy, ContextDeleteErrorCode, ContextGateRejectReason, ContextType, DASHBOARD_REQUEST_TYPE_SET, DEFAULT_APPROVAL_EXPIRY_SECONDS, DEFAULT_CONCURRENCY_STRATEGY, DEFAULT_HOLD_EXPIRY_SECONDS, DEFERRED_PATHS_SUMMARY_SUFFIX, DashboardResponseErrorCode, DeploymentContainerRuntimeSchema, DeploymentModeSchema, EVENT_LOG_PAYLOAD_CHUNK_BYTES, EventLogPayloadStreamError, EventLogSource, EventLogStatus, ExecutionJobStatus, ExecutionRunStatus, ExecutionStepStatus, FanoutCause, FanoutError, FleetHostWriteRefusal, ForkPolicy, GLOBAL_EVAL_SKIPS_RESULT_AWARE_LABEL, HeldRunQueueType, HeldRunStatus, HoldScope, HoldType, ID_TOKEN_CLAIM_NAMES, INIT_LABEL, INIT_RUNNER_ROLE_LABEL, INIT_STEP_TYPE_PREFIX, INSTALL_JOB_ID_PREFIX, INVALID_JOIN_REQUEST_MESSAGE, InitFailureCategory, InventorySelectorSchema, JOB_IMAGE_RUNTIME_LABEL, JOIN_PROTOCOL_UPGRADE_TOKEN, JOIN_PROTOCOL_V1_REMOVED_MESSAGE, JobRejectReason, JoinErrorCode, JoinRequestKind, KICI_AGENT_ENV_PREFIX, KICI_EVENT_NAME_PREFIX, KNOWN_ROLES, LabelMatcher, LockFileParseError, LogStream, MAX_APPROVAL_EXPIRY_SECONDS, MIN_APPROVAL_EXPIRY_SECONDS, MIN_PROTOCOL_VERSION, MinimumTrustSchema, NackCode, ORCH_AGENT_CAPABILITIES, ORCH_CAPABILITIES, OWN_INGRESS_MODES, OrchLogPhase, OrchRole, OrchestratorMode, PEER_MUTUAL_AUTH_REQUIRED_REASON, PLATFORM_CONNECTED_MODES, PLATFORM_TO_ORCH_RECOGNIZED_TYPES, PRIVILEGED_ROOT_LABEL, PROTOCOL_VERSION, PayloadOmittedReason, PeerAuthMode, PeerAuthScheme, PeerForgetOutcome, RELAY_INGRESS_MODES, RegisterableTriggerType, RunFailureClass, RuntimeFact, SCALER_EVENT_NAMES, SCHEMA_VERSION, SECURITY_HOLD_JOB_IDS, SSH_TRANSPORT_CAPABILITY, ScaleDownReason, ScaleDownReason as ScaleDownReason$1, ScalerBackendType, ScalerEventType, ScalerEventType as ScalerEventType$1, ScalerOrphansAction, ScalerReloadOutcome, ScalerScaleDownPayload, ScalerScaleUpPayload, ScalerVmStatus, ScalerVmStopOutcome, ScalerVmTracker, SetupStepType, SourceOrigin, SourceSubtype, StepPhase, TERMINAL_JOB_STATES, TERMINAL_RUN_STATES, TEST_RUN_LOG_CURSOR_START, TRIGGER_EVENT_TYPES, TimeoutReason, TraceCheck, TriggerSource, TrustTierSchema, UnavailablePathsTrace, VariantKind, WEBHOOK_RELAY_MAX_BODY_BYTES, WS_CLOSE_AGENT_AUTH_FAILED, WS_CLOSE_AUTH_TIMEOUT, WS_CLOSE_DISPATCH_ACK_TIMEOUT, WS_CLOSE_GOING_AWAY, WS_CLOSE_HEARTBEAT_TIMEOUT, WS_CLOSE_INTERNAL_ERROR, WS_CLOSE_INVALID_MESSAGE, WS_CLOSE_PLAN_LIMIT, WS_CLOSE_PROTOCOL_ERROR, WS_CLOSE_SUPERSEDED_BY_RECONNECT, WS_CLOSE_UNAUTHORIZED, WS_MAX_PAYLOAD_BYTES, WebhookRelayResult, WsRateLimiter, accessLogWarmSqlCase, agentAuthRequestSchema, agentLabelOf, agentToOrchestratorMessageSchema, agentTypeLabel, appendChecks, approvalTimeoutSecondsSchema, artifactInvalidNameError, assertValidScopeName, assertValidSecretKey, attestationVerifyStatusSchema, buildEventClaims, buildIdTokenSubject, buildJoinRefusal, buildTrustedPassthroughEnv, buildUnsupportedMessageNack, canonicalizeCapability, canonicalizeLabel, canonicalizeLabelSet, canonicalizeLabels, canonicalizeMatcher, checkArtifactName, clampInitFailure, clampStatusFreeText, classifyJoinRequest, coerceDispatchInputs, collectDiscriminatorTypes, compareStepsByPhase, createContentRequirementsTraceEntry, createDispatchFailureTraceEntry, createGlobalFilterTraceEntry, createWorkflowDecision, dashboardArtifactsListResponseSchema, dashboardAttestationGetResponseSchema, dashboardAttestationsListAllResponseSchema, dashboardAttestationsListResponseSchema, dashboardRunDetailApiResponseSchema, dashboardStepLogsApiResponseSchema, deriveOsArchLabels, diffRangeKindSchema, executionStatusSchema, fanoutEnvelopeFields, flattenActor, formatLabelMatcher, getAccessLogColdDays, getRepoGlobMatcher, getSecretAuditLogColdDays, githubIngressPath, githubWebhookPath, globalEvalRoundResultSchema, hostLabel, hostSatisfiesTarget, hostToScalerPlatform, initStepIndex, installGateJobId, invalidFramePaths, isFailureStatus, isJoinRequestFrame, isKnownCapability, isLockDynamicJobFn, isLockParallelStep, isLockStaticJob, isPullRequestFamilyTriggerEvent, isRunId, isSecurityHoldJobId, isSelfReportedLabel, jobStatusForwardSchema, joinRequestSchema, logPullPlatformToOrchSchema, matchAllWorkflows, matchScopePattern, matchWorkflowsForEvent, matcherSatisfiedBy, materializeFanout, materializeResolvedHosts, materializeResolvedMatrix, matrixEnvelopeFields, mergeOrderedMaps, minAccessLogWarmDays, minSecretAuditLogWarmDays, parseRunIdRef, partitionMatchers, peerAuthRequestSchema, peerFromPeerMessageSchema, peerHelloResponseSchema, peerHelloSchema, platformToOrchestratorMessageSchema, platformToOsArchLabels, platformToTaints, reservedEventNamePrefix, resolveDiffRange, resolveRoleLabels, resolveScheduleInputs, resolveSecretsWithProvenance, resourceRequestNestedSchema, runIdPrefixRange, runtimeLabel, scalerAgentLabels, scalerLabel, scalerPlatformSchema, scheduleTriggerKey, secretAuditLogWarmSqlCase, shouldRecordAccess, shouldRecordSecretResolve, sleep, stateReplaySchema, stepPhase, stepStatusForwardSchema, stepTypeOf, stringifyActor, testRelayTriggerRequestSchema, testRelayUploadsInitRequestSchema, toIsoString, truncateDecisionsToByteBudget, truncateReasonText, trustPolicyUpdateSchema, trustedContributorHoldReason, validateScopeName, validateSecretKey, wrapUntrusted } from "@kici-dev/engine";
|
|
9
9
|
import * as fs$2 from "node:fs";
|
|
10
10
|
import fs, { chmodSync, closeSync, createReadStream, createWriteStream, fsyncSync, mkdirSync, mkdtempSync, openSync, promises, readFileSync, renameSync, rmSync, statSync, unwatchFile, watchFile, writeFileSync, writeSync } from "node:fs";
|
|
11
11
|
import { z } from "zod";
|
|
@@ -8056,7 +8056,7 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
8056
8056
|
const run = this.runs.get(runId);
|
|
8057
8057
|
const prefix = `needs-pending-${jobName}-`;
|
|
8058
8058
|
if (run) {
|
|
8059
|
-
for (const key of run.jobs
|
|
8059
|
+
for (const [key, job] of run.jobs) if (key.startsWith(prefix) && job.name === jobName) return key;
|
|
8060
8060
|
}
|
|
8061
8061
|
return (await this.db.selectFrom("execution_jobs").select("job_id").where("run_id", "=", runId).where("job_name", "=", jobName).where("job_id", "like", `${prefix}%`).executeTakeFirst())?.job_id;
|
|
8062
8062
|
}
|
|
@@ -9130,6 +9130,10 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
9130
9130
|
async recordInitFailureRun(args) {
|
|
9131
9131
|
const now = /* @__PURE__ */ new Date();
|
|
9132
9132
|
const customerId = await this.resolveCustomerId(args.routingKey);
|
|
9133
|
+
const testRunColumns = args.testRun ? {
|
|
9134
|
+
is_test_run: true,
|
|
9135
|
+
fixture_id: args.testRun.fixtureId
|
|
9136
|
+
} : {};
|
|
9133
9137
|
const crossRepoWorkflowRepo = crossRepoWorkflowRepoOf(args);
|
|
9134
9138
|
if (!guardedWriteApplied(await this.db.insertInto("execution_runs").values({
|
|
9135
9139
|
run_id: args.runId,
|
|
@@ -9151,7 +9155,8 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
9151
9155
|
init_failure: JSON.stringify(args.initFailure),
|
|
9152
9156
|
...inheritedChainDepth(args.chainDepth),
|
|
9153
9157
|
...rerunLineageColumns(args.rerunLineage),
|
|
9154
|
-
...crossRepoWorkflowRepo && { workflow_repo_identifier: crossRepoWorkflowRepo }
|
|
9158
|
+
...crossRepoWorkflowRepo && { workflow_repo_identifier: crossRepoWorkflowRepo },
|
|
9159
|
+
...testRunColumns
|
|
9155
9160
|
}).onConflict((oc) => oc.column("run_id").doUpdateSet({
|
|
9156
9161
|
completed_at: now,
|
|
9157
9162
|
duration_ms: sql`extract(epoch from (${now} - execution_runs.started_at)) * 1000`,
|
|
@@ -9160,7 +9165,8 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
9160
9165
|
failure_class: RunFailureClass.enum.never_started,
|
|
9161
9166
|
init_failure: JSON.stringify(args.initFailure),
|
|
9162
9167
|
...inheritedChainDepth(args.chainDepth),
|
|
9163
|
-
...crossRepoWorkflowRepo && { workflow_repo_identifier: crossRepoWorkflowRepo }
|
|
9168
|
+
...crossRepoWorkflowRepo && { workflow_repo_identifier: crossRepoWorkflowRepo },
|
|
9169
|
+
...testRunColumns
|
|
9164
9170
|
}).where("execution_runs.status", "not in", [...TERMINAL_RUN_STATES])).executeTakeFirst())) {
|
|
9165
9171
|
logger$171.debug("Init-failure record skipped: run already terminal in DB", { runId: args.runId });
|
|
9166
9172
|
return;
|
|
@@ -9265,6 +9271,10 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
9265
9271
|
*/
|
|
9266
9272
|
async recordRunHeld(args) {
|
|
9267
9273
|
const now = /* @__PURE__ */ new Date();
|
|
9274
|
+
const testRunColumns = args.testRun ? {
|
|
9275
|
+
is_test_run: true,
|
|
9276
|
+
fixture_id: args.testRun.fixtureId
|
|
9277
|
+
} : {};
|
|
9268
9278
|
const customerId = await this.resolveCustomerId(args.routingKey);
|
|
9269
9279
|
const crossRepoProvenance = crossRepoProvenanceOf(args.repoIdentifier, {
|
|
9270
9280
|
identifier: args.workflowRepoIdentifier,
|
|
@@ -9292,11 +9302,13 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
9292
9302
|
...rerunLineageColumns(args.rerunLineage),
|
|
9293
9303
|
...crossRepoProvenance && workflowProvenanceColumns(crossRepoProvenance),
|
|
9294
9304
|
...args.isGlobalEvalRound === true && { is_global_eval_round: true },
|
|
9295
|
-
...args.dispatchRoutingKey != null && args.dispatchRoutingKey !== args.routingKey && { dispatch_routing_key: args.dispatchRoutingKey }
|
|
9305
|
+
...args.dispatchRoutingKey != null && args.dispatchRoutingKey !== args.routingKey && { dispatch_routing_key: args.dispatchRoutingKey },
|
|
9306
|
+
...testRunColumns
|
|
9296
9307
|
}).onConflict((oc) => oc.column("run_id").doUpdateSet({
|
|
9297
9308
|
status: ExecutionRunStatus.enum.held,
|
|
9298
9309
|
...args.contextName && { context: args.contextName },
|
|
9299
9310
|
...args.prNumber != null && { pr_number: args.prNumber },
|
|
9311
|
+
...testRunColumns,
|
|
9300
9312
|
...inheritedChainDepth(args.chainDepth),
|
|
9301
9313
|
...crossRepoProvenance && {
|
|
9302
9314
|
workflow_repo_identifier: crossRepoProvenance.identifier,
|
|
@@ -9562,7 +9574,8 @@ var init_execution_tracker = __esmMin((() => {
|
|
|
9562
9574
|
log_path: logPath,
|
|
9563
9575
|
routing_key: this.runs.get(runId)?.routingKey ?? null
|
|
9564
9576
|
};
|
|
9565
|
-
|
|
9577
|
+
const stepType = stepTypeOf(data);
|
|
9578
|
+
if (stepType) values.step_type = stepType;
|
|
9566
9579
|
if (state === ExecutionStepStatus.enum.running) values.started_at = now;
|
|
9567
9580
|
if (TERMINAL_JOB_STATES.has(state)) {
|
|
9568
9581
|
values.completed_at = now;
|
|
@@ -14920,6 +14933,17 @@ var init_reduced_privilege_note = __esmMin((() => {
|
|
|
14920
14933
|
* - Size safety: 65535 byte limit with progressive truncation
|
|
14921
14934
|
*/
|
|
14922
14935
|
/**
|
|
14936
|
+
* Record one step's progress: replace the entry for its index, or add it in display
|
|
14937
|
+
* order. Pseudo-steps have high indices (init at 1_000_000 + n), so the list is keyed
|
|
14938
|
+
* by index rather than position; a positional list would pad every gap up to it.
|
|
14939
|
+
*/
|
|
14940
|
+
function applyStepProgress(steps, entry) {
|
|
14941
|
+
return [...steps.map((s, position) => ({
|
|
14942
|
+
...s,
|
|
14943
|
+
stepIndex: s.stepIndex ?? position
|
|
14944
|
+
})).filter((s) => s.stepIndex !== entry.stepIndex), entry].sort(compareStepsByPhase);
|
|
14945
|
+
}
|
|
14946
|
+
/**
|
|
14923
14947
|
* Cut `summary` to fit the API's cap, whatever a caller wrapped around it. The last line of
|
|
14924
14948
|
* defence: `reservedBytes` keeps a summary readable by dropping log tiers first.
|
|
14925
14949
|
*/
|
|
@@ -15904,27 +15928,13 @@ var init_check_run_reporter = __esmMin((() => {
|
|
|
15904
15928
|
if (!checkRunId) return;
|
|
15905
15929
|
if (this.terminalSent.has(key)) return;
|
|
15906
15930
|
this.trackRunKey(opts.runId, key);
|
|
15907
|
-
|
|
15908
|
-
if (!steps) {
|
|
15909
|
-
steps = [];
|
|
15910
|
-
this.stepProgress.set(key, steps);
|
|
15911
|
-
}
|
|
15912
|
-
if (opts.stepIndex < steps.length) steps[opts.stepIndex] = {
|
|
15931
|
+
const steps = applyStepProgress(this.stepProgress.get(key) ?? [], {
|
|
15913
15932
|
name: opts.stepName,
|
|
15914
15933
|
status: opts.state,
|
|
15915
|
-
durationMs: opts.durationMs
|
|
15916
|
-
|
|
15917
|
-
|
|
15918
|
-
|
|
15919
|
-
name: `Step ${steps.length}`,
|
|
15920
|
-
status: "pending"
|
|
15921
|
-
});
|
|
15922
|
-
steps.push({
|
|
15923
|
-
name: opts.stepName,
|
|
15924
|
-
status: opts.state,
|
|
15925
|
-
durationMs: opts.durationMs
|
|
15926
|
-
});
|
|
15927
|
-
}
|
|
15934
|
+
durationMs: opts.durationMs,
|
|
15935
|
+
stepIndex: opts.stepIndex,
|
|
15936
|
+
...opts.stepType && { stepType: opts.stepType }
|
|
15937
|
+
});
|
|
15928
15938
|
await this.persistStepProgress(key, steps, opts.runId);
|
|
15929
15939
|
if (opts.state === ExecutionStepStatus.enum.running && !this.inProgressSent.get(key)) {
|
|
15930
15940
|
await this.persistInProgressSent(key, opts.runId);
|
|
@@ -48284,7 +48294,9 @@ function createAdminQueueExecutionRoutes(deps) {
|
|
|
48284
48294
|
});
|
|
48285
48295
|
app.get("/executions/:runId", async (c) => {
|
|
48286
48296
|
deps.rbac.requirePermission(c.get("role"), "secret.read");
|
|
48287
|
-
const
|
|
48297
|
+
const rawRunId = c.req.param("runId");
|
|
48298
|
+
if (!isRunId(rawRunId)) return c.json({ error: `Invalid run id '${rawRunId}': a run id is a full UUID.` }, 400);
|
|
48299
|
+
const runId = rawRunId.toLowerCase();
|
|
48288
48300
|
const runRow = await sql`
|
|
48289
48301
|
SELECT id, run_id, workflow_name, status, provider, repo_identifier,
|
|
48290
48302
|
ref, sha, routing_key, context, trust_tier, created_at,
|
|
@@ -49220,6 +49232,10 @@ var init_decorating_secret_resolver = __esmMin((() => {
|
|
|
49220
49232
|
* decorating secret resolver), and the fixture's `secrets` context mapping
|
|
49221
49233
|
* resolves into namespaced secrets;
|
|
49222
49234
|
* - direct workflow execution (bypass trigger matching) is supported.
|
|
49235
|
+
*
|
|
49236
|
+
* Like a webhook, it creates one run per matched workflow. A caller that
|
|
49237
|
+
* follows a single run (no `acceptsMultipleRuns`) gets one shared run instead,
|
|
49238
|
+
* and only when the workflows' job names cannot collide in it.
|
|
49223
49239
|
*/
|
|
49224
49240
|
/**
|
|
49225
49241
|
* Repo identity for an inline-lock (local working tree) run. Derived from the
|
|
@@ -49438,9 +49454,90 @@ function buildTestDispatchContext(shared, workflow, decision, runId) {
|
|
|
49438
49454
|
...Object.keys(shared.runWideFlatSecrets).length > 0 && { runWideFlatSecrets: shared.runWideFlatSecrets }
|
|
49439
49455
|
};
|
|
49440
49456
|
}
|
|
49457
|
+
/** The static job names a workflow defines; null when it has a dynamic job, whose names are unknown until it runs. */
|
|
49458
|
+
function staticJobNames(workflow) {
|
|
49459
|
+
const names = [];
|
|
49460
|
+
for (const job of workflow.jobs) {
|
|
49461
|
+
if (job._type !== "static") return null;
|
|
49462
|
+
names.push(job.name);
|
|
49463
|
+
}
|
|
49464
|
+
return names;
|
|
49465
|
+
}
|
|
49466
|
+
/**
|
|
49467
|
+
* The job names two or more matched workflows define, sorted. Null when a
|
|
49468
|
+
* matched workflow has a dynamic job, so the names cannot be compared before
|
|
49469
|
+
* the run.
|
|
49470
|
+
*/
|
|
49471
|
+
function sharedJobNames(fullLockFile, matchedDecisions) {
|
|
49472
|
+
const owners = /* @__PURE__ */ new Map();
|
|
49473
|
+
for (const decision of matchedDecisions) {
|
|
49474
|
+
const workflow = fullLockFile.workflows.find((w) => w.name === decision.workflowName);
|
|
49475
|
+
if (!workflow) continue;
|
|
49476
|
+
const names = staticJobNames(workflow);
|
|
49477
|
+
if (names === null) return null;
|
|
49478
|
+
for (const name of new Set(names)) owners.set(name, (owners.get(name) ?? 0) + 1);
|
|
49479
|
+
}
|
|
49480
|
+
return [...owners.entries()].filter(([, count]) => count > 1).map(([name]) => name).sort();
|
|
49481
|
+
}
|
|
49482
|
+
/**
|
|
49483
|
+
* Split the matched workflows into runs: one run per workflow, as every other
|
|
49484
|
+
* run producer does.
|
|
49485
|
+
*
|
|
49486
|
+
* A caller that does not set `acceptsMultipleRuns` follows only `runId`. For
|
|
49487
|
+
* it, several matched workflows share one run when their job names cannot
|
|
49488
|
+
* collide (a run keys its needs edges, pending contexts and logs by job name),
|
|
49489
|
+
* and the trigger is refused when they can.
|
|
49490
|
+
*/
|
|
49491
|
+
function planTestRuns(input, fullLockFile, matchedDecisions, firstRunId) {
|
|
49492
|
+
if (input.acceptsMultipleRuns || matchedDecisions.length === 1) return matchedDecisions.map((decision, i) => ({
|
|
49493
|
+
runId: i === 0 ? firstRunId : randomUUID(),
|
|
49494
|
+
decisions: [decision]
|
|
49495
|
+
}));
|
|
49496
|
+
const shared = sharedJobNames(fullLockFile, matchedDecisions);
|
|
49497
|
+
if (shared === null || shared.length > 0) return { rejected: `This fixture matches several workflows (${matchedDecisions.map((d) => d.workflowName).join(", ")}) and ${shared === null ? "one of them defines dynamic jobs, whose names cannot be checked before the run" : `they share job names (${shared.join(", ")})`}. This kici version follows a single run, so upgrade kici to run each workflow as its own run, or pass --workflow <name> to run one workflow.` };
|
|
49498
|
+
return [{
|
|
49499
|
+
runId: firstRunId,
|
|
49500
|
+
decisions: matchedDecisions
|
|
49501
|
+
}];
|
|
49502
|
+
}
|
|
49503
|
+
/**
|
|
49504
|
+
* Dispatch one planned run. A run of several workflows (the shared run of a
|
|
49505
|
+
* caller without `acceptsMultipleRuns`) is held open from its first
|
|
49506
|
+
* registration until its last workflow has registered: a workflow whose jobs
|
|
49507
|
+
* all end before the next one registers would otherwise complete the run, and
|
|
49508
|
+
* the next workflow would start it over.
|
|
49509
|
+
*/
|
|
49510
|
+
async function dispatchPlannedRun(shared, deps, planned) {
|
|
49511
|
+
const { runId, decisions } = planned;
|
|
49512
|
+
const out = {
|
|
49513
|
+
jobIds: [],
|
|
49514
|
+
deferredJobCount: 0,
|
|
49515
|
+
warnings: []
|
|
49516
|
+
};
|
|
49517
|
+
let runHeld = false;
|
|
49518
|
+
const holdRunOpen = () => {
|
|
49519
|
+
if (!runHeld && decisions.length > 1) runHeld = deps.executionTracker?.holdRunForPendingJobs(runId) ?? false;
|
|
49520
|
+
};
|
|
49521
|
+
try {
|
|
49522
|
+
for (const decision of decisions) {
|
|
49523
|
+
const workflow = shared.fullLockFile.workflows.find((w) => w.name === decision.workflowName);
|
|
49524
|
+
if (!workflow) continue;
|
|
49525
|
+
const ctx = buildTestDispatchContext(shared, workflow, decision, runId);
|
|
49526
|
+
ctx.onRunRegistered = holdRunOpen;
|
|
49527
|
+
const result = await dispatchMatchedWorkflow(ctx);
|
|
49528
|
+
out.jobIds.push(...result.dispatchedJobIds);
|
|
49529
|
+
out.deferredJobCount += result.deferredJobCount ?? 0;
|
|
49530
|
+
if (result.envWarnings?.length) out.warnings.push(...result.envWarnings);
|
|
49531
|
+
}
|
|
49532
|
+
} finally {
|
|
49533
|
+
if (runHeld) await deps.executionTracker?.releasePendingJobsHold(runId);
|
|
49534
|
+
}
|
|
49535
|
+
return out;
|
|
49536
|
+
}
|
|
49441
49537
|
/**
|
|
49442
49538
|
* Process a test trigger through the shared dispatch core: one
|
|
49443
|
-
* `WorkflowDispatchContext` per matched workflow, into `dispatchMatchedWorkflow
|
|
49539
|
+
* `WorkflowDispatchContext` per matched workflow, into `dispatchMatchedWorkflow`,
|
|
49540
|
+
* each under its own run id.
|
|
49444
49541
|
*/
|
|
49445
49542
|
async function processTestTrigger(input, deps) {
|
|
49446
49543
|
const runId = randomUUID();
|
|
@@ -49476,6 +49573,13 @@ async function processTestTrigger(input, deps) {
|
|
|
49476
49573
|
jobIds: []
|
|
49477
49574
|
};
|
|
49478
49575
|
const matchedDecisions = matchResult;
|
|
49576
|
+
const plan = planTestRuns(input, fullLockFile, matchedDecisions, runId);
|
|
49577
|
+
if (!Array.isArray(plan)) return {
|
|
49578
|
+
runId,
|
|
49579
|
+
status: "rejected",
|
|
49580
|
+
reason: plan.rejected,
|
|
49581
|
+
jobIds: []
|
|
49582
|
+
};
|
|
49479
49583
|
const resolvedOrgId = deps.db ? await resolveOrgId(deps.db, input.routingKey) : "__default__";
|
|
49480
49584
|
const dispatchInputsResult = resolveDispatchInputs(input, fullLockFile, matchedDecisions);
|
|
49481
49585
|
if ("rejected" in dispatchInputsResult) return {
|
|
@@ -49491,13 +49595,13 @@ async function processTestTrigger(input, deps) {
|
|
|
49491
49595
|
reason: namespacedResult.rejected,
|
|
49492
49596
|
jobIds: []
|
|
49493
49597
|
};
|
|
49494
|
-
await storeFixturePayload(input, deps, runId);
|
|
49598
|
+
for (const planned of plan) await storeFixturePayload(input, deps, planned.runId);
|
|
49495
49599
|
const cliSecrets = decryptCliSecrets(input);
|
|
49496
49600
|
const testDeps = deps.secretResolver ? {
|
|
49497
49601
|
...deps,
|
|
49498
49602
|
secretResolver: new DecoratingSecretResolver(deps.secretResolver, cliSecrets)
|
|
49499
49603
|
} : deps;
|
|
49500
|
-
deps.executionTracker?.markTestRun(runId);
|
|
49604
|
+
for (const planned of plan) deps.executionTracker?.markTestRun(planned.runId);
|
|
49501
49605
|
const provider = inlineProvider ?? input.routingKey.split(":")[0] ?? "local";
|
|
49502
49606
|
const shared = {
|
|
49503
49607
|
input,
|
|
@@ -49523,34 +49627,31 @@ async function processTestTrigger(input, deps) {
|
|
|
49523
49627
|
const jobIds = [];
|
|
49524
49628
|
const warnings = [];
|
|
49525
49629
|
let deferredJobCount = 0;
|
|
49526
|
-
|
|
49527
|
-
const
|
|
49528
|
-
|
|
49529
|
-
|
|
49530
|
-
|
|
49531
|
-
|
|
49532
|
-
|
|
49533
|
-
|
|
49534
|
-
|
|
49535
|
-
|
|
49536
|
-
|
|
49537
|
-
|
|
49538
|
-
|
|
49539
|
-
if (result.envWarnings?.length) warnings.push(...result.envWarnings);
|
|
49540
|
-
}
|
|
49541
|
-
} finally {
|
|
49542
|
-
if (runHeld) await deps.executionTracker?.releasePendingJobsHold(runId);
|
|
49543
|
-
}
|
|
49630
|
+
const runs = [];
|
|
49631
|
+
for (const planned of plan) {
|
|
49632
|
+
const dispatched = await dispatchPlannedRun(shared, deps, planned);
|
|
49633
|
+
jobIds.push(...dispatched.jobIds);
|
|
49634
|
+
deferredJobCount += dispatched.deferredJobCount;
|
|
49635
|
+
warnings.push(...dispatched.warnings);
|
|
49636
|
+
if (planned.decisions.length === 1) runs.push({
|
|
49637
|
+
runId: planned.runId,
|
|
49638
|
+
workflowName: planned.decisions[0].workflowName,
|
|
49639
|
+
jobIds: dispatched.jobIds
|
|
49640
|
+
});
|
|
49641
|
+
}
|
|
49642
|
+
const runsField = runs.length === plan.length ? { runs } : {};
|
|
49544
49643
|
if (jobIds.length === 0 && deferredJobCount === 0) return {
|
|
49545
49644
|
runId,
|
|
49546
49645
|
status: "rejected",
|
|
49547
49646
|
reason: "No jobs dispatched (all matched workflows had no static jobs or dispatch was rejected)",
|
|
49548
|
-
jobIds: []
|
|
49647
|
+
jobIds: [],
|
|
49648
|
+
...runsField
|
|
49549
49649
|
};
|
|
49550
49650
|
return {
|
|
49551
49651
|
runId,
|
|
49552
49652
|
status: "accepted",
|
|
49553
49653
|
jobIds,
|
|
49654
|
+
...runsField,
|
|
49554
49655
|
...warnings.length > 0 && { warnings }
|
|
49555
49656
|
};
|
|
49556
49657
|
}
|
|
@@ -49632,17 +49733,19 @@ async function handleTestTrigger(msg, deps) {
|
|
|
49632
49733
|
checkMode: msg.checkMode,
|
|
49633
49734
|
target: msg.target,
|
|
49634
49735
|
dispatchInputs: msg.dispatchInputs,
|
|
49736
|
+
...msg.acceptsMultipleRuns && { acceptsMultipleRuns: true },
|
|
49635
49737
|
requestId: msg.requestId,
|
|
49636
49738
|
actor: msg.actor
|
|
49637
49739
|
}, deps);
|
|
49638
|
-
|
|
49740
|
+
const runIds = result.runs?.length ? result.runs.map((r) => r.runId) : [result.runId];
|
|
49741
|
+
for (const runId of runIds) runDetached(logger$93, "Access log write", () => deps.accessLog?.record({
|
|
49639
49742
|
orgId: deps.orgId ?? null,
|
|
49640
49743
|
routingKey: deps.routingKey ?? msg.routingKey,
|
|
49641
49744
|
actor: msg.actor,
|
|
49642
49745
|
action: "run.trigger",
|
|
49643
49746
|
target: {
|
|
49644
49747
|
type: "run",
|
|
49645
|
-
id:
|
|
49748
|
+
id: runId
|
|
49646
49749
|
},
|
|
49647
49750
|
requestId: msg.requestId,
|
|
49648
49751
|
source: deps.accessLogSource ?? AccessLogSource.enum.platform_proxy,
|
|
@@ -49650,10 +49753,11 @@ async function handleTestTrigger(msg, deps) {
|
|
|
49650
49753
|
...result.reason ? { errorMessage: result.reason } : {}
|
|
49651
49754
|
}), {
|
|
49652
49755
|
requestId: msg.requestId,
|
|
49653
|
-
runId
|
|
49756
|
+
runId
|
|
49654
49757
|
});
|
|
49655
49758
|
return {
|
|
49656
49759
|
runId: result.runId,
|
|
49760
|
+
...result.runs && { runs: result.runs },
|
|
49657
49761
|
status: result.status,
|
|
49658
49762
|
...result.reason ? { reason: result.reason } : {},
|
|
49659
49763
|
jobIds: result.jobIds,
|
|
@@ -49688,7 +49792,8 @@ async function handleTestRunStatus(msg, deps) {
|
|
|
49688
49792
|
const run = await deps.db.selectFrom("execution_runs").select([
|
|
49689
49793
|
"run_id",
|
|
49690
49794
|
"status",
|
|
49691
|
-
"is_test_run"
|
|
49795
|
+
"is_test_run",
|
|
49796
|
+
"failure_reason"
|
|
49692
49797
|
]).where("run_id", "=", msg.runId).executeTakeFirst();
|
|
49693
49798
|
if (!run || !run.is_test_run) return { error: "Run not found" };
|
|
49694
49799
|
const jobs = await deps.db.selectFrom("execution_jobs").select([
|
|
@@ -49708,6 +49813,7 @@ async function handleTestRunStatus(msg, deps) {
|
|
|
49708
49813
|
errorMessage: j.error_message ?? null,
|
|
49709
49814
|
durationMs: j.duration_ms ?? null
|
|
49710
49815
|
})),
|
|
49816
|
+
failureReason: run.failure_reason ?? null,
|
|
49711
49817
|
done: TERMINAL_RUN_STATES.has(run.status)
|
|
49712
49818
|
};
|
|
49713
49819
|
}
|
|
@@ -49784,14 +49890,18 @@ async function collectRunLogLines(runId, logStorage) {
|
|
|
49784
49890
|
async function readFromFileOffsets(runId, logStorage, offsets, terminal) {
|
|
49785
49891
|
const next = { ...offsets };
|
|
49786
49892
|
const lines = [];
|
|
49893
|
+
const lineJobNames = [];
|
|
49787
49894
|
if (logStorage) for (const file of await listRunLogFiles(runId, logStorage)) {
|
|
49788
49895
|
const fileLines = splitLogLines((await logStorage.read(file.path)).data, terminal);
|
|
49789
49896
|
const from = Math.min(offsets[file.key] ?? 0, fileLines.length);
|
|
49790
|
-
|
|
49897
|
+
const fresh = fileLines.slice(from);
|
|
49898
|
+
lines.push(...fresh);
|
|
49899
|
+
for (let i = 0; i < fresh.length; i++) lineJobNames.push(file.jobName);
|
|
49791
49900
|
next[file.key] = Math.max(offsets[file.key] ?? 0, fileLines.length);
|
|
49792
49901
|
}
|
|
49793
49902
|
return {
|
|
49794
49903
|
lines,
|
|
49904
|
+
lineJobNames,
|
|
49795
49905
|
nextCursor: Object.values(next).reduce((sum, n) => sum + n, 0),
|
|
49796
49906
|
done: terminal,
|
|
49797
49907
|
nextLogCursor: encodeRunLogCursor(next)
|
|
@@ -52270,26 +52380,47 @@ var init_admin_registrations = __esmMin((() => {
|
|
|
52270
52380
|
*
|
|
52271
52381
|
* Sorting `execution_steps` by `step_index` alone puts a pseudo-step where its index landed,
|
|
52272
52382
|
* not where it ran. That suits the cache pseudo-steps (indices above the real steps, mostly
|
|
52273
|
-
* bracketing the work), but a job's image build
|
|
52383
|
+
* bracketing the work), but a job's image build and its init commands run strictly FIRST.
|
|
52274
52384
|
*
|
|
52275
52385
|
* The index cannot express this: `step.status` rejects a negative index (an agent sending one
|
|
52276
52386
|
* to an older orchestrator is disconnected mid-job), and the check-run reporter
|
|
52277
52387
|
* (`steps[stepIndex]`) and the dashboard (log fetching gated on `stepIndex >= 0`) treat a
|
|
52278
|
-
* negative index as absent. So the ordering is expressed by TYPE,
|
|
52388
|
+
* negative index as absent. So the ordering is expressed by TYPE, as the engine's
|
|
52389
|
+
* `StepPhase`, here, once.
|
|
52279
52390
|
*/
|
|
52280
52391
|
/**
|
|
52281
|
-
* Sort key placing setup pseudo-steps
|
|
52282
|
-
* the `step_index` sort:
|
|
52392
|
+
* Sort key placing steps by `StepPhase`: setup pseudo-steps, then init commands, then the
|
|
52393
|
+
* job's steps. Apply BEFORE the `step_index` sort:
|
|
52283
52394
|
*
|
|
52284
52395
|
* ```ts
|
|
52285
52396
|
* qb.orderBy(setupStepsFirst()).orderBy('step_index', 'asc')
|
|
52286
52397
|
* ```
|
|
52287
52398
|
*
|
|
52288
52399
|
* Untyped steps and every real step share one key, so `step_index` alone orders each group.
|
|
52400
|
+
* The init pattern matches `initStepIndex`: the prefix followed by digits only.
|
|
52289
52401
|
*/
|
|
52290
52402
|
function setupStepsFirst() {
|
|
52291
52403
|
const setupTypes = SetupStepType.options;
|
|
52292
|
-
|
|
52404
|
+
const initPattern = `^${INIT_STEP_TYPE_PREFIX}[0-9]+$`;
|
|
52405
|
+
return sql`case when step_type in (${sql.join(setupTypes.map((t) => sql.lit(t)))}) then ${sql.lit(StepPhase.options.indexOf(StepPhase.enum.setup))} when step_type ~ ${sql.lit(initPattern)} then ${sql.lit(StepPhase.options.indexOf(StepPhase.enum.init))} else ${sql.lit(StepPhase.options.indexOf(StepPhase.enum.steps))} end`;
|
|
52406
|
+
}
|
|
52407
|
+
/** In-memory equivalent over DB rows, kept beside the SQL so the two agree on the phases. */
|
|
52408
|
+
function compareStepsForDisplay(a, b) {
|
|
52409
|
+
return compareStepsByPhase({
|
|
52410
|
+
stepType: a.step_type,
|
|
52411
|
+
stepIndex: a.step_index
|
|
52412
|
+
}, {
|
|
52413
|
+
stepType: b.step_type,
|
|
52414
|
+
stepIndex: b.step_index
|
|
52415
|
+
});
|
|
52416
|
+
}
|
|
52417
|
+
/** {@link compareStepsForDisplay} over untyped rows, such as cold-store rows read back from S3. */
|
|
52418
|
+
function compareStepRowsForDisplay(a, b) {
|
|
52419
|
+
const typed = (r) => ({
|
|
52420
|
+
step_type: typeof r.step_type === "string" ? r.step_type : null,
|
|
52421
|
+
step_index: Number(r.step_index ?? 0)
|
|
52422
|
+
});
|
|
52423
|
+
return compareStepsForDisplay(typed(a), typed(b));
|
|
52293
52424
|
}
|
|
52294
52425
|
var init_step_display_order = __esmMin((() => {}));
|
|
52295
52426
|
//#endregion
|
|
@@ -52792,6 +52923,19 @@ function parseCountFlag(raw) {
|
|
|
52792
52923
|
function spansWorkflow(workflowName) {
|
|
52793
52924
|
return (eb) => eb.or([eb("execution_runs.workflow_name", "=", workflowName), eb.exists(eb.selectFrom("execution_jobs").select("execution_jobs.job_id").whereRef("execution_jobs.run_id", "=", "execution_runs.run_id").where("execution_jobs.workflow_name", "=", workflowName))]);
|
|
52794
52925
|
}
|
|
52926
|
+
/**
|
|
52927
|
+
* `?runIdPrefix=`: the run ids that start with the given characters, as a UUID range
|
|
52928
|
+
* the primary-key index answers. A full run id is its own one-id range.
|
|
52929
|
+
*/
|
|
52930
|
+
function parseRunIdPrefixQuery(raw) {
|
|
52931
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
52932
|
+
const ref = parseRunIdRef(raw);
|
|
52933
|
+
if (ref.kind === "invalid") return { error: `Invalid "runIdPrefix" '${raw}': ${ref.reason}` };
|
|
52934
|
+
return ref.kind === "uuid" ? {
|
|
52935
|
+
low: ref.runId,
|
|
52936
|
+
high: ref.runId
|
|
52937
|
+
} : runIdPrefixRange(ref.hex);
|
|
52938
|
+
}
|
|
52795
52939
|
/** Run routes, mounted at /api/v1/admin/runs. */
|
|
52796
52940
|
function createAdminRunRoutes(deps) {
|
|
52797
52941
|
const app = createAdminApp(logger$85);
|
|
@@ -52801,12 +52945,16 @@ function createAdminRunRoutes(deps) {
|
|
|
52801
52945
|
});
|
|
52802
52946
|
app.use("/api/v1/admin/runs", authMiddleware);
|
|
52803
52947
|
app.use("/api/v1/admin/runs/*", authMiddleware);
|
|
52948
|
+
app.use("/api/v1/admin/runs/:runId", requireFullRunId);
|
|
52949
|
+
app.use("/api/v1/admin/runs/:runId/*", requireFullRunId);
|
|
52804
52950
|
app.get("/api/v1/admin/runs", async (c) => {
|
|
52805
52951
|
deps.rbac.requirePermission(c.get("role"), "run.read");
|
|
52806
52952
|
const statuses = parseStatus(c.req.query("status"));
|
|
52807
52953
|
const workflowName = c.req.query("workflowName");
|
|
52808
52954
|
const repo = c.req.query("repo");
|
|
52809
52955
|
const deliveryId = c.req.query("deliveryId");
|
|
52956
|
+
const runIdPrefix = parseRunIdPrefixQuery(c.req.query("runIdPrefix"));
|
|
52957
|
+
if (runIdPrefix && "error" in runIdPrefix) return c.json({ error: runIdPrefix.error }, 400);
|
|
52810
52958
|
const sinceParsed = parseSince(c.req.query("since"));
|
|
52811
52959
|
if (!sinceParsed.ok) return c.json({ error: "Invalid \"since\" query parameter: expected ISO-8601 timestamp" }, 400);
|
|
52812
52960
|
const since = sinceParsed.value;
|
|
@@ -52823,6 +52971,7 @@ function createAdminRunRoutes(deps) {
|
|
|
52823
52971
|
if (workflowName) countQuery = countQuery.where(spansWorkflow(workflowName));
|
|
52824
52972
|
if (repo) countQuery = countQuery.where("repo_identifier", "=", repo);
|
|
52825
52973
|
if (deliveryId) countQuery = countQuery.where("delivery_id", "=", deliveryId);
|
|
52974
|
+
if (runIdPrefix) countQuery = countQuery.where("run_id", ">=", runIdPrefix.low).where("run_id", "<=", runIdPrefix.high);
|
|
52826
52975
|
if (since) countQuery = countQuery.where("created_at", ">", since);
|
|
52827
52976
|
if (tokenRoutingKey) countQuery = countQuery.where("routing_key", "=", tokenRoutingKey);
|
|
52828
52977
|
if (countOnly) {
|
|
@@ -52858,6 +53007,7 @@ function createAdminRunRoutes(deps) {
|
|
|
52858
53007
|
if (workflowName) query = query.where(spansWorkflow(workflowName));
|
|
52859
53008
|
if (repo) query = query.where("repo_identifier", "=", repo);
|
|
52860
53009
|
if (deliveryId) query = query.where("delivery_id", "=", deliveryId);
|
|
53010
|
+
if (runIdPrefix) query = query.where("run_id", ">=", runIdPrefix.low).where("run_id", "<=", runIdPrefix.high);
|
|
52861
53011
|
if (since) query = query.where("created_at", ">", since);
|
|
52862
53012
|
if (tokenRoutingKey) query = query.where("routing_key", "=", tokenRoutingKey);
|
|
52863
53013
|
const [runs, countResult] = await Promise.all([query.orderBy("created_at", "desc").limit(limit).offset(offset).execute(), countQuery.executeTakeFirstOrThrow()]);
|
|
@@ -52889,7 +53039,7 @@ function createAdminRunRoutes(deps) {
|
|
|
52889
53039
|
});
|
|
52890
53040
|
app.get("/api/v1/admin/runs/:runId", async (c) => {
|
|
52891
53041
|
deps.rbac.requirePermission(c.get("role"), "run.read");
|
|
52892
|
-
const runId = c.req.param("runId");
|
|
53042
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
52893
53043
|
const run = await deps.db.selectFrom("execution_runs").select([
|
|
52894
53044
|
"run_id",
|
|
52895
53045
|
"workflow_name",
|
|
@@ -52953,7 +53103,7 @@ function createAdminRunRoutes(deps) {
|
|
|
52953
53103
|
});
|
|
52954
53104
|
app.get("/api/v1/admin/runs/:runId/jobs", async (c) => {
|
|
52955
53105
|
deps.rbac.requirePermission(c.get("role"), "run.read");
|
|
52956
|
-
const runId = c.req.param("runId");
|
|
53106
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
52957
53107
|
const includeSteps = parseCountFlag(c.req.query("includeSteps"));
|
|
52958
53108
|
const runExists = await deps.db.selectFrom("execution_runs").select([
|
|
52959
53109
|
"run_id",
|
|
@@ -53005,6 +53155,7 @@ function createAdminRunRoutes(deps) {
|
|
|
53005
53155
|
jobSteps = [];
|
|
53006
53156
|
stepsByJob.set(step.job_id, jobSteps);
|
|
53007
53157
|
}
|
|
53158
|
+
const initIndex = initStepIndex(step.step_type);
|
|
53008
53159
|
jobSteps.push({
|
|
53009
53160
|
stepIndex: step.step_index,
|
|
53010
53161
|
stepName: step.step_name,
|
|
@@ -53014,7 +53165,9 @@ function createAdminRunRoutes(deps) {
|
|
|
53014
53165
|
durationMs: step.duration_ms,
|
|
53015
53166
|
exitCode: step.exit_code,
|
|
53016
53167
|
errorMessage: step.error_message,
|
|
53017
|
-
stepType: step.step_type
|
|
53168
|
+
stepType: step.step_type,
|
|
53169
|
+
phase: stepPhase(step.step_type),
|
|
53170
|
+
...initIndex !== void 0 && { initIndex }
|
|
53018
53171
|
});
|
|
53019
53172
|
}
|
|
53020
53173
|
}
|
|
@@ -53041,7 +53194,7 @@ function createAdminRunRoutes(deps) {
|
|
|
53041
53194
|
});
|
|
53042
53195
|
app.get("/api/v1/admin/runs/:runId/structured", async (c) => {
|
|
53043
53196
|
deps.rbac.requirePermission(c.get("role"), "run.read");
|
|
53044
|
-
const runId = c.req.param("runId");
|
|
53197
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
53045
53198
|
const detail = await aggregateRunDetail(deps.db, runId);
|
|
53046
53199
|
if (!detail) return c.json({ error: `Run ${runId} not found` }, 404);
|
|
53047
53200
|
const denied = enforceRoutingKeyScope(c, detail.routingKey);
|
|
@@ -53050,7 +53203,7 @@ function createAdminRunRoutes(deps) {
|
|
|
53050
53203
|
});
|
|
53051
53204
|
app.get("/api/v1/admin/runs/:runId/jobs/:jobId/steps/:stepIndex/logs", async (c) => {
|
|
53052
53205
|
deps.rbac.requirePermission(c.get("role"), "run.read");
|
|
53053
|
-
const runId = c.req.param("runId");
|
|
53206
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
53054
53207
|
const jobId = c.req.param("jobId");
|
|
53055
53208
|
const stepIndex = parseInt(c.req.param("stepIndex"), 10);
|
|
53056
53209
|
if (Number.isNaN(stepIndex)) return c.json({ error: "Invalid stepIndex" }, 400);
|
|
@@ -53076,7 +53229,7 @@ function createAdminRunRoutes(deps) {
|
|
|
53076
53229
|
});
|
|
53077
53230
|
app.get("/api/v1/admin/runs/:runId/ephemeral-key", async (c) => {
|
|
53078
53231
|
deps.rbac.requirePermission(c.get("role"), "run.read");
|
|
53079
|
-
const runId = c.req.param("runId");
|
|
53232
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
53080
53233
|
const runExists = await deps.db.selectFrom("execution_runs").select(["run_id", "routing_key"]).where("run_id", "=", runId).executeTakeFirst();
|
|
53081
53234
|
if (!runExists) return c.json({ error: `Run ${runId} not found` }, 404);
|
|
53082
53235
|
const denied = enforceRoutingKeyScope(c, runExists.routing_key);
|
|
@@ -53094,7 +53247,7 @@ function createAdminRunRoutes(deps) {
|
|
|
53094
53247
|
app.get("/api/v1/admin/runs/:runId/secret-outputs", async (c) => {
|
|
53095
53248
|
const role = c.get("role");
|
|
53096
53249
|
deps.rbac.requirePermission(role, "run.read");
|
|
53097
|
-
const runId = c.req.param("runId");
|
|
53250
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
53098
53251
|
const outputKeyFilter = c.req.query("outputKey");
|
|
53099
53252
|
const reveal = parseCountFlag(c.req.query("reveal"));
|
|
53100
53253
|
if (reveal) {
|
|
@@ -53165,7 +53318,7 @@ function createAdminRunRoutes(deps) {
|
|
|
53165
53318
|
});
|
|
53166
53319
|
return app;
|
|
53167
53320
|
}
|
|
53168
|
-
var logger$85, RUN_STATUSES;
|
|
53321
|
+
var logger$85, RUN_STATUSES, requireFullRunId;
|
|
53169
53322
|
var init_admin_runs = __esmMin((() => {
|
|
53170
53323
|
init_step_display_order();
|
|
53171
53324
|
init_secret_output_crypto();
|
|
@@ -53179,6 +53332,11 @@ var init_admin_runs = __esmMin((() => {
|
|
|
53179
53332
|
init_admin_env();
|
|
53180
53333
|
logger$85 = createLogger({ prefix: "admin-runs" });
|
|
53181
53334
|
RUN_STATUSES = new Set(CANONICAL_STATUSES);
|
|
53335
|
+
requireFullRunId = async (c, next) => {
|
|
53336
|
+
const runId = c.req.param("runId") ?? "";
|
|
53337
|
+
if (!isRunId(runId)) return c.json({ error: `Invalid run id '${runId}': a run id is a full UUID. List runs (or filter with ?runIdPrefix=) to find it.` }, 400);
|
|
53338
|
+
return next();
|
|
53339
|
+
};
|
|
53182
53340
|
}));
|
|
53183
53341
|
//#endregion
|
|
53184
53342
|
//#region src/cold-store/load-event-log-range.ts
|
|
@@ -54276,14 +54434,14 @@ function createHealthRoutes$1(deps = {}) {
|
|
|
54276
54434
|
return createHealthRoutes({
|
|
54277
54435
|
livenessInfo: () => {
|
|
54278
54436
|
return {
|
|
54279
|
-
version: "0.
|
|
54280
|
-
buildDate: "2026-10-
|
|
54281
|
-
sdkVersion: "0.
|
|
54437
|
+
version: "0.21.0",
|
|
54438
|
+
buildDate: "2026-10-18T02:27:04.078Z",
|
|
54439
|
+
sdkVersion: "0.21.0",
|
|
54282
54440
|
sdkBundleHash: "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d",
|
|
54283
|
-
sharedVersion: "0.
|
|
54441
|
+
sharedVersion: "0.21.0",
|
|
54284
54442
|
sharedBundleHash: "23378ace59973f47203be3ff171bb7d5e66702eaa335927b390f94b9771a1f8b",
|
|
54285
|
-
engineVersion: "0.
|
|
54286
|
-
engineBundleHash: "
|
|
54443
|
+
engineVersion: "0.21.0",
|
|
54444
|
+
engineBundleHash: "d9dfe7c806a7fdbd64da7ef48455a139c1d8db8510964ab79e233efdc3f171ba"
|
|
54287
54445
|
};
|
|
54288
54446
|
},
|
|
54289
54447
|
readinessCheck: deps.db ? async () => {
|
|
@@ -54315,7 +54473,7 @@ function createCapabilitiesRoutes() {
|
|
|
54315
54473
|
const app = new Hono();
|
|
54316
54474
|
app.get("/api/v1/capabilities", (c) => {
|
|
54317
54475
|
const manifest = {
|
|
54318
|
-
orchestratorVersion: "0.
|
|
54476
|
+
orchestratorVersion: "0.21.0",
|
|
54319
54477
|
protocolVersion: PROTOCOL_VERSION,
|
|
54320
54478
|
minProtocolVersion: MIN_PROTOCOL_VERSION
|
|
54321
54479
|
};
|
|
@@ -59081,6 +59239,7 @@ function createApp(deps) {
|
|
|
59081
59239
|
jobName: deps.executionTracker.getJobName(msg.runId, msg.jobId) ?? msg.jobId,
|
|
59082
59240
|
stepIndex: msg.stepIndex,
|
|
59083
59241
|
stepName: msg.stepName,
|
|
59242
|
+
stepType: stepTypeOf(msg.data),
|
|
59084
59243
|
state: msg.state,
|
|
59085
59244
|
durationMs: msg.data?.durationMs ?? void 0,
|
|
59086
59245
|
installationId: execContext.installationId,
|
|
@@ -59303,7 +59462,7 @@ function createApp(deps) {
|
|
|
59303
59462
|
app.use("*", (c, next) => c.req.path.startsWith("/api/v1/cache/blob/") ? next() : webhookBodyLimit(c, next));
|
|
59304
59463
|
if (deps.fsCache) registerBlobRoutes(app, deps.fsCache);
|
|
59305
59464
|
app.post("/api/v1/admin/runs/:runId/cancel", async (c) => {
|
|
59306
|
-
const runId = c.req.param("runId");
|
|
59465
|
+
const runId = c.req.param("runId").toLowerCase();
|
|
59307
59466
|
if (!runId) return c.json({ error: "Missing runId" }, 400);
|
|
59308
59467
|
if (!deps.adminDeps) return c.json({ error: "Admin API not available" }, 503);
|
|
59309
59468
|
const auth = await resolveBearerAuth(c, {
|
|
@@ -59338,6 +59497,11 @@ function createApp(deps) {
|
|
|
59338
59497
|
recordAccess("denied", `role "${tokenInfo.role}" lacks run.cancel`);
|
|
59339
59498
|
return c.json({ error: "Permission denied: run.cancel required" }, 403);
|
|
59340
59499
|
}
|
|
59500
|
+
if (!isRunId(runId)) {
|
|
59501
|
+
const error = `Invalid run id '${runId}': a run id is a full UUID.`;
|
|
59502
|
+
recordAccess("allowed", error);
|
|
59503
|
+
return c.json({ error }, 400);
|
|
59504
|
+
}
|
|
59341
59505
|
try {
|
|
59342
59506
|
let force = false;
|
|
59343
59507
|
try {
|
|
@@ -59811,7 +59975,7 @@ var init_app = __esmMin((() => {
|
|
|
59811
59975
|
init_agent_metrics_aggregator();
|
|
59812
59976
|
init_run_detached();
|
|
59813
59977
|
logger$66 = createLogger({ prefix: "app" });
|
|
59814
|
-
ORCHESTRATOR_VERSION$2 = "0.
|
|
59978
|
+
ORCHESTRATOR_VERSION$2 = "0.21.0";
|
|
59815
59979
|
SourceLocationStore = class {
|
|
59816
59980
|
cache = /* @__PURE__ */ new Map();
|
|
59817
59981
|
key(workflowName, jobName) {
|
|
@@ -68902,7 +69066,7 @@ var init_peer_client = __esmMin((() => {
|
|
|
68902
69066
|
PeerDialOrigin["Discovered"] = "discovered";
|
|
68903
69067
|
return PeerDialOrigin;
|
|
68904
69068
|
}({});
|
|
68905
|
-
SOFTWARE_VERSION$1 = "0.
|
|
69069
|
+
SOFTWARE_VERSION$1 = "0.21.0";
|
|
68906
69070
|
PeerClient$1 = class {
|
|
68907
69071
|
ws = null;
|
|
68908
69072
|
_state = "disconnected";
|
|
@@ -71373,7 +71537,7 @@ var init_peer_handler = __esmMin((() => {
|
|
|
71373
71537
|
init_join_token();
|
|
71374
71538
|
init_run_detached();
|
|
71375
71539
|
logger$46 = createLogger({ prefix: "peer-handler" });
|
|
71376
|
-
SOFTWARE_VERSION = "0.
|
|
71540
|
+
SOFTWARE_VERSION = "0.21.0";
|
|
71377
71541
|
ADVERTISED_PEER_AUTH_SCHEMES = [PeerAuthScheme.enum["mutual-v2"]];
|
|
71378
71542
|
MAX_TOKEN_CANDIDATES = 8;
|
|
71379
71543
|
RATE_LIMIT_MAX = 5;
|
|
@@ -87804,7 +87968,8 @@ async function recordInitFailureFromSkip(args) {
|
|
|
87804
87968
|
},
|
|
87805
87969
|
triggerEvent: dispatchTriggerEvent(ctx),
|
|
87806
87970
|
commitMessage: extractCommitMessage(setup.info.event, setup.info.payload),
|
|
87807
|
-
...preDispatchRunProvenance(ctx)
|
|
87971
|
+
...preDispatchRunProvenance(ctx),
|
|
87972
|
+
...ctx.testRun && { testRun: ctx.testRun }
|
|
87808
87973
|
});
|
|
87809
87974
|
await completeChecksForUndispatchedRun({
|
|
87810
87975
|
ctx,
|
|
@@ -87855,7 +88020,8 @@ async function holdWorkflowForInstallGate(args) {
|
|
|
87855
88020
|
commitMessage: extractCommitMessage(setup.info.event, setup.info.payload),
|
|
87856
88021
|
workflowSha: ctx.global?.workflowSha ?? null,
|
|
87857
88022
|
workflowBranch: ctx.global?.workflowBranch ?? null,
|
|
87858
|
-
...preDispatchRunProvenance(ctx)
|
|
88023
|
+
...preDispatchRunProvenance(ctx),
|
|
88024
|
+
...ctx.testRun && { testRun: ctx.testRun }
|
|
87859
88025
|
});
|
|
87860
88026
|
if (deps.heldRunStore) await deps.heldRunStore.createHold(ctx.resolvedOrgId, {
|
|
87861
88027
|
runId,
|
|
@@ -87931,7 +88097,8 @@ async function holdRunForSecurityPolicy(args) {
|
|
|
87931
88097
|
prNumber: event.prNumber ?? null,
|
|
87932
88098
|
workflowSha: ctx.global?.workflowSha ?? null,
|
|
87933
88099
|
workflowBranch: ctx.global?.workflowBranch ?? null,
|
|
87934
|
-
...preDispatchRunProvenance(ctx)
|
|
88100
|
+
...preDispatchRunProvenance(ctx),
|
|
88101
|
+
...ctx.testRun && { testRun: ctx.testRun }
|
|
87935
88102
|
});
|
|
87936
88103
|
let heldRow;
|
|
87937
88104
|
if (deps.heldRunStore) {
|
|
@@ -95022,7 +95189,7 @@ var init_handler = __esmMin((() => {
|
|
|
95022
95189
|
outputs: typeof r.outputs === "string" ? r.outputs : null,
|
|
95023
95190
|
init_failure: r.init_failure ?? null
|
|
95024
95191
|
}));
|
|
95025
|
-
stepRows.sort(
|
|
95192
|
+
stepRows.sort(compareStepRowsForDisplay);
|
|
95026
95193
|
out.steps = stepRows.map((r) => ({
|
|
95027
95194
|
job_id: String(r.job_id ?? ""),
|
|
95028
95195
|
step_index: Number(r.step_index ?? 0),
|
|
@@ -100577,13 +100744,13 @@ var init_worker_core = __esmMin((() => {
|
|
|
100577
100744
|
init_app_on_error();
|
|
100578
100745
|
init_run_detached();
|
|
100579
100746
|
init_peer_job_cancel();
|
|
100580
|
-
ORCHESTRATOR_VERSION$1 = "0.
|
|
100581
|
-
WORKER_SDK_VERSION = "0.
|
|
100747
|
+
ORCHESTRATOR_VERSION$1 = "0.21.0";
|
|
100748
|
+
WORKER_SDK_VERSION = "0.21.0";
|
|
100582
100749
|
WORKER_SDK_BUNDLE_HASH = "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d";
|
|
100583
|
-
WORKER_SHARED_VERSION = "0.
|
|
100750
|
+
WORKER_SHARED_VERSION = "0.21.0";
|
|
100584
100751
|
WORKER_SHARED_BUNDLE_HASH = "23378ace59973f47203be3ff171bb7d5e66702eaa335927b390f94b9771a1f8b";
|
|
100585
|
-
WORKER_ENGINE_VERSION = "0.
|
|
100586
|
-
WORKER_ENGINE_BUNDLE_HASH = "
|
|
100752
|
+
WORKER_ENGINE_VERSION = "0.21.0";
|
|
100753
|
+
WORKER_ENGINE_BUNDLE_HASH = "d9dfe7c806a7fdbd64da7ef48455a139c1d8db8510964ab79e233efdc3f171ba";
|
|
100587
100754
|
logger$2 = createLogger({ prefix: "worker" });
|
|
100588
100755
|
DRAIN_TIMEOUT_MS = 3e5;
|
|
100589
100756
|
}));
|
|
@@ -100610,13 +100777,13 @@ init_run_detached();
|
|
|
100610
100777
|
init_dashboard_access();
|
|
100611
100778
|
init_peer_job_cancel();
|
|
100612
100779
|
init_orphan_requests();
|
|
100613
|
-
const ORCHESTRATOR_VERSION = "0.
|
|
100614
|
-
const SDK_VERSION = "0.
|
|
100780
|
+
const ORCHESTRATOR_VERSION = "0.21.0";
|
|
100781
|
+
const SDK_VERSION = "0.21.0";
|
|
100615
100782
|
const SDK_BUNDLE_HASH = "b012bd8bace3df9e574252bf290c652bc39766da617acf51729a08586756266d";
|
|
100616
|
-
const SHARED_VERSION = "0.
|
|
100783
|
+
const SHARED_VERSION = "0.21.0";
|
|
100617
100784
|
const SHARED_BUNDLE_HASH = "23378ace59973f47203be3ff171bb7d5e66702eaa335927b390f94b9771a1f8b";
|
|
100618
|
-
const ENGINE_VERSION = "0.
|
|
100619
|
-
const ENGINE_BUNDLE_HASH = "
|
|
100785
|
+
const ENGINE_VERSION = "0.21.0";
|
|
100786
|
+
const ENGINE_BUNDLE_HASH = "d9dfe7c806a7fdbd64da7ef48455a139c1d8db8510964ab79e233efdc3f171ba";
|
|
100620
100787
|
const otelSdk = initTelemetry({
|
|
100621
100788
|
serviceName: "kici-orchestrator",
|
|
100622
100789
|
otlpEndpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT
|