@kici-dev/compiler 0.1.14 → 0.1.16
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/README.md +21 -1
- package/dist/cli.d.ts +9 -1
- package/dist/cli.js +213 -179
- package/dist/commands/approve.d.ts +23 -0
- package/dist/commands/approve.js +46 -0
- package/dist/commands/compile.js +1 -1
- package/dist/commands/docs.js +2 -2
- package/dist/commands/endpoints.js +1 -1
- package/dist/commands/held-run-client.d.ts +26 -0
- package/dist/commands/held-run-client.js +98 -0
- package/dist/commands/held-run-resolve.d.ts +45 -0
- package/dist/commands/held-run-resolve.js +53 -0
- package/dist/commands/hook.js +1 -1
- package/dist/commands/index.d.ts +4 -0
- package/dist/commands/index.js +3 -1
- package/dist/commands/init.js +1 -1
- package/dist/commands/login.js +4 -15
- package/dist/commands/reject.d.ts +25 -0
- package/dist/commands/reject.js +49 -0
- package/dist/commands/run.js +13 -2
- package/dist/commands/secrets-list.js +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/test.d.ts +2 -0
- package/dist/commands/test.js +1 -1
- package/dist/commands/types.js +1 -1
- package/dist/commands/watch.js +1 -1
- package/dist/execution/executor.js +2 -2
- package/dist/execution/sdk-alias.js +1 -1
- package/dist/fixtures/compiler.js +2 -2
- package/dist/fixtures/defaults/index.js +2 -2
- package/dist/hooks/detector.js +1 -1
- package/dist/hooks/installer.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/llm-context/llms-full.txt +1141 -349
- package/dist/llm-context/llms.txt +4 -2
- package/dist/local-executor/index.js +5 -4
- package/dist/local-executor/job-runner.js +3 -5
- package/dist/local-executor/materializer.d.ts +5 -0
- package/dist/local-executor/materializer.js +23 -2
- package/dist/local-executor/secret-loader.js +1 -1
- package/dist/local-executor/to-event-payload.d.ts +16 -0
- package/dist/local-executor/to-event-payload.js +21 -0
- package/dist/local-executor/workflow-lock.d.ts +4 -3
- package/dist/local-executor/workflow-lock.js +0 -0
- package/dist/lockfile/generator.js +22 -5
- package/dist/lockfile/hash-files.js +1 -1
- package/dist/postinstall.js +1 -1
- package/dist/remote/client.d.ts +4 -0
- package/dist/remote/config.js +1 -1
- package/dist/remote/history.js +1 -1
- package/dist/remote/prod-defaults.d.ts +18 -0
- package/dist/remote/prod-defaults.js +23 -0
- package/dist/remote/secret-upload.d.ts +20 -0
- package/dist/remote/secret-upload.js +58 -0
- package/dist/remote/uploader.js +1 -1
- package/dist/templates/index.js +1 -1
- package/dist/templates/package-json.js +1 -1
- package/dist/templates/workflows/pr-checks.js +3 -2
- package/dist/templates/workflows/pr-checks.ts +4 -2
- package/dist/test-runner/git-detector.js +1 -1
- package/dist/test-runner/job-executor.js +2 -2
- package/dist/test-runner/secrets-file.js +1 -1
- package/dist/test-runner/step-context.js +6 -2
- package/dist/types.d.ts +33 -2
- package/dist/types.js +1 -0
- package/dist/workflows/pr-checks.ts +4 -2
- package/package.json +13 -9
- package/sbom.spdx.json +34 -34
|
@@ -7,7 +7,7 @@ The full markdown bundle of every page indexed here is available at https://docs
|
|
|
7
7
|
## Getting started
|
|
8
8
|
|
|
9
9
|
- [User guide](https://docs.kici.dev/user/): Writing and testing CI/CD workflows in TypeScript
|
|
10
|
-
- [Getting started with
|
|
10
|
+
- [Getting started with workflows](https://docs.kici.dev/user/getting-started/): Install the SDK, write your first workflow, compile and test locally
|
|
11
11
|
- [5-minute quickstart](https://docs.kici.dev/user/quickstart/): Stand up a KiCI orchestrator + agent and run your first workflow
|
|
12
12
|
|
|
13
13
|
## Workflow patterns
|
|
@@ -20,7 +20,9 @@ The full markdown bundle of every page indexed here is available at https://docs
|
|
|
20
20
|
|
|
21
21
|
## SDK reference
|
|
22
22
|
|
|
23
|
+
- [Caching](https://docs.kici.dev/user/sdk/caching/): Cache files and directories across runs with declarative job/step cache or the imperative ctx.cache API
|
|
23
24
|
- [SDK reference: core](https://docs.kici.dev/user/sdk/core/): Factory functions (workflow, job, step) and authoring patterns: needs, output chaining, dynamic groups
|
|
25
|
+
- [Event payload reference](https://docs.kici.dev/user/sdk/event-payloads/): Generated schema of the normalized event envelope passed to rules and dynamic functions.
|
|
24
26
|
- [SDK reference: idempotent](https://docs.kici.dev/user/sdk/idempotent/): Idempotent helpers for declarative check / apply patterns inside workflow steps
|
|
25
27
|
- [SDK reference: rules, matrix, dynamic jobs](https://docs.kici.dev/user/sdk/rules-matrix-dynamic/): rule(), skip(), matrix builds (static + dynamic), and dynamicJob / dynamicGroup
|
|
26
28
|
- [SDK reference: runtime](https://docs.kici.dev/user/sdk/runtime/): Types index, StepContext, secrets, fixtures
|
|
@@ -40,6 +42,7 @@ The full markdown bundle of every page indexed here is available at https://docs
|
|
|
40
42
|
|
|
41
43
|
## Workflow features
|
|
42
44
|
|
|
45
|
+
- [Account and sign-in](https://docs.kici.dev/user/account-and-login/): How your KiCI account relates to sign-in methods, and how to change the way you sign in.
|
|
43
46
|
- [Concurrency groups](https://docs.kici.dev/user/concurrency/): Control parallel execution with auto-cancel and queue modes
|
|
44
47
|
- [Dashboard](https://docs.kici.dev/user/dashboard/)
|
|
45
48
|
- [Dynamic values](https://docs.kici.dev/user/dynamic-values/)
|
|
@@ -58,5 +61,4 @@ The full markdown bundle of every page indexed here is available at https://docs
|
|
|
58
61
|
## Architecture overview
|
|
59
62
|
|
|
60
63
|
- [Data flows](https://docs.kici.dev/architecture/data-flows/): End-to-end data flows through the KiCI three-tier architecture
|
|
61
|
-
- [Design decisions](https://docs.kici.dev/architecture/design-decisions/): Why KiCI's architecture is shaped the way it is
|
|
62
64
|
- [Architecture overview](https://docs.kici.dev/architecture/overview/): Three-tier relay model, package structure, and component responsibilities
|
|
@@ -2,18 +2,18 @@ import "../chunk-gOLHoazu.js";
|
|
|
2
2
|
import { discoverWorkflows, resolveKiciDir } from "../execution/executor.js";
|
|
3
3
|
import "../execution/index.js";
|
|
4
4
|
import { transformTriggers } from "../lockfile/generator.js";
|
|
5
|
+
import { loadLocalSecrets } from "./secret-loader.js";
|
|
5
6
|
import { executeDag, resolveJobFilter } from "./dag-scheduler.js";
|
|
6
7
|
import { compileCommand } from "../commands/compile.js";
|
|
7
|
-
import { loadLocalSecrets } from "./secret-loader.js";
|
|
8
8
|
import { generateEventPayload } from "./payload-generator.js";
|
|
9
9
|
import { executeResolvedJob, resolveJobs } from "./job-runner.js";
|
|
10
10
|
import { displayLocalSummary, formatLocalJsonResult, formatLocalJunitResult } from "./output-streamer.js";
|
|
11
11
|
import { PickerCancelledError, runPicker } from "./picker.js";
|
|
12
|
-
import { materializeCheckout } from "./materializer.js";
|
|
12
|
+
import { gcStaleRunCheckouts, materializeCheckout } from "./materializer.js";
|
|
13
13
|
import { ConcurrencyKeyEvaluationError, acquireWorkflowLock } from "./workflow-lock.js";
|
|
14
|
+
import path from "node:path";
|
|
14
15
|
import pc from "picocolors";
|
|
15
16
|
import { writeFile } from "node:fs/promises";
|
|
16
|
-
import path from "node:path";
|
|
17
17
|
import { logger } from "@kici-dev/core";
|
|
18
18
|
import { matchAllWorkflows } from "@kici-dev/engine";
|
|
19
19
|
import os from "node:os";
|
|
@@ -107,7 +107,7 @@ async function runOneMatchedWorkflow(workflow, ctx) {
|
|
|
107
107
|
lockHandle = await acquireWorkflowLock({
|
|
108
108
|
workflowName: workflow.name,
|
|
109
109
|
workflow,
|
|
110
|
-
event
|
|
110
|
+
event,
|
|
111
111
|
branch: deriveBranchForGroupCtx(event),
|
|
112
112
|
debug: options.debug
|
|
113
113
|
});
|
|
@@ -272,6 +272,7 @@ async function executeLocal(options) {
|
|
|
272
272
|
let materialized = null;
|
|
273
273
|
let execDir = repoRoot;
|
|
274
274
|
if (!options.inPlace) {
|
|
275
|
+
await gcStaleRunCheckouts(process.env.KICI_RUN_DIR ?? os.tmpdir());
|
|
275
276
|
materialized = await materializeCheckout(repoRoot, { runDir: process.env.KICI_RUN_DIR });
|
|
276
277
|
execDir = materialized.path;
|
|
277
278
|
logger.info(pc.gray(`running in ${execDir}`));
|
|
@@ -3,8 +3,9 @@ import { ensureTsLoaderHook } from "../execution/ts-loader.js";
|
|
|
3
3
|
import { formatter } from "../test-runner/output-formatter.js";
|
|
4
4
|
import { createStepContext } from "../test-runner/step-context.js";
|
|
5
5
|
import { createRuleContext, evaluateRules as evaluateRulesWithFormatting } from "../test-runner/rule-evaluator.js";
|
|
6
|
-
import
|
|
6
|
+
import { toEventPayload } from "./to-event-payload.js";
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
8
|
+
import path from "node:path";
|
|
8
9
|
import { applyIncludeExclude, expandMatrix, isDynamicJobFn, setJobOutputsMap, setStepOutputsMap, setStepRefMap } from "@kici-dev/sdk";
|
|
9
10
|
//#region src/local-executor/job-runner.ts
|
|
10
11
|
/**
|
|
@@ -72,10 +73,7 @@ async function resolveJobs(workflow, event) {
|
|
|
72
73
|
$: (await import("zx")).$,
|
|
73
74
|
ctx: {
|
|
74
75
|
workflow: { name: workflow.name },
|
|
75
|
-
event:
|
|
76
|
-
type: event.type,
|
|
77
|
-
...event.payload
|
|
78
|
-
}
|
|
76
|
+
event: toEventPayload(event)
|
|
79
77
|
},
|
|
80
78
|
log: {
|
|
81
79
|
info: () => {},
|
|
@@ -36,4 +36,9 @@ export interface MaterializeOptions {
|
|
|
36
36
|
* @throws If `repoRoot` is not inside a git work tree
|
|
37
37
|
*/
|
|
38
38
|
export declare function materializeCheckout(repoRoot: string, opts?: MaterializeOptions): Promise<MaterializedCheckout>;
|
|
39
|
+
/**
|
|
40
|
+
* Collect stale retained checkouts under the run base. Invoked on every
|
|
41
|
+
* `kici run local`; never throws (the GC must not break the run).
|
|
42
|
+
*/
|
|
43
|
+
export declare function gcStaleRunCheckouts(base: string): Promise<string[]>;
|
|
39
44
|
//# sourceMappingURL=materializer.d.ts.map
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import "../chunk-gOLHoazu.js";
|
|
2
2
|
import { selectOverlayFiles } from "../remote/uploader.js";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
|
+
import { logger } from "@kici-dev/core";
|
|
5
6
|
import { execSync } from "node:child_process";
|
|
6
7
|
import os from "node:os";
|
|
7
8
|
import { randomBytes } from "node:crypto";
|
|
9
|
+
import { gcStaleTmpDirs } from "@kici-dev/core/tmp-gc";
|
|
8
10
|
//#region src/local-executor/materializer.ts
|
|
9
11
|
/**
|
|
10
12
|
* Materialize an isolated tmp checkout of the repo for `kici run local`.
|
|
@@ -52,6 +54,25 @@ async function materializeCheckout(repoRoot, opts) {
|
|
|
52
54
|
};
|
|
53
55
|
}
|
|
54
56
|
/**
|
|
57
|
+
* Checkouts retained for inspection (failed runs, --keep) stay around this
|
|
58
|
+
* long before the next `kici run local` invocation collects them.
|
|
59
|
+
*/
|
|
60
|
+
const RUN_CHECKOUT_GC_MAX_AGE_MS = 4320 * 60 * 1e3;
|
|
61
|
+
/** Matches the kici-run-<6 hex> dirs materializeCheckout creates — nothing else. */
|
|
62
|
+
const RUN_CHECKOUT_PATTERN = /^kici-run-[0-9a-f]{6}$/;
|
|
63
|
+
/**
|
|
64
|
+
* Collect stale retained checkouts under the run base. Invoked on every
|
|
65
|
+
* `kici run local`; never throws (the GC must not break the run).
|
|
66
|
+
*/
|
|
67
|
+
async function gcStaleRunCheckouts(base) {
|
|
68
|
+
return gcStaleTmpDirs({
|
|
69
|
+
base,
|
|
70
|
+
pattern: RUN_CHECKOUT_PATTERN,
|
|
71
|
+
maxAgeMs: RUN_CHECKOUT_GC_MAX_AGE_MS,
|
|
72
|
+
log: (m) => logger.debug(m)
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
55
76
|
* Throw an actionable error if `repoRoot` is not a git work tree.
|
|
56
77
|
*/
|
|
57
78
|
function requireGitRepo(repoRoot) {
|
|
@@ -106,6 +127,6 @@ function shellQuote(value) {
|
|
|
106
127
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
107
128
|
}
|
|
108
129
|
//#endregion
|
|
109
|
-
export { materializeCheckout };
|
|
130
|
+
export { gcStaleRunCheckouts, materializeCheckout };
|
|
110
131
|
|
|
111
132
|
//# sourceMappingURL=materializer.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../chunk-gOLHoazu.js";
|
|
2
2
|
import { loadSecretsFile } from "../test-runner/secrets-file.js";
|
|
3
|
-
import { readFile } from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { parse } from "yaml";
|
|
6
6
|
//#region src/local-executor/secret-loader.ts
|
|
7
7
|
/**
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SimulatedEvent } from '@kici-dev/engine';
|
|
2
|
+
import type { EventPayload } from '@kici-dev/sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Map a {@link SimulatedEvent} into the normalized SDK {@link EventPayload}
|
|
5
|
+
* envelope that every user-authored dynamic function (dynamic job generators,
|
|
6
|
+
* `concurrency.group()`) receives as its `event` argument.
|
|
7
|
+
*
|
|
8
|
+
* `SimulatedEvent` already carries the normalized fields (`type`, `action`,
|
|
9
|
+
* `targetBranch`, …) alongside the raw provider body under `payload`, so the
|
|
10
|
+
* single cast at this boundary is a deliberate type assertion over a
|
|
11
|
+
* structurally-identical value: it asserts the discriminated-union view
|
|
12
|
+
* without reshaping anything. Raw provider fields stay nested under
|
|
13
|
+
* `payload.<field>`; normalized fields live at the top level.
|
|
14
|
+
*/
|
|
15
|
+
export declare function toEventPayload(event: SimulatedEvent): EventPayload;
|
|
16
|
+
//# sourceMappingURL=to-event-payload.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "../chunk-gOLHoazu.js";
|
|
2
|
+
//#region src/local-executor/to-event-payload.ts
|
|
3
|
+
/**
|
|
4
|
+
* Map a {@link SimulatedEvent} into the normalized SDK {@link EventPayload}
|
|
5
|
+
* envelope that every user-authored dynamic function (dynamic job generators,
|
|
6
|
+
* `concurrency.group()`) receives as its `event` argument.
|
|
7
|
+
*
|
|
8
|
+
* `SimulatedEvent` already carries the normalized fields (`type`, `action`,
|
|
9
|
+
* `targetBranch`, …) alongside the raw provider body under `payload`, so the
|
|
10
|
+
* single cast at this boundary is a deliberate type assertion over a
|
|
11
|
+
* structurally-identical value: it asserts the discriminated-union view
|
|
12
|
+
* without reshaping anything. Raw provider fields stay nested under
|
|
13
|
+
* `payload.<field>`; normalized fields live at the top level.
|
|
14
|
+
*/
|
|
15
|
+
function toEventPayload(event) {
|
|
16
|
+
return event;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { toEventPayload };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=to-event-payload.js.map
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* `os.tmpdir()/kici-local-locks-<uid>/`).
|
|
21
21
|
*/
|
|
22
22
|
import type { Workflow } from '@kici-dev/sdk';
|
|
23
|
+
import type { SimulatedEvent } from '@kici-dev/engine';
|
|
23
24
|
/** Sidecar metadata persisted next to the lock dir for diagnostics + reclamation. */
|
|
24
25
|
export interface LockHolderMetadata {
|
|
25
26
|
pid: number;
|
|
@@ -35,8 +36,8 @@ export interface WorkflowLockHandle {
|
|
|
35
36
|
export interface AcquireWorkflowLockOptions {
|
|
36
37
|
workflowName: string;
|
|
37
38
|
workflow: Workflow;
|
|
38
|
-
/** The simulated
|
|
39
|
-
event:
|
|
39
|
+
/** The simulated event mapped to the normalized envelope passed as `groupCtx.event`. */
|
|
40
|
+
event: SimulatedEvent;
|
|
40
41
|
/** Branch derived from the simulated event for `groupCtx.branch`. */
|
|
41
42
|
branch: string;
|
|
42
43
|
debug?: boolean;
|
|
@@ -68,7 +69,7 @@ export declare function resolveLockDir(): Promise<string>;
|
|
|
68
69
|
* Returns `null` when the workflow has no `concurrency` block. Throws
|
|
69
70
|
* {@link ConcurrencyKeyEvaluationError} when the group function throws or rejects.
|
|
70
71
|
*/
|
|
71
|
-
export declare function resolveConcurrencyKey(workflow: Workflow, event:
|
|
72
|
+
export declare function resolveConcurrencyKey(workflow: Workflow, event: SimulatedEvent, branch: string): Promise<string | null>;
|
|
72
73
|
/**
|
|
73
74
|
* Acquire the workflow-level concurrency lock for a `kici run local` invocation.
|
|
74
75
|
*
|
|
Binary file
|
|
@@ -3,9 +3,9 @@ import { SCHEMA_VERSION as SCHEMA_VERSION$1 } from "../types.js";
|
|
|
3
3
|
import { computeContentHash } from "./hasher.js";
|
|
4
4
|
import { resolveHashFiles } from "./hash-files.js";
|
|
5
5
|
import { analyzePurity } from "./purity-analyzer.js";
|
|
6
|
-
import { readFileSync } from "node:fs";
|
|
7
6
|
import path from "node:path";
|
|
8
|
-
import {
|
|
7
|
+
import { readFileSync } from "node:fs";
|
|
8
|
+
import { getDynamicJobGroup, isDynamicFunction, isDynamicGroupRef, isDynamicJobFn, isStaticArray, isStaticObject, normalizeCacheSpecs, normalizeRequireApproval } from "@kici-dev/sdk";
|
|
9
9
|
import { sha256 } from "@kici-dev/core";
|
|
10
10
|
import { PackageManager, detectPackageManagerSync } from "@kici-dev/core/package-manager";
|
|
11
11
|
import { validateResourceRequest } from "@kici-dev/engine";
|
|
@@ -151,7 +151,9 @@ function transformWorkflow(workflow, sourceFile, exportRef, bundleSource, gitRoo
|
|
|
151
151
|
hasGroup: !!workflow.concurrency.group,
|
|
152
152
|
...workflow.concurrency.cancelInProgress !== void 0 && { cancelInProgress: workflow.concurrency.cancelInProgress },
|
|
153
153
|
...workflow.concurrency.max !== void 0 && { max: workflow.concurrency.max }
|
|
154
|
-
} }
|
|
154
|
+
} },
|
|
155
|
+
...workflow.timeout !== void 0 && { timeout: workflow.timeout },
|
|
156
|
+
...workflow.requireApproval !== void 0 && { approval: toLockApproval(workflow.requireApproval) }
|
|
155
157
|
};
|
|
156
158
|
}
|
|
157
159
|
/**
|
|
@@ -528,6 +530,7 @@ function transformJob(job, configPath, index, gitRoot, uuidToName) {
|
|
|
528
530
|
rules: job.rules ? transformRules(job.rules, configPath, index) : void 0,
|
|
529
531
|
description: job.description,
|
|
530
532
|
...job.checkout !== void 0 && { checkout: job.checkout },
|
|
533
|
+
...job.cache !== void 0 && { cache: normalizeCacheSpecs(job.cache) },
|
|
531
534
|
...job.container !== void 0 && { container: job.container },
|
|
532
535
|
...environmentFields,
|
|
533
536
|
...envFields,
|
|
@@ -539,7 +542,10 @@ function transformJob(job, configPath, index, gitRoot, uuidToName) {
|
|
|
539
542
|
...job.beforeStep !== void 0 && { hasBeforeStep: true },
|
|
540
543
|
...job.afterStep !== void 0 && { hasAfterStep: true },
|
|
541
544
|
...job.gracePeriod !== void 0 && { gracePeriod: job.gracePeriod },
|
|
542
|
-
...job.
|
|
545
|
+
...job.timeout !== void 0 && { timeout: job.timeout },
|
|
546
|
+
...job.resources !== void 0 && { resources: job.resources },
|
|
547
|
+
...job.init !== void 0 && { init: job.init },
|
|
548
|
+
...job.requireApproval !== void 0 && { approval: toLockApproval(job.requireApproval) }
|
|
543
549
|
};
|
|
544
550
|
}
|
|
545
551
|
/**
|
|
@@ -587,6 +593,15 @@ function resolveNeedsForLock(needs, uuidToName) {
|
|
|
587
593
|
* Assigns counter-based IDs to unnamed steps (bare functions and id-less steps).
|
|
588
594
|
* Counter only increments for unnamed entries; named steps keep their names.
|
|
589
595
|
*/
|
|
596
|
+
/** Map an SDK `requireApproval` to the normalized lock `approval` block. */
|
|
597
|
+
function toLockApproval(r) {
|
|
598
|
+
const n = normalizeRequireApproval(r);
|
|
599
|
+
return {
|
|
600
|
+
clauses: n.clauses,
|
|
601
|
+
...n.reason !== void 0 && { reason: n.reason },
|
|
602
|
+
...n.timeoutSeconds !== void 0 && { timeoutSeconds: n.timeoutSeconds }
|
|
603
|
+
};
|
|
604
|
+
}
|
|
590
605
|
function transformSteps(steps, gitRoot) {
|
|
591
606
|
let stepCounter = 0;
|
|
592
607
|
return steps.map((stepOrFn) => {
|
|
@@ -603,6 +618,7 @@ function transformSteps(steps, gitRoot) {
|
|
|
603
618
|
hasOutputs: !!step.outputs && Object.keys(step.outputs).length > 0,
|
|
604
619
|
...step.continueOnError !== void 0 && { continueOnError: step.continueOnError },
|
|
605
620
|
...step.timeout !== void 0 && { timeout: step.timeout },
|
|
621
|
+
...step.cache !== void 0 && { cache: normalizeCacheSpecs(step.cache) },
|
|
606
622
|
...step._sourceLocation && { sourceLocation: {
|
|
607
623
|
file: makeRelativePath(step._sourceLocation.file, gitRoot),
|
|
608
624
|
line: step._sourceLocation.line,
|
|
@@ -613,7 +629,8 @@ function transformSteps(steps, gitRoot) {
|
|
|
613
629
|
rules: transformRules(step.rules, makeRelativePath(step._sourceLocation?.file ?? "", gitRoot))
|
|
614
630
|
},
|
|
615
631
|
...step.onCancel !== void 0 && { hasOnCancel: true },
|
|
616
|
-
...step.cleanup !== void 0 && { hasCleanup: true }
|
|
632
|
+
...step.cleanup !== void 0 && { hasCleanup: true },
|
|
633
|
+
...step.requireApproval !== void 0 && { approval: toLockApproval(step.requireApproval) }
|
|
617
634
|
};
|
|
618
635
|
});
|
|
619
636
|
}
|
package/dist/postinstall.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import "./chunk-gOLHoazu.js";
|
|
3
|
-
import { readFile } from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
import { confirm } from "@inquirer/prompts";
|
|
7
7
|
//#region src/postinstall.ts
|
package/dist/remote/client.d.ts
CHANGED
|
@@ -33,6 +33,10 @@ export interface TestTriggerInput {
|
|
|
33
33
|
/** CLI's ephemeral public key (base64, SPKI/DER) for overlay decryption */
|
|
34
34
|
cliPublicKey?: string;
|
|
35
35
|
secrets?: Record<string, string>;
|
|
36
|
+
/** Base64 X25519+AES-GCM blob of the developer's local secrets ({flat, contexts}). */
|
|
37
|
+
encryptedSecrets?: string;
|
|
38
|
+
/** Base64 ephemeral CLI public key that encrypted `encryptedSecrets`. */
|
|
39
|
+
encryptedSecretsKey?: string;
|
|
36
40
|
workflowName?: string;
|
|
37
41
|
/** JSON-stringified lock file content for repos with no remote. */
|
|
38
42
|
inlineLockFile?: string;
|
package/dist/remote/config.js
CHANGED
package/dist/remote/history.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "../chunk-gOLHoazu.js";
|
|
2
2
|
import { formatRelativeTime } from "../format.js";
|
|
3
3
|
import { getConfigDir } from "./config.js";
|
|
4
|
+
import path from "node:path";
|
|
4
5
|
import pc from "picocolors";
|
|
5
6
|
import fs from "node:fs/promises";
|
|
6
|
-
import path from "node:path";
|
|
7
7
|
import { formatDuration } from "@kici-dev/core";
|
|
8
8
|
import picomatch from "picomatch";
|
|
9
9
|
//#region src/remote/history.ts
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production defaults for the `kici login` OAuth flow. When the matching
|
|
3
|
+
* env var (or the `--platform-endpoint` flag) is unset, login resolves
|
|
4
|
+
* these so a developer targeting the hosted KiCI Platform authenticates
|
|
5
|
+
* with no setup. Setting the env var overrides the default — staging E2E
|
|
6
|
+
* and self-hosted Platforms depend on that override path.
|
|
7
|
+
*
|
|
8
|
+
* Resolution is login-local: these are read into locals in `oauthLogin`,
|
|
9
|
+
* never written back into `process.env`, so the orchestrator's separate
|
|
10
|
+
* `wss://…/ws` meaning of `KICI_PLATFORM_URL` is unaffected.
|
|
11
|
+
*/
|
|
12
|
+
/** Platform API base URL — login POSTs to `${value}/api/v1/cli/exchange-token`. */
|
|
13
|
+
export declare const PROD_PLATFORM_URL = "https://api.kici.dev";
|
|
14
|
+
/** OIDC issuer for the hosted Platform's Keycloak realm. */
|
|
15
|
+
export declare const PROD_OIDC_ISSUER = "https://auth.kici.dev/realms/kici-internal";
|
|
16
|
+
/** Public OIDC client id registered for the `kici` CLI. */
|
|
17
|
+
export declare const PROD_OIDC_CLIENT_ID = "kici-cli";
|
|
18
|
+
//# sourceMappingURL=prod-defaults.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import "../chunk-gOLHoazu.js";
|
|
2
|
+
//#region src/remote/prod-defaults.ts
|
|
3
|
+
/**
|
|
4
|
+
* Production defaults for the `kici login` OAuth flow. When the matching
|
|
5
|
+
* env var (or the `--platform-endpoint` flag) is unset, login resolves
|
|
6
|
+
* these so a developer targeting the hosted KiCI Platform authenticates
|
|
7
|
+
* with no setup. Setting the env var overrides the default — staging E2E
|
|
8
|
+
* and self-hosted Platforms depend on that override path.
|
|
9
|
+
*
|
|
10
|
+
* Resolution is login-local: these are read into locals in `oauthLogin`,
|
|
11
|
+
* never written back into `process.env`, so the orchestrator's separate
|
|
12
|
+
* `wss://…/ws` meaning of `KICI_PLATFORM_URL` is unaffected.
|
|
13
|
+
*/
|
|
14
|
+
/** Platform API base URL — login POSTs to `${value}/api/v1/cli/exchange-token`. */
|
|
15
|
+
const PROD_PLATFORM_URL = "https://api.kici.dev";
|
|
16
|
+
/** OIDC issuer for the hosted Platform's Keycloak realm. */
|
|
17
|
+
const PROD_OIDC_ISSUER = "https://auth.kici.dev/realms/kici-internal";
|
|
18
|
+
/** Public OIDC client id registered for the `kici` CLI. */
|
|
19
|
+
const PROD_OIDC_CLIENT_ID = "kici-cli";
|
|
20
|
+
//#endregion
|
|
21
|
+
export { PROD_OIDC_CLIENT_ID, PROD_OIDC_ISSUER, PROD_PLATFORM_URL };
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=prod-defaults.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse `--context ctx.key=value` flag values into a nested
|
|
3
|
+
* `{ context: { key: value } }` map. The first `.` splits the context name
|
|
4
|
+
* from `key=value`; the first `=` splits key from value (values may contain
|
|
5
|
+
* `=`). Malformed entries (missing `.` or `=`, empty context/key) are skipped.
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseContextFlags(flags: string[] | undefined): Record<string, Record<string, string>>;
|
|
8
|
+
/**
|
|
9
|
+
* Load the developer's local secrets (same sources as `kici run local`: the
|
|
10
|
+
* `.kici` secret files plus `--env` flat flags) and `--context` namespaced
|
|
11
|
+
* flags, and encrypt them to the orchestrator's per-upload X25519 public key.
|
|
12
|
+
* `--context` values override `.kici/.secrets` file contexts for the same key.
|
|
13
|
+
* Returns the base64 ciphertext and the ephemeral CLI public key the
|
|
14
|
+
* orchestrator needs to decrypt, or null when there is nothing to send.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildEncryptedSecrets(kiciDir: string, envFlags: string[] | undefined, contextFlags: string[] | undefined, orchestratorPublicKeyB64: string): Promise<{
|
|
17
|
+
encryptedSecrets: string;
|
|
18
|
+
cliPublicKey: string;
|
|
19
|
+
} | null>;
|
|
20
|
+
//# sourceMappingURL=secret-upload.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import "../chunk-gOLHoazu.js";
|
|
2
|
+
import { loadLocalSecrets } from "../local-executor/secret-loader.js";
|
|
3
|
+
import { encryptJson } from "@kici-dev/core";
|
|
4
|
+
//#region src/remote/secret-upload.ts
|
|
5
|
+
/**
|
|
6
|
+
* Parse `--context ctx.key=value` flag values into a nested
|
|
7
|
+
* `{ context: { key: value } }` map. The first `.` splits the context name
|
|
8
|
+
* from `key=value`; the first `=` splits key from value (values may contain
|
|
9
|
+
* `=`). Malformed entries (missing `.` or `=`, empty context/key) are skipped.
|
|
10
|
+
*/
|
|
11
|
+
function parseContextFlags(flags) {
|
|
12
|
+
const contexts = {};
|
|
13
|
+
for (const flag of flags ?? []) {
|
|
14
|
+
const dotIndex = flag.indexOf(".");
|
|
15
|
+
if (dotIndex === -1) continue;
|
|
16
|
+
const contextName = flag.slice(0, dotIndex).trim();
|
|
17
|
+
const rest = flag.slice(dotIndex + 1);
|
|
18
|
+
const eqIndex = rest.indexOf("=");
|
|
19
|
+
if (eqIndex === -1) continue;
|
|
20
|
+
const key = rest.slice(0, eqIndex).trim();
|
|
21
|
+
const value = rest.slice(eqIndex + 1).trim();
|
|
22
|
+
if (!contextName || !key) continue;
|
|
23
|
+
(contexts[contextName] ??= {})[key] = value;
|
|
24
|
+
}
|
|
25
|
+
return contexts;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load the developer's local secrets (same sources as `kici run local`: the
|
|
29
|
+
* `.kici` secret files plus `--env` flat flags) and `--context` namespaced
|
|
30
|
+
* flags, and encrypt them to the orchestrator's per-upload X25519 public key.
|
|
31
|
+
* `--context` values override `.kici/.secrets` file contexts for the same key.
|
|
32
|
+
* Returns the base64 ciphertext and the ephemeral CLI public key the
|
|
33
|
+
* orchestrator needs to decrypt, or null when there is nothing to send.
|
|
34
|
+
*/
|
|
35
|
+
async function buildEncryptedSecrets(kiciDir, envFlags, contextFlags, orchestratorPublicKeyB64) {
|
|
36
|
+
const local = await loadLocalSecrets(kiciDir, envFlags);
|
|
37
|
+
const contexts = {};
|
|
38
|
+
for (const [ctxName, vals] of Object.entries(local.contexts)) contexts[ctxName] = { ...vals };
|
|
39
|
+
for (const [ctxName, vals] of Object.entries(parseContextFlags(contextFlags))) contexts[ctxName] = {
|
|
40
|
+
...contexts[ctxName] ?? {},
|
|
41
|
+
...vals
|
|
42
|
+
};
|
|
43
|
+
const hasFlat = Object.keys(local.flat).length > 0;
|
|
44
|
+
const hasContexts = Object.values(contexts).some((c) => Object.keys(c).length > 0);
|
|
45
|
+
if (!hasFlat && !hasContexts) return null;
|
|
46
|
+
const { ciphertextB64, senderPublicKeyB64 } = encryptJson({
|
|
47
|
+
flat: local.flat,
|
|
48
|
+
contexts
|
|
49
|
+
}, Buffer.from(orchestratorPublicKeyB64, "base64"));
|
|
50
|
+
return {
|
|
51
|
+
encryptedSecrets: ciphertextB64,
|
|
52
|
+
cliPublicKey: senderPublicKeyB64
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//#endregion
|
|
56
|
+
export { buildEncryptedSecrets, parseContextFlags };
|
|
57
|
+
|
|
58
|
+
//# sourceMappingURL=secret-upload.js.map
|
package/dist/remote/uploader.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../chunk-gOLHoazu.js";
|
|
2
2
|
import { encryptTarball } from "./encryption.js";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
3
|
import path from "node:path";
|
|
4
|
+
import fs from "node:fs/promises";
|
|
5
5
|
import { formatBytes, sha256, sha256File } from "@kici-dev/core";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
7
|
import os from "node:os";
|
package/dist/templates/index.js
CHANGED
|
@@ -4,8 +4,8 @@ import { helloWorldWorkflow } from "./workflows/hello-world.js";
|
|
|
4
4
|
import { prChecksWorkflow } from "./workflows/pr-checks.js";
|
|
5
5
|
import { tsconfigTemplate } from "./tsconfig-json.js";
|
|
6
6
|
import { generatePackageJson } from "./package-json.js";
|
|
7
|
-
import path from "node:path";
|
|
8
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
import path from "node:path";
|
|
9
9
|
//#region src/templates/index.ts
|
|
10
10
|
/**
|
|
11
11
|
* Template aggregator for kici init command
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "../../chunk-gOLHoazu.js";
|
|
2
|
-
import { job, pr, rule, skip, step, workflow } from "@kici-dev/sdk";
|
|
2
|
+
import { isEventType, job, pr, rule, skip, step, workflow } from "@kici-dev/sdk";
|
|
3
3
|
//#region src/templates/workflows/pr-checks.ts
|
|
4
4
|
const prChecksWorkflow = workflow("pr-checks", {
|
|
5
5
|
on: pr({
|
|
@@ -7,7 +7,8 @@ const prChecksWorkflow = workflow("pr-checks", {
|
|
|
7
7
|
paths: ["src/**"]
|
|
8
8
|
}),
|
|
9
9
|
rules: [skip("skip-draft-prs", async (ctx) => {
|
|
10
|
-
|
|
10
|
+
if (!isEventType(ctx.event, "pull_request")) return false;
|
|
11
|
+
return ctx.event.payload.pull_request.draft === true;
|
|
11
12
|
}), rule("require-src-changes", async (ctx) => {
|
|
12
13
|
return ctx.changedFiles.some((file) => file.startsWith("src/"));
|
|
13
14
|
})],
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Docs: https://kici.dev/docs/sdk-reference
|
|
3
3
|
// Patterns: https://kici.dev/docs/workflow-patterns
|
|
4
4
|
|
|
5
|
-
import { workflow, job, step, pr, rule, skip } from '@kici-dev/sdk';
|
|
5
|
+
import { workflow, job, step, pr, rule, skip, isEventType } from '@kici-dev/sdk';
|
|
6
6
|
|
|
7
7
|
export const prChecksWorkflow = workflow('pr-checks', {
|
|
8
8
|
// Trigger: pr() matches pull request events
|
|
@@ -13,7 +13,9 @@ export const prChecksWorkflow = workflow('pr-checks', {
|
|
|
13
13
|
// skip() = skip if true, rule() = run only if true
|
|
14
14
|
rules: [
|
|
15
15
|
skip('skip-draft-prs', async (ctx) => {
|
|
16
|
-
|
|
16
|
+
// Raw provider fields live under `ctx.event.payload`; narrow first for typing.
|
|
17
|
+
if (!isEventType(ctx.event, 'pull_request')) return false;
|
|
18
|
+
return ctx.event.payload.pull_request.draft === true;
|
|
17
19
|
}),
|
|
18
20
|
|
|
19
21
|
rule('require-src-changes', async (ctx) => {
|
|
@@ -2,9 +2,9 @@ import "../chunk-gOLHoazu.js";
|
|
|
2
2
|
import { formatter } from "./output-formatter.js";
|
|
3
3
|
import { createStepContext } from "./step-context.js";
|
|
4
4
|
import { createRuleContext, evaluateRules as evaluateRulesWithFormatting } from "./rule-evaluator.js";
|
|
5
|
-
import pc from "picocolors";
|
|
6
|
-
import path from "node:path";
|
|
7
5
|
import { pathToFileURL } from "node:url";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import pc from "picocolors";
|
|
8
8
|
import { setJobOutputsMap, setStepOutputsMap, setStepRefMap } from "@kici-dev/sdk";
|
|
9
9
|
import { logger } from "@kici-dev/core";
|
|
10
10
|
//#region src/test-runner/job-executor.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "../chunk-gOLHoazu.js";
|
|
2
2
|
import { formatter } from "./output-formatter.js";
|
|
3
|
-
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { createStepSecrets, resolveJobOutputs, resolveStepOutputs } from "@kici-dev/sdk";
|
|
6
6
|
import { initZx } from "@kici-dev/core";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
@@ -131,7 +131,11 @@ function createStepContext(workflowInfo, jobInfo, repoRoot, inputs = {}, matrix,
|
|
|
131
131
|
kici: { infrastructure: { list: () => Promise.resolve({
|
|
132
132
|
scalers: [],
|
|
133
133
|
agents: []
|
|
134
|
-
}) } }
|
|
134
|
+
}) } },
|
|
135
|
+
cache: {
|
|
136
|
+
restore: async () => ({ hit: false }),
|
|
137
|
+
save: async () => {}
|
|
138
|
+
}
|
|
135
139
|
};
|
|
136
140
|
}
|
|
137
141
|
//#endregion
|