@mannyc1/ts-release 0.0.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/README.md +249 -0
- package/SPEC.md +254 -0
- package/dist/cli/command.d.ts +4 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +90 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +12 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/programmatic.d.ts +25 -0
- package/dist/cli/programmatic.d.ts.map +1 -0
- package/dist/cli/programmatic.js +48 -0
- package/dist/cli/programmatic.js.map +1 -0
- package/dist/config/errors.d.ts +23 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +18 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/load.d.ts +9 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +27 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/schema.d.ts +8 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +6 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/domain/artifact.d.ts +36 -0
- package/dist/domain/artifact.d.ts.map +1 -0
- package/dist/domain/artifact.js +29 -0
- package/dist/domain/artifact.js.map +1 -0
- package/dist/domain/evidence.d.ts +58 -0
- package/dist/domain/evidence.d.ts.map +1 -0
- package/dist/domain/evidence.js +50 -0
- package/dist/domain/evidence.js.map +1 -0
- package/dist/domain/operation.d.ts +98 -0
- package/dist/domain/operation.d.ts.map +1 -0
- package/dist/domain/operation.js +133 -0
- package/dist/domain/operation.js.map +1 -0
- package/dist/domain/release.d.ts +66 -0
- package/dist/domain/release.d.ts.map +1 -0
- package/dist/domain/release.js +56 -0
- package/dist/domain/release.js.map +1 -0
- package/dist/domain/target.d.ts +75 -0
- package/dist/domain/target.d.ts.map +1 -0
- package/dist/domain/target.js +67 -0
- package/dist/domain/target.js.map +1 -0
- package/dist/host/bun.d.ts +9 -0
- package/dist/host/bun.d.ts.map +1 -0
- package/dist/host/bun.js +156 -0
- package/dist/host/bun.js.map +1 -0
- package/dist/host/host.d.ts +47 -0
- package/dist/host/host.d.ts.map +1 -0
- package/dist/host/host.js +42 -0
- package/dist/host/host.js.map +1 -0
- package/dist/host/test.d.ts +19 -0
- package/dist/host/test.d.ts.map +1 -0
- package/dist/host/test.js +76 -0
- package/dist/host/test.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/planner/create-release-plan.d.ts +5 -0
- package/dist/planner/create-release-plan.d.ts.map +1 -0
- package/dist/planner/create-release-plan.js +25 -0
- package/dist/planner/create-release-plan.js.map +1 -0
- package/dist/planner/errors.d.ts +37 -0
- package/dist/planner/errors.d.ts.map +1 -0
- package/dist/planner/errors.js +30 -0
- package/dist/planner/errors.js.map +1 -0
- package/dist/planner/evidence-recorder.d.ts +18 -0
- package/dist/planner/evidence-recorder.d.ts.map +1 -0
- package/dist/planner/evidence-recorder.js +95 -0
- package/dist/planner/evidence-recorder.js.map +1 -0
- package/dist/planner/executor.d.ts +19 -0
- package/dist/planner/executor.d.ts.map +1 -0
- package/dist/planner/executor.js +59 -0
- package/dist/planner/executor.js.map +1 -0
- package/dist/planner/normalize-release.d.ts +7 -0
- package/dist/planner/normalize-release.d.ts.map +1 -0
- package/dist/planner/normalize-release.js +101 -0
- package/dist/planner/normalize-release.js.map +1 -0
- package/dist/planner/render-plan.d.ts +5 -0
- package/dist/planner/render-plan.d.ts.map +1 -0
- package/dist/planner/render-plan.js +49 -0
- package/dist/planner/render-plan.js.map +1 -0
- package/dist/targets/adapter.d.ts +15 -0
- package/dist/targets/adapter.d.ts.map +1 -0
- package/dist/targets/adapter.js +2 -0
- package/dist/targets/adapter.js.map +1 -0
- package/dist/targets/github.d.ts +11 -0
- package/dist/targets/github.d.ts.map +1 -0
- package/dist/targets/github.js +174 -0
- package/dist/targets/github.js.map +1 -0
- package/dist/targets/homebrew.d.ts +11 -0
- package/dist/targets/homebrew.d.ts.map +1 -0
- package/dist/targets/homebrew.js +153 -0
- package/dist/targets/homebrew.js.map +1 -0
- package/dist/targets/live.d.ts +5 -0
- package/dist/targets/live.d.ts.map +1 -0
- package/dist/targets/live.js +31 -0
- package/dist/targets/live.js.map +1 -0
- package/dist/targets/npm.d.ts +11 -0
- package/dist/targets/npm.d.ts.map +1 -0
- package/dist/targets/npm.js +105 -0
- package/dist/targets/npm.js.map +1 -0
- package/dist/targets/registry.d.ts +25 -0
- package/dist/targets/registry.d.ts.map +1 -0
- package/dist/targets/registry.js +34 -0
- package/dist/targets/registry.js.map +1 -0
- package/dist/types/effect-internal.d.ts +5 -0
- package/dist/types/effect-internal.d.ts.map +1 -0
- package/dist/types/effect-internal.js +2 -0
- package/dist/types/effect-internal.js.map +1 -0
- package/examples/README.md +15 -0
- package/examples/github-release/artifacts/release-example-github-0.1.0.tgz +1 -0
- package/examples/github-release/release.config.json +31 -0
- package/examples/homebrew-tap/artifacts/release-example-homebrew-0.1.0.tgz +1 -0
- package/examples/homebrew-tap/release.config.json +34 -0
- package/examples/non-strict-skips/artifacts/release-example-skips-0.1.0.tgz +1 -0
- package/examples/non-strict-skips/release.config.json +29 -0
- package/examples/npm-only/index.js +1 -0
- package/examples/npm-only/package.json +8 -0
- package/examples/npm-only/release.config.json +30 -0
- package/package.json +176 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Layer from "effect/Layer";
|
|
3
|
+
import { CommandResult, FileInfo, HostError, ReleaseHost } from "./host.js";
|
|
4
|
+
export const commandKey = (command) => [command.executable, ...command.args].join("\u0000");
|
|
5
|
+
const checksumPrefix = (algorithm) => algorithm === "sha256" ? "sha256" : "sha512";
|
|
6
|
+
export const makeTestReleaseHostLayer = (options = {}) => {
|
|
7
|
+
const files = new Map(options.files ?? []);
|
|
8
|
+
const directories = new Set(options.directories ?? []);
|
|
9
|
+
const env = new Map(options.env ?? []);
|
|
10
|
+
const commands = new Map(options.commands ?? []);
|
|
11
|
+
const timestamps = [...(options.timestamps ?? ["2026-06-16T00:00:00.000Z"])];
|
|
12
|
+
let timestampIndex = 0;
|
|
13
|
+
const nextTimestamp = () => {
|
|
14
|
+
const value = timestamps[timestampIndex] ?? timestamps[timestamps.length - 1] ?? "2026-06-16T00:00:00.000Z";
|
|
15
|
+
timestampIndex += 1;
|
|
16
|
+
return value;
|
|
17
|
+
};
|
|
18
|
+
return Layer.succeed(ReleaseHost)({
|
|
19
|
+
readFileString: (path) => Effect.sync(() => files.get(path)).pipe(Effect.flatMap((contents) => contents === undefined
|
|
20
|
+
? Effect.fail(HostError.make({ operation: "readFileString", path, reason: "File not found" }))
|
|
21
|
+
: Effect.succeed(contents))),
|
|
22
|
+
writeFileString: (path, contents) => Effect.sync(() => {
|
|
23
|
+
files.set(path, contents);
|
|
24
|
+
}),
|
|
25
|
+
stat: (path) => Effect.sync(() => {
|
|
26
|
+
const contents = files.get(path);
|
|
27
|
+
if (contents !== undefined) {
|
|
28
|
+
return FileInfo.make({ path, sizeBytes: contents.length, kind: "file" });
|
|
29
|
+
}
|
|
30
|
+
if (directories.has(path)) {
|
|
31
|
+
return FileInfo.make({ path, sizeBytes: 0, kind: "directory" });
|
|
32
|
+
}
|
|
33
|
+
return undefined;
|
|
34
|
+
}).pipe(Effect.flatMap((info) => info === undefined
|
|
35
|
+
? Effect.fail(HostError.make({ operation: "stat", path, reason: "File not found" }))
|
|
36
|
+
: Effect.succeed(info))),
|
|
37
|
+
hashFile: (path, algorithm) => Effect.sync(() => files.get(path)).pipe(Effect.flatMap((contents) => directories.has(path)
|
|
38
|
+
? Effect.fail(HostError.make({ operation: "hashFile", path, reason: "Only file artifacts can be hashed" }))
|
|
39
|
+
: contents === undefined
|
|
40
|
+
? Effect.fail(HostError.make({ operation: "hashFile", path, reason: "File not found" }))
|
|
41
|
+
: Effect.succeed(`${checksumPrefix(algorithm)}:${contents.length}:${path}`))),
|
|
42
|
+
readEnv: (name) => Effect.sync(() => env.get(name)),
|
|
43
|
+
runCommand: (command) => Effect.gen(function* () {
|
|
44
|
+
const missing = [];
|
|
45
|
+
for (const name of command.requiredEnv) {
|
|
46
|
+
if (!env.has(name)) {
|
|
47
|
+
missing.push(name);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (missing.length > 0) {
|
|
51
|
+
return yield* Effect.fail(HostError.make({
|
|
52
|
+
operation: "runCommand",
|
|
53
|
+
reason: `Missing required environment variables: ${missing.join(", ")}`
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
const startedAt = nextTimestamp();
|
|
57
|
+
const endedAt = nextTimestamp();
|
|
58
|
+
const response = commands.get(commandKey(command)) ?? {
|
|
59
|
+
exitCode: 0,
|
|
60
|
+
stdout: "",
|
|
61
|
+
stderr: ""
|
|
62
|
+
};
|
|
63
|
+
return CommandResult.make({
|
|
64
|
+
command,
|
|
65
|
+
exitCode: response.exitCode,
|
|
66
|
+
stdout: response.stdout,
|
|
67
|
+
stderr: response.stderr,
|
|
68
|
+
startedAt,
|
|
69
|
+
endedAt,
|
|
70
|
+
durationMillis: 0
|
|
71
|
+
});
|
|
72
|
+
}),
|
|
73
|
+
now: Effect.sync(nextTimestamp)
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/host/test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { ReleaseIntent, ReleasePlan } from "../domain/release.js";
|
|
3
|
+
export type * from "../types/effect-internal.js";
|
|
4
|
+
export declare const createReleasePlan: (intent: ReleaseIntent, root?: string | undefined, configPath?: string | undefined) => Effect.Effect<ReleasePlan, import("./errors.js").ReleaseNormalizationError | import("./errors.js").PlanConstructionError | import("../targets/registry.js").MissingTargetAdapterError, import("../host/host.js").ReleaseHost | import("../targets/registry.js").TargetRegistry>;
|
|
5
|
+
//# sourceMappingURL=create-release-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-release-plan.d.ts","sourceRoot":"","sources":["../../src/planner/create-release-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAmB,aAAa,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAIlF,mBAAmB,6BAA6B,CAAA;AAEhD,eAAO,MAAM,iBAAiB,wWAuB5B,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { operationOrder } from "../domain/operation.js";
|
|
3
|
+
import { PlannerMetadata, ReleasePlan } from "../domain/release.js";
|
|
4
|
+
import { allTargetCapabilities, planAllTargetOperations } from "../targets/registry.js";
|
|
5
|
+
import { normalizeReleaseIntent } from "./normalize-release.js";
|
|
6
|
+
export const createReleasePlan = Effect.fn("createReleasePlan")(function* (intent, root = ".", configPath = undefined) {
|
|
7
|
+
const model = yield* normalizeReleaseIntent(intent, root, configPath);
|
|
8
|
+
const targetCapabilities = yield* allTargetCapabilities(model);
|
|
9
|
+
const operations = yield* planAllTargetOperations(model);
|
|
10
|
+
return ReleasePlan.make({
|
|
11
|
+
schemaVersion: "release-plan/v1",
|
|
12
|
+
identity: model.identity,
|
|
13
|
+
source: model.source,
|
|
14
|
+
artifacts: model.artifacts,
|
|
15
|
+
targets: model.targets,
|
|
16
|
+
targetCapabilities,
|
|
17
|
+
operations: [...operations].sort(operationOrder),
|
|
18
|
+
evidenceDirectory: model.evidenceDirectory,
|
|
19
|
+
metadata: PlannerMetadata.make({
|
|
20
|
+
createdBy: "release",
|
|
21
|
+
planSchemaVersion: "release-plan/v1"
|
|
22
|
+
})
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=create-release-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-release-plan.js","sourceRoot":"","sources":["../../src/planner/create-release-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAiB,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClF,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AACvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAI/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,QAAQ,CAAC,EACvE,MAAqB,EACrB,OAAe,GAAG,EAClB,aAAiC,SAAS;IAE1C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,sBAAsB,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;IACrE,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;IAC9D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAA;IAExD,OAAO,WAAW,CAAC,IAAI,CAAC;QACtB,aAAa,EAAE,iBAAiB;QAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,MAAM,EAAE,KAAK,CAAC,MAAM;QACpB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,kBAAkB;QAClB,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC;QAChD,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;QAC1C,QAAQ,EAAE,eAAe,CAAC,IAAI,CAAC;YAC7B,SAAS,EAAE,SAAS;YACpB,iBAAiB,EAAE,iBAAiB;SACrC,CAAC;KACH,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
import { EvidenceBundle } from "../domain/evidence.js";
|
|
3
|
+
export type * from "../types/effect-internal.js";
|
|
4
|
+
declare const ReleaseNormalizationError_base: Schema.Class<ReleaseNormalizationError, Schema.TaggedStruct<"ReleaseNormalizationError", {
|
|
5
|
+
readonly field: Schema.String;
|
|
6
|
+
readonly reason: Schema.String;
|
|
7
|
+
}>, import("effect/Cause").YieldableError>;
|
|
8
|
+
export declare class ReleaseNormalizationError extends ReleaseNormalizationError_base {
|
|
9
|
+
}
|
|
10
|
+
declare const ArtifactInventoryError_base: Schema.Class<ArtifactInventoryError, Schema.TaggedStruct<"ArtifactInventoryError", {
|
|
11
|
+
readonly path: Schema.String;
|
|
12
|
+
readonly reason: Schema.String;
|
|
13
|
+
}>, import("effect/Cause").YieldableError>;
|
|
14
|
+
export declare class ArtifactInventoryError extends ArtifactInventoryError_base {
|
|
15
|
+
}
|
|
16
|
+
declare const PlanConstructionError_base: Schema.Class<PlanConstructionError, Schema.TaggedStruct<"PlanConstructionError", {
|
|
17
|
+
readonly targetId: Schema.optionalKey<Schema.String>;
|
|
18
|
+
readonly reason: Schema.String;
|
|
19
|
+
}>, import("effect/Cause").YieldableError>;
|
|
20
|
+
export declare class PlanConstructionError extends PlanConstructionError_base {
|
|
21
|
+
}
|
|
22
|
+
declare const EvidenceWriteError_base: Schema.Class<EvidenceWriteError, Schema.TaggedStruct<"EvidenceWriteError", {
|
|
23
|
+
readonly path: Schema.String;
|
|
24
|
+
readonly reason: Schema.String;
|
|
25
|
+
}>, import("effect/Cause").YieldableError>;
|
|
26
|
+
export declare class EvidenceWriteError extends EvidenceWriteError_base {
|
|
27
|
+
}
|
|
28
|
+
declare const OperationFailedError_base: Schema.Class<OperationFailedError, Schema.TaggedStruct<"OperationFailedError", {
|
|
29
|
+
readonly operationId: Schema.String;
|
|
30
|
+
readonly exitCode: Schema.Number;
|
|
31
|
+
readonly reason: Schema.String;
|
|
32
|
+
readonly evidence: Schema.optionalKey<typeof EvidenceBundle>;
|
|
33
|
+
}>, import("effect/Cause").YieldableError>;
|
|
34
|
+
export declare class OperationFailedError extends OperationFailedError_base {
|
|
35
|
+
}
|
|
36
|
+
export type PlannerError = ReleaseNormalizationError | ArtifactInventoryError | PlanConstructionError | EvidenceWriteError | OperationFailedError;
|
|
37
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/planner/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,mBAAmB,6BAA6B,CAAA;;;;;AAEhD,qBAAa,yBAA0B,SAAQ,8BAM9C;CAAG;;;;;AAEJ,qBAAa,sBAAuB,SAAQ,2BAM3C;CAAG;;;;;AAEJ,qBAAa,qBAAsB,SAAQ,0BAGzC;CAAG;;;;;AAEL,qBAAa,kBAAmB,SAAQ,uBAGtC;CAAG;;;;;;;AAEL,qBAAa,oBAAqB,SAAQ,yBAKxC;CAAG;AAEL,MAAM,MAAM,YAAY,GACpB,yBAAyB,GACzB,sBAAsB,GACtB,qBAAqB,GACrB,kBAAkB,GAClB,oBAAoB,CAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as Schema from "effect/Schema";
|
|
2
|
+
import { EvidenceBundle } from "../domain/evidence.js";
|
|
3
|
+
export class ReleaseNormalizationError extends Schema.TaggedErrorClass()("ReleaseNormalizationError", {
|
|
4
|
+
field: Schema.String,
|
|
5
|
+
reason: Schema.String
|
|
6
|
+
}) {
|
|
7
|
+
}
|
|
8
|
+
export class ArtifactInventoryError extends Schema.TaggedErrorClass()("ArtifactInventoryError", {
|
|
9
|
+
path: Schema.String,
|
|
10
|
+
reason: Schema.String
|
|
11
|
+
}) {
|
|
12
|
+
}
|
|
13
|
+
export class PlanConstructionError extends Schema.TaggedErrorClass()("PlanConstructionError", {
|
|
14
|
+
targetId: Schema.optionalKey(Schema.String),
|
|
15
|
+
reason: Schema.String
|
|
16
|
+
}) {
|
|
17
|
+
}
|
|
18
|
+
export class EvidenceWriteError extends Schema.TaggedErrorClass()("EvidenceWriteError", {
|
|
19
|
+
path: Schema.String,
|
|
20
|
+
reason: Schema.String
|
|
21
|
+
}) {
|
|
22
|
+
}
|
|
23
|
+
export class OperationFailedError extends Schema.TaggedErrorClass()("OperationFailedError", {
|
|
24
|
+
operationId: Schema.String,
|
|
25
|
+
exitCode: Schema.Number,
|
|
26
|
+
reason: Schema.String,
|
|
27
|
+
evidence: Schema.optionalKey(EvidenceBundle)
|
|
28
|
+
}) {
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/planner/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAItD,MAAM,OAAO,yBAA0B,SAAQ,MAAM,CAAC,gBAAgB,EAA6B,CACjG,2BAA2B,EAC3B;IACE,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CACF;CAAG;AAEJ,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,gBAAgB,EAA0B,CAC3F,wBAAwB,EACxB;IACE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CACF;CAAG;AAEJ,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,gBAAgB,EAAyB,CAAC,uBAAuB,EAAE;IACnH,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC;CAAG;AAEL,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,gBAAgB,EAAsB,CAAC,oBAAoB,EAAE;IAC1G,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC;CAAG;AAEL,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,gBAAgB,EAAwB,CAAC,sBAAsB,EAAE;IAChH,WAAW,EAAE,MAAM,CAAC,MAAM;IAC1B,QAAQ,EAAE,MAAM,CAAC,MAAM;IACvB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC;CAC7C,CAAC;CAAG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { CommandEvidence, EvidenceBundle, EvidenceRecord, ExecutionEvidence, ValidationEvidence } from "../domain/evidence.js";
|
|
4
|
+
import { ReleasePlan } from "../domain/release.js";
|
|
5
|
+
import { ReleaseHost } from "../host/host.js";
|
|
6
|
+
import { EvidenceWriteError } from "./errors.js";
|
|
7
|
+
export type * from "../types/effect-internal.js";
|
|
8
|
+
export declare const emptyEvidenceBundle: (plan: ReleasePlan) => EvidenceBundle;
|
|
9
|
+
export declare const appendEvidenceRecord: (bundle: EvidenceBundle, record: EvidenceRecord) => EvidenceBundle;
|
|
10
|
+
export declare const redactText: (input: string, secrets: ReadonlyArray<string>) => string;
|
|
11
|
+
export declare const readRedactionSecrets: (operation: import("../domain/operation.js").RenderFileOperation | import("../domain/operation.js").ValidateCommandOperation | import("../domain/operation.js").ValidationNoteOperation | import("../domain/operation.js").PublishCommandOperation | import("../domain/operation.js").VerifyRemoteOperation) => Effect.Effect<string[], never, ReleaseHost>;
|
|
12
|
+
export declare const commandEvidenceFromResult: (operation: import("../domain/operation.js").ValidateCommandOperation | import("../domain/operation.js").PublishCommandOperation | import("../domain/operation.js").VerifyRemoteOperation) => Effect.Effect<CommandEvidence, import("../host/host.js").HostError, ReleaseHost>;
|
|
13
|
+
export declare const executionEvidence: (operation: import("../domain/operation.js").RenderFileOperation | import("../domain/operation.js").ValidateCommandOperation | import("../domain/operation.js").ValidationNoteOperation | import("../domain/operation.js").PublishCommandOperation | import("../domain/operation.js").VerifyRemoteOperation, message: string) => Effect.Effect<ExecutionEvidence, never, ReleaseHost>;
|
|
14
|
+
export declare const validationNoteEvidence: (operation: import("../domain/operation.js").ValidationNoteOperation) => Effect.Effect<ValidationEvidence, never, ReleaseHost>;
|
|
15
|
+
export declare const renderEvidenceJson: (bundle: EvidenceBundle) => string;
|
|
16
|
+
export declare const writeEvidenceBundle: (path: string, bundle: EvidenceBundle) => Effect.Effect<void, EvidenceWriteError, ReleaseHost>;
|
|
17
|
+
export declare const decodeEvidenceBundle: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Effect.Effect<EvidenceBundle, Schema.SchemaError, never>;
|
|
18
|
+
//# sourceMappingURL=evidence-recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-recorder.d.ts","sourceRoot":"","sources":["../../src/planner/evidence-recorder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EACL,eAAe,EACf,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAEhD,mBAAmB,6BAA6B,CAAA;AAEhD,eAAO,MAAM,mBAAmB,GAAI,MAAM,WAAW,KAAG,cAMpD,CAAA;AAEJ,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,cAAc,EACtB,QAAQ,cAAc,KACrB,cAMC,CAAA;AAEJ,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,EAAE,SAAS,aAAa,CAAC,MAAM,CAAC,KAAG,MAQ1E,CAAA;AAED,eAAO,MAAM,oBAAoB,6VAW/B,CAAA;AAEF,eAAO,MAAM,yBAAyB,gRAqBpC,CAAA;AAEF,eAAO,MAAM,iBAAiB,uXAY5B,CAAA;AAEF,eAAO,MAAM,sBAAsB,gIAejC,CAAA;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,cAAc,KAAG,MACpB,CAAA;AAExC,eAAO,MAAM,mBAAmB,gGAU9B,CAAA;AAEF,eAAO,MAAM,oBAAoB,iIAA6C,CAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
import { CommandEvidence, EvidenceBundle, ExecutionEvidence, ValidationEvidence } from "../domain/evidence.js";
|
|
4
|
+
import { ReleaseHost } from "../host/host.js";
|
|
5
|
+
import { EvidenceWriteError } from "./errors.js";
|
|
6
|
+
export const emptyEvidenceBundle = (plan) => EvidenceBundle.make({
|
|
7
|
+
schemaVersion: "release-evidence/v1",
|
|
8
|
+
releaseName: plan.identity.name,
|
|
9
|
+
releaseVersion: plan.identity.version,
|
|
10
|
+
records: []
|
|
11
|
+
});
|
|
12
|
+
export const appendEvidenceRecord = (bundle, record) => EvidenceBundle.make({
|
|
13
|
+
schemaVersion: bundle.schemaVersion,
|
|
14
|
+
releaseName: bundle.releaseName,
|
|
15
|
+
releaseVersion: bundle.releaseVersion,
|
|
16
|
+
records: [...bundle.records, record]
|
|
17
|
+
});
|
|
18
|
+
export const redactText = (input, secrets) => {
|
|
19
|
+
let output = input;
|
|
20
|
+
for (const secret of secrets) {
|
|
21
|
+
if (secret.length > 0) {
|
|
22
|
+
output = output.split(secret).join("[REDACTED]");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return output;
|
|
26
|
+
};
|
|
27
|
+
export const readRedactionSecrets = Effect.fn("readRedactionSecrets")(function* (operation) {
|
|
28
|
+
const host = yield* ReleaseHost;
|
|
29
|
+
const secrets = [];
|
|
30
|
+
const names = "command" in operation ? operation.command.redactedEnv : [];
|
|
31
|
+
for (const name of names) {
|
|
32
|
+
const value = yield* host.readEnv(name);
|
|
33
|
+
if (value !== undefined) {
|
|
34
|
+
secrets.push(value);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return secrets;
|
|
38
|
+
});
|
|
39
|
+
export const commandEvidenceFromResult = Effect.fn("commandEvidenceFromResult")(function* (operation) {
|
|
40
|
+
const host = yield* ReleaseHost;
|
|
41
|
+
const secrets = yield* readRedactionSecrets(operation);
|
|
42
|
+
const result = yield* host.runCommand(operation.command);
|
|
43
|
+
const status = result.exitCode === 0 ? "passed" : "failed";
|
|
44
|
+
return CommandEvidence.make({
|
|
45
|
+
id: `${operation.id}:command`,
|
|
46
|
+
operationId: operation.id,
|
|
47
|
+
...(operation.targetId === undefined ? {} : { targetId: operation.targetId }),
|
|
48
|
+
status,
|
|
49
|
+
severity: result.exitCode === 0 ? "info" : "error",
|
|
50
|
+
command: result.command,
|
|
51
|
+
exitCode: result.exitCode,
|
|
52
|
+
stdout: redactText(result.stdout, secrets),
|
|
53
|
+
stderr: redactText(result.stderr, secrets),
|
|
54
|
+
startedAt: result.startedAt,
|
|
55
|
+
endedAt: result.endedAt,
|
|
56
|
+
durationMillis: result.durationMillis
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
export const executionEvidence = Effect.fn("executionEvidence")(function* (operation, message) {
|
|
60
|
+
const host = yield* ReleaseHost;
|
|
61
|
+
const timestamp = yield* host.now;
|
|
62
|
+
return ExecutionEvidence.make({
|
|
63
|
+
id: `${operation.id}:execution`,
|
|
64
|
+
operationId: operation.id,
|
|
65
|
+
...(operation.targetId === undefined ? {} : { targetId: operation.targetId }),
|
|
66
|
+
status: "passed",
|
|
67
|
+
severity: "info",
|
|
68
|
+
message,
|
|
69
|
+
timestamp
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
export const validationNoteEvidence = Effect.fn("validationNoteEvidence")(function* (operation) {
|
|
73
|
+
const host = yield* ReleaseHost;
|
|
74
|
+
const timestamp = yield* host.now;
|
|
75
|
+
const status = operation.skipped ? "skipped" : operation.severity === "warning" ? "warning" : "passed";
|
|
76
|
+
return ValidationEvidence.make({
|
|
77
|
+
id: `${operation.id}:validation`,
|
|
78
|
+
...(operation.targetId === undefined ? {} : { targetId: operation.targetId }),
|
|
79
|
+
status,
|
|
80
|
+
severity: operation.severity,
|
|
81
|
+
message: operation.message,
|
|
82
|
+
timestamp,
|
|
83
|
+
skipped: operation.skipped
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
export const renderEvidenceJson = (bundle) => `${JSON.stringify(bundle, null, 2)}\n`;
|
|
87
|
+
export const writeEvidenceBundle = Effect.fn("writeEvidenceBundle")(function* (path, bundle) {
|
|
88
|
+
const host = yield* ReleaseHost;
|
|
89
|
+
yield* host.writeFileString(path, renderEvidenceJson(bundle)).pipe(Effect.mapError((error) => EvidenceWriteError.make({
|
|
90
|
+
path,
|
|
91
|
+
reason: error.reason
|
|
92
|
+
})));
|
|
93
|
+
});
|
|
94
|
+
export const decodeEvidenceBundle = Schema.decodeUnknownEffect(EvidenceBundle);
|
|
95
|
+
//# sourceMappingURL=evidence-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evidence-recorder.js","sourceRoot":"","sources":["../../src/planner/evidence-recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { CommandEvidence, EvidenceBundle } from "../domain/evidence.js";
|
|
3
|
+
import { ExecutionApproval, Operation } from "../domain/operation.js";
|
|
4
|
+
import { ReleasePlan } from "../domain/release.js";
|
|
5
|
+
import { ReleaseHost } from "../host/host.js";
|
|
6
|
+
import { OperationFailedError } from "./errors.js";
|
|
7
|
+
export type * from "../types/effect-internal.js";
|
|
8
|
+
export declare const runOperationEvidence: (operation: import("../domain/operation.js").RenderFileOperation | import("../domain/operation.js").ValidateCommandOperation | import("../domain/operation.js").ValidationNoteOperation | import("../domain/operation.js").PublishCommandOperation | import("../domain/operation.js").VerifyRemoteOperation, approval: ExecutionApproval) => Effect.Effect<CommandEvidence | import("../domain/evidence.js").ValidationEvidence | import("../domain/evidence.js").ExecutionEvidence, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError, ReleaseHost>;
|
|
9
|
+
export declare const runOperation: (operation: import("../domain/operation.js").RenderFileOperation | import("../domain/operation.js").ValidateCommandOperation | import("../domain/operation.js").ValidationNoteOperation | import("../domain/operation.js").PublishCommandOperation | import("../domain/operation.js").VerifyRemoteOperation, approval: ExecutionApproval) => Effect.Effect<import("../domain/evidence.js").ValidationEvidence | import("../domain/evidence.js").ExecutionEvidence, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError | OperationFailedError, ReleaseHost>;
|
|
10
|
+
export declare const runOperations: (plan: ReleasePlan, operations: readonly (import("../domain/operation.js").RenderFileOperation | import("../domain/operation.js").ValidateCommandOperation | import("../domain/operation.js").ValidationNoteOperation | import("../domain/operation.js").PublishCommandOperation | import("../domain/operation.js").VerifyRemoteOperation)[], approval: ExecutionApproval) => Effect.Effect<EvidenceBundle, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError | OperationFailedError, ReleaseHost>;
|
|
11
|
+
export declare const validationOperations: (plan: ReleasePlan) => ReadonlyArray<Operation>;
|
|
12
|
+
export declare const publishOperations: (plan: ReleasePlan) => ReadonlyArray<Operation>;
|
|
13
|
+
export declare const renderOperations: (plan: ReleasePlan) => ReadonlyArray<Operation>;
|
|
14
|
+
export declare const verificationOperations: (plan: ReleasePlan) => ReadonlyArray<Operation>;
|
|
15
|
+
export declare const validatePlan: (plan: ReleasePlan) => Effect.Effect<EvidenceBundle, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError | OperationFailedError, ReleaseHost>;
|
|
16
|
+
export declare const executePlan: (plan: ReleasePlan, approval: ExecutionApproval) => Effect.Effect<EvidenceBundle, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError | OperationFailedError, ReleaseHost>;
|
|
17
|
+
export declare const renderPlan: (plan: ReleasePlan, approval: ExecutionApproval) => Effect.Effect<EvidenceBundle, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError | OperationFailedError, ReleaseHost>;
|
|
18
|
+
export declare const verifyPlan: (plan: ReleasePlan) => Effect.Effect<EvidenceBundle, import("../domain/operation.js").ExecutionApprovalError | import("../host/host.js").HostError | OperationFailedError, ReleaseHost>;
|
|
19
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/planner/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAkB,MAAM,uBAAuB,CAAA;AACvF,OAAO,EACL,iBAAiB,EACjB,SAAS,EAEV,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAQ7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAElD,mBAAmB,6BAA6B,CAAA;AAkBhD,eAAO,MAAM,oBAAoB,kkBAiB/B,CAAA;AAEF,eAAO,MAAM,YAAY,ukBASvB,CAAA;AAEF,eAAO,MAAM,aAAa,ghBAcxB,CAAA;AAEF,eAAO,MAAM,oBAAoB,GAAI,MAAM,WAAW,KAAG,aAAa,CAAC,SAAS,CAG7E,CAAA;AAEH,eAAO,MAAM,iBAAiB,GAAI,MAAM,WAAW,KAAG,aAAa,CAAC,SAAS,CACQ,CAAA;AAErF,eAAO,MAAM,gBAAgB,GAAI,MAAM,WAAW,KAAG,aAAa,CAAC,SAAS,CACK,CAAA;AAEjF,eAAO,MAAM,sBAAsB,GAAI,MAAM,WAAW,KAAG,aAAa,CAAC,SAAS,CACC,CAAA;AAEnF,eAAO,MAAM,YAAY,yLAEvB,CAAA;AAEF,eAAO,MAAM,WAAW,sNAEtB,CAAA;AAEF,eAAO,MAAM,UAAU,sNAErB,CAAA;AAEF,eAAO,MAAM,UAAU,yLAErB,CAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { ExecutionApproval, requireExecutionApproval } from "../domain/operation.js";
|
|
3
|
+
import { ReleaseHost } from "../host/host.js";
|
|
4
|
+
import { appendEvidenceRecord, commandEvidenceFromResult, emptyEvidenceBundle, executionEvidence, validationNoteEvidence } from "./evidence-recorder.js";
|
|
5
|
+
import { OperationFailedError } from "./errors.js";
|
|
6
|
+
const commandFailed = (evidence) => "exitCode" in evidence && evidence.status === "failed";
|
|
7
|
+
const failCommandEvidence = (evidence, bundle) => Effect.fail(OperationFailedError.make({
|
|
8
|
+
operationId: evidence.operationId,
|
|
9
|
+
exitCode: evidence.exitCode,
|
|
10
|
+
reason: "Command exited with a nonzero status.",
|
|
11
|
+
...(bundle === undefined ? {} : { evidence: bundle })
|
|
12
|
+
}));
|
|
13
|
+
export const runOperationEvidence = Effect.fn("runOperationEvidence")(function* (operation, approval) {
|
|
14
|
+
yield* requireExecutionApproval(operation, approval);
|
|
15
|
+
if (operation._tag === "RenderFileOperation") {
|
|
16
|
+
const host = yield* ReleaseHost;
|
|
17
|
+
yield* host.writeFileString(operation.path, operation.contents);
|
|
18
|
+
return yield* executionEvidence(operation, `Rendered ${operation.path}`);
|
|
19
|
+
}
|
|
20
|
+
if (operation._tag === "ValidationNoteOperation") {
|
|
21
|
+
return yield* validationNoteEvidence(operation);
|
|
22
|
+
}
|
|
23
|
+
return yield* commandEvidenceFromResult(operation);
|
|
24
|
+
});
|
|
25
|
+
export const runOperation = Effect.fn("runOperation")(function* (operation, approval) {
|
|
26
|
+
const evidence = yield* runOperationEvidence(operation, approval);
|
|
27
|
+
if (commandFailed(evidence)) {
|
|
28
|
+
return yield* failCommandEvidence(evidence, undefined);
|
|
29
|
+
}
|
|
30
|
+
return evidence;
|
|
31
|
+
});
|
|
32
|
+
export const runOperations = Effect.fn("runOperations")(function* (plan, operations, approval) {
|
|
33
|
+
let bundle = emptyEvidenceBundle(plan);
|
|
34
|
+
for (const operation of operations) {
|
|
35
|
+
const evidence = yield* runOperationEvidence(operation, approval);
|
|
36
|
+
bundle = appendEvidenceRecord(bundle, evidence);
|
|
37
|
+
if (commandFailed(evidence)) {
|
|
38
|
+
return yield* failCommandEvidence(evidence, bundle);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return bundle;
|
|
42
|
+
});
|
|
43
|
+
export const validationOperations = (plan) => plan.operations.filter((operation) => operation._tag === "ValidateCommandOperation" || operation._tag === "ValidationNoteOperation");
|
|
44
|
+
export const publishOperations = (plan) => plan.operations.filter((operation) => operation._tag === "PublishCommandOperation");
|
|
45
|
+
export const renderOperations = (plan) => plan.operations.filter((operation) => operation._tag === "RenderFileOperation");
|
|
46
|
+
export const verificationOperations = (plan) => plan.operations.filter((operation) => operation._tag === "VerifyRemoteOperation");
|
|
47
|
+
export const validatePlan = Effect.fn("validatePlan")(function* (plan) {
|
|
48
|
+
return yield* runOperations(plan, validationOperations(plan), ExecutionApproval.none);
|
|
49
|
+
});
|
|
50
|
+
export const executePlan = Effect.fn("executePlan")(function* (plan, approval) {
|
|
51
|
+
return yield* runOperations(plan, publishOperations(plan), approval);
|
|
52
|
+
});
|
|
53
|
+
export const renderPlan = Effect.fn("renderPlan")(function* (plan, approval) {
|
|
54
|
+
return yield* runOperations(plan, renderOperations(plan), approval);
|
|
55
|
+
});
|
|
56
|
+
export const verifyPlan = Effect.fn("verifyPlan")(function* (plan) {
|
|
57
|
+
return yield* runOperations(plan, verificationOperations(plan), ExecutionApproval.none);
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/planner/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { ReleaseIntent, ReleaseModel } from "../domain/release.js";
|
|
3
|
+
import { ReleaseHost } from "../host/host.js";
|
|
4
|
+
import { ReleaseNormalizationError } from "./errors.js";
|
|
5
|
+
export type * from "../types/effect-internal.js";
|
|
6
|
+
export declare const normalizeReleaseIntent: (intent: ReleaseIntent, root?: string | undefined, configPath?: string | undefined) => Effect.Effect<ReleaseModel, ReleaseNormalizationError, ReleaseHost>;
|
|
7
|
+
//# sourceMappingURL=normalize-release.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-release.d.ts","sourceRoot":"","sources":["../../src/planner/normalize-release.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAkB,MAAM,sBAAsB,CAAA;AAElF,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,mBAAmB,6BAA6B,CAAA;AA8ChD,eAAO,MAAM,sBAAsB,4JAuFjC,CAAA"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { ArtifactInventoryItem, artifactInventoryOrder, Checksum } from "../domain/artifact.js";
|
|
3
|
+
import { ReleaseModel, SourceMetadata } from "../domain/release.js";
|
|
4
|
+
import { targetOrder } from "../domain/target.js";
|
|
5
|
+
import { ReleaseHost } from "../host/host.js";
|
|
6
|
+
import { ReleaseNormalizationError } from "./errors.js";
|
|
7
|
+
const validateUnique = (values, field) => Effect.sync(() => {
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
const duplicates = new Set();
|
|
10
|
+
for (const value of values) {
|
|
11
|
+
if (seen.has(value)) {
|
|
12
|
+
duplicates.add(value);
|
|
13
|
+
}
|
|
14
|
+
seen.add(value);
|
|
15
|
+
}
|
|
16
|
+
return [...duplicates].sort();
|
|
17
|
+
}).pipe(Effect.flatMap((duplicates) => duplicates.length === 0
|
|
18
|
+
? Effect.void
|
|
19
|
+
: Effect.fail(ReleaseNormalizationError.make({
|
|
20
|
+
field,
|
|
21
|
+
reason: `Duplicate values: ${duplicates.join(", ")}`
|
|
22
|
+
}))));
|
|
23
|
+
const validateSafeRelativePath = (field, value) => {
|
|
24
|
+
const isAbsolute = value.startsWith("/") || /^[A-Za-z]:[\\/]/.test(value);
|
|
25
|
+
const hasTraversal = value.split(/[\\/]+/).includes("..");
|
|
26
|
+
if (!isAbsolute && !hasTraversal) {
|
|
27
|
+
return Effect.void;
|
|
28
|
+
}
|
|
29
|
+
return Effect.fail(ReleaseNormalizationError.make({
|
|
30
|
+
field,
|
|
31
|
+
reason: "Path must be relative and must not contain parent traversal."
|
|
32
|
+
}));
|
|
33
|
+
};
|
|
34
|
+
export const normalizeReleaseIntent = Effect.fn("normalizeReleaseIntent")(function* (intent, root = ".", configPath = undefined) {
|
|
35
|
+
yield* validateUnique(intent.artifacts.map((artifact) => artifact.id), "artifacts.id");
|
|
36
|
+
yield* validateUnique(intent.targets.map((target) => target.id), "targets.id");
|
|
37
|
+
yield* validateSafeRelativePath("evidenceDirectory", intent.evidenceDirectory ?? ".release/evidence");
|
|
38
|
+
for (const artifact of intent.artifacts) {
|
|
39
|
+
yield* validateSafeRelativePath(`artifacts.${artifact.id}.path`, artifact.path);
|
|
40
|
+
}
|
|
41
|
+
for (const target of intent.targets) {
|
|
42
|
+
if (target._tag === "NpmRegistryTarget") {
|
|
43
|
+
yield* validateSafeRelativePath(`targets.${target.id}.packagePath`, target.packagePath);
|
|
44
|
+
}
|
|
45
|
+
if (target._tag === "HomebrewTapTarget") {
|
|
46
|
+
yield* validateSafeRelativePath(`targets.${target.id}.formulaPath`, target.formulaPath);
|
|
47
|
+
if (target.tapDirectory !== undefined) {
|
|
48
|
+
yield* validateSafeRelativePath(`targets.${target.id}.tapDirectory`, target.tapDirectory);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const host = yield* ReleaseHost;
|
|
53
|
+
const inventory = [];
|
|
54
|
+
for (const artifact of intent.artifacts) {
|
|
55
|
+
const info = yield* host.stat(artifact.path).pipe(Effect.mapError((error) => ReleaseNormalizationError.make({
|
|
56
|
+
field: `artifacts.${artifact.id}.path`,
|
|
57
|
+
reason: error.reason
|
|
58
|
+
})));
|
|
59
|
+
if (artifact.format === "directory" && info.kind !== "directory") {
|
|
60
|
+
return yield* Effect.fail(ReleaseNormalizationError.make({
|
|
61
|
+
field: `artifacts.${artifact.id}.format`,
|
|
62
|
+
reason: `Expected directory artifact at ${artifact.path}`
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
if (artifact.format !== "directory" && info.kind === "directory") {
|
|
66
|
+
return yield* Effect.fail(ReleaseNormalizationError.make({
|
|
67
|
+
field: `artifacts.${artifact.id}.format`,
|
|
68
|
+
reason: `Expected file-like artifact at ${artifact.path}`
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
const checksum = artifact.checksum ?? (artifact.format === "directory"
|
|
72
|
+
? undefined
|
|
73
|
+
: Checksum.make({
|
|
74
|
+
algorithm: "sha256",
|
|
75
|
+
value: yield* host.hashFile(artifact.path, "sha256").pipe(Effect.mapError((error) => ReleaseNormalizationError.make({
|
|
76
|
+
field: `artifacts.${artifact.id}.checksum`,
|
|
77
|
+
reason: error.reason
|
|
78
|
+
})))
|
|
79
|
+
}));
|
|
80
|
+
inventory.push(ArtifactInventoryItem.make({
|
|
81
|
+
id: artifact.id,
|
|
82
|
+
path: artifact.path,
|
|
83
|
+
format: artifact.format,
|
|
84
|
+
consumers: [...artifact.consumers].sort(),
|
|
85
|
+
sizeBytes: info.sizeBytes,
|
|
86
|
+
...(checksum === undefined ? {} : { checksum })
|
|
87
|
+
}));
|
|
88
|
+
}
|
|
89
|
+
return ReleaseModel.make({
|
|
90
|
+
identity: intent.identity,
|
|
91
|
+
source: SourceMetadata.make({
|
|
92
|
+
root,
|
|
93
|
+
...(configPath === undefined ? {} : { configPath })
|
|
94
|
+
}),
|
|
95
|
+
artifacts: inventory.sort(artifactInventoryOrder),
|
|
96
|
+
targets: [...intent.targets].sort(targetOrder),
|
|
97
|
+
strict: intent.strict ?? true,
|
|
98
|
+
evidenceDirectory: intent.evidenceDirectory ?? ".release/evidence"
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=normalize-release.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-release.js","sourceRoot":"","sources":["../../src/planner/normalize-release.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ReleasePlan } from "../domain/release.js";
|
|
2
|
+
export type * from "../types/effect-internal.js";
|
|
3
|
+
export declare const renderPlanJson: (plan: ReleasePlan) => string;
|
|
4
|
+
export declare const renderPlanText: (plan: ReleasePlan) => string;
|
|
5
|
+
//# sourceMappingURL=render-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-plan.d.ts","sourceRoot":"","sources":["../../src/planner/render-plan.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,mBAAmB,6BAA6B,CAAA;AAYhD,eAAO,MAAM,cAAc,GAAI,MAAM,WAAW,KAAG,MACb,CAAA;AAEtC,eAAO,MAAM,cAAc,GAAI,MAAM,WAAW,KAAG,MA6ClD,CAAA"}
|