@kici-dev/shared 0.1.27 → 0.2.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/agent-platform.d.ts +32 -0
- package/dist/agent-platform.js +27 -0
- package/dist/agent-platform.test.d.ts +2 -0
- package/dist/ci-env.d.ts +2 -0
- package/dist/ci-env.js +3 -0
- package/dist/cold-store/bucket.d.ts +1 -1
- package/dist/cold-store/cold-store.d.ts +24 -1
- package/dist/cold-store/cold-store.js +17 -5
- package/dist/cold-store/index.js +1 -1
- package/dist/db-admin.d.ts +150 -9
- package/dist/db-admin.js +160 -46
- package/dist/db.d.ts +34 -0
- package/dist/db.js +30 -1
- package/dist/diagnostics/bundle-archive.js +5 -5
- package/dist/env/allowlist.d.ts +5 -0
- package/dist/env/allowlist.js +6 -1
- package/dist/env/define-env.d.ts +19 -2
- package/dist/env/define-env.js +18 -3
- package/dist/env/logger-env.d.ts +11 -9
- package/dist/env/logger-env.js +25 -9
- package/dist/idempotency-files.d.ts +7 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -4
- package/dist/telemetry/init.d.ts +18 -7
- package/dist/telemetry/init.js +36 -11
- package/dist/tmp-dir.d.ts +14 -0
- package/dist/tmp-dir.js +13 -0
- package/dist/tmp-dir.test.d.ts +2 -0
- package/dist/tmp.d.ts +2 -0
- package/dist/tmp.js +3 -0
- package/package.json +26 -17
- package/sbom.spdx.json +1222 -1618
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** Supported fresh-box agent target platforms (glibc-Linux bootstrap set). */
|
|
3
|
+
export declare const AgentPlatform: z.ZodEnum<{
|
|
4
|
+
"linux-arm64": "linux-arm64";
|
|
5
|
+
"linux-x64": "linux-x64";
|
|
6
|
+
}>;
|
|
7
|
+
export type AgentPlatform = z.infer<typeof AgentPlatform>;
|
|
8
|
+
/**
|
|
9
|
+
* How a fresh-box agent payload is delivered to the target during bring-up.
|
|
10
|
+
* `s3-direct`: the box pulls the payload from the orchestrator cache bucket via
|
|
11
|
+
* a presigned URL (no 50 MB through the ops agent). `ssh-push`: the ops agent
|
|
12
|
+
* fetches the payload and streams it to the box over a binary-safe scp (the
|
|
13
|
+
* fallback for a box that cannot reach object storage).
|
|
14
|
+
*/
|
|
15
|
+
export declare const AgentDeliveryMode: z.ZodEnum<{
|
|
16
|
+
"s3-direct": "s3-direct";
|
|
17
|
+
"ssh-push": "ssh-push";
|
|
18
|
+
}>;
|
|
19
|
+
export type AgentDeliveryMode = z.infer<typeof AgentDeliveryMode>;
|
|
20
|
+
export interface AgentPlatformParts {
|
|
21
|
+
/** nodejs.org os token. */
|
|
22
|
+
nodeOs: 'linux';
|
|
23
|
+
/** nodejs.org arch token. */
|
|
24
|
+
nodeArch: 'x64' | 'arm64';
|
|
25
|
+
/** npm `--os` token. */
|
|
26
|
+
npmOs: 'linux';
|
|
27
|
+
/** npm `--cpu` token. */
|
|
28
|
+
npmCpu: 'x64' | 'arm64';
|
|
29
|
+
}
|
|
30
|
+
/** Decompose an AgentPlatform into the os/arch tokens npm and nodejs.org expect. */
|
|
31
|
+
export declare function splitAgentPlatform(platform: AgentPlatform): AgentPlatformParts;
|
|
32
|
+
//# sourceMappingURL=agent-platform.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import "./rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/agent-platform.ts
|
|
4
|
+
/** Supported fresh-box agent target platforms (glibc-Linux bootstrap set). */
|
|
5
|
+
const AgentPlatform = z.enum(["linux-x64", "linux-arm64"]);
|
|
6
|
+
/**
|
|
7
|
+
* How a fresh-box agent payload is delivered to the target during bring-up.
|
|
8
|
+
* `s3-direct`: the box pulls the payload from the orchestrator cache bucket via
|
|
9
|
+
* a presigned URL (no 50 MB through the ops agent). `ssh-push`: the ops agent
|
|
10
|
+
* fetches the payload and streams it to the box over a binary-safe scp (the
|
|
11
|
+
* fallback for a box that cannot reach object storage).
|
|
12
|
+
*/
|
|
13
|
+
const AgentDeliveryMode = z.enum(["ssh-push", "s3-direct"]);
|
|
14
|
+
/** Decompose an AgentPlatform into the os/arch tokens npm and nodejs.org expect. */
|
|
15
|
+
function splitAgentPlatform(platform) {
|
|
16
|
+
const arch = platform === "linux-x64" ? "x64" : "arm64";
|
|
17
|
+
return {
|
|
18
|
+
nodeOs: "linux",
|
|
19
|
+
nodeArch: arch,
|
|
20
|
+
npmOs: "linux",
|
|
21
|
+
npmCpu: arch
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { AgentDeliveryMode, AgentPlatform, splitAgentPlatform };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=agent-platform.js.map
|
package/dist/ci-env.d.ts
ADDED
package/dist/ci-env.js
ADDED
|
@@ -21,6 +21,6 @@ export declare function coldDaysToBucket(days: ColdRetention): string;
|
|
|
21
21
|
*/
|
|
22
22
|
export declare function isLongerColdRetention(a: ColdRetention, b: ColdRetention): boolean;
|
|
23
23
|
/** Stable, ordered set of bucket names emitted by `coldDaysToBucket`. */
|
|
24
|
-
export declare const COLD_BUCKET_NAMES: readonly [
|
|
24
|
+
export declare const COLD_BUCKET_NAMES: readonly ['30d', '180d', '1y', '2y', 'forever'];
|
|
25
25
|
export type ColdBucketName = (typeof COLD_BUCKET_NAMES)[number];
|
|
26
26
|
//# sourceMappingURL=bucket.d.ts.map
|
|
@@ -37,7 +37,12 @@ export interface ColdStoreFetchRangeArgs<TRow> {
|
|
|
37
37
|
table: string;
|
|
38
38
|
tenantId: string;
|
|
39
39
|
fromTs: Date;
|
|
40
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Upper bound (exclusive). Omit to use `warmCutoff(table)` — the table's
|
|
42
|
+
* resolved warm/cold boundary. Pass an explicit value only when the caller
|
|
43
|
+
* genuinely owns the range (e.g. a user-supplied time filter).
|
|
44
|
+
*/
|
|
45
|
+
toTs?: Date;
|
|
41
46
|
decode?: (line: string) => TRow;
|
|
42
47
|
}
|
|
43
48
|
export interface ColdStoreReplayChunkArgs {
|
|
@@ -125,6 +130,23 @@ export interface PurgeableChunk {
|
|
|
125
130
|
* flow.
|
|
126
131
|
*/
|
|
127
132
|
export interface ColdStore {
|
|
133
|
+
/**
|
|
134
|
+
* The table's warm/cold boundary: `now − warmTtlDays`, resolved from the
|
|
135
|
+
* SAME config the archival writer uses — the registered adapter's effective
|
|
136
|
+
* config (built-in defaults merged with any
|
|
137
|
+
* `KICI_COLD_STORE_<TABLE>_WARM_TTL_DAYS` env override). Rows older than
|
|
138
|
+
* this may live in cold storage; rows newer are guaranteed PG-only.
|
|
139
|
+
*
|
|
140
|
+
* Readers MUST derive their cold-read upper bound from this rather than
|
|
141
|
+
* restating a literal. A reader-side value LARGER than the writer's
|
|
142
|
+
* produces an EARLIER cutoff, which silently hides archived rows: a
|
|
143
|
+
* manifest whose `min` timestamp is newer than the bound is skipped
|
|
144
|
+
* entirely, so a read 404s on data that exists in S3.
|
|
145
|
+
*
|
|
146
|
+
* A `warmTtlDays` of zero or less yields a cutoff at or after `now` — the
|
|
147
|
+
* widest window, which is the safe direction.
|
|
148
|
+
*/
|
|
149
|
+
warmCutoff(table: string): Date;
|
|
128
150
|
/** Stream archived rows that overlap [fromTs, toTs). */
|
|
129
151
|
fetchRange<TRow>(args: ColdStoreFetchRangeArgs<TRow>): AsyncIterable<TRow>;
|
|
130
152
|
hasRange(args: Omit<ColdStoreFetchRangeArgs<unknown>, 'decode'>): Promise<boolean>;
|
|
@@ -268,6 +290,7 @@ export declare abstract class BaseColdStore implements ColdStore {
|
|
|
268
290
|
private putChunkData;
|
|
269
291
|
private verifyChunkData;
|
|
270
292
|
private putManifest;
|
|
293
|
+
warmCutoff(table: string): Date;
|
|
271
294
|
fetchRange<TRow>(args: ColdStoreFetchRangeArgs<TRow>): AsyncIterable<TRow>;
|
|
272
295
|
hasRange(args: Omit<ColdStoreFetchRangeArgs<unknown>, 'decode'>): Promise<boolean>;
|
|
273
296
|
countRange(args: Omit<ColdStoreFetchRangeArgs<unknown>, 'decode'>): Promise<number>;
|
|
@@ -6,6 +6,7 @@ import { computeChunkId } from "./chunk-id.js";
|
|
|
6
6
|
import { decodeChunk, encodeChunk } from "./chunk-encoder.js";
|
|
7
7
|
import { parseManifest, serializeManifest } from "./manifest.js";
|
|
8
8
|
import { coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal } from "./metrics.js";
|
|
9
|
+
import { resolveTableConfig } from "./config.js";
|
|
9
10
|
import { sha256 } from "@kici-dev/core";
|
|
10
11
|
import { DeleteObjectCommand, GetObjectCommand, HeadObjectCommand, ListObjectsV2Command, PutObjectCommand } from "@aws-sdk/client-s3";
|
|
11
12
|
//#region src/cold-store/cold-store.ts
|
|
@@ -195,7 +196,7 @@ var BaseColdStore = class {
|
|
|
195
196
|
summary.skipped.disabled += 1;
|
|
196
197
|
return;
|
|
197
198
|
}
|
|
198
|
-
const warmCutoff =
|
|
199
|
+
const warmCutoff = this.warmCutoff(adapter.table);
|
|
199
200
|
let rowsThisCycle = 0;
|
|
200
201
|
for await (const { tenantId, partitionDate } of adapter.listEligiblePartitions({ warmCutoff })) {
|
|
201
202
|
if (rowsThisCycle >= adapter.config.maxRowsPerCycle) {
|
|
@@ -561,17 +562,22 @@ var BaseColdStore = class {
|
|
|
561
562
|
ContentType: "application/json"
|
|
562
563
|
}));
|
|
563
564
|
}
|
|
565
|
+
warmCutoff(table) {
|
|
566
|
+
const cfg = this.adapters.get(table)?.config ?? resolveTableConfig(this.config.tables[table]);
|
|
567
|
+
return /* @__PURE__ */ new Date(Date.now() - cfg.warmTtlDays * 864e5);
|
|
568
|
+
}
|
|
564
569
|
async *fetchRange(args) {
|
|
565
570
|
if (!this.config.enabled) return;
|
|
566
571
|
const adapter = this.adapters.get(args.table);
|
|
567
572
|
const decodeLine = args.decode ?? (adapter ? (line) => adapter.decodeRow(line) : (line) => JSON.parse(line));
|
|
568
573
|
const rowTimestamp = adapter ? (row) => this.toDate(adapter.rowTimestamp(row)) : null;
|
|
574
|
+
const toTs = args.toTs ?? this.warmCutoff(args.table);
|
|
569
575
|
const manifests = await this.listRelevantManifests({
|
|
570
576
|
db: args.db,
|
|
571
577
|
table: args.table,
|
|
572
578
|
tenantId: args.tenantId,
|
|
573
579
|
fromTs: args.fromTs,
|
|
574
|
-
toTs
|
|
580
|
+
toTs
|
|
575
581
|
});
|
|
576
582
|
const label = {
|
|
577
583
|
db: args.db,
|
|
@@ -597,7 +603,7 @@ var BaseColdStore = class {
|
|
|
597
603
|
})) {
|
|
598
604
|
if (rowTimestamp) {
|
|
599
605
|
const ts = rowTimestamp(row);
|
|
600
|
-
if (ts < args.fromTs || ts >=
|
|
606
|
+
if (ts < args.fromTs || ts >= toTs) continue;
|
|
601
607
|
}
|
|
602
608
|
yield row;
|
|
603
609
|
}
|
|
@@ -605,11 +611,17 @@ var BaseColdStore = class {
|
|
|
605
611
|
}
|
|
606
612
|
async hasRange(args) {
|
|
607
613
|
if (!this.config.enabled) return false;
|
|
608
|
-
return (await this.listRelevantManifests(
|
|
614
|
+
return (await this.listRelevantManifests({
|
|
615
|
+
...args,
|
|
616
|
+
toTs: args.toTs ?? this.warmCutoff(args.table)
|
|
617
|
+
})).length > 0;
|
|
609
618
|
}
|
|
610
619
|
async countRange(args) {
|
|
611
620
|
if (!this.config.enabled) return 0;
|
|
612
|
-
const manifests = await this.listRelevantManifests(
|
|
621
|
+
const manifests = await this.listRelevantManifests({
|
|
622
|
+
...args,
|
|
623
|
+
toTs: args.toTs ?? this.warmCutoff(args.table)
|
|
624
|
+
});
|
|
613
625
|
let total = 0;
|
|
614
626
|
for (const m of manifests) total += m.rowCount;
|
|
615
627
|
return total;
|
package/dist/cold-store/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { computeChunkId } from "./chunk-id.js";
|
|
|
5
5
|
import { decodeChunk, encodeChunk } from "./chunk-encoder.js";
|
|
6
6
|
import { parseManifest, serializeManifest } from "./manifest.js";
|
|
7
7
|
import { coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal } from "./metrics.js";
|
|
8
|
+
import { DEFAULT_TABLE_CONFIG, resolveTableConfig } from "./config.js";
|
|
8
9
|
import { BaseColdStore } from "./cold-store.js";
|
|
9
10
|
import { ChunkLru } from "./lru.js";
|
|
10
|
-
import { DEFAULT_TABLE_CONFIG, resolveTableConfig } from "./config.js";
|
|
11
11
|
export { BaseColdStore, COLD_BUCKET_NAMES, ChunkLru, DEFAULT_TABLE_CONFIG, chunkObjectKey, coldDaysToBucket, coldStoreArchiveBytesTotal, coldStoreArchiveCyclesTotal, coldStoreArchiveDurationSeconds, coldStoreArchiveRowsTotal, coldStorePurgeBytesTotal, coldStorePurgeChunksTotal, coldStorePurgeDurationSeconds, coldStoreRehydrateBytesTotal, coldStoreRehydrateDurationSeconds, coldStoreRehydrateRequestsTotal, coldStoreReplayDurationSeconds, coldStoreReplayRowsTotal, coldStoreVerifyFailuresTotal, computeChunkId, decodeChunk, encodeChunk, encodeKeySegment, isLongerColdRetention, parseManifest, resolveTableConfig, serializeManifest, tablePrefix, tenantDayBucketPrefix, tenantDayPrefix };
|
package/dist/db-admin.d.ts
CHANGED
|
@@ -210,9 +210,15 @@ export interface SeedContextResult {
|
|
|
210
210
|
created: boolean;
|
|
211
211
|
}
|
|
212
212
|
/**
|
|
213
|
-
* Upsert
|
|
213
|
+
* Upsert a context row keyed by (org_id, name). Returns the env id and
|
|
214
214
|
* whether the row was newly inserted. `branchRestrictions` / `requiredReviewers`
|
|
215
215
|
* are JSON-serialised server-side; pass them as plain arrays or objects.
|
|
216
|
+
*
|
|
217
|
+
* An omitted `holdExpirySeconds` is written as NULL rather than a literal
|
|
218
|
+
* window: the column carries no DDL default, so "never set" and "cleared" both
|
|
219
|
+
* land on NULL and resolve through the one `DEFAULT_HOLD_EXPIRY_SECONDS`
|
|
220
|
+
* fallback on read. Writing a literal here would give this path a second,
|
|
221
|
+
* longer default that no read-side code knows about.
|
|
216
222
|
*/
|
|
217
223
|
export declare function seedContextDirect(databaseUrl: string, opts: SeedContextOpts): Promise<SeedContextResult>;
|
|
218
224
|
export interface DeleteContextOpts {
|
|
@@ -220,7 +226,7 @@ export interface DeleteContextOpts {
|
|
|
220
226
|
name: string;
|
|
221
227
|
}
|
|
222
228
|
/**
|
|
223
|
-
* Delete
|
|
229
|
+
* Delete a context keyed by (org_id, name). Returns whether a row was
|
|
224
230
|
* removed. The `context_bindings`, `context_variables`, and
|
|
225
231
|
* `context_source_overrides` children all carry
|
|
226
232
|
* `FOREIGN KEY (context_id) REFERENCES contexts(id) ON DELETE CASCADE`,
|
|
@@ -322,9 +328,13 @@ export interface CreateContextTemplateOpts {
|
|
|
322
328
|
variables?: Record<string, string>;
|
|
323
329
|
}
|
|
324
330
|
/**
|
|
325
|
-
* Create (or update)
|
|
331
|
+
* Create (or update) a context template + its seed variables in one
|
|
326
332
|
* transaction. Templates are represented as contexts with `type='template'`
|
|
327
333
|
* by convention. Returns `{ envId, variablesSet }`.
|
|
334
|
+
*
|
|
335
|
+
* An omitted `holdExpirySeconds` is written as NULL rather than a literal
|
|
336
|
+
* window, for the same reason as `seedContextDirect`: the column has no DDL
|
|
337
|
+
* default and every read resolves NULL through `DEFAULT_HOLD_EXPIRY_SECONDS`.
|
|
328
338
|
*/
|
|
329
339
|
export declare function createContextTemplateDirect(databaseUrl: string, opts: CreateContextTemplateOpts): Promise<{
|
|
330
340
|
envId: string;
|
|
@@ -435,6 +445,79 @@ export interface ListExecutionRunsOpts {
|
|
|
435
445
|
export declare function listExecutionRunsDirect(databaseUrl: string, opts?: ListExecutionRunsOpts): Promise<{
|
|
436
446
|
runs: ExecutionRunRow[];
|
|
437
447
|
}>;
|
|
448
|
+
/**
|
|
449
|
+
* One `check_run_tracking` row: the orchestrator's record of a check run it posted.
|
|
450
|
+
*
|
|
451
|
+
* Named `...DirectRow` rather than `CheckRunTrackingRow` because the
|
|
452
|
+
* orchestrator's own `db/types.ts` already exports that name for the Kysely
|
|
453
|
+
* `Selectable`, whose `check_run_id` is a `number`. Two same-named types with
|
|
454
|
+
* different field types, both in scope inside the orchestrator package, is a
|
|
455
|
+
* silent-comparison-bug waiting to happen.
|
|
456
|
+
*/
|
|
457
|
+
export interface CheckRunTrackingDirectRow {
|
|
458
|
+
provider: string;
|
|
459
|
+
owner: string;
|
|
460
|
+
repo: string;
|
|
461
|
+
sha: string;
|
|
462
|
+
check_name: string;
|
|
463
|
+
/**
|
|
464
|
+
* The id the provider returned when the check run was CREATED. It is written
|
|
465
|
+
* once, at create time, when the check run is still `queued` — the later
|
|
466
|
+
* terminal update is a PATCH that writes nothing here. So a non-null value
|
|
467
|
+
* proves creation, NOT that the check run reached a conclusion.
|
|
468
|
+
*
|
|
469
|
+
* Null does not prove the create failed either: the write is best-effort and
|
|
470
|
+
* falls back to cache-only on a DB error, so the check run can exist at the
|
|
471
|
+
* provider with no id recorded here.
|
|
472
|
+
*
|
|
473
|
+
* Selected as `::text` because the column is BIGINT and node-postgres maps
|
|
474
|
+
* int8 to a string to avoid precision loss. The cast makes that explicit in
|
|
475
|
+
* the query rather than depending on driver defaults, so adding a global
|
|
476
|
+
* int8 type parser later cannot silently change this field's type.
|
|
477
|
+
*/
|
|
478
|
+
check_run_id: string | null;
|
|
479
|
+
/**
|
|
480
|
+
* `'pending'` is stamped BEFORE the create call and `'completed'` after it
|
|
481
|
+
* returns an id. Nothing resets it when a create fails, so a row stuck on
|
|
482
|
+
* `'pending'` means the create never returned — still in flight or
|
|
483
|
+
* permanently failed, which this column alone cannot distinguish.
|
|
484
|
+
*/
|
|
485
|
+
build_creation_state: string | null;
|
|
486
|
+
run_id: string | null;
|
|
487
|
+
/**
|
|
488
|
+
* Written only for per-job check names (`kici/<workflow>/job/<job>`). The
|
|
489
|
+
* workflow-level `kici/<workflow>` row always has null here.
|
|
490
|
+
*/
|
|
491
|
+
in_progress_sent_at: Date | null;
|
|
492
|
+
/**
|
|
493
|
+
* When the terminal (`completed`) update was accepted by the provider. This
|
|
494
|
+
* is the column that answers "did we complete it?" — `check_run_id` only
|
|
495
|
+
* answers "did we create it?".
|
|
496
|
+
*
|
|
497
|
+
* Best-effort like every write on this table, so null means "we have no
|
|
498
|
+
* record of sending it", not "it was never sent".
|
|
499
|
+
*/
|
|
500
|
+
terminal_sent_at: Date | null;
|
|
501
|
+
}
|
|
502
|
+
export interface ListCheckRunTrackingOpts {
|
|
503
|
+
sha: string;
|
|
504
|
+
checkName?: string;
|
|
505
|
+
limit?: number;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* READ-ONLY: SELECT check_run_tracking rows for a commit. One row per
|
|
509
|
+
* `(provider, owner, repo, sha, check_name)`, ordered by check_name.
|
|
510
|
+
*
|
|
511
|
+
* Each column answers a different question. `check_run_id` is written once,
|
|
512
|
+
* when the check run is created in the `queued` state, so it answers "did we
|
|
513
|
+
* create it?". `terminal_sent_at` is stamped only after the provider accepts
|
|
514
|
+
* the terminal `completed` PATCH, so it answers "did we complete it?". Every
|
|
515
|
+
* write here is best-effort, so a null column is "no record", never proof of
|
|
516
|
+
* failure — see the per-field notes for what each one does and does not prove.
|
|
517
|
+
*/
|
|
518
|
+
export declare function listCheckRunTrackingDirect(databaseUrl: string, opts: ListCheckRunTrackingOpts): Promise<{
|
|
519
|
+
rows: CheckRunTrackingDirectRow[];
|
|
520
|
+
}>;
|
|
438
521
|
/**
|
|
439
522
|
* READ-ONLY: fetch a single run by run_id AND its jobs. Throws if no run
|
|
440
523
|
* matches the run_id. Jobs list may be empty for pending runs.
|
|
@@ -887,24 +970,80 @@ export interface SeedCiSecurityFixturesOpts {
|
|
|
887
970
|
trustedRunId: string;
|
|
888
971
|
trustedDeliveryId: string;
|
|
889
972
|
trustedJobId: string;
|
|
973
|
+
/**
|
|
974
|
+
* Second PR on the SAME repo (`repo_identifier='.'`, `pr_number=2`) with its
|
|
975
|
+
* own pending security hold. Seeded so PR-scoping tests can prove that a
|
|
976
|
+
* `/kici approve` on the first PR (pr_number=1) leaves this one held.
|
|
977
|
+
*/
|
|
978
|
+
secondPrRunId: string;
|
|
979
|
+
secondPrDeliveryId: string;
|
|
980
|
+
secondPrJobId: string;
|
|
981
|
+
/**
|
|
982
|
+
* Hold on a DIFFERENT repo (`repo_identifier='other/repo'`, `pr_number=1`) —
|
|
983
|
+
* same PR number as the first hold but a different repo, proving the scoping
|
|
984
|
+
* isolates on repo as well as PR number.
|
|
985
|
+
*/
|
|
986
|
+
otherRepoRunId: string;
|
|
987
|
+
otherRepoDeliveryId: string;
|
|
988
|
+
otherRepoJobId: string;
|
|
989
|
+
/**
|
|
990
|
+
* Workflow-modification hold (`repo_identifier='.'`, `pr_number=3`,
|
|
991
|
+
* `reason='workflow_modification'`) — the hold a non-trusted contributor's
|
|
992
|
+
* workflow-editing PR produces. Seeded so the PR-scoped `/kici approve`
|
|
993
|
+
* (which joins on `pr_number`) can find and resolve it.
|
|
994
|
+
*/
|
|
995
|
+
wfModRunId: string;
|
|
996
|
+
wfModDeliveryId: string;
|
|
997
|
+
wfModJobId: string;
|
|
998
|
+
/**
|
|
999
|
+
* Fork-PR hold (`repo_identifier='.'`, `pr_number=4`, `reason='fork_pr'`) —
|
|
1000
|
+
* the hold the org trust policy's fork arm produces. Reachable only since the
|
|
1001
|
+
* policy became enforced, so it is seeded to prove PR-scoped selection and
|
|
1002
|
+
* approval work for it exactly as they do for the workflow-modification hold.
|
|
1003
|
+
*/
|
|
1004
|
+
forkPrRunId: string;
|
|
1005
|
+
forkPrDeliveryId: string;
|
|
1006
|
+
forkPrJobId: string;
|
|
890
1007
|
}
|
|
891
1008
|
export interface SeedCiSecurityFixturesResult {
|
|
1009
|
+
/**
|
|
1010
|
+
* The context name the fixture seeded (the `contextName` option, or its
|
|
1011
|
+
* default). Assertions build the expected `held_runs.reason` from this rather
|
|
1012
|
+
* than re-deriving the name, so an override cannot desync them.
|
|
1013
|
+
*/
|
|
1014
|
+
contextName: string;
|
|
892
1015
|
envId: string;
|
|
1016
|
+
/** Held run for the unknown contributor (repo `.`, pr_number 1). */
|
|
893
1017
|
heldRunId: string;
|
|
1018
|
+
/** Held run for the same-repo second PR (repo `.`, pr_number 2). */
|
|
1019
|
+
secondHeldRunId: string;
|
|
1020
|
+
/** Held run for the different-repo run (repo `other/repo`, pr_number 1). */
|
|
1021
|
+
otherRepoHeldRunId: string;
|
|
1022
|
+
/** Held run for the workflow-modification PR (repo `.`, pr_number 3). */
|
|
1023
|
+
wfModHeldRunId: string;
|
|
1024
|
+
/** Held run for the fork PR (repo `.`, pr_number 4). */
|
|
1025
|
+
forkPrHeldRunId: string;
|
|
894
1026
|
}
|
|
1027
|
+
/** repo_identifier used for the different-repo isolation hold. */
|
|
1028
|
+
export declare const CI_SECURITY_OTHER_REPO = "other/repo";
|
|
895
1029
|
export declare function seedCiSecurityFixturesDirect(databaseUrl: string, opts: SeedCiSecurityFixturesOpts): Promise<SeedCiSecurityFixturesResult>;
|
|
896
1030
|
/**
|
|
897
|
-
* Poll `execution_runs` for
|
|
898
|
-
* `
|
|
899
|
-
*
|
|
1031
|
+
* Poll `execution_runs` for the newest run started since `since` whose status
|
|
1032
|
+
* is in `statuses`, returning that status. Resolves `{ status: null }` if the
|
|
1033
|
+
* deadline passes before any run reaches a target status.
|
|
1034
|
+
*
|
|
1035
|
+
* Callers wanting "did the run finish?" pass the terminal status set and read
|
|
1036
|
+
* the landed status — a terminal failure is reported immediately rather than
|
|
1037
|
+
* indistinguishable from a timeout. Used by the cluster reroute tests to gate
|
|
1038
|
+
* on a workflow reaching a terminal state after a webhook trigger.
|
|
900
1039
|
*/
|
|
901
|
-
export declare function
|
|
902
|
-
status: string;
|
|
1040
|
+
export declare function waitForExecutionRunReachesStatusSinceDirect(databaseUrl: string, opts: {
|
|
903
1041
|
since: Date;
|
|
1042
|
+
statuses: readonly string[];
|
|
904
1043
|
timeoutMs?: number;
|
|
905
1044
|
intervalMs?: number;
|
|
906
1045
|
}): Promise<{
|
|
907
|
-
|
|
1046
|
+
status: string | null;
|
|
908
1047
|
}>;
|
|
909
1048
|
/**
|
|
910
1049
|
* Fetch the most recent `execution_runs` row matching `status`, plus its
|
|
@@ -1250,6 +1389,7 @@ export declare function bumpRegistryVersionSimpleDirect(databaseUrl: string, opt
|
|
|
1250
1389
|
export declare function upsertCronLastFiredDirect(databaseUrl: string, opts: {
|
|
1251
1390
|
registrationId: string;
|
|
1252
1391
|
agoInterval: string;
|
|
1392
|
+
scheduleKey: string;
|
|
1253
1393
|
}): Promise<void>;
|
|
1254
1394
|
/**
|
|
1255
1395
|
* READ-ONLY: count cron_last_fired rows for a registration. Used by
|
|
@@ -1264,6 +1404,7 @@ export declare function countCronLastFiredDirect(databaseUrl: string, opts: {
|
|
|
1264
1404
|
*/
|
|
1265
1405
|
export declare function insertCronLastFiredNowDirect(databaseUrl: string, opts: {
|
|
1266
1406
|
registrationId: string;
|
|
1407
|
+
scheduleKey: string;
|
|
1267
1408
|
}): Promise<void>;
|
|
1268
1409
|
/**
|
|
1269
1410
|
* DELETE cron_last_fired rows for a registration. Teardown helper.
|