@kici-dev/sdk 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/agent-cloud-init.d.ts +66 -0
- package/dist/agent-cloud-init.js +128 -0
- package/dist/api-types.d.ts +26 -0
- package/dist/api-types.js +20 -1
- package/dist/context.d.ts +21 -0
- package/dist/filter-context.d.ts +32 -0
- package/dist/filter-context.js +36 -0
- package/dist/filter.d.ts +81 -0
- package/dist/filter.js +2 -0
- package/dist/filter.test-d.d.ts +2 -0
- package/dist/filter.test-d.js +30 -0
- package/dist/git-types.d.ts +162 -0
- package/dist/git-types.js +32 -0
- package/dist/idempotent.js +3 -2
- package/dist/index.d.ts +11 -1
- package/dist/index.js +11 -5
- package/dist/invoke.d.ts +29 -0
- package/dist/invoke.js +27 -0
- package/dist/job-outputs.test-d.js +32 -18
- package/dist/job.js +93 -1
- package/dist/needs-context.d.ts +31 -2
- package/dist/needs-context.js +3 -1
- package/dist/rules/changed-files.d.ts +37 -0
- package/dist/rules/changed-files.js +54 -0
- package/dist/rules/context.d.ts +12 -11
- package/dist/rules/context.js +7 -25
- package/dist/rules/evaluator.js +2 -1
- package/dist/rules/index.js +2 -1
- package/dist/rules/types.d.ts +9 -0
- package/dist/testing/step-context.js +4 -2
- package/dist/triggers/pr.js +2 -0
- package/dist/triggers/push.js +2 -0
- package/dist/triggers/tag.js +2 -0
- package/dist/triggers/types.d.ts +26 -0
- package/dist/types.d.ts +119 -3
- package/dist/workflow.js +2 -0
- package/package.json +4 -3
- package/sbom.spdx.json +64 -34
package/dist/rules/context.js
CHANGED
|
@@ -1,23 +1,8 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { ChangedFilesUnavailableError, defineChangedFilesGetter, eventTypeOf } from "./changed-files.js";
|
|
2
3
|
import { $ } from "zx";
|
|
3
4
|
//#region src/rules/context.ts
|
|
4
5
|
/**
|
|
5
|
-
* Thrown when a rule reads `ctx.changedFiles` but the diff is not available
|
|
6
|
-
* (`changedFilesStatus !== 'fetched'`). `evaluateRules` re-throws this rather
|
|
7
|
-
* than folding it into a `passed=false` skip, so the job fails loudly instead
|
|
8
|
-
* of silently mis-evaluating a path-based gate.
|
|
9
|
-
*/
|
|
10
|
-
var ChangedFilesUnavailableError = class extends Error {
|
|
11
|
-
changedFilesStatus;
|
|
12
|
-
eventType;
|
|
13
|
-
constructor(status, eventType) {
|
|
14
|
-
super(`ctx.changedFiles is not available (status: ${status}` + (eventType ? `, event: ${eventType}` : "") + "). Changed files are only defined for push / pull_request events with a computable diff. Guard with ctx.changedFilesStatus before accessing, e.g. `if (ctx.changedFilesStatus !== 'fetched') return true`.");
|
|
15
|
-
this.name = "ChangedFilesUnavailableError";
|
|
16
|
-
this.changedFilesStatus = status;
|
|
17
|
-
this.eventType = eventType;
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
6
|
* Build a RuleContext. `changedFiles` is exposed as a getter: it returns the
|
|
22
7
|
* list when `changedFilesStatus === 'fetched'`, otherwise it throws
|
|
23
8
|
* `ChangedFilesUnavailableError`. This is the single construction site for a
|
|
@@ -25,23 +10,20 @@ var ChangedFilesUnavailableError = class extends Error {
|
|
|
25
10
|
*/
|
|
26
11
|
function createRuleContext(input) {
|
|
27
12
|
const status = input.changedFilesStatus ?? "fetched";
|
|
28
|
-
const files = input.changedFiles ?? [];
|
|
29
|
-
const eventType = typeof input.event.type === "string" ? input.event.type : void 0;
|
|
30
13
|
const base = {
|
|
31
14
|
event: input.event,
|
|
32
15
|
changedFilesStatus: status,
|
|
33
16
|
env: input.env ?? {},
|
|
34
17
|
dispatchInputs: input.dispatchInputs ?? {},
|
|
35
18
|
...input.fanout && { fanout: input.fanout },
|
|
19
|
+
...input.sourceRepo && { sourceRepo: input.sourceRepo },
|
|
20
|
+
...input.workflowRepo && { workflowRepo: input.workflowRepo },
|
|
36
21
|
$
|
|
37
22
|
};
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (status !== "fetched") throw new ChangedFilesUnavailableError(status, eventType);
|
|
43
|
-
return files;
|
|
44
|
-
}
|
|
23
|
+
defineChangedFilesGetter(base, {
|
|
24
|
+
files: input.changedFiles ?? [],
|
|
25
|
+
status,
|
|
26
|
+
eventType: eventTypeOf(input.event)
|
|
45
27
|
});
|
|
46
28
|
return base;
|
|
47
29
|
}
|
package/dist/rules/evaluator.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
-
import { ChangedFilesUnavailableError } from "./
|
|
2
|
+
import { ChangedFilesUnavailableError } from "./changed-files.js";
|
|
3
|
+
import "./context.js";
|
|
3
4
|
import { toErrorMessage } from "@kici-dev/core";
|
|
4
5
|
//#region src/rules/evaluator.ts
|
|
5
6
|
/**
|
package/dist/rules/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { ChangedFilesUnavailableError } from "./changed-files.js";
|
|
2
3
|
import { onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, rule, skip } from "./rule.js";
|
|
3
|
-
import {
|
|
4
|
+
import { createRuleContext } from "./context.js";
|
|
4
5
|
import { evaluateRules } from "./evaluator.js";
|
|
5
6
|
import { isEventType } from "../events/event-payloads.js";
|
|
6
7
|
export { ChangedFilesUnavailableError, createRuleContext, evaluateRules, isEventType, onlyOnFanoutIndex, onlyOnFirstHost, onlyOnLastHost, rule, skip };
|
package/dist/rules/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { $ as Shell } from 'zx';
|
|
2
2
|
import type { EventPayload } from '../events/event-payloads.js';
|
|
3
3
|
import type { FanoutPosition } from '../fanout-context.js';
|
|
4
|
+
import type { RepoInfo } from '../context.js';
|
|
4
5
|
export type { EventPayload } from '../events/event-payloads.js';
|
|
5
6
|
/**
|
|
6
7
|
* Context passed to rule check functions.
|
|
@@ -21,6 +22,14 @@ export interface RuleContext {
|
|
|
21
22
|
changedFiles: string[];
|
|
22
23
|
/** Availability of `changedFiles` (see `changedFiles`). */
|
|
23
24
|
changedFilesStatus: import('@kici-dev/engine').ChangedFilesStatus;
|
|
25
|
+
/**
|
|
26
|
+
* The repo whose event triggered this run. Present for a global workflow and
|
|
27
|
+
* for any evaluation that runs with a checkout; undefined otherwise.
|
|
28
|
+
* Read through `.path`; never embed it in a job name (see FilterContext).
|
|
29
|
+
*/
|
|
30
|
+
sourceRepo?: RepoInfo;
|
|
31
|
+
/** The repo that registered the workflow. Identical to `sourceRepo` outside a global workflow. */
|
|
32
|
+
workflowRepo?: RepoInfo;
|
|
24
33
|
/** Environment variables */
|
|
25
34
|
env: Record<string, string | undefined>;
|
|
26
35
|
/** Operator-supplied, validated + coerced workflow-dispatch inputs. Empty when none declared. */
|
|
@@ -2,8 +2,8 @@ import "../rolldown-runtime-ClRpJifh.js";
|
|
|
2
2
|
import { resolveJobOutputs, resolveStepOutputs } from "../outputs.js";
|
|
3
3
|
import { createStepSecrets } from "../secrets.js";
|
|
4
4
|
import { isEventDefinition } from "../events/define-event.js";
|
|
5
|
-
import { initZx } from "@kici-dev/core";
|
|
6
5
|
import { $ } from "zx";
|
|
6
|
+
import { initZx } from "@kici-dev/core";
|
|
7
7
|
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { tmpdir } from "node:os";
|
|
9
9
|
import { dirname, join } from "node:path";
|
|
@@ -218,13 +218,15 @@ function createTestStepContext(options = {}) {
|
|
|
218
218
|
get: () => Promise.resolve(null)
|
|
219
219
|
},
|
|
220
220
|
oidc: { token: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.oidc.token() is not available in a test step context")) },
|
|
221
|
+
git: { github: { getToken: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.git.github.getToken() is not available in a test step context")) } },
|
|
221
222
|
host: { requestReboot: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.host.requestReboot() is not available in a test step context")) },
|
|
222
223
|
bootstrap: {
|
|
223
224
|
ensureInitRunner: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.ensureInitRunner() is not available in a test step context")),
|
|
224
225
|
preBootSend: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.preBootSend() is not available in a test step context")),
|
|
225
226
|
agentVersionStatus: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.agentVersionStatus() is not available in a test step context")),
|
|
226
227
|
restageAgent: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.restageAgent() is not available in a test step context"))
|
|
227
|
-
}
|
|
228
|
+
},
|
|
229
|
+
scaler: { claimAgentCredentials: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.scaler.claimAgentCredentials() is not available in a test step context")) }
|
|
228
230
|
},
|
|
229
231
|
cache: {
|
|
230
232
|
restore: async () => ({ hit: false }),
|
package/dist/triggers/pr.js
CHANGED
|
@@ -38,6 +38,8 @@ function pr(config) {
|
|
|
38
38
|
sourceBranches: Object.freeze([...sourceBranches]),
|
|
39
39
|
paths: Object.freeze([...paths]),
|
|
40
40
|
repos: Object.freeze([...repos]),
|
|
41
|
+
...config?.requires !== void 0 && { requires: Object.freeze([...config.requires]) },
|
|
42
|
+
...config?.commitMessage !== void 0 && { commitMessage: config.commitMessage },
|
|
41
43
|
...config?.description !== void 0 && { description: config.description }
|
|
42
44
|
};
|
|
43
45
|
return Object.freeze(result);
|
package/dist/triggers/push.js
CHANGED
|
@@ -38,6 +38,8 @@ function push(config) {
|
|
|
38
38
|
tags: Object.freeze([...tags]),
|
|
39
39
|
paths: Object.freeze([...paths]),
|
|
40
40
|
repos: Object.freeze([...repos]),
|
|
41
|
+
...config?.requires !== void 0 && { requires: Object.freeze([...config.requires]) },
|
|
42
|
+
...config?.commitMessage !== void 0 && { commitMessage: config.commitMessage },
|
|
41
43
|
...config?.description !== void 0 && { description: config.description }
|
|
42
44
|
};
|
|
43
45
|
return Object.freeze(result);
|
package/dist/triggers/tag.js
CHANGED
|
@@ -21,6 +21,8 @@ function tag(config) {
|
|
|
21
21
|
_tag: "TagTrigger",
|
|
22
22
|
patterns: Object.freeze([...patterns]),
|
|
23
23
|
repos: Object.freeze([...repos]),
|
|
24
|
+
...config?.requires !== void 0 && { requires: Object.freeze([...config.requires]) },
|
|
25
|
+
...config?.commitMessage !== void 0 && { commitMessage: config.commitMessage },
|
|
24
26
|
...config?.description !== void 0 && { description: config.description }
|
|
25
27
|
};
|
|
26
28
|
return Object.freeze(result);
|
package/dist/triggers/types.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Supports both glob patterns and regex patterns for branch/path matching.
|
|
4
4
|
*/
|
|
5
5
|
import type { z } from 'zod';
|
|
6
|
+
import type { ContentRequirement, TextMatch } from '@kici-dev/engine';
|
|
7
|
+
export type { ContentRequirement, ContentFormat, TextMatch } from '@kici-dev/engine';
|
|
6
8
|
/**
|
|
7
9
|
* A declared map of typed workflow-dispatch inputs: `{ name: ZodSchema }`.
|
|
8
10
|
* Each schema must fall within the closed dispatch-input subset (extracted by
|
|
@@ -44,6 +46,10 @@ export interface PrTriggerConfig {
|
|
|
44
46
|
readonly sourceBranches: readonly BranchPattern[];
|
|
45
47
|
readonly paths: readonly string[];
|
|
46
48
|
readonly repos: readonly BranchPattern[];
|
|
49
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
50
|
+
readonly requires?: readonly ContentRequirement[];
|
|
51
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
52
|
+
readonly commitMessage?: TextMatch;
|
|
47
53
|
readonly description?: string;
|
|
48
54
|
}
|
|
49
55
|
/**
|
|
@@ -55,6 +61,10 @@ export interface PushTriggerConfig {
|
|
|
55
61
|
readonly tags: readonly BranchPattern[];
|
|
56
62
|
readonly paths: readonly string[];
|
|
57
63
|
readonly repos: readonly BranchPattern[];
|
|
64
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
65
|
+
readonly requires?: readonly ContentRequirement[];
|
|
66
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
67
|
+
readonly commitMessage?: TextMatch;
|
|
58
68
|
readonly description?: string;
|
|
59
69
|
}
|
|
60
70
|
/**
|
|
@@ -64,6 +74,10 @@ export interface TagTriggerConfig {
|
|
|
64
74
|
readonly _tag: 'TagTrigger';
|
|
65
75
|
readonly patterns: readonly BranchPattern[];
|
|
66
76
|
readonly repos: readonly BranchPattern[];
|
|
77
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
78
|
+
readonly requires?: readonly ContentRequirement[];
|
|
79
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
80
|
+
readonly commitMessage?: TextMatch;
|
|
67
81
|
readonly description?: string;
|
|
68
82
|
}
|
|
69
83
|
/**
|
|
@@ -72,6 +86,10 @@ export interface TagTriggerConfig {
|
|
|
72
86
|
export interface TagConfigInput {
|
|
73
87
|
readonly patterns?: string | RegExp | (string | RegExp)[];
|
|
74
88
|
readonly repos?: string | RegExp | (string | RegExp)[];
|
|
89
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
90
|
+
readonly requires?: readonly ContentRequirement[];
|
|
91
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
92
|
+
readonly commitMessage?: TextMatch;
|
|
75
93
|
readonly description?: string;
|
|
76
94
|
}
|
|
77
95
|
export type CommentAction = 'created' | 'edited' | 'deleted';
|
|
@@ -558,6 +576,10 @@ export interface PrConfigInput {
|
|
|
558
576
|
readonly source?: string | RegExp | (string | RegExp)[];
|
|
559
577
|
readonly paths?: string[];
|
|
560
578
|
readonly repos?: string | RegExp | (string | RegExp)[];
|
|
579
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
580
|
+
readonly requires?: readonly ContentRequirement[];
|
|
581
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
582
|
+
readonly commitMessage?: TextMatch;
|
|
561
583
|
readonly description?: string;
|
|
562
584
|
}
|
|
563
585
|
/**
|
|
@@ -569,6 +591,10 @@ export interface PushConfigInput {
|
|
|
569
591
|
readonly tags?: string | RegExp | (string | RegExp)[];
|
|
570
592
|
readonly paths?: string[];
|
|
571
593
|
readonly repos?: string | RegExp | (string | RegExp)[];
|
|
594
|
+
/** Declarative static content filter over source files at the event ref (AND-ed). */
|
|
595
|
+
readonly requires?: readonly ContentRequirement[];
|
|
596
|
+
/** Declarative static filter over the event's commit message / PR title+body. */
|
|
597
|
+
readonly commitMessage?: TextMatch;
|
|
572
598
|
readonly description?: string;
|
|
573
599
|
}
|
|
574
600
|
/**
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import type { $ as Shell } from 'zx';
|
|
3
3
|
import type { RetryBackoff } from '@kici-dev/core';
|
|
4
|
+
import type { GitCredentialMap, ContainerRegistryAuth } from './git-types.js';
|
|
4
5
|
import type { ResourceRequest, RunsOnAllInput, OnUnreachableMode, NeedsWhen, ExecutionJobStatus } from '@kici-dev/engine';
|
|
5
|
-
import type { StepContext, Logger } from './context.js';
|
|
6
|
+
import type { StepContext, Logger, RepoInfo } from './context.js';
|
|
7
|
+
import type { FilterFn } from './filter.js';
|
|
6
8
|
import type { SingleNeedEntry, NeedsContext } from './needs-context.js';
|
|
7
9
|
import type { TriggerConfig } from './triggers/types.js';
|
|
8
10
|
import type { Rule } from './rules/types.js';
|
|
@@ -308,6 +310,14 @@ export interface DynamicJobContext {
|
|
|
308
310
|
env: Record<string, string | undefined>;
|
|
309
311
|
/** Typed KiCI API — orchestrator queries over WS (e.g., kici.infrastructure.list()) */
|
|
310
312
|
kici: KiciApi;
|
|
313
|
+
/**
|
|
314
|
+
* The repo whose event triggered this run. Present for a global workflow and
|
|
315
|
+
* for any evaluation that runs with a checkout; undefined otherwise.
|
|
316
|
+
* Read through `.path`; never embed it in a job name (see FilterContext).
|
|
317
|
+
*/
|
|
318
|
+
sourceRepo?: RepoInfo;
|
|
319
|
+
/** The repo that registered the workflow. Identical to `sourceRepo` outside a global workflow. */
|
|
320
|
+
workflowRepo?: RepoInfo;
|
|
311
321
|
}
|
|
312
322
|
/**
|
|
313
323
|
* Async function that generates jobs dynamically at runtime.
|
|
@@ -397,10 +407,43 @@ export { DYNAMIC_JOB_NEEDS_TAG };
|
|
|
397
407
|
* When set, all steps run inside the specified container.
|
|
398
408
|
*/
|
|
399
409
|
export interface ContainerConfig {
|
|
400
|
-
/**
|
|
401
|
-
|
|
410
|
+
/**
|
|
411
|
+
* Docker image name (e.g., 'node:20-alpine'). Mutually exclusive with
|
|
412
|
+
* `dockerfile`; exactly one of the two is required.
|
|
413
|
+
*/
|
|
414
|
+
image?: string;
|
|
415
|
+
/**
|
|
416
|
+
* Repo-relative path to a Dockerfile the agent builds before the job runs.
|
|
417
|
+
* Mutually exclusive with `image`.
|
|
418
|
+
*
|
|
419
|
+
* The build runs on the agent host, NOT inside the job's hardened sandbox.
|
|
420
|
+
* See the container-jobs documentation for the trust model and the
|
|
421
|
+
* untrusted-ref rule.
|
|
422
|
+
*/
|
|
423
|
+
dockerfile?: string;
|
|
424
|
+
/**
|
|
425
|
+
* Repo-relative build context. Defaults to the repository root.
|
|
426
|
+
* Meaningful only with `dockerfile`.
|
|
427
|
+
*/
|
|
428
|
+
context?: string;
|
|
429
|
+
/** Build stage to stop at (`--target`). Meaningful only with `dockerfile`. */
|
|
430
|
+
target?: string;
|
|
431
|
+
/**
|
|
432
|
+
* Build arguments. Meaningful only with `dockerfile`.
|
|
433
|
+
*
|
|
434
|
+
* Plain strings only, deliberately: a build argument is recorded in the
|
|
435
|
+
* image's history, so a secret placed here is readable by anyone who can
|
|
436
|
+
* inspect the image. Pass a secret to a step instead.
|
|
437
|
+
*/
|
|
438
|
+
args?: Record<string, string>;
|
|
402
439
|
/** Additional environment variables for the container */
|
|
403
440
|
env?: Record<string, string>;
|
|
441
|
+
/**
|
|
442
|
+
* Private-registry credentials. With `image` they pull that image; with
|
|
443
|
+
* `dockerfile` they pull the Dockerfile's own `FROM` base — and must name
|
|
444
|
+
* the registry, because there is no image reference to derive it from.
|
|
445
|
+
*/
|
|
446
|
+
auth?: ContainerRegistryAuth;
|
|
404
447
|
}
|
|
405
448
|
/**
|
|
406
449
|
* Per-job sandbox escape hatch for container-sandbox jobs (a job with a
|
|
@@ -565,6 +608,13 @@ export interface Job<TOutputs = Record<string, unknown>, TName extends string =
|
|
|
565
608
|
readonly maxParallel?: number;
|
|
566
609
|
/** Halt the fan-out on first child failure, skipping the remainder. Default `false`. */
|
|
567
610
|
readonly failFast?: boolean;
|
|
611
|
+
/**
|
|
612
|
+
* Invoke the source repo's opt-in workflows and gate on them. Mutually
|
|
613
|
+
* exclusive with `steps` / `run` — an invoke job never runs step code on an
|
|
614
|
+
* agent; it fans out into one proxy node per triggered run. Built by
|
|
615
|
+
* `invokeSource()`.
|
|
616
|
+
*/
|
|
617
|
+
readonly invoke?: import('./invoke.js').InvokeConfig;
|
|
568
618
|
readonly steps: readonly StepInput[];
|
|
569
619
|
readonly needs?: ReadonlyArray<Job | string | DynamicGroupRef | {
|
|
570
620
|
name: string;
|
|
@@ -585,6 +635,17 @@ export interface Job<TOutputs = Record<string, unknown>, TName extends string =
|
|
|
585
635
|
readonly exclude?: MatrixExclude[];
|
|
586
636
|
/** When false, agent skips git clone (default: true). Useful for deploy/notify jobs. */
|
|
587
637
|
readonly checkout?: boolean;
|
|
638
|
+
/**
|
|
639
|
+
* Named git credentials available to every step in this job.
|
|
640
|
+
*
|
|
641
|
+
* Values are **secret names**, resolved from the secrets backend — never
|
|
642
|
+
* secret material. `default` is used whenever a call names no credential;
|
|
643
|
+
* any other key is referenced by name, e.g.
|
|
644
|
+
* `kici.git.clone({ repo, credential: 'forge' })`.
|
|
645
|
+
*
|
|
646
|
+
* Omit entirely and the source credential applies, which is all a read needs.
|
|
647
|
+
*/
|
|
648
|
+
readonly gitCredentials?: GitCredentialMap;
|
|
588
649
|
/** Docker image for job execution. All steps run inside the container. */
|
|
589
650
|
readonly container?: string | ContainerConfig;
|
|
590
651
|
/** Per-job sandbox escape hatch (container jobs only); granted within the operator allow-list. */
|
|
@@ -700,6 +761,13 @@ export interface JobOptions {
|
|
|
700
761
|
* of sibling outcomes). Applies to both matrix and `runsOnAll` fan-out.
|
|
701
762
|
*/
|
|
702
763
|
failFast?: boolean;
|
|
764
|
+
/**
|
|
765
|
+
* Invoke the source repo's opt-in workflows and gate on them. Mutually
|
|
766
|
+
* exclusive with `steps` / `run` — an invoke job never runs step code on an
|
|
767
|
+
* agent; it fans out into one proxy node per triggered run. Built by
|
|
768
|
+
* `invokeSource()`.
|
|
769
|
+
*/
|
|
770
|
+
invoke?: import('./invoke.js').InvokeConfig;
|
|
703
771
|
/**
|
|
704
772
|
* Steps to execute in this job. Accepts Step objects and bare async functions.
|
|
705
773
|
* Mutually exclusive with `run`.
|
|
@@ -740,6 +808,17 @@ export interface JobOptions {
|
|
|
740
808
|
exclude?: MatrixExclude[];
|
|
741
809
|
/** When false, agent skips git clone (default: true). Useful for deploy/notify jobs. */
|
|
742
810
|
checkout?: boolean;
|
|
811
|
+
/**
|
|
812
|
+
* Named git credentials available to every step in this job.
|
|
813
|
+
*
|
|
814
|
+
* Values are **secret names**, resolved from the secrets backend — never
|
|
815
|
+
* secret material. `default` is used whenever a call names no credential;
|
|
816
|
+
* any other key is referenced by name, e.g.
|
|
817
|
+
* `kici.git.clone({ repo, credential: 'forge' })`.
|
|
818
|
+
*
|
|
819
|
+
* Omit entirely and the source credential applies, which is all a read needs.
|
|
820
|
+
*/
|
|
821
|
+
gitCredentials?: GitCredentialMap;
|
|
743
822
|
/**
|
|
744
823
|
* Docker image for job execution.
|
|
745
824
|
* Simple string form for image name, object form for additional config.
|
|
@@ -845,6 +924,23 @@ export interface Workflow {
|
|
|
845
924
|
readonly on?: TriggerConfig[];
|
|
846
925
|
/** Rules for conditional execution */
|
|
847
926
|
readonly rules?: Rule[];
|
|
927
|
+
/**
|
|
928
|
+
* Pre-dispatch predicate deciding whether this workflow applies to the event's
|
|
929
|
+
* source repo. A `false` result suppresses the workflow's jobs — none is
|
|
930
|
+
* dispatched, and none is reported as skipped.
|
|
931
|
+
*
|
|
932
|
+
* An organization-wide workflow is evaluated once per (event × workflow repo)
|
|
933
|
+
* before any run row is created, so a `false` verdict produces no run. A
|
|
934
|
+
* same-repo workflow is evaluated once per job and once per job generator,
|
|
935
|
+
* after the run row exists — so a run is recorded showing the evaluation and
|
|
936
|
+
* none of the workflow's own jobs. Because it runs once per job there, the
|
|
937
|
+
* predicate must be cheap, side-effect free, and deterministic; see `FilterFn`.
|
|
938
|
+
*
|
|
939
|
+
* One same-repo exception: a job **held for approval** or **rejected by a
|
|
940
|
+
* context rule** is not filtered at all. The hold or the rule is its gate, so
|
|
941
|
+
* an approved job dispatches with no filter verdict having been taken.
|
|
942
|
+
*/
|
|
943
|
+
readonly filter?: FilterFn;
|
|
848
944
|
/** Optional description */
|
|
849
945
|
readonly description?: string;
|
|
850
946
|
/**
|
|
@@ -899,6 +995,26 @@ export interface WorkflowOptions {
|
|
|
899
995
|
on?: Trigger | Trigger[];
|
|
900
996
|
/** Rules that must pass for workflow to execute */
|
|
901
997
|
rules?: Rule[];
|
|
998
|
+
/**
|
|
999
|
+
* Pre-dispatch predicate deciding whether this workflow applies to the event's
|
|
1000
|
+
* source repo. Runs on an evaluating agent with the tree(s) on disk, and a
|
|
1001
|
+
* `false` result suppresses the workflow's jobs — none is dispatched, and none
|
|
1002
|
+
* is reported as skipped.
|
|
1003
|
+
*
|
|
1004
|
+
* An organization-wide workflow is evaluated once per (event × workflow repo)
|
|
1005
|
+
* before any run row is created, so a `false` verdict produces no run. A
|
|
1006
|
+
* same-repo workflow is evaluated once per job and once per job generator,
|
|
1007
|
+
* after the run row exists — so a run is recorded showing the evaluation and
|
|
1008
|
+
* none of the workflow's own jobs. Because it runs once per job there, the
|
|
1009
|
+
* predicate must be cheap, side-effect free, and deterministic; see `FilterFn`.
|
|
1010
|
+
*
|
|
1011
|
+
* One same-repo exception: a job **held for approval** or **rejected by a
|
|
1012
|
+
* context rule** is not filtered at all. The hold or the rule is its gate, so
|
|
1013
|
+
* an approved job dispatches with no filter verdict having been taken.
|
|
1014
|
+
*
|
|
1015
|
+
* See `FilterContext` for what it receives and what it deliberately does not.
|
|
1016
|
+
*/
|
|
1017
|
+
filter?: FilterFn;
|
|
902
1018
|
/** Optional description for documentation */
|
|
903
1019
|
description?: string;
|
|
904
1020
|
/**
|
package/dist/workflow.js
CHANGED
|
@@ -60,12 +60,14 @@ function workflow(name, options) {
|
|
|
60
60
|
if (options.installEnv) {
|
|
61
61
|
for (const [i, ref] of options.installEnv.entries()) if (!isQualifiedSecretRef(ref)) throw new Error(`workflow('${name}'): installEnv[${i}] must use qualified <context>:<secret-name> syntax (got: ${ref})`);
|
|
62
62
|
}
|
|
63
|
+
if (options.filter !== void 0 && typeof options.filter !== "function") throw new Error(`workflow('${name}'): filter must be a function (got: ${typeof options.filter})`);
|
|
63
64
|
return {
|
|
64
65
|
_tag: "Workflow",
|
|
65
66
|
name,
|
|
66
67
|
jobs: options.jobs,
|
|
67
68
|
on: normalizeTriggers(options.on),
|
|
68
69
|
rules: options.rules,
|
|
70
|
+
filter: options.filter,
|
|
69
71
|
description: options.description,
|
|
70
72
|
hashFiles: options.hashFiles,
|
|
71
73
|
registries: options.registries,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kici-dev/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "TypeScript SDK for defining KiCI workflows. Import into `.kici/workflows/*.ts` to declare workflows, jobs, steps, triggers, rules, and matrix configurations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ci",
|
|
@@ -52,10 +52,11 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"micromatch": "^4.0.8",
|
|
55
|
+
"yaml": "^2.9.0",
|
|
55
56
|
"zod": "^4.4.3",
|
|
56
57
|
"zx": "^8.8.5",
|
|
57
|
-
"@kici-dev/core": "0.
|
|
58
|
-
"@kici-dev/engine": "0.
|
|
58
|
+
"@kici-dev/core": "0.6.0",
|
|
59
|
+
"@kici-dev/engine": "0.6.0"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@types/micromatch": "^4.0.10"
|