@xemahq/xema 0.31.1 → 0.32.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/commands/biome.js +1 -1
- package/dist/commands/biome.js.map +1 -1
- package/dist/commands/installation.js +3 -3
- package/dist/commands/installation.js.map +1 -1
- package/dist/commands/objects.js +1 -1
- package/dist/commands/objects.js.map +1 -1
- package/dist/dev/forked-worker.d.ts.map +1 -1
- package/dist/dev/forked-worker.js +9 -6
- package/dist/dev/forked-worker.js.map +1 -1
- package/dist/edition/verify-image-evidence.bundle.provenance.json +42 -36
- package/dist/lib/control-plane.js +2 -2
- package/dist/lib/control-plane.js.map +1 -1
- package/dist/lib/plan-format.js.map +1 -1
- package/dist/lib/promise-from-sync.d.ts +2 -0
- package/dist/lib/promise-from-sync.d.ts.map +1 -0
- package/dist/lib/promise-from-sync.js +9 -0
- package/dist/lib/promise-from-sync.js.map +1 -0
- package/dist/runtime/biome-local-install.js +1 -1
- package/dist/runtime/biome-local-install.js.map +1 -1
- package/dist/runtime/boot-graph-loader.js.map +1 -1
- package/dist/runtime/config/sources-config.js.map +1 -1
- package/dist/runtime/infra/infra-catalog.d.ts +3 -1
- package/dist/runtime/infra/infra-catalog.d.ts.map +1 -1
- package/dist/runtime/infra/infra-catalog.js.map +1 -1
- package/dist/runtime/installation/lifecycle.d.ts.map +1 -1
- package/dist/runtime/installation/lifecycle.js +7 -6
- package/dist/runtime/installation/lifecycle.js.map +1 -1
- package/dist/runtime/installation/state-store.d.ts.map +1 -1
- package/dist/runtime/installation/state-store.js +2 -1
- package/dist/runtime/installation/state-store.js.map +1 -1
- package/dist/runtime/read-only-no-follow-flags.d.ts +2 -0
- package/dist/runtime/read-only-no-follow-flags.d.ts.map +1 -0
- package/dist/runtime/read-only-no-follow-flags.js +6 -0
- package/dist/runtime/read-only-no-follow-flags.js.map +1 -0
- package/dist/runtime/roster.d.ts.map +1 -1
- package/dist/runtime/roster.js +3 -5
- package/dist/runtime/roster.js.map +1 -1
- package/dist/runtime/run-manifest.d.ts.map +1 -1
- package/dist/runtime/run-manifest.js +1 -3
- package/dist/runtime/run-manifest.js.map +1 -1
- package/dist/runtime/secrets/managed-local-files.d.ts.map +1 -1
- package/dist/runtime/secrets/managed-local-files.js +2 -1
- package/dist/runtime/secrets/managed-local-files.js.map +1 -1
- package/dist/runtime/secrets/managed-local-key-provider.d.ts.map +1 -1
- package/dist/runtime/secrets/managed-local-key-provider.js +13 -10
- package/dist/runtime/secrets/managed-local-key-provider.js.map +1 -1
- package/dist/runtime/secrets/resolver.d.ts.map +1 -1
- package/dist/runtime/secrets/resolver.js +2 -1
- package/dist/runtime/secrets/resolver.js.map +1 -1
- package/dist/runtime/sources/credentials.d.ts.map +1 -1
- package/dist/runtime/sources/credentials.js +6 -9
- package/dist/runtime/sources/credentials.js.map +1 -1
- package/dist/runtime/store-client.d.ts.map +1 -1
- package/dist/runtime/store-client.js.map +1 -1
- package/dist/runtime/supervisor.js +2 -2
- package/dist/runtime/supervisor.js.map +1 -1
- package/edition/README.md +4 -0
- package/edition/build-ledger-completeness.mjs +67 -0
- package/edition/build-ledger.mjs +107 -0
- package/edition/resolve-distribution.mjs +3 -0
- package/edition/resolve-images.mjs +109 -18
- package/edition/source-authority.mjs +7 -20
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store-client.js","sourceRoot":"","sources":["../../src/runtime/store-client.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"store-client.js","sourceRoot":"","sources":["../../src/runtime/store-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -66,7 +66,7 @@ class Supervisor {
|
|
|
66
66
|
const mandatoryFailures = results.flatMap((result, index) => {
|
|
67
67
|
const member = wave.members[index];
|
|
68
68
|
if (member === undefined ||
|
|
69
|
-
result
|
|
69
|
+
result.status !== 'rejected' ||
|
|
70
70
|
member.tier !== MANDATORY_TIER) {
|
|
71
71
|
return [];
|
|
72
72
|
}
|
|
@@ -80,7 +80,7 @@ class Supervisor {
|
|
|
80
80
|
const cleanupFailures = results.flatMap((result, index) => {
|
|
81
81
|
const member = wave.members[index];
|
|
82
82
|
if (member === undefined ||
|
|
83
|
-
result
|
|
83
|
+
result.status !== 'rejected' ||
|
|
84
84
|
!(result.reason instanceof forked_worker_1.PreReadyCleanupError)) {
|
|
85
85
|
return [];
|
|
86
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/runtime/supervisor.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/runtime/supervisor.ts"],"names":[],"mappings":"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"}
|
package/edition/README.md
CHANGED
|
@@ -100,6 +100,10 @@ The CLI is coupled to the kernel's edition protocol, not to the kernel package.
|
|
|
100
100
|
- `xema edition evidence statement entitlement stage` writes entitlement predicate v2 (`lockDigest`, `catalogueDigest`, read from the edition's committed locks), so it takes `--editions-root` besides `--data-root` and `--kernel`.
|
|
101
101
|
- The runtime image source index is v2 and carries operator-stated `producerWorkflowPins` (the workflow commit a producer certificate must be signed from, per repository). `xema edition index runtime-image-source [--producer-workflow-pin <owner/repo>=<40-hex>]...` preserves the committed pins exactly; each flag sets one repository's pin (repeatable; a repeated or non-GitHub `owner/repo` is refused; only `--trusted-write` writes an index, so the flag with any other mode, `--check-sources` included, is refused); a bootstrap index with none writes `[]`. A v1 index is refused, never migrated: delete it and bootstrap a new one with `--kernel-commit`.
|
|
102
102
|
|
|
103
|
+
## Build ledger completeness
|
|
104
|
+
|
|
105
|
+
`build-ledger.json` schema 2 records, per repository, the commits that published images and each `imageRef:contentHash` with its platforms and digest (schema 1, a bare commit list, is still read and is removed once the data root is re-projected). With a v2 ledger, `resolve-images` (and so `dist:check` and an exact-commit `--at` pin) refuses an edition when any resolved subject lacks its contentHash or one of that edition's required platforms in the ledger, listing every missing coordinate with the repository pin that produced it. There is no override; a v1 ledger gets no check.
|
|
106
|
+
|
|
103
107
|
## Customer editions
|
|
104
108
|
|
|
105
109
|
A customer edition is resolved against a catalogue pinned in `catalogue.pin.json` beside the definition file. The catalogue is the ceiling: it supplies availability, pins and digests and never adds a component. It also names the kernel: `kernel` is `{name, version, integrity}` (`@xemahq/contracts`, an exact `x.y.z`, the npm `sha512-` integrity of that tarball), and a catalogue without it is refused.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Release-lane completeness: with a v2 ledger, every resolved subject's
|
|
2
|
+
// `imageRef:contentHash` must be published with every platform its edition
|
|
3
|
+
// requires. Seal stays the final registry check; this refuses earlier, and
|
|
4
|
+
// names everything missing in one error.
|
|
5
|
+
import { platformIdentity } from './verify-image-platforms.mjs';
|
|
6
|
+
|
|
7
|
+
export class BuildLedgerIncompleteError extends Error {
|
|
8
|
+
constructor(distributionId, missing) {
|
|
9
|
+
const lines = missing.map(
|
|
10
|
+
(entry) =>
|
|
11
|
+
` ${entry.imageRef}:${entry.contentHash} lacks ${entry.platform} (repo ${entry.repo} pinned at ${entry.sourceCommit})`,
|
|
12
|
+
);
|
|
13
|
+
super(
|
|
14
|
+
`edition "${distributionId}" names ${missing.length} image coordinate(s) the build ledger ` +
|
|
15
|
+
`does not show published with every required platform:\n${lines.join('\n')}\n` +
|
|
16
|
+
`Build or re-project those images, or pin a repository commit whose images are complete.`,
|
|
17
|
+
);
|
|
18
|
+
this.name = 'BuildLedgerIncompleteError';
|
|
19
|
+
this.missing = missing;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class BuildLedgerMissingError extends Error {
|
|
24
|
+
constructor(distributionId, expectedAt) {
|
|
25
|
+
super(
|
|
26
|
+
`edition "${distributionId}" is resolved on the release lane, which needs the build ledger, but ` +
|
|
27
|
+
`${expectedAt} does not exist. Project the ledger into the data root; an absent ledger is not ` +
|
|
28
|
+
`read as "nothing to check".`,
|
|
29
|
+
);
|
|
30
|
+
this.name = 'BuildLedgerMissingError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `ledger` is the parsed ledger (`readBuildLedger`); null means it is absent and is REFUSED.
|
|
36
|
+
* A v1 ledger records no per-image facts, so nothing is checked (transitional, like the v1 parser branch).
|
|
37
|
+
*/
|
|
38
|
+
export function assertBuildLedgerComplete({
|
|
39
|
+
ledger,
|
|
40
|
+
distributionId,
|
|
41
|
+
subjects,
|
|
42
|
+
requiredPlatforms,
|
|
43
|
+
expectedAt,
|
|
44
|
+
}) {
|
|
45
|
+
if (ledger === null) {throw new BuildLedgerMissingError(distributionId, expectedAt);}
|
|
46
|
+
if (ledger.schemaVersion !== 2) {return;}
|
|
47
|
+
const required = requiredPlatforms.map(platformIdentity);
|
|
48
|
+
const missing = [];
|
|
49
|
+
for (const subject of subjects) {
|
|
50
|
+
const repository = ledger.repositories[subject.repo];
|
|
51
|
+
const published =
|
|
52
|
+
repository?.images?.[subject.imageRef]?.contentHashes?.[subject.contentHash];
|
|
53
|
+
const have = new Set(published?.platforms ?? []);
|
|
54
|
+
for (const platform of required) {
|
|
55
|
+
if (!have.has(platform)) {
|
|
56
|
+
missing.push({
|
|
57
|
+
repo: subject.repo,
|
|
58
|
+
sourceCommit: subject.sourceCommit,
|
|
59
|
+
imageRef: subject.imageRef,
|
|
60
|
+
contentHash: subject.contentHash,
|
|
61
|
+
platform,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (missing.length > 0) {throw new BuildLedgerIncompleteError(distributionId, missing);}
|
|
67
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// The committed build ledger (`build-ledger.json`): which commits of each source
|
|
2
|
+
// repository published images, and (schema v2) which `imageRef:contentHash`
|
|
3
|
+
// coordinates are published with which platforms.
|
|
4
|
+
//
|
|
5
|
+
// `node:` builtins plus the workspace locator only, so `source-authority.mjs`
|
|
6
|
+
// (which resolves from a bare checkout) can read it.
|
|
7
|
+
import { readFileSync } from 'node:fs';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
|
|
10
|
+
import { dataRoot } from './edition-workspace.mjs';
|
|
11
|
+
|
|
12
|
+
export const BUILD_LEDGER_FILE = 'build-ledger.json';
|
|
13
|
+
|
|
14
|
+
export class BuildLedgerError extends Error {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
super(`${BUILD_LEDGER_FILE} is malformed: ${message}`);
|
|
17
|
+
this.name = 'BuildLedgerError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const SHA1_PATTERN = /^[0-9a-f]{40}$/u;
|
|
22
|
+
const SHA256_PATTERN = /^[0-9a-f]{64}$/u;
|
|
23
|
+
const DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/u;
|
|
24
|
+
const PLATFORM_PATTERN = /^[a-z0-9]+\/[a-z0-9]+(\/[a-z0-9]+)?$/u;
|
|
25
|
+
|
|
26
|
+
const isRecord = (value) =>
|
|
27
|
+
value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
28
|
+
|
|
29
|
+
function parseImages(repo, images) {
|
|
30
|
+
if (!isRecord(images)) {
|
|
31
|
+
throw new BuildLedgerError(`repositories["${repo}"].images must be an object`);
|
|
32
|
+
}
|
|
33
|
+
for (const [imageRef, image] of Object.entries(images)) {
|
|
34
|
+
const where = `repositories["${repo}"].images["${imageRef}"]`;
|
|
35
|
+
if (!isRecord(image) || !isRecord(image.contentHashes)) {
|
|
36
|
+
throw new BuildLedgerError(`${where}.contentHashes must be an object`);
|
|
37
|
+
}
|
|
38
|
+
for (const [hash, entry] of Object.entries(image.contentHashes)) {
|
|
39
|
+
const at = `${where}.contentHashes["${hash}"]`;
|
|
40
|
+
if (!SHA256_PATTERN.test(hash)) {
|
|
41
|
+
throw new BuildLedgerError(`${at}: key is not 64 lowercase hex characters`);
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
!isRecord(entry) ||
|
|
45
|
+
!Array.isArray(entry.platforms) ||
|
|
46
|
+
entry.platforms.length === 0 ||
|
|
47
|
+
entry.platforms.some(
|
|
48
|
+
(platform) => typeof platform !== 'string' || !PLATFORM_PATTERN.test(platform),
|
|
49
|
+
) ||
|
|
50
|
+
new Set(entry.platforms).size !== entry.platforms.length
|
|
51
|
+
) {
|
|
52
|
+
throw new BuildLedgerError(
|
|
53
|
+
`${at}.platforms must be a non-empty list of distinct "os/arch" strings`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
if (typeof entry.digest !== 'string' || !DIGEST_PATTERN.test(entry.digest)) {
|
|
57
|
+
throw new BuildLedgerError(`${at}.digest must be "sha256:<64 hex>"`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Parse a ledger document strictly. Returns `{ schemaVersion, repositories }`
|
|
65
|
+
* where each repository is `{ commits, images }`; `images` is null for v1.
|
|
66
|
+
*/
|
|
67
|
+
export function parseBuildLedger(raw) {
|
|
68
|
+
if (
|
|
69
|
+
!isRecord(raw) ||
|
|
70
|
+
(raw.schemaVersion !== 1 && raw.schemaVersion !== 2) ||
|
|
71
|
+
!isRecord(raw.repositories)
|
|
72
|
+
) {
|
|
73
|
+
throw new BuildLedgerError('expected schemaVersion 1 or 2 with a repositories object');
|
|
74
|
+
}
|
|
75
|
+
const repositories = {};
|
|
76
|
+
for (const [repo, value] of Object.entries(raw.repositories)) {
|
|
77
|
+
// v1 is removed once the data root is re-projected at v2.
|
|
78
|
+
if (raw.schemaVersion === 1) {
|
|
79
|
+
if (!Array.isArray(value)) {
|
|
80
|
+
throw new BuildLedgerError(`repositories["${repo}"] must be a commit list`);
|
|
81
|
+
}
|
|
82
|
+
repositories[repo] = { commits: value, images: null };
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (!isRecord(value) || !Array.isArray(value.commits)) {
|
|
86
|
+
throw new BuildLedgerError(`repositories["${repo}"].commits must be a list`);
|
|
87
|
+
}
|
|
88
|
+
if (value.commits.some((commit) => typeof commit !== 'string' || !SHA1_PATTERN.test(commit))) {
|
|
89
|
+
throw new BuildLedgerError(`repositories["${repo}"].commits holds a non-40-hex entry`);
|
|
90
|
+
}
|
|
91
|
+
parseImages(repo, value.images);
|
|
92
|
+
repositories[repo] = { commits: value.commits, images: value.images };
|
|
93
|
+
}
|
|
94
|
+
return { schemaVersion: raw.schemaVersion, repositories };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** The parsed ledger of a data root, or null when none is projected. Malformed THROWS. */
|
|
98
|
+
export function readBuildLedger(distributionsDir = dataRoot()) {
|
|
99
|
+
let raw;
|
|
100
|
+
try {
|
|
101
|
+
raw = JSON.parse(readFileSync(join(distributionsDir, BUILD_LEDGER_FILE), 'utf8'));
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (error?.code === 'ENOENT') {return null;}
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
return parseBuildLedger(raw);
|
|
107
|
+
}
|
|
@@ -1473,6 +1473,9 @@ export function resolveDistributionFromInputs(
|
|
|
1473
1473
|
// lose its UI. A web joins once EVERY server it requires is in the edition
|
|
1474
1474
|
// (the last of them to be processed completes it), so a UI is never pulled
|
|
1475
1475
|
// in ahead of the capability it administers.
|
|
1476
|
+
// An operator-audience web is skipped here on purpose: operator biomes enter an edition only by explicit
|
|
1477
|
+
// selection (selectors skip them in applySelectors; naming one forces it in; a required service owned by
|
|
1478
|
+
// one must be selected explicitly). Pulling one in implicitly from a server biome would bypass that rule.
|
|
1476
1479
|
const webBiomesByRequiredServer = new Map();
|
|
1477
1480
|
for (const candidate of resourceProviderCandidates) {
|
|
1478
1481
|
if (
|
|
@@ -36,6 +36,8 @@ import { execFileSync } from 'node:child_process';
|
|
|
36
36
|
import { writeFileSync } from 'node:fs';
|
|
37
37
|
import { join, relative, sep } from 'node:path';
|
|
38
38
|
|
|
39
|
+
import { assertBuildLedgerComplete } from './build-ledger-completeness.mjs';
|
|
40
|
+
import { BUILD_LEDGER_FILE, readBuildLedger } from './build-ledger.mjs';
|
|
39
41
|
import { resolveDispatchedRuntimeComponents } from './dispatched-runtime-components.mjs';
|
|
40
42
|
import {
|
|
41
43
|
assertCanonicalDistributionId,
|
|
@@ -43,7 +45,7 @@ import {
|
|
|
43
45
|
readBoundDistributionFile,
|
|
44
46
|
} from './distribution-paths.mjs';
|
|
45
47
|
import { editionWorkspaceConfig } from './edition-config.mjs';
|
|
46
|
-
import { biomeIndexPath, editionsRoot, runtimeImageSourceIndexPath, WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule, sourcePath, sourcesRoot } from './edition-workspace.mjs';
|
|
48
|
+
import { biomeIndexPath, dataRoot, editionsRoot, runtimeImageSourceIndexPath, WorkspaceRoot, configureEditionWorkspaceFromProcess, isEntryModule, sourcePath, sourcesRoot } from './edition-workspace.mjs';
|
|
47
49
|
import {
|
|
48
50
|
externalSourceCacheDir,
|
|
49
51
|
materializeGitSource,
|
|
@@ -870,6 +872,63 @@ export function editionSourceIds(lock) {
|
|
|
870
872
|
return { get: (repo) => ids.get(repo) ?? firstPartySourceId(repo) };
|
|
871
873
|
}
|
|
872
874
|
|
|
875
|
+
/**
|
|
876
|
+
* A composed-process declaration the build cannot be read from. Named so a
|
|
877
|
+
* caller can tell "this image's inputs are unknown" from any other refusal:
|
|
878
|
+
* the carried set is evidence, and with none there is no owner to derive.
|
|
879
|
+
*/
|
|
880
|
+
export class ComposedProcessInputsError extends Error {
|
|
881
|
+
constructor(message) {
|
|
882
|
+
super(message);
|
|
883
|
+
this.name = 'ComposedProcessInputsError';
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Which of a repository's biome services the composed image CARRIES, read from
|
|
889
|
+
* the composed build's own inputs at the sealed commit.
|
|
890
|
+
*
|
|
891
|
+
* `image-build-inputs.json` lists the member package directories the image is
|
|
892
|
+
* built from (its hash is the subject's `sourceManifestHash`). A service is
|
|
893
|
+
* carried when its manifest-declared source directory (`subjectServicePath`,
|
|
894
|
+
* the `components[].artifact.path` mapping) is one of them. Returns one row
|
|
895
|
+
* per biome: the service ids carried and the ones not.
|
|
896
|
+
*/
|
|
897
|
+
function composedProcessCarriage(structure, enums, repo, sourceCommit, locate) {
|
|
898
|
+
const inputsPath = `${COMPOSED_PROCESS_IMAGE_PATH}/${COMPOSED_PROCESS_DECLARATION_FILE}`;
|
|
899
|
+
const { dir } = locate(repo);
|
|
900
|
+
let members;
|
|
901
|
+
try {
|
|
902
|
+
members = readGitJsonAtCommit(dir, inputsPath, sourceCommit)?.workspacePackages;
|
|
903
|
+
} catch (cause) {
|
|
904
|
+
throw new ComposedProcessInputsError(
|
|
905
|
+
`composed-process inputs "${inputsPath}" of "${repo}" are unreadable at ${sourceCommit} ` +
|
|
906
|
+
`(${cause.message}) — the biomes the image carries cannot be derived`,
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
if (!Array.isArray(members) || members.some((member) => typeof member !== 'string')) {
|
|
910
|
+
throw new ComposedProcessInputsError(
|
|
911
|
+
`composed-process inputs "${inputsPath}" of "${repo}" at ${sourceCommit} declare no ` +
|
|
912
|
+
'"workspacePackages" array of directories — the biomes the image carries cannot be derived',
|
|
913
|
+
);
|
|
914
|
+
}
|
|
915
|
+
const carried = new Set(members);
|
|
916
|
+
const byBiome = new Map();
|
|
917
|
+
for (const subject of structure.subjects) {
|
|
918
|
+
if (subject.kind !== enums.RuntimeImageSubjectKind.Service || subject.repo !== repo) {continue;}
|
|
919
|
+
const servicePath = subjectServicePath(subject, sourceCommit, locate);
|
|
920
|
+
for (const owner of subject.owners) {
|
|
921
|
+
if (owner.kind !== enums.RuntimeImageOwnerKind.Biome) {continue;}
|
|
922
|
+
const row = byBiome.get(owner.biomeId) ?? { biomeId: owner.biomeId, carried: [], uncarried: [] };
|
|
923
|
+
(carried.has(servicePath) ? row.carried : row.uncarried).push(subject.id);
|
|
924
|
+
byBiome.set(owner.biomeId, row);
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return [...byBiome.values()]
|
|
928
|
+
.map((row) => ({ ...row, carried: row.carried.sort(compareStrings), uncarried: row.uncarried.sort(compareStrings) }))
|
|
929
|
+
.sort((a, b) => compareStrings(a.biomeId, b.biomeId));
|
|
930
|
+
}
|
|
931
|
+
|
|
873
932
|
/**
|
|
874
933
|
* Read each repository's composed-process DECLARATION at the commit the
|
|
875
934
|
* edition builds its services from. Only repositories that contribute a
|
|
@@ -920,6 +979,7 @@ export function readComposedProcessDeclarations(
|
|
|
920
979
|
repo,
|
|
921
980
|
sourceId,
|
|
922
981
|
sourceCommit,
|
|
982
|
+
carriage: composedProcessCarriage(structure, enums, repo, sourceCommit, locate),
|
|
923
983
|
path: `${repoRelative}/${COMPOSED_PROCESS_IMAGE_PATH}`,
|
|
924
984
|
sourceManifestPath: `${repoRelative}/${declarationPath}`,
|
|
925
985
|
sourceManifestHash: exactSourceManifestHash(dir, declarationPath, sourceCommit),
|
|
@@ -933,10 +993,17 @@ export function readComposedProcessDeclarations(
|
|
|
933
993
|
* structure. Pure over its inputs, so the structural check and the source
|
|
934
994
|
* resolve derive the same subject from the same declarations.
|
|
935
995
|
*
|
|
936
|
-
* Owners are the biomes
|
|
937
|
-
*
|
|
996
|
+
* Owners are the biomes the image CARRIES, derived from the composed build's
|
|
997
|
+
* inputs at the sealed commit (`declaration.carriage`): the biomes all of whose
|
|
998
|
+
* services are members, never every biome with a service in the repository.
|
|
938
999
|
*/
|
|
939
|
-
export function withComposedProcessSubjects(
|
|
1000
|
+
export function withComposedProcessSubjects(
|
|
1001
|
+
structure,
|
|
1002
|
+
declarations,
|
|
1003
|
+
enums,
|
|
1004
|
+
requiredPlatforms,
|
|
1005
|
+
{ onNotice = (message) => console.warn(`[dist:images] ${message}`) } = {},
|
|
1006
|
+
) {
|
|
940
1007
|
if (declarations.length === 0) {return structure;}
|
|
941
1008
|
const subjects = new Map(structure.subjects.map((subject) => [subjectKey(subject), subject]));
|
|
942
1009
|
for (const declaration of declarations) {
|
|
@@ -944,20 +1011,32 @@ export function withComposedProcessSubjects(structure, declarations, enums, requ
|
|
|
944
1011
|
(subject) =>
|
|
945
1012
|
subject.kind === enums.RuntimeImageSubjectKind.Service && subject.repo === declaration.repo,
|
|
946
1013
|
);
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
];
|
|
1014
|
+
if (!Array.isArray(declaration.carriage)) {
|
|
1015
|
+
throw new ComposedProcessInputsError(
|
|
1016
|
+
`composed-process declaration for "${declaration.repo}" carries no evidence of the ` +
|
|
1017
|
+
'biomes the image carries — refusing to guess its owners',
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
// Owners are the biomes ALL of whose services the image carries. A biome
|
|
1021
|
+
// with only some carried deploys dedicated, so it is no owner (and is
|
|
1022
|
+
// named); a biome with none carried is simply not one.
|
|
1023
|
+
const biomeOwners = [];
|
|
1024
|
+
for (const row of declaration.carriage) {
|
|
1025
|
+
if (row.carried.length === 0) {continue;}
|
|
1026
|
+
if (row.uncarried.length > 0) {
|
|
1027
|
+
onNotice(
|
|
1028
|
+
`composed-process "${declaration.repo}": biome "${row.biomeId}" is only partly carried ` +
|
|
1029
|
+
`(carried: ${row.carried.join(', ')}; not carried: ${row.uncarried.join(', ')}) — ` +
|
|
1030
|
+
'it is not an owner and deploys dedicated',
|
|
1031
|
+
);
|
|
1032
|
+
continue;
|
|
1033
|
+
}
|
|
1034
|
+
biomeOwners.push({ kind: enums.RuntimeImageOwnerKind.Biome, biomeId: row.biomeId });
|
|
1035
|
+
}
|
|
957
1036
|
if (biomeOwners.length === 0) {
|
|
958
1037
|
throw new Error(
|
|
959
|
-
`composed-process declaration for "${declaration.repo}"
|
|
960
|
-
'
|
|
1038
|
+
`composed-process declaration for "${declaration.repo}" carries no biome's services in ` +
|
|
1039
|
+
'this edition — a composed image carries services, so it has no owner',
|
|
961
1040
|
);
|
|
962
1041
|
}
|
|
963
1042
|
for (const subject of services) {
|
|
@@ -1001,7 +1080,7 @@ export function withComposedProcessSubjects(structure, declarations, enums, requ
|
|
|
1001
1080
|
sourceManifestHash: declaration.sourceManifestHash,
|
|
1002
1081
|
sourceManifestPath: declaration.sourceManifestPath,
|
|
1003
1082
|
requiredPlatforms,
|
|
1004
|
-
owners: biomeOwners
|
|
1083
|
+
owners: biomeOwners,
|
|
1005
1084
|
});
|
|
1006
1085
|
}
|
|
1007
1086
|
return {
|
|
@@ -1023,7 +1102,7 @@ export function resolveComposedProcessStructure(
|
|
|
1023
1102
|
structure,
|
|
1024
1103
|
enums,
|
|
1025
1104
|
requiredPlatforms,
|
|
1026
|
-
{ locate } = {},
|
|
1105
|
+
{ locate, onNotice } = {},
|
|
1027
1106
|
) {
|
|
1028
1107
|
return withComposedProcessSubjects(
|
|
1029
1108
|
structure,
|
|
@@ -1036,6 +1115,7 @@ export function resolveComposedProcessStructure(
|
|
|
1036
1115
|
),
|
|
1037
1116
|
enums,
|
|
1038
1117
|
requiredPlatforms,
|
|
1118
|
+
onNotice === undefined ? undefined : { onNotice },
|
|
1039
1119
|
);
|
|
1040
1120
|
}
|
|
1041
1121
|
|
|
@@ -1574,6 +1654,17 @@ export async function resolveImageRows(id, { inputs, lock } = {}) {
|
|
|
1574
1654
|
),
|
|
1575
1655
|
};
|
|
1576
1656
|
});
|
|
1657
|
+
// Release lane only: a develop snapshot or customer overlay is not covered by
|
|
1658
|
+
// the committed ledger.
|
|
1659
|
+
if (inputs === undefined) {
|
|
1660
|
+
assertBuildLedgerComplete({
|
|
1661
|
+
ledger: readBuildLedger(),
|
|
1662
|
+
distributionId: id,
|
|
1663
|
+
subjects,
|
|
1664
|
+
requiredPlatforms,
|
|
1665
|
+
expectedAt: join(dataRoot(), BUILD_LEDGER_FILE),
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1577
1668
|
const webBiomes = structure.webBiomes.map((biome) => ({
|
|
1578
1669
|
...biome,
|
|
1579
1670
|
sourceCommit: commitsBefore.get(biome.repo),
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
import { tmpdir } from 'node:os';
|
|
10
10
|
import { join, relative, resolve, sep } from 'node:path';
|
|
11
11
|
|
|
12
|
+
import { BUILD_LEDGER_FILE, readBuildLedger } from './build-ledger.mjs';
|
|
12
13
|
import { dataRoot, sourcesRoot } from './edition-workspace.mjs';
|
|
13
14
|
|
|
14
15
|
export const PUBLISHED_SOURCE_REF = 'refs/remotes/origin/main';
|
|
@@ -91,7 +92,7 @@ const BUILT_COMMIT_SEARCH_LIMIT = 500;
|
|
|
91
92
|
* A pin frozen eight days in the past is what kept a fix for a production
|
|
92
93
|
* crashloop out of every image built from it.
|
|
93
94
|
*/
|
|
94
|
-
export
|
|
95
|
+
export { BUILD_LEDGER_FILE };
|
|
95
96
|
|
|
96
97
|
/**
|
|
97
98
|
* Read the committed ledger. A caller that resolves many repositories should
|
|
@@ -106,25 +107,11 @@ export const BUILD_LEDGER_FILE = 'build-ledger.json';
|
|
|
106
107
|
export function loadBuildLedger(
|
|
107
108
|
distributionsDir = dataRoot(),
|
|
108
109
|
) {
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
if (error?.code === 'ENOENT') {return null;}
|
|
115
|
-
throw error;
|
|
116
|
-
}
|
|
117
|
-
if (
|
|
118
|
-
raw === null ||
|
|
119
|
-
typeof raw !== 'object' ||
|
|
120
|
-
raw.schemaVersion !== 1 ||
|
|
121
|
-
typeof raw.repositories !== 'object' ||
|
|
122
|
-
raw.repositories === null ||
|
|
123
|
-
Array.isArray(raw.repositories)
|
|
124
|
-
) {
|
|
125
|
-
throw new Error(`${BUILD_LEDGER_FILE} is not strict schema v1`);
|
|
126
|
-
}
|
|
127
|
-
return raw.repositories;
|
|
110
|
+
const ledger = readBuildLedger(distributionsDir);
|
|
111
|
+
if (ledger === null) {return null;}
|
|
112
|
+
return Object.fromEntries(
|
|
113
|
+
Object.entries(ledger.repositories).map(([repo, entry]) => [repo, entry.commits]),
|
|
114
|
+
);
|
|
128
115
|
}
|
|
129
116
|
|
|
130
117
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/xema",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/xema-dev/xema-cli.git",
|
|
@@ -85,13 +85,13 @@
|
|
|
85
85
|
"verify:pack": "node ./scripts/verify-packed-assets.cjs",
|
|
86
86
|
"format": "prettier --write \"src/**/*.ts\"",
|
|
87
87
|
"start": "node ./dist/cli.js",
|
|
88
|
-
"lint": "eslint .",
|
|
88
|
+
"lint": "eslint . --max-warnings 0",
|
|
89
89
|
"lint:fix": "eslint . --fix",
|
|
90
90
|
"test": "jest --config jest.config.cjs && pnpm run test:edition",
|
|
91
91
|
"test:edition": "node --test \"edition/*.test.mjs\" \"edition/*-contract-tests.mjs\"",
|
|
92
92
|
"typecheck": "tsc --noEmit"
|
|
93
93
|
},
|
|
94
94
|
"xemaRelease": {
|
|
95
|
-
"sourceDigest": "sha256:
|
|
95
|
+
"sourceDigest": "sha256:94a9ed139c70716ccb6c498689b91e849e0f1576901722f0bef67403ba7fe593"
|
|
96
96
|
}
|
|
97
97
|
}
|