@kici-dev/sdk 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/api-types.d.ts +28 -0
- package/dist/api-types.js +3 -1
- package/dist/approval.d.ts +3 -8
- package/dist/approval.js +9 -0
- package/dist/artifacts-types.d.ts +45 -0
- package/dist/artifacts-types.js +3 -0
- package/dist/context.d.ts +65 -15
- package/dist/events/define-event.d.ts +11 -3
- package/dist/events/define-event.js +14 -4
- package/dist/events/emit-typing.test-d.d.ts +2 -0
- package/dist/events/emit-typing.test-d.js +36 -0
- package/dist/events/event-payloads.d.ts +4 -0
- package/dist/events/index.d.ts +1 -1
- package/dist/events/index.js +2 -2
- package/dist/fleet/agent-version-converge.d.ts +23 -0
- package/dist/fleet/agent-version-converge.js +58 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +6 -2
- package/dist/job-outputs.test-d.d.ts +2 -0
- package/dist/job-outputs.test-d.js +164 -0
- package/dist/job.d.ts +71 -9
- package/dist/job.js +14 -0
- package/dist/matrix/expand.d.ts +1 -1
- package/dist/matrix/expand.js +2 -2
- package/dist/needs-context.d.ts +13 -6
- package/dist/outputs.d.ts +19 -4
- package/dist/outputs.js +21 -7
- package/dist/parallel.d.ts +1 -1
- package/dist/parallel.js +1 -1
- package/dist/provenance-types.d.ts +3 -3
- package/dist/rules/context.d.ts +33 -0
- package/dist/rules/context.js +51 -0
- package/dist/rules/evaluator.d.ts +10 -0
- package/dist/rules/evaluator.js +9 -1
- package/dist/rules/index.d.ts +2 -0
- package/dist/rules/index.js +2 -1
- package/dist/rules/types.d.ts +11 -1
- package/dist/step.d.ts +6 -6
- package/dist/step.js +6 -3
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/step-context.d.ts +56 -0
- package/dist/testing/step-context.js +259 -0
- package/dist/triggers/index.d.ts +2 -1
- package/dist/triggers/index.js +2 -1
- package/dist/triggers/types.d.ts +23 -1
- package/dist/triggers/workflows-failed-batch.d.ts +20 -0
- package/dist/triggers/workflows-failed-batch.js +25 -0
- package/dist/types.d.ts +142 -9
- package/dist/validation/dag.js +11 -3
- package/package.json +10 -5
- package/sbom.spdx.json +192 -192
package/dist/rules/types.d.ts
CHANGED
|
@@ -9,8 +9,18 @@ export type { EventPayload } from '../events/event-payloads.js';
|
|
|
9
9
|
export interface RuleContext {
|
|
10
10
|
/** The triggering event payload */
|
|
11
11
|
event: EventPayload;
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* Files changed in this event (PR diff / push diff). Available on push and
|
|
14
|
+
* pull_request events (the agent computes the diff from the checkout — no
|
|
15
|
+
* `paths:` trigger required). Accessing this throws
|
|
16
|
+
* `ChangedFilesUnavailableError` when the diff is not available
|
|
17
|
+
* (`changedFilesStatus !== 'fetched'`) — e.g. a schedule/tag/manual event.
|
|
18
|
+
* Guard with `changedFilesStatus` first when a rule runs on such events:
|
|
19
|
+
* `if (ctx.changedFilesStatus !== 'fetched') return true`.
|
|
20
|
+
*/
|
|
13
21
|
changedFiles: string[];
|
|
22
|
+
/** Availability of `changedFiles` (see `changedFiles`). */
|
|
23
|
+
changedFilesStatus: import('@kici-dev/engine').ChangedFilesStatus;
|
|
14
24
|
/** Environment variables */
|
|
15
25
|
env: Record<string, string | undefined>;
|
|
16
26
|
/** Operator-supplied, validated + coerced workflow-dispatch inputs. Empty when none declared. */
|
package/dist/step.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { Step, StepOptions, StepOptionsWithCheck, StepRunFn } from './types
|
|
|
8
8
|
* await ctx.$`echo hello`;
|
|
9
9
|
* });
|
|
10
10
|
*/
|
|
11
|
-
export declare function step<TResult = void>(run: (ctx: import('./context.js').StepContext) => Promise<TResult>): Step<TResult>;
|
|
11
|
+
export declare function step<TResult = void>(run: (ctx: import('./context.js').StepContext) => Promise<TResult>): Step<TResult, ''>;
|
|
12
12
|
/**
|
|
13
13
|
* Create an id-less step with full options.
|
|
14
14
|
* The compiler assigns a counter-based ID at lock file generation.
|
|
@@ -21,7 +21,7 @@ export declare function step<TResult = void>(run: (ctx: import('./context.js').S
|
|
|
21
21
|
* timeout: 60000,
|
|
22
22
|
* });
|
|
23
23
|
*/
|
|
24
|
-
export declare function step<TResult = void>(options: StepOptions<TResult>): Step<TResult>;
|
|
24
|
+
export declare function step<TResult = void>(options: StepOptions<TResult>): Step<TResult, ''>;
|
|
25
25
|
/**
|
|
26
26
|
* Create a named step with just a run function (no outputs).
|
|
27
27
|
*
|
|
@@ -30,7 +30,7 @@ export declare function step<TResult = void>(options: StepOptions<TResult>): Ste
|
|
|
30
30
|
* await ctx.$`git checkout`;
|
|
31
31
|
* });
|
|
32
32
|
*/
|
|
33
|
-
export declare function step(name:
|
|
33
|
+
export declare function step<TName extends string>(name: TName, run: StepRunFn): Step<void, TName>;
|
|
34
34
|
/**
|
|
35
35
|
* Create a named step with full options and generic return type.
|
|
36
36
|
*
|
|
@@ -46,7 +46,7 @@ export declare function step(name: string, run: StepRunFn): Step<void>;
|
|
|
46
46
|
* }
|
|
47
47
|
* });
|
|
48
48
|
*/
|
|
49
|
-
export declare function step<TResult = void>(name:
|
|
49
|
+
export declare function step<TResult = void, TName extends string = string>(name: TName, options: StepOptions<TResult>): Step<TResult, TName>;
|
|
50
50
|
/**
|
|
51
51
|
* Create a named idempotent step with a check facet.
|
|
52
52
|
*
|
|
@@ -62,9 +62,9 @@ export declare function step<TResult = void>(name: string, options: StepOptions<
|
|
|
62
62
|
* whenInSync: async () => ({ reloaded: false }),
|
|
63
63
|
* });
|
|
64
64
|
*/
|
|
65
|
-
export declare function step<TResult = void, TDrift = unknown>(name:
|
|
65
|
+
export declare function step<TResult = void, TDrift = unknown, TName extends string = string>(name: TName, options: StepOptionsWithCheck<TResult, TDrift>): Step<TResult, TName>;
|
|
66
66
|
/**
|
|
67
67
|
* Create an id-less idempotent step with a check facet.
|
|
68
68
|
*/
|
|
69
|
-
export declare function step<TResult = void, TDrift = unknown>(options: StepOptionsWithCheck<TResult, TDrift>): Step<TResult>;
|
|
69
|
+
export declare function step<TResult = void, TDrift = unknown>(options: StepOptionsWithCheck<TResult, TDrift>): Step<TResult, ''>;
|
|
70
70
|
//# sourceMappingURL=step.d.ts.map
|
package/dist/step.js
CHANGED
|
@@ -40,6 +40,8 @@ function captureCallSite() {
|
|
|
40
40
|
if (match) {
|
|
41
41
|
let file = match[1];
|
|
42
42
|
if (file.startsWith("file://")) file = file.slice(7);
|
|
43
|
+
const queryIndex = file.indexOf("?");
|
|
44
|
+
if (queryIndex !== -1) file = file.slice(0, queryIndex);
|
|
43
45
|
return {
|
|
44
46
|
file,
|
|
45
47
|
line: parseInt(match[2], 10),
|
|
@@ -78,7 +80,7 @@ function step(nameOrRunOrOptions, runOrOptions) {
|
|
|
78
80
|
if (options.check && !options.summarize) throw new Error("summarize is required when check is set");
|
|
79
81
|
if (options.approval !== void 0 && normalizeApproval(options.approval).when === "drift" && !options.check) throw new Error("approval.when \"drift\" requires a check facet");
|
|
80
82
|
const retry = normalizeRetry(options.retry);
|
|
81
|
-
|
|
83
|
+
const stepObj = {
|
|
82
84
|
_tag: "Step",
|
|
83
85
|
name,
|
|
84
86
|
outputs: options.outputs,
|
|
@@ -95,9 +97,10 @@ function step(nameOrRunOrOptions, runOrOptions) {
|
|
|
95
97
|
onCancel: options.onCancel,
|
|
96
98
|
cleanup: options.cleanup,
|
|
97
99
|
...options.approval !== void 0 && { approval: options.approval },
|
|
98
|
-
_sourceLocation
|
|
99
|
-
result: createStepOutputProxy(name)
|
|
100
|
+
_sourceLocation
|
|
100
101
|
};
|
|
102
|
+
stepObj.result = createStepOutputProxy(stepObj);
|
|
103
|
+
return stepObj;
|
|
101
104
|
}
|
|
102
105
|
//#endregion
|
|
103
106
|
export { step };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type TempScope } from '@kici-dev/core/tmp';
|
|
2
|
+
import type { StepContext, Logger } from '../context.js';
|
|
3
|
+
import type { EventEmitOptions } from '../events/types.js';
|
|
4
|
+
/** A single recorded `ctx.emit(...)` invocation, for assertion in tests. */
|
|
5
|
+
export interface RecordedEmit {
|
|
6
|
+
eventName: string;
|
|
7
|
+
payload?: Record<string, unknown>;
|
|
8
|
+
options?: EventEmitOptions;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Options for {@link createTestStepContext}. Every field is optional — call it
|
|
12
|
+
* with no arguments for a fully-defaulted context. Convenience seed fields
|
|
13
|
+
* (`repoRoot`, `secrets`) sit alongside direct `StepContext` member overrides
|
|
14
|
+
* (everything else), which are shallow-merged on top of the defaults.
|
|
15
|
+
*/
|
|
16
|
+
export interface TestStepContextOptions extends Partial<Omit<StepContext, 'secrets' | 'log'>> {
|
|
17
|
+
/** Working directory `ctx.$` is pinned to. Defaults to `process.cwd()`. */
|
|
18
|
+
repoRoot?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Seed secrets for `ctx.secrets`. `flat` keys are global; `contexts` values are
|
|
21
|
+
* flattened into the flat map (last-write-wins), matching the local runner.
|
|
22
|
+
*/
|
|
23
|
+
secrets?: {
|
|
24
|
+
flat?: Record<string, string>;
|
|
25
|
+
contexts?: Record<string, Record<string, string>>;
|
|
26
|
+
};
|
|
27
|
+
/** Logger override. Defaults to a console-backed logger. */
|
|
28
|
+
log?: Logger;
|
|
29
|
+
}
|
|
30
|
+
/** Handle returned by {@link createTestStepContext}. */
|
|
31
|
+
export interface TestStepContext {
|
|
32
|
+
/** The built step context to pass into your step function. */
|
|
33
|
+
ctx: StepContext;
|
|
34
|
+
/** Every `ctx.emit(...)` call, in order — assert against this in tests. */
|
|
35
|
+
emitCalls: ReadonlyArray<RecordedEmit>;
|
|
36
|
+
/**
|
|
37
|
+
* The job-scoped temp allocator backing `ctx.mktemp`/`ctx.mktempFile`. Call
|
|
38
|
+
* `tempScope.disposeAll()` to drain every still-live temp dir/file manually;
|
|
39
|
+
* `dispose()` also drains it.
|
|
40
|
+
*/
|
|
41
|
+
tempScope: TempScope;
|
|
42
|
+
/** Tear down secrets state + the per-context tmpdir + temp scope. Call in `afterEach`. */
|
|
43
|
+
dispose: () => Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Build a real {@link StepContext} for unit-testing a step function in vitest.
|
|
47
|
+
*
|
|
48
|
+
* `ctx.$` is real zx pinned to `repoRoot`, `ctx.secrets` is real
|
|
49
|
+
* (`createStepSecrets` seeded from `options.secrets`), and `ctx.emit` records
|
|
50
|
+
* each call on `emitCalls` while returning the local delivery receipt.
|
|
51
|
+
* Orchestrator-backed APIs (`ctx.kici.*`, `ctx.attestProvenance`,
|
|
52
|
+
* `ctx.artifacts.*`) reject, and `ctx.cache` no-ops — override any of them via
|
|
53
|
+
* the options object.
|
|
54
|
+
*/
|
|
55
|
+
export declare function createTestStepContext(options?: TestStepContextOptions): TestStepContext;
|
|
56
|
+
//# sourceMappingURL=step-context.d.ts.map
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
import { resolveJobOutputs, resolveStepOutputs } from "../outputs.js";
|
|
3
|
+
import { createStepSecrets } from "../secrets.js";
|
|
4
|
+
import { isEventDefinition } from "../events/define-event.js";
|
|
5
|
+
import { initZx } from "@kici-dev/core";
|
|
6
|
+
import { $ } from "zx";
|
|
7
|
+
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
8
|
+
import { tmpdir } from "node:os";
|
|
9
|
+
import { dirname, join } from "node:path";
|
|
10
|
+
import { createTempScope } from "@kici-dev/core/tmp";
|
|
11
|
+
//#region src/testing/step-context.ts
|
|
12
|
+
initZx();
|
|
13
|
+
const DEFAULT_WORKFLOW = { name: "test-workflow" };
|
|
14
|
+
const DEFAULT_JOB = {
|
|
15
|
+
name: "test-job",
|
|
16
|
+
runsOn: "local"
|
|
17
|
+
};
|
|
18
|
+
const NOOP_DELIVERY_ID = "local-test-noop";
|
|
19
|
+
function createConsoleLogger() {
|
|
20
|
+
return {
|
|
21
|
+
info: (message, ...args) => console.log(message, ...args),
|
|
22
|
+
warn: (message, ...args) => console.warn(`⚠ ${message}`, ...args),
|
|
23
|
+
error: (message, ...args) => console.error(`✗ ${message}`, ...args),
|
|
24
|
+
debug: (message, ...args) => {
|
|
25
|
+
if (process.env.KICI_DEBUG === "true") console.debug(`[debug] ${message}`, ...args);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Wire a real secrets surface backed by an on-demand tmpdir file host.
|
|
31
|
+
*
|
|
32
|
+
* The tmpdir is allocated lazily on first `mountFile`/`exposeFile` so steps that
|
|
33
|
+
* never mount pay nothing, and the `process.on('exit')` cleanup handler is
|
|
34
|
+
* registered lazily too (to avoid Node's MaxListeners warning at scale).
|
|
35
|
+
*/
|
|
36
|
+
function createTestSecrets(mergedFlat, env) {
|
|
37
|
+
let tmpdirPath = null;
|
|
38
|
+
const exposedEnvVars = /* @__PURE__ */ new Set();
|
|
39
|
+
let mountCounter = 0;
|
|
40
|
+
let exitHandlerRegistered = false;
|
|
41
|
+
const onProcessExit = () => {
|
|
42
|
+
for (const envVar of exposedEnvVars) delete env[envVar];
|
|
43
|
+
exposedEnvVars.clear();
|
|
44
|
+
if (tmpdirPath !== null) {
|
|
45
|
+
try {
|
|
46
|
+
rmSync(tmpdirPath, {
|
|
47
|
+
recursive: true,
|
|
48
|
+
force: true
|
|
49
|
+
});
|
|
50
|
+
} catch {}
|
|
51
|
+
tmpdirPath = null;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const handle = createStepSecrets(mergedFlat, env, void 0, {
|
|
55
|
+
host: {
|
|
56
|
+
async writeMountedFile(args) {
|
|
57
|
+
if (tmpdirPath === null) tmpdirPath = mkdtempSync(join(tmpdir(), "kici-secret-files-"));
|
|
58
|
+
if (!exitHandlerRegistered) {
|
|
59
|
+
process.once("exit", onProcessExit);
|
|
60
|
+
exitHandlerRegistered = true;
|
|
61
|
+
}
|
|
62
|
+
mountCounter += 1;
|
|
63
|
+
const filename = args.name ?? `secret-${mountCounter}`;
|
|
64
|
+
const filePath = join(tmpdirPath, filename);
|
|
65
|
+
writeFileSync(filePath, args.content);
|
|
66
|
+
chmodSync(filePath, args.mode);
|
|
67
|
+
return filePath;
|
|
68
|
+
},
|
|
69
|
+
trackExposedEnv(envVar) {
|
|
70
|
+
exposedEnvVars.add(envVar);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
cleanup: async () => {
|
|
74
|
+
if (exitHandlerRegistered) {
|
|
75
|
+
process.off("exit", onProcessExit);
|
|
76
|
+
exitHandlerRegistered = false;
|
|
77
|
+
}
|
|
78
|
+
onProcessExit();
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
return {
|
|
82
|
+
secrets: handle.secrets,
|
|
83
|
+
dispose: handle.dispose
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Sanitize a raw identifier into a valid temp label: lowercase, every
|
|
88
|
+
* non-`[a-z0-9-]` char to `-`, falling back to `'step'` when the result is
|
|
89
|
+
* empty. Applied to both the caller-supplied label and the default step id so
|
|
90
|
+
* `ctx.mktemp(...)` never rejects a friendly-but-irregular label.
|
|
91
|
+
*/
|
|
92
|
+
function sanitizeTempLabel(raw) {
|
|
93
|
+
const cleaned = raw.toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
94
|
+
return cleaned.length > 0 ? cleaned : "step";
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Wire a job-scoped temp allocator for the test step context.
|
|
98
|
+
*
|
|
99
|
+
* `mktemp`/`mktempFile` delegate to a {@link createTempScope} instance and track
|
|
100
|
+
* each allocated root so an exit backstop can reclaim it. The `process.once('exit')`
|
|
101
|
+
* handler is registered lazily on first allocation (to avoid Node's MaxListeners
|
|
102
|
+
* warning at scale) and synchronously removes any still-live temp paths — mirroring
|
|
103
|
+
* the secrets-tmpdir exit cleanup. `dispose()` drains the scope and removes the
|
|
104
|
+
* handler; the scope is exposed for manual drain in tests.
|
|
105
|
+
*/
|
|
106
|
+
function createTestTempScope(defaultLabel) {
|
|
107
|
+
const scope = createTempScope();
|
|
108
|
+
const liveRoots = [];
|
|
109
|
+
let exitHandlerRegistered = false;
|
|
110
|
+
const onProcessExit = () => {
|
|
111
|
+
for (const root of liveRoots) try {
|
|
112
|
+
rmSync(root, {
|
|
113
|
+
recursive: true,
|
|
114
|
+
force: true
|
|
115
|
+
});
|
|
116
|
+
} catch {}
|
|
117
|
+
liveRoots.length = 0;
|
|
118
|
+
};
|
|
119
|
+
const ensureExitHandler = () => {
|
|
120
|
+
if (!exitHandlerRegistered) {
|
|
121
|
+
process.once("exit", onProcessExit);
|
|
122
|
+
exitHandlerRegistered = true;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
async mktemp(label) {
|
|
127
|
+
ensureExitHandler();
|
|
128
|
+
const handle = await scope.mktemp(sanitizeTempLabel(label ?? defaultLabel));
|
|
129
|
+
liveRoots.push(handle.path);
|
|
130
|
+
return handle;
|
|
131
|
+
},
|
|
132
|
+
async mktempFile(label, opts) {
|
|
133
|
+
ensureExitHandler();
|
|
134
|
+
const handle = await scope.mktempFile(sanitizeTempLabel(label ?? defaultLabel), opts);
|
|
135
|
+
liveRoots.push(dirname(handle.path));
|
|
136
|
+
return handle;
|
|
137
|
+
},
|
|
138
|
+
scope,
|
|
139
|
+
async dispose() {
|
|
140
|
+
if (exitHandlerRegistered) {
|
|
141
|
+
process.off("exit", onProcessExit);
|
|
142
|
+
exitHandlerRegistered = false;
|
|
143
|
+
}
|
|
144
|
+
await scope.disposeAll();
|
|
145
|
+
liveRoots.length = 0;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Build a real {@link StepContext} for unit-testing a step function in vitest.
|
|
151
|
+
*
|
|
152
|
+
* `ctx.$` is real zx pinned to `repoRoot`, `ctx.secrets` is real
|
|
153
|
+
* (`createStepSecrets` seeded from `options.secrets`), and `ctx.emit` records
|
|
154
|
+
* each call on `emitCalls` while returning the local delivery receipt.
|
|
155
|
+
* Orchestrator-backed APIs (`ctx.kici.*`, `ctx.attestProvenance`,
|
|
156
|
+
* `ctx.artifacts.*`) reject, and `ctx.cache` no-ops — override any of them via
|
|
157
|
+
* the options object.
|
|
158
|
+
*/
|
|
159
|
+
function createTestStepContext(options = {}) {
|
|
160
|
+
const { repoRoot = process.cwd(), secrets: seed, log, ...overrides } = options;
|
|
161
|
+
const flat = seed?.flat ?? {};
|
|
162
|
+
const namespaced = seed?.contexts ?? {};
|
|
163
|
+
const mergedFlat = { ...flat };
|
|
164
|
+
for (const contextSecrets of Object.values(namespaced)) Object.assign(mergedFlat, contextSecrets);
|
|
165
|
+
const env = overrides.env ?? { ...process.env };
|
|
166
|
+
const processEnvRestores = /* @__PURE__ */ new Map();
|
|
167
|
+
const recordProcessEnvOriginal = (key) => {
|
|
168
|
+
if (!processEnvRestores.has(key)) processEnvRestores.set(key, process.env[key]);
|
|
169
|
+
};
|
|
170
|
+
const scoped$ = $({ cwd: repoRoot });
|
|
171
|
+
const { secrets, dispose: disposeSecrets } = createTestSecrets(mergedFlat, env);
|
|
172
|
+
const temp = createTestTempScope((overrides.job ?? DEFAULT_JOB).name);
|
|
173
|
+
const emitCalls = [];
|
|
174
|
+
const emit = (async (nameOrDefinition, payload, opts) => {
|
|
175
|
+
const eventName = isEventDefinition(nameOrDefinition) ? nameOrDefinition.name : nameOrDefinition;
|
|
176
|
+
emitCalls.push({
|
|
177
|
+
eventName,
|
|
178
|
+
payload,
|
|
179
|
+
options: opts
|
|
180
|
+
});
|
|
181
|
+
return { deliveryId: NOOP_DELIVERY_ID };
|
|
182
|
+
});
|
|
183
|
+
const ctx = {
|
|
184
|
+
$: scoped$,
|
|
185
|
+
log: log ?? createConsoleLogger(),
|
|
186
|
+
signal: overrides.signal ?? new AbortController().signal,
|
|
187
|
+
env,
|
|
188
|
+
setEnv: (key, value) => {
|
|
189
|
+
env[key] = value;
|
|
190
|
+
recordProcessEnvOriginal(key);
|
|
191
|
+
process.env[key] = value;
|
|
192
|
+
},
|
|
193
|
+
addPath: (dir) => {
|
|
194
|
+
const updated = `${dir}:${env.PATH ?? process.env.PATH ?? ""}`;
|
|
195
|
+
env.PATH = updated;
|
|
196
|
+
recordProcessEnvOriginal("PATH");
|
|
197
|
+
process.env.PATH = updated;
|
|
198
|
+
},
|
|
199
|
+
inputs: {},
|
|
200
|
+
dispatchInputs: {},
|
|
201
|
+
workflow: DEFAULT_WORKFLOW,
|
|
202
|
+
job: DEFAULT_JOB,
|
|
203
|
+
isTestRun: false,
|
|
204
|
+
secrets,
|
|
205
|
+
emit,
|
|
206
|
+
outputsOf: (ref) => resolveStepOutputs(ref),
|
|
207
|
+
jobOutputs: (ref) => resolveJobOutputs(ref),
|
|
208
|
+
setSecretOutput: () => {},
|
|
209
|
+
mktemp: (label) => temp.mktemp(label),
|
|
210
|
+
mktempFile: (label, opts) => temp.mktempFile(label, opts),
|
|
211
|
+
kici: {
|
|
212
|
+
infrastructure: { list: () => Promise.resolve({
|
|
213
|
+
scalers: [],
|
|
214
|
+
agents: []
|
|
215
|
+
}) },
|
|
216
|
+
inventory: {
|
|
217
|
+
query: () => Promise.resolve([]),
|
|
218
|
+
get: () => Promise.resolve(null)
|
|
219
|
+
},
|
|
220
|
+
oidc: { token: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.oidc.token() is not available in a test step context")) },
|
|
221
|
+
host: { requestReboot: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.host.requestReboot() is not available in a test step context")) },
|
|
222
|
+
bootstrap: {
|
|
223
|
+
ensureInitRunner: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.ensureInitRunner() is not available in a test step context")),
|
|
224
|
+
preBootSend: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.preBootSend() is not available in a test step context")),
|
|
225
|
+
agentVersionStatus: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.agentVersionStatus() is not available in a test step context")),
|
|
226
|
+
restageAgent: () => Promise.reject(/* @__PURE__ */ new Error("ctx.kici.bootstrap.restageAgent() is not available in a test step context"))
|
|
227
|
+
}
|
|
228
|
+
},
|
|
229
|
+
cache: {
|
|
230
|
+
restore: async () => ({ hit: false }),
|
|
231
|
+
save: async () => {}
|
|
232
|
+
},
|
|
233
|
+
artifacts: {
|
|
234
|
+
upload: () => Promise.reject(/* @__PURE__ */ new Error("ctx.artifacts.upload() is not available in a test step context")),
|
|
235
|
+
download: () => Promise.reject(/* @__PURE__ */ new Error("ctx.artifacts.download() is not available in a test step context"))
|
|
236
|
+
},
|
|
237
|
+
attestProvenance: () => Promise.reject(/* @__PURE__ */ new Error("ctx.attestProvenance() is not available in a test step context")),
|
|
238
|
+
...overrides,
|
|
239
|
+
env,
|
|
240
|
+
$: overrides.$ ?? scoped$
|
|
241
|
+
};
|
|
242
|
+
const dispose = async () => {
|
|
243
|
+
await disposeSecrets();
|
|
244
|
+
await temp.dispose();
|
|
245
|
+
for (const [key, original] of processEnvRestores) if (original === void 0) delete process.env[key];
|
|
246
|
+
else process.env[key] = original;
|
|
247
|
+
processEnvRestores.clear();
|
|
248
|
+
};
|
|
249
|
+
return {
|
|
250
|
+
ctx,
|
|
251
|
+
emitCalls,
|
|
252
|
+
tempScope: temp.scope,
|
|
253
|
+
dispose
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
//#endregion
|
|
257
|
+
export { createTestStepContext };
|
|
258
|
+
|
|
259
|
+
//# sourceMappingURL=step-context.js.map
|
package/dist/triggers/index.d.ts
CHANGED
|
@@ -19,12 +19,13 @@ export { watch } from './watch.js';
|
|
|
19
19
|
export { webhook } from './webhook.js';
|
|
20
20
|
export { kiciEvent } from './kici-event.js';
|
|
21
21
|
export { workflowComplete } from './workflow-complete.js';
|
|
22
|
+
export { workflowsFailedBatch } from './workflows-failed-batch.js';
|
|
22
23
|
export { jobComplete } from './job-complete.js';
|
|
23
24
|
export { genericWebhook } from './generic-webhook.js';
|
|
24
25
|
export { schedule } from './schedule.js';
|
|
25
26
|
export { lifecycle } from './lifecycle.js';
|
|
26
27
|
export { defineDispatchInputs } from './dispatch-inputs.js';
|
|
27
28
|
export type { DefinedDispatchInputs, InferDispatchInputs } from './dispatch-inputs.js';
|
|
28
|
-
export type { DispatchInputsMap, BranchPattern, BodyMatchPattern, PrEvent, PushEvent, PrTriggerConfig, PushTriggerConfig, TagTriggerConfig, CommentTriggerConfig, ReviewTriggerConfig, ReviewCommentTriggerConfig, ReleaseTriggerConfig, DispatchTriggerConfig, CreateTriggerConfig, DeleteTriggerConfig, StatusTriggerConfig, WorkflowRunTriggerConfig, ForkTriggerConfig, StarTriggerConfig, WatchTriggerConfig, WebhookTriggerConfig, TriggerConfig, PrConfigInput, PushConfigInput, TagConfigInput, CommentConfigInput, CommentAction, CommentSource, ReviewConfigInput, ReviewAction, ReviewState, ReviewCommentConfigInput, ReviewCommentAction, ReleaseConfigInput, ReleaseAction, DispatchConfigInput, CreateConfigInput, DeleteConfigInput, RefType, StatusConfigInput, StatusState, WorkflowRunConfigInput, WorkflowRunAction, ForkConfigInput, StarConfigInput, StarAction, WatchConfigInput, WatchAction, WebhookConfigInput, KiciEventConfigInput, KiciEventTriggerConfig, WorkflowCompleteConfigInput, WorkflowCompleteTriggerConfig, WorkflowCompleteStatus, JobCompleteConfigInput, JobCompleteTriggerConfig, JobCompleteStatus, GenericWebhookConfigInput, GenericWebhookTriggerConfig, GenericWebhookAuthMethod, GenericWebhookHmacAuth, GenericWebhookApiKeyAuth, GenericWebhookAuth, ScheduleConfigInput, ScheduleTriggerConfig, LifecycleEvent, LifecycleConfigInput, LifecycleTriggerConfig, } from './types.js';
|
|
29
|
+
export type { DispatchInputsMap, BranchPattern, BodyMatchPattern, PrEvent, PushEvent, PrTriggerConfig, PushTriggerConfig, TagTriggerConfig, CommentTriggerConfig, ReviewTriggerConfig, ReviewCommentTriggerConfig, ReleaseTriggerConfig, DispatchTriggerConfig, CreateTriggerConfig, DeleteTriggerConfig, StatusTriggerConfig, WorkflowRunTriggerConfig, ForkTriggerConfig, StarTriggerConfig, WatchTriggerConfig, WebhookTriggerConfig, TriggerConfig, PrConfigInput, PushConfigInput, TagConfigInput, CommentConfigInput, CommentAction, CommentSource, ReviewConfigInput, ReviewAction, ReviewState, ReviewCommentConfigInput, ReviewCommentAction, ReleaseConfigInput, ReleaseAction, DispatchConfigInput, CreateConfigInput, DeleteConfigInput, RefType, StatusConfigInput, StatusState, WorkflowRunConfigInput, WorkflowRunAction, ForkConfigInput, StarConfigInput, StarAction, WatchConfigInput, WatchAction, WebhookConfigInput, KiciEventConfigInput, KiciEventTriggerConfig, WorkflowCompleteConfigInput, WorkflowCompleteTriggerConfig, WorkflowCompleteStatus, WorkflowsFailedBatchConfigInput, WorkflowsFailedBatchTriggerConfig, JobCompleteConfigInput, JobCompleteTriggerConfig, JobCompleteStatus, GenericWebhookConfigInput, GenericWebhookTriggerConfig, GenericWebhookAuthMethod, GenericWebhookHmacAuth, GenericWebhookApiKeyAuth, GenericWebhookAuth, ScheduleConfigInput, ScheduleTriggerConfig, LifecycleEvent, LifecycleConfigInput, LifecycleTriggerConfig, } from './types.js';
|
|
29
30
|
export { DEFAULT_PR_EVENTS, toBranchPattern } from './types.js';
|
|
30
31
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/triggers/index.js
CHANGED
|
@@ -18,9 +18,10 @@ import { watch } from "./watch.js";
|
|
|
18
18
|
import { webhook } from "./webhook.js";
|
|
19
19
|
import { kiciEvent } from "./kici-event.js";
|
|
20
20
|
import { workflowComplete } from "./workflow-complete.js";
|
|
21
|
+
import { workflowsFailedBatch } from "./workflows-failed-batch.js";
|
|
21
22
|
import { jobComplete } from "./job-complete.js";
|
|
22
23
|
import { genericWebhook } from "./generic-webhook.js";
|
|
23
24
|
import { schedule } from "./schedule.js";
|
|
24
25
|
import { lifecycle } from "./lifecycle.js";
|
|
25
26
|
import { defineDispatchInputs } from "./dispatch-inputs.js";
|
|
26
|
-
export { DEFAULT_PR_EVENTS, comment, create, defineDispatchInputs, del as delete, dispatch, fork, genericWebhook, jobComplete, kiciEvent, lifecycle, pr, push, release, review, reviewComment, schedule, star, status, tag, toBranchPattern, watch, webhook, workflowComplete, workflowRun };
|
|
27
|
+
export { DEFAULT_PR_EVENTS, comment, create, defineDispatchInputs, del as delete, dispatch, fork, genericWebhook, jobComplete, kiciEvent, lifecycle, pr, push, release, review, reviewComment, schedule, star, status, tag, toBranchPattern, watch, webhook, workflowComplete, workflowRun, workflowsFailedBatch };
|
package/dist/triggers/types.d.ts
CHANGED
|
@@ -371,6 +371,28 @@ export interface WorkflowCompleteTriggerConfig {
|
|
|
371
371
|
readonly source?: string;
|
|
372
372
|
readonly description?: string;
|
|
373
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Input configuration for workflowsFailedBatch() factory function.
|
|
376
|
+
* Accumulate failed workflow completions over a window, notify once.
|
|
377
|
+
*/
|
|
378
|
+
export interface WorkflowsFailedBatchConfigInput {
|
|
379
|
+
/** Accumulation window in milliseconds; the window opens on the first failure. */
|
|
380
|
+
readonly accumulateFor: number;
|
|
381
|
+
readonly name?: string;
|
|
382
|
+
readonly source?: string;
|
|
383
|
+
readonly description?: string;
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Configuration for a workflows-failed-batch trigger.
|
|
387
|
+
*/
|
|
388
|
+
export interface WorkflowsFailedBatchTriggerConfig {
|
|
389
|
+
readonly _tag: 'WorkflowsFailedBatchTrigger';
|
|
390
|
+
/** Accumulation window in milliseconds; the window opens on the first failure. */
|
|
391
|
+
readonly accumulateFor: number;
|
|
392
|
+
readonly name?: string;
|
|
393
|
+
readonly source?: string;
|
|
394
|
+
readonly description?: string;
|
|
395
|
+
}
|
|
374
396
|
/**
|
|
375
397
|
* Valid job completion statuses.
|
|
376
398
|
*/
|
|
@@ -525,7 +547,7 @@ export interface WebhookConfigInput {
|
|
|
525
547
|
/**
|
|
526
548
|
* Union type for all trigger configurations (21 types).
|
|
527
549
|
*/
|
|
528
|
-
export type TriggerConfig = PrTriggerConfig | PushTriggerConfig | TagTriggerConfig | CommentTriggerConfig | ReviewTriggerConfig | ReviewCommentTriggerConfig | ReleaseTriggerConfig | DispatchTriggerConfig | CreateTriggerConfig | DeleteTriggerConfig | StatusTriggerConfig | WorkflowRunTriggerConfig | ForkTriggerConfig | StarTriggerConfig | WatchTriggerConfig | WebhookTriggerConfig | KiciEventTriggerConfig | WorkflowCompleteTriggerConfig | JobCompleteTriggerConfig | GenericWebhookTriggerConfig | ScheduleTriggerConfig | LifecycleTriggerConfig;
|
|
550
|
+
export type TriggerConfig = PrTriggerConfig | PushTriggerConfig | TagTriggerConfig | CommentTriggerConfig | ReviewTriggerConfig | ReviewCommentTriggerConfig | ReleaseTriggerConfig | DispatchTriggerConfig | CreateTriggerConfig | DeleteTriggerConfig | StatusTriggerConfig | WorkflowRunTriggerConfig | ForkTriggerConfig | StarTriggerConfig | WatchTriggerConfig | WebhookTriggerConfig | KiciEventTriggerConfig | WorkflowCompleteTriggerConfig | WorkflowsFailedBatchTriggerConfig | JobCompleteTriggerConfig | GenericWebhookTriggerConfig | ScheduleTriggerConfig | LifecycleTriggerConfig;
|
|
529
551
|
/**
|
|
530
552
|
* Input configuration for pr() factory function.
|
|
531
553
|
* All fields optional - sensible defaults applied.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workflows-failed-batch trigger helper.
|
|
3
|
+
*
|
|
4
|
+
* Accumulates failed workflow completions over a time window and fires the
|
|
5
|
+
* subscribing global workflow once per window with the batched run list, so a
|
|
6
|
+
* mass incident notifies a single time instead of once per failed run.
|
|
7
|
+
*/
|
|
8
|
+
import type { WorkflowsFailedBatchConfigInput, WorkflowsFailedBatchTriggerConfig } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Create a workflows-failed-batch trigger configuration.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Notify once for every burst of failures within a 10s window
|
|
14
|
+
* workflowsFailedBatch({ accumulateFor: 10000 })
|
|
15
|
+
*
|
|
16
|
+
* // Scope the batch to a named workflow and a specific source repo
|
|
17
|
+
* workflowsFailedBatch({ accumulateFor: 10000, name: 'CI', source: 'org/repo' })
|
|
18
|
+
*/
|
|
19
|
+
export declare function workflowsFailedBatch(config: WorkflowsFailedBatchConfigInput): WorkflowsFailedBatchTriggerConfig;
|
|
20
|
+
//# sourceMappingURL=workflows-failed-batch.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import "../rolldown-runtime-ClRpJifh.js";
|
|
2
|
+
//#region src/triggers/workflows-failed-batch.ts
|
|
3
|
+
/**
|
|
4
|
+
* Create a workflows-failed-batch trigger configuration.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* // Notify once for every burst of failures within a 10s window
|
|
8
|
+
* workflowsFailedBatch({ accumulateFor: 10000 })
|
|
9
|
+
*
|
|
10
|
+
* // Scope the batch to a named workflow and a specific source repo
|
|
11
|
+
* workflowsFailedBatch({ accumulateFor: 10000, name: 'CI', source: 'org/repo' })
|
|
12
|
+
*/
|
|
13
|
+
function workflowsFailedBatch(config) {
|
|
14
|
+
return Object.freeze({
|
|
15
|
+
_tag: "WorkflowsFailedBatchTrigger",
|
|
16
|
+
accumulateFor: config.accumulateFor,
|
|
17
|
+
...config.name !== void 0 && { name: config.name },
|
|
18
|
+
...config.source !== void 0 && { source: config.source },
|
|
19
|
+
...config.description !== void 0 && { description: config.description }
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { workflowsFailedBatch };
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=workflows-failed-batch.js.map
|