@kungfu-tech/buildchain 2.14.3 → 2.14.4-alpha.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/actions/promote-buildchain-ref/README.md +8 -0
- package/bin/buildchain.mjs +4 -0
- package/dist/site/buildchain-contract.json +39 -25
- package/dist/site/buildchain-site.json +26 -26
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/controller-registry.json +28 -4
- package/dist/site/kfd-claims.json +24 -6
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +6 -6
- package/dist/site/node-api-registry.json +20 -7
- package/dist/site/page-registry.json +16 -16
- package/dist/site/public-surface-audit.json +11 -5
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-passport-check-manifest.json +1 -0
- package/dist/site/release-provenance.json +1 -0
- package/dist/site/schemas/release-passport-v1.schema.json +3 -0
- package/dist/site/site-manifest.json +10 -10
- package/dist/site/workflow-registry.json +9 -3
- package/docs/MAP.md +1 -0
- package/docs/cli.md +7 -0
- package/docs/lifecycle-protocol.md +14 -0
- package/docs/release-governance.md +10 -1
- package/docs/release-passport.md +21 -0
- package/docs/versioning.md +1 -0
- package/package.json +2 -1
- package/packages/core/README.md +2 -0
- package/packages/core/anchored-version-material.js +281 -0
- package/packages/core/buildchain-config.js +68 -0
- package/packages/core/buildchain-contract.js +4 -0
- package/packages/core/controller-evidence.js +30 -4
- package/packages/core/index.js +6 -0
- package/packages/core/release-passport-contract.js +2 -0
- package/packages/core/release-passport.js +186 -1
- package/scripts/anchored-version-material.mjs +42 -0
- package/scripts/check-inventory.mjs +6 -0
- package/scripts/generate-site-bundle.mjs +1 -0
- package/scripts/stable-candidate-patrol.mjs +55 -6
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { execFileSync } from "node:child_process";
|
|
5
|
+
import {
|
|
6
|
+
discoverConfiguredDerivedVersionMaterial,
|
|
7
|
+
discoverConfiguredVersionStateFiles,
|
|
8
|
+
getLifecycleStage,
|
|
9
|
+
getVersionStrategy,
|
|
10
|
+
loadBuildchainConfig,
|
|
11
|
+
loadConfiguredAnchorManifest,
|
|
12
|
+
runLifecycleStage,
|
|
13
|
+
} from "./buildchain-config.js";
|
|
14
|
+
|
|
15
|
+
export const ANCHORED_VERSION_MATERIAL_CONTRACT =
|
|
16
|
+
"kungfu-buildchain-anchored-version-material/v1";
|
|
17
|
+
|
|
18
|
+
function git(cwd, args, { buffer = false } = {}) {
|
|
19
|
+
return execFileSync("git", args, {
|
|
20
|
+
cwd,
|
|
21
|
+
encoding: buffer ? undefined : "utf8",
|
|
22
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function sha256(content) {
|
|
27
|
+
return `sha256:${crypto.createHash("sha256").update(content).digest("hex")}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function stableJson(value) {
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
return `[${value.map(stableJson).join(",")}]`;
|
|
33
|
+
}
|
|
34
|
+
if (value && typeof value === "object") {
|
|
35
|
+
return `{${Object.keys(value)
|
|
36
|
+
.sort()
|
|
37
|
+
.map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`)
|
|
38
|
+
.join(",")}}`;
|
|
39
|
+
}
|
|
40
|
+
return JSON.stringify(value);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function normalizeTargetChannel(targetChannel, targetRef) {
|
|
44
|
+
if (targetChannel) {
|
|
45
|
+
return targetChannel;
|
|
46
|
+
}
|
|
47
|
+
if (String(targetRef || "").startsWith("release/")) {
|
|
48
|
+
return "release";
|
|
49
|
+
}
|
|
50
|
+
if (String(targetRef || "").startsWith("alpha/")) {
|
|
51
|
+
return "alpha";
|
|
52
|
+
}
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function resolveLatestAlphaRef(cwd, targetRef) {
|
|
57
|
+
const match = String(targetRef || "").match(/^release\/v(\d+)\/v\1\.(\d+)$/);
|
|
58
|
+
if (!match) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`anchored derived material preflight requires release/vN/vN.M target ref, got ${targetRef || "<empty>"}`,
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
const prefix = `v${match[1]}.${match[2]}.`;
|
|
64
|
+
const tags = git(cwd, [
|
|
65
|
+
"tag",
|
|
66
|
+
"--list",
|
|
67
|
+
`${prefix}*-alpha.*`,
|
|
68
|
+
"--sort=-version:refname",
|
|
69
|
+
])
|
|
70
|
+
.trim()
|
|
71
|
+
.split(/\r?\n/)
|
|
72
|
+
.filter(Boolean);
|
|
73
|
+
if (tags.length === 0) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`anchored derived material preflight found no exact alpha tag matching ${prefix}*-alpha.*`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
return tags[0];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function gitStatus(cwd) {
|
|
82
|
+
return git(cwd, ["status", "--porcelain", "--untracked-files=all"]).trim();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function fileAtRef(cwd, ref, filePath) {
|
|
86
|
+
try {
|
|
87
|
+
const content = git(cwd, ["show", `${ref}:${filePath}`], { buffer: true });
|
|
88
|
+
return {
|
|
89
|
+
present: true,
|
|
90
|
+
sha256: sha256(content),
|
|
91
|
+
bytes: content.length,
|
|
92
|
+
};
|
|
93
|
+
} catch {
|
|
94
|
+
return {
|
|
95
|
+
present: false,
|
|
96
|
+
sha256: "",
|
|
97
|
+
bytes: 0,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function pathEvidence(cwd, ref, paths) {
|
|
103
|
+
return paths.map((filePath) => ({
|
|
104
|
+
path: filePath,
|
|
105
|
+
...fileAtRef(cwd, ref, filePath),
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function readPackageVersion(cwd) {
|
|
110
|
+
const packagePath = path.join(cwd, "package.json");
|
|
111
|
+
if (!fs.existsSync(packagePath)) {
|
|
112
|
+
return "";
|
|
113
|
+
}
|
|
114
|
+
const value = JSON.parse(fs.readFileSync(packagePath, "utf8"));
|
|
115
|
+
return typeof value.version === "string" ? value.version : "";
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function createAnchoredVersionMaterialEvidence({
|
|
119
|
+
cwd = process.cwd(),
|
|
120
|
+
targetChannel = "",
|
|
121
|
+
targetRef = "",
|
|
122
|
+
alphaRef = "",
|
|
123
|
+
releaseRef = "HEAD",
|
|
124
|
+
runLifecycle = true,
|
|
125
|
+
} = {}) {
|
|
126
|
+
const resolvedCwd = path.resolve(cwd);
|
|
127
|
+
const loadedConfig = loadBuildchainConfig(resolvedCwd);
|
|
128
|
+
const versionStrategy = getVersionStrategy(loadedConfig);
|
|
129
|
+
const derivedFiles = loadedConfig
|
|
130
|
+
? discoverConfiguredDerivedVersionMaterial(resolvedCwd, loadedConfig)
|
|
131
|
+
: [];
|
|
132
|
+
const channel = normalizeTargetChannel(targetChannel, targetRef);
|
|
133
|
+
const base = {
|
|
134
|
+
schemaVersion: 1,
|
|
135
|
+
contract: ANCHORED_VERSION_MATERIAL_CONTRACT,
|
|
136
|
+
applicable: false,
|
|
137
|
+
targetChannel: channel,
|
|
138
|
+
targetRef,
|
|
139
|
+
versionStrategy,
|
|
140
|
+
};
|
|
141
|
+
if (
|
|
142
|
+
!loadedConfig ||
|
|
143
|
+
versionStrategy.strategy !== "anchored" ||
|
|
144
|
+
versionStrategy.next !== "manual" ||
|
|
145
|
+
derivedFiles.length === 0
|
|
146
|
+
) {
|
|
147
|
+
return {
|
|
148
|
+
...base,
|
|
149
|
+
reason: "anchored-derived-version-material-not-configured",
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (channel !== "release") {
|
|
153
|
+
return {
|
|
154
|
+
...base,
|
|
155
|
+
reason: "target-channel-is-not-release",
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const initialStatus = gitStatus(resolvedCwd);
|
|
160
|
+
if (initialStatus) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`anchored derived material preflight requires a clean checkout: ${initialStatus}`,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const anchorManifest = loadConfiguredAnchorManifest(resolvedCwd, loadedConfig);
|
|
167
|
+
const version = anchorManifest?.fields?.npmVersion || readPackageVersion(resolvedCwd);
|
|
168
|
+
const lifecycleEnv = {
|
|
169
|
+
BUILDCHAIN_VERSION: version,
|
|
170
|
+
BUILDCHAIN_VERSION_STRATEGY: versionStrategy.strategy,
|
|
171
|
+
BUILDCHAIN_VERSION_NEXT: versionStrategy.next,
|
|
172
|
+
...(anchorManifest
|
|
173
|
+
? {
|
|
174
|
+
BUILDCHAIN_ANCHOR_MANIFEST: anchorManifest.path,
|
|
175
|
+
BUILDCHAIN_ANCHOR_MANIFEST_JSON: JSON.stringify(anchorManifest.fields),
|
|
176
|
+
}
|
|
177
|
+
: {}),
|
|
178
|
+
};
|
|
179
|
+
if (runLifecycle) {
|
|
180
|
+
const installStage = getLifecycleStage(loadedConfig, "install");
|
|
181
|
+
if (installStage) {
|
|
182
|
+
runLifecycleStage({
|
|
183
|
+
cwd: resolvedCwd,
|
|
184
|
+
loadedConfig,
|
|
185
|
+
name: "install",
|
|
186
|
+
stage: installStage,
|
|
187
|
+
env: lifecycleEnv,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
const versionStateStage =
|
|
191
|
+
getLifecycleStage(loadedConfig, "version-state") ||
|
|
192
|
+
getLifecycleStage(loadedConfig, "version_state");
|
|
193
|
+
runLifecycleStage({
|
|
194
|
+
cwd: resolvedCwd,
|
|
195
|
+
loadedConfig,
|
|
196
|
+
name: "version-state",
|
|
197
|
+
stage: versionStateStage,
|
|
198
|
+
env: lifecycleEnv,
|
|
199
|
+
});
|
|
200
|
+
runLifecycleStage({
|
|
201
|
+
cwd: resolvedCwd,
|
|
202
|
+
loadedConfig,
|
|
203
|
+
name: "verify",
|
|
204
|
+
stage: getLifecycleStage(loadedConfig, "verify"),
|
|
205
|
+
env: lifecycleEnv,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
const derivedStatus = gitStatus(resolvedCwd);
|
|
209
|
+
if (derivedStatus) {
|
|
210
|
+
throw new Error(
|
|
211
|
+
`anchored derived version material is stale or hand-edited; derivation changed the committed tree: ${derivedStatus}`,
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const resolvedAlphaRef = alphaRef || resolveLatestAlphaRef(resolvedCwd, targetRef);
|
|
216
|
+
const versionFiles = discoverConfiguredVersionStateFiles(resolvedCwd, loadedConfig)
|
|
217
|
+
.map((file) => file.path);
|
|
218
|
+
const derivedPaths = derivedFiles.map((file) => file.path);
|
|
219
|
+
const allowedPaths = [
|
|
220
|
+
...new Set([
|
|
221
|
+
...versionFiles,
|
|
222
|
+
...(anchorManifest?.path ? [anchorManifest.path] : []),
|
|
223
|
+
...derivedPaths,
|
|
224
|
+
]),
|
|
225
|
+
].sort();
|
|
226
|
+
const changedPaths = git(resolvedCwd, [
|
|
227
|
+
"diff",
|
|
228
|
+
"--name-only",
|
|
229
|
+
resolvedAlphaRef,
|
|
230
|
+
releaseRef,
|
|
231
|
+
"--",
|
|
232
|
+
])
|
|
233
|
+
.trim()
|
|
234
|
+
.split(/\r?\n/)
|
|
235
|
+
.filter(Boolean)
|
|
236
|
+
.sort();
|
|
237
|
+
const allowed = new Set(allowedPaths);
|
|
238
|
+
const unexpectedPaths = changedPaths.filter((filePath) => !allowed.has(filePath));
|
|
239
|
+
if (unexpectedPaths.length > 0) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`anchored release tree changed undeclared paths: ${unexpectedPaths.join(", ")}`,
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const alphaCommit = git(resolvedCwd, ["rev-parse", resolvedAlphaRef]).trim();
|
|
246
|
+
const alphaTree = git(resolvedCwd, ["rev-parse", `${resolvedAlphaRef}^{tree}`]).trim();
|
|
247
|
+
const releaseCommit = git(resolvedCwd, ["rev-parse", releaseRef]).trim();
|
|
248
|
+
const releaseTree = git(resolvedCwd, ["rev-parse", `${releaseRef}^{tree}`]).trim();
|
|
249
|
+
const evidence = {
|
|
250
|
+
...base,
|
|
251
|
+
applicable: true,
|
|
252
|
+
reason: "verified",
|
|
253
|
+
version,
|
|
254
|
+
alpha: {
|
|
255
|
+
ref: resolvedAlphaRef,
|
|
256
|
+
commit: alphaCommit,
|
|
257
|
+
tree: alphaTree,
|
|
258
|
+
material: pathEvidence(resolvedCwd, resolvedAlphaRef, allowedPaths),
|
|
259
|
+
},
|
|
260
|
+
release: {
|
|
261
|
+
ref: releaseRef,
|
|
262
|
+
commit: releaseCommit,
|
|
263
|
+
tree: releaseTree,
|
|
264
|
+
material: pathEvidence(resolvedCwd, releaseRef, allowedPaths),
|
|
265
|
+
},
|
|
266
|
+
allowedPaths,
|
|
267
|
+
versionFiles,
|
|
268
|
+
manifest: anchorManifest?.path || "",
|
|
269
|
+
derivedPaths,
|
|
270
|
+
changedPaths,
|
|
271
|
+
lifecycle: {
|
|
272
|
+
install: Boolean(getLifecycleStage(loadedConfig, "install")),
|
|
273
|
+
derivation: "version-state",
|
|
274
|
+
verification: "verify",
|
|
275
|
+
},
|
|
276
|
+
};
|
|
277
|
+
return {
|
|
278
|
+
...evidence,
|
|
279
|
+
digest: sha256(stableJson(evidence)),
|
|
280
|
+
};
|
|
281
|
+
}
|
|
@@ -220,6 +220,7 @@ export function normalizeBuildchainConfig(config) {
|
|
|
220
220
|
}
|
|
221
221
|
validateWebSurfaceConfig(normalized);
|
|
222
222
|
validateInfraContractConfig(normalized);
|
|
223
|
+
validateAnchoredDerivedVersionMaterialConfig(normalized);
|
|
223
224
|
return normalized;
|
|
224
225
|
}
|
|
225
226
|
|
|
@@ -1087,6 +1088,42 @@ function validateInfraContractConfig(config) {
|
|
|
1087
1088
|
}
|
|
1088
1089
|
}
|
|
1089
1090
|
|
|
1091
|
+
function validateAnchoredDerivedVersionMaterialConfig(config) {
|
|
1092
|
+
const derivedFiles = config.version?.derivedFiles || [];
|
|
1093
|
+
if (derivedFiles.length === 0) {
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (config.version.strategy !== "anchored" || config.version.next !== "manual") {
|
|
1097
|
+
throw new Error(
|
|
1098
|
+
"version.derived_files requires version.strategy = \"anchored\" and version.next = \"manual\"",
|
|
1099
|
+
);
|
|
1100
|
+
}
|
|
1101
|
+
const versionState =
|
|
1102
|
+
config.lifecycle?.["version-state"] ||
|
|
1103
|
+
config.lifecycle?.version_state;
|
|
1104
|
+
if (!versionState) {
|
|
1105
|
+
throw new Error(
|
|
1106
|
+
"version.derived_files requires lifecycle.version-state to regenerate declared material",
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
if (!config.lifecycle?.verify) {
|
|
1110
|
+
throw new Error(
|
|
1111
|
+
"version.derived_files requires lifecycle.verify to validate regenerated material",
|
|
1112
|
+
);
|
|
1113
|
+
}
|
|
1114
|
+
const versionPaths = new Set((config.version.files || []).map((file) => file.path));
|
|
1115
|
+
if (config.version.manifest) {
|
|
1116
|
+
versionPaths.add(config.version.manifest);
|
|
1117
|
+
}
|
|
1118
|
+
for (const filePath of derivedFiles) {
|
|
1119
|
+
if (versionPaths.has(filePath)) {
|
|
1120
|
+
throw new Error(
|
|
1121
|
+
`version.derived_files must not repeat version.files or version.manifest: ${filePath}`,
|
|
1122
|
+
);
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1090
1127
|
function validateWebSurfaceSurfaces(config) {
|
|
1091
1128
|
const surfaces = config.surfaces || {};
|
|
1092
1129
|
for (const [name, surface] of Object.entries(surfaces)) {
|
|
@@ -1129,6 +1166,13 @@ function normalizeVersionSection(version) {
|
|
|
1129
1166
|
if (strategy === "anchored" && next !== "manual") {
|
|
1130
1167
|
throw new Error('version.strategy = "anchored" requires version.next = "manual"');
|
|
1131
1168
|
}
|
|
1169
|
+
const derivedFiles = normalizeStringArray(
|
|
1170
|
+
version.derived_files,
|
|
1171
|
+
"version.derived_files",
|
|
1172
|
+
).map((filePath) => posixPath(filePath));
|
|
1173
|
+
if (new Set(derivedFiles).size !== derivedFiles.length) {
|
|
1174
|
+
throw new Error("version.derived_files must not contain duplicate paths");
|
|
1175
|
+
}
|
|
1132
1176
|
return {
|
|
1133
1177
|
required: version.required === undefined ? false : Boolean(version.required),
|
|
1134
1178
|
strategy,
|
|
@@ -1137,6 +1181,7 @@ function normalizeVersionSection(version) {
|
|
|
1137
1181
|
? undefined
|
|
1138
1182
|
: posixPath(assertString(version.manifest, "version.manifest")),
|
|
1139
1183
|
files: files.map((file, index) => normalizeVersionFile(file, index)),
|
|
1184
|
+
derivedFiles,
|
|
1140
1185
|
};
|
|
1141
1186
|
}
|
|
1142
1187
|
|
|
@@ -1319,6 +1364,27 @@ export function discoverConfiguredVersionStateFiles(cwd = process.cwd(), loadedC
|
|
|
1319
1364
|
return files;
|
|
1320
1365
|
}
|
|
1321
1366
|
|
|
1367
|
+
export function discoverConfiguredDerivedVersionMaterial(
|
|
1368
|
+
cwd = process.cwd(),
|
|
1369
|
+
loadedConfig = loadBuildchainConfig(cwd),
|
|
1370
|
+
) {
|
|
1371
|
+
const configured = loadedConfig?.config?.version?.derivedFiles || [];
|
|
1372
|
+
return configured.map((filePath) => {
|
|
1373
|
+
const absolutePath = path.join(cwd, filePath);
|
|
1374
|
+
if (!fs.existsSync(absolutePath)) {
|
|
1375
|
+
throw new Error(`Configured derived version material does not exist: ${filePath}`);
|
|
1376
|
+
}
|
|
1377
|
+
if (!fs.statSync(absolutePath).isFile()) {
|
|
1378
|
+
throw new Error(`Configured derived version material must be a file: ${filePath}`);
|
|
1379
|
+
}
|
|
1380
|
+
return {
|
|
1381
|
+
path: filePath,
|
|
1382
|
+
filePath: absolutePath,
|
|
1383
|
+
content: fs.readFileSync(absolutePath),
|
|
1384
|
+
};
|
|
1385
|
+
});
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1322
1388
|
function summarizeManifestFields(content) {
|
|
1323
1389
|
assertPlainObject(content, "version.manifest content");
|
|
1324
1390
|
return Object.fromEntries(
|
|
@@ -1499,6 +1565,8 @@ export function validateBuildchainConfig(
|
|
|
1499
1565
|
key: file.key,
|
|
1500
1566
|
pattern: file.pattern?.source,
|
|
1501
1567
|
})),
|
|
1568
|
+
derivedVersionMaterial: discoverConfiguredDerivedVersionMaterial(cwd, loadedConfig)
|
|
1569
|
+
.map((file) => ({ path: file.path })),
|
|
1502
1570
|
lifecycleStages,
|
|
1503
1571
|
publish: loadedConfig.config.publish,
|
|
1504
1572
|
release: loadedConfig.config.release,
|
|
@@ -193,6 +193,8 @@ export function createBuildchainContractWorld({
|
|
|
193
193
|
"release-passport-kfd-3-prebuild-witness-jsons",
|
|
194
194
|
"release-passport-kfd-3-artifact-witness-jsons",
|
|
195
195
|
"release-passport-kfd-3-artifact-verify-command",
|
|
196
|
+
"release-passport-invariant-passport-jsons",
|
|
197
|
+
"release-passport-invariant-passport-command",
|
|
196
198
|
"buildchain-contract-lock-path",
|
|
197
199
|
"buildchain-contract-drift-issue-mode",
|
|
198
200
|
"github-release",
|
|
@@ -319,6 +321,8 @@ export function createBuildchainContractWorld({
|
|
|
319
321
|
"release-passport-kfd-3-prebuild-witness-jsons",
|
|
320
322
|
"release-passport-kfd-3-artifact-witness-jsons",
|
|
321
323
|
"release-passport-kfd-3-artifact-verify-command",
|
|
324
|
+
"release-passport-invariant-passport-jsons",
|
|
325
|
+
"release-passport-invariant-passport-command",
|
|
322
326
|
"github-release",
|
|
323
327
|
"github-release-title",
|
|
324
328
|
"github-release-notes",
|
|
@@ -23,8 +23,20 @@ const CONTROLLER_SPECS = [
|
|
|
23
23
|
workflowId: ".build",
|
|
24
24
|
version: 1,
|
|
25
25
|
capabilities: ["source-lock", "lifecycle-build", "lifecycle-verify", "artifact-admission"],
|
|
26
|
-
stages: [
|
|
27
|
-
|
|
26
|
+
stages: [
|
|
27
|
+
"resolve-runtime",
|
|
28
|
+
"resolve-source",
|
|
29
|
+
"anchored-release-preflight",
|
|
30
|
+
"build",
|
|
31
|
+
"verify",
|
|
32
|
+
"aggregate",
|
|
33
|
+
],
|
|
34
|
+
optionalStages: ["anchored-release-preflight"],
|
|
35
|
+
evidence: [
|
|
36
|
+
"platform-manifests",
|
|
37
|
+
"build-summary",
|
|
38
|
+
"controller-receipt",
|
|
39
|
+
],
|
|
28
40
|
},
|
|
29
41
|
{
|
|
30
42
|
id: "build-channel-router",
|
|
@@ -83,8 +95,22 @@ const CONTROLLER_SPECS = [
|
|
|
83
95
|
workflowId: "release-propagation",
|
|
84
96
|
version: 1,
|
|
85
97
|
capabilities: ["release-propagation-plan", "downstream-lock", "pull-request-handoff"],
|
|
86
|
-
stages: [
|
|
87
|
-
|
|
98
|
+
stages: [
|
|
99
|
+
"resolve-runtime",
|
|
100
|
+
"plan",
|
|
101
|
+
"write-lock",
|
|
102
|
+
"prepare-consumer",
|
|
103
|
+
"refresh-badges",
|
|
104
|
+
"verify-consumer",
|
|
105
|
+
"open-pr",
|
|
106
|
+
"aggregate",
|
|
107
|
+
],
|
|
108
|
+
optionalStages: [
|
|
109
|
+
"prepare-consumer",
|
|
110
|
+
"refresh-badges",
|
|
111
|
+
"verify-consumer",
|
|
112
|
+
"open-pr",
|
|
113
|
+
],
|
|
88
114
|
evidence: ["propagation-plan", "propagation-lock", "controller-receipt"],
|
|
89
115
|
},
|
|
90
116
|
];
|
package/packages/core/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export {
|
|
2
|
+
discoverConfiguredDerivedVersionMaterial,
|
|
2
3
|
discoverConfiguredVersionStateFiles,
|
|
3
4
|
getLifecycleStage,
|
|
4
5
|
getNativeDiagnosticsProfile,
|
|
@@ -14,6 +15,11 @@ export {
|
|
|
14
15
|
validateBuildchainConfig,
|
|
15
16
|
} from "./buildchain-config.js";
|
|
16
17
|
|
|
18
|
+
export {
|
|
19
|
+
ANCHORED_VERSION_MATERIAL_CONTRACT,
|
|
20
|
+
createAnchoredVersionMaterialEvidence,
|
|
21
|
+
} from "./anchored-version-material.js";
|
|
22
|
+
|
|
17
23
|
export {
|
|
18
24
|
STABLE_CANDIDATE_LEDGER_CONTRACT,
|
|
19
25
|
STABLE_CANDIDATE_STATES,
|
|
@@ -87,6 +87,7 @@ export const RELEASE_PASSPORT_SCHEMA = {
|
|
|
87
87
|
surfaceImpacts: { type: "array", items: OBJECT },
|
|
88
88
|
packageSet: OBJECT,
|
|
89
89
|
anchorManifest: OBJECT,
|
|
90
|
+
versionMaterial: OBJECT,
|
|
90
91
|
trustedPublishing: OBJECT,
|
|
91
92
|
transaction: OBJECT,
|
|
92
93
|
surfaceTimestampPolicy: OBJECT,
|
|
@@ -111,6 +112,7 @@ const BUILDCHAIN_AGGREGATION_FIELDS = [
|
|
|
111
112
|
"surfaceImpacts",
|
|
112
113
|
"packageSet",
|
|
113
114
|
"anchorManifest",
|
|
115
|
+
"versionMaterial",
|
|
114
116
|
"trustedPublishing",
|
|
115
117
|
"transaction",
|
|
116
118
|
"surfaceTimestampPolicy",
|