@kungfu-tech/buildchain 3.0.5-alpha.7 → 3.0.5
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 +0 -31
- package/actions/macos-credential-island/README.md +0 -8
- package/bin/buildchain.mjs +1 -1
- package/contracts/auditable-demo-media-profiles-v1.json +0 -61
- package/contracts/evidence/auditable-demo-responsive-web-delivery-v1.json +3 -3
- package/contracts/evidence/auditable-demo-web-delivery-v1.json +3 -3
- package/dist/site/buildchain-contract.json +25 -86
- package/dist/site/buildchain-site.json +38 -64
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/cli-registry.json +2 -6
- package/dist/site/controller-registry.json +3 -11
- package/dist/site/kfd-claims.json +11 -53
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +7 -7
- package/dist/site/node-api-registry.json +31 -213
- package/dist/site/page-registry.json +20 -50
- package/dist/site/public-surface-audit.json +8 -98
- package/dist/site/publication-authority-registry.json +1 -42
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +11 -11
- package/dist/site/workflow-registry.json +2 -67
- package/docs/auditable-demo.md +7 -74
- package/docs/aws-us-elastic-runner-burst-plane.md +16 -151
- package/docs/cli-reference.md +2 -24
- package/docs/node-api-reference.md +72 -90
- package/docs/publish-transaction.md +5 -7
- package/docs/release-flow.md +0 -4
- package/docs/release-governance.md +0 -39
- package/docs/reusable-build-surface.md +0 -9
- package/package.json +1 -1
- package/packages/core/buildchain-contract.js +1 -36
- package/packages/core/buildchain-publication-authority.js +0 -2
- package/packages/core/public-surface-audit.js +35 -4
- package/packages/core/release-propagation-release.js +18 -61
- package/packages/core/release-propagation-work.js +3 -7
- package/packages/core/release-propagation.js +2 -12
- package/scripts/auditable-demo-renditions.mjs +2 -7
- package/scripts/auditable-demo.mjs +21 -27
- package/scripts/aws-windows-jit-controller-core.mjs +2 -20
- package/scripts/aws-windows-jit-controller.mjs +109 -184
- package/scripts/aws-windows-jit-core.mjs +3 -21
- package/scripts/aws-windows-jit.mjs +0 -2
- package/scripts/build-standalone-binary.mjs +0 -4
- package/scripts/buildchain-cli-help.mjs +1 -2
- package/scripts/capture-package-release-propagation.mjs +1 -24
- package/scripts/check-inventory.mjs +0 -5
- package/scripts/finalize-native-artifact-signing-result.mjs +15 -37
- package/scripts/generate-site-bundle.mjs +0 -2
- package/scripts/locked-source-checkout.mjs +3 -17
- package/scripts/release-propagation.mjs +2 -77
- package/contracts/auditable-demo-scenario-v1.schema.json +0 -153
- package/packages/core/release-propagation-pickup.js +0 -386
- package/packages/core/workflow-call-contract.js +0 -308
- package/packages/core/workflow-yaml-contract.js +0 -272
- package/scripts/auditable-demo-platform.mjs +0 -506
- package/scripts/aws-macos-jit-controller-core.mjs +0 -389
- package/scripts/aws-macos-jit-controller-runtime.mjs +0 -82
- package/scripts/aws-macos-jit-controller.mjs +0 -558
- package/scripts/aws-macos-jit-job-controller.mjs +0 -401
- package/scripts/aws-windows-jit-campaign-core.mjs +0 -296
- package/scripts/aws-windows-jit-campaign.mjs +0 -202
- package/scripts/workflow-call-contract.mjs +0 -133
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
artifactSigningEvidenceDigest,
|
|
13
13
|
createArtifactSigningResult,
|
|
14
14
|
} from "../packages/core/artifact-signing-result.js";
|
|
15
|
-
import { acceptedMacosCredentialEvidence } from "../actions/macos-credential-island/dmg-assembly.js";
|
|
16
15
|
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
17
16
|
|
|
18
17
|
function required(value, label) {
|
|
@@ -33,39 +32,15 @@ function resolveBelow(root, relative, label) {
|
|
|
33
32
|
return target;
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
function expectedCredentialExecution(
|
|
37
|
-
appBundleResult,
|
|
38
|
-
expectedRunId,
|
|
39
|
-
expectedRunAttempt,
|
|
40
|
-
) {
|
|
41
|
-
if (!appBundleResult) return null;
|
|
42
|
-
return {
|
|
43
|
-
runId: required(expectedRunId, "credential execution run id"),
|
|
44
|
-
runAttempt: required(
|
|
45
|
-
expectedRunAttempt,
|
|
46
|
-
"credential execution run attempt",
|
|
47
|
-
),
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function acceptedProviderEvidence(evidence, request, expectedExecution) {
|
|
52
|
-
return expectedExecution
|
|
53
|
-
? acceptedMacosCredentialEvidence(evidence, request, expectedExecution)
|
|
54
|
-
: evidence.status === "passed" &&
|
|
55
|
-
evidence.provider === request.signature.provider;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
35
|
export function finalizeNativeArtifactSigningResult({
|
|
59
36
|
requestRoot = process.env.BUILDCHAIN_SIGNING_REQUEST_ROOT,
|
|
60
37
|
requestPath = process.env.BUILDCHAIN_SIGNING_REQUEST_PATH,
|
|
61
38
|
signedPayload = process.env.BUILDCHAIN_SIGNED_PAYLOAD,
|
|
62
39
|
evidencePath = process.env.BUILDCHAIN_SIGNING_EVIDENCE,
|
|
63
|
-
credentialArtifactRoot =
|
|
64
|
-
.BUILDCHAIN_SIGNING_CREDENTIAL_ARTIFACT_ROOT,
|
|
40
|
+
credentialArtifactRoot =
|
|
41
|
+
process.env.BUILDCHAIN_SIGNING_CREDENTIAL_ARTIFACT_ROOT,
|
|
65
42
|
outputRoot = process.env.BUILDCHAIN_SIGNING_RESULT_ROOT,
|
|
66
43
|
checks = process.env.BUILDCHAIN_SIGNING_VERIFICATION_CHECKS,
|
|
67
|
-
expectedRunId = process.env.GITHUB_RUN_ID,
|
|
68
|
-
expectedRunAttempt = process.env.GITHUB_RUN_ATTEMPT,
|
|
69
44
|
} = {}) {
|
|
70
45
|
const requests = path.resolve(required(requestRoot, "signing request root"));
|
|
71
46
|
const request = JSON.parse(
|
|
@@ -102,16 +77,19 @@ export function finalizeNativeArtifactSigningResult({
|
|
|
102
77
|
fs.copyFileSync(evidenceSource, evidenceOutput, fs.constants.COPYFILE_EXCL);
|
|
103
78
|
const evidenceDocument = JSON.parse(fs.readFileSync(evidenceOutput, "utf8"));
|
|
104
79
|
const appBundleResult = request.artifact.kind === "app-bundle";
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
80
|
+
const providerEvidencePassed = appBundleResult
|
|
81
|
+
? evidenceDocument.schema ===
|
|
82
|
+
"buildchain.macos-credential-island-evidence/v1" &&
|
|
83
|
+
evidenceDocument.status === "accepted" &&
|
|
84
|
+
evidenceDocument.source?.repository === request.source.repository &&
|
|
85
|
+
evidenceDocument.source?.sha === request.source.sha &&
|
|
86
|
+
evidenceDocument.source?.treeSha === request.source.treeSha &&
|
|
87
|
+
evidenceDocument.buildchain?.runtimeSha === request.runtime.sha &&
|
|
88
|
+
evidenceDocument.app?.architecture === request.artifact.arch &&
|
|
89
|
+
evidenceDocument.notarization?.application?.status === "Accepted" &&
|
|
90
|
+
evidenceDocument.notarization?.diskImage?.status === "Accepted"
|
|
91
|
+
: evidenceDocument.status === "passed" &&
|
|
92
|
+
evidenceDocument.provider === request.signature.provider;
|
|
115
93
|
if (!providerEvidencePassed) {
|
|
116
94
|
throw new Error(
|
|
117
95
|
"provider evidence does not prove the requested native signature",
|
|
@@ -767,7 +767,6 @@ function buildSiteBundle() {
|
|
|
767
767
|
["build", "channel-build-router"],
|
|
768
768
|
[".build", "reusable-build"],
|
|
769
769
|
[".auditable-demo", "auditable-demo"],
|
|
770
|
-
[".declarative-auditable-demo", "declarative-auditable-demo"],
|
|
771
770
|
["web-surface", "site-app-deployment"],
|
|
772
771
|
["buildchain-ref-promotion", "release-governance"],
|
|
773
772
|
["release-line-bootstrap", "release-governance"],
|
|
@@ -794,7 +793,6 @@ function buildSiteBundle() {
|
|
|
794
793
|
]);
|
|
795
794
|
const statusById = new Map([
|
|
796
795
|
[".auditable-demo", "preview"],
|
|
797
|
-
[".declarative-auditable-demo", "preview"],
|
|
798
796
|
["release-propagation", "preview"],
|
|
799
797
|
["candidate-lab", "repository-internal"],
|
|
800
798
|
["build-surface-fixture", "repository-internal"],
|
|
@@ -46,14 +46,6 @@ function normalizeFallback(value = "github") {
|
|
|
46
46
|
return fallback;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function normalizeHistoryMode(value = "shallow") {
|
|
50
|
-
const mode = String(value || "shallow").trim().toLowerCase() || "shallow";
|
|
51
|
-
if (!["shallow", "full"].includes(mode)) {
|
|
52
|
-
throw new Error(`checkout-history-mode must be shallow or full; got ${value}`);
|
|
53
|
-
}
|
|
54
|
-
return mode;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
49
|
function splitRepository(repository) {
|
|
58
50
|
const match = String(repository || "").trim().match(/^([^/\s]+)\/([^/\s]+)$/);
|
|
59
51
|
if (!match) {
|
|
@@ -245,25 +237,19 @@ export function fetchSourceCommit({
|
|
|
245
237
|
sourceTreeSha = "",
|
|
246
238
|
timeoutMs,
|
|
247
239
|
env = {},
|
|
248
|
-
historyMode = readEnv("BUILDCHAIN_CHECKOUT_HISTORY_MODE", "shallow"),
|
|
249
240
|
allowFullFetchRetry = false,
|
|
250
241
|
runGit = git,
|
|
251
242
|
containsCommit = hasCommit,
|
|
252
243
|
}) {
|
|
253
|
-
const normalizedHistoryMode = normalizeHistoryMode(historyMode);
|
|
254
244
|
const fetchEnv = isolatedGitFetchEnv(env, targetPath);
|
|
255
245
|
const fetch = (refspec) => {
|
|
256
246
|
const options = { cwd: targetPath, timeoutMs, env: fetchEnv };
|
|
257
|
-
const fetchArgs = ["fetch", "--no-tags"];
|
|
258
|
-
if (normalizedHistoryMode === "shallow") fetchArgs.push("--depth=1");
|
|
259
|
-
fetchArgs.push(remoteName, refspec);
|
|
260
247
|
try {
|
|
261
|
-
runGit(
|
|
262
|
-
return
|
|
248
|
+
runGit(["fetch", "--no-tags", "--depth=1", remoteName, refspec], options);
|
|
249
|
+
return "shallow";
|
|
263
250
|
} catch (error) {
|
|
264
251
|
if (
|
|
265
|
-
|
|
266
|
-
|| !allowFullFetchRetry
|
|
252
|
+
!allowFullFetchRetry
|
|
267
253
|
|| !/dumb http transport does not support shallow capabilities/i.test(
|
|
268
254
|
String(error?.message || error || ""),
|
|
269
255
|
)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { execFileSync } from "node:child_process";
|
|
5
4
|
import { pathToFileURL } from "node:url";
|
|
6
5
|
import {
|
|
7
6
|
claimReleasePropagationWork,
|
|
@@ -16,10 +15,6 @@ import {
|
|
|
16
15
|
resumeReleasePropagationWork,
|
|
17
16
|
verifyReleasePropagationWork,
|
|
18
17
|
writeReleasePropagationLock,
|
|
19
|
-
createManualUpstreamPickupCapture,
|
|
20
|
-
createManualUpstreamPickupPlan,
|
|
21
|
-
normalizeManualUpstreamPickupConfig,
|
|
22
|
-
resolveNpmRegistryRelease,
|
|
23
18
|
} from "../packages/core/release-propagation.js";
|
|
24
19
|
|
|
25
20
|
function usage() {
|
|
@@ -66,15 +61,6 @@ function usage() {
|
|
|
66
61
|
--completion-decision <json-or-path>
|
|
67
62
|
--expected-work-root <sha256:...>
|
|
68
63
|
[--output <file>] [--json]
|
|
69
|
-
buildchain release-propagation pickup plan --config <json-or-path>
|
|
70
|
-
--source-id <id> --channel <alpha|release>
|
|
71
|
-
--current-version <version>
|
|
72
|
-
[--output <file>] [--json]
|
|
73
|
-
buildchain release-propagation pickup create --config <json-or-path>
|
|
74
|
-
--source-id <id> --channel <alpha|release>
|
|
75
|
-
--current-version <version>
|
|
76
|
-
--expected-downstream-base-sha <git-sha>
|
|
77
|
-
[--output <file>] [--json]
|
|
78
64
|
`;
|
|
79
65
|
}
|
|
80
66
|
|
|
@@ -185,61 +171,7 @@ function runWorkCli(args) {
|
|
|
185
171
|
throw new Error(`unsupported release-propagation work command: ${mode}`);
|
|
186
172
|
}
|
|
187
173
|
|
|
188
|
-
|
|
189
|
-
const config = normalizeManualUpstreamPickupConfig(readJsonFlag(args, "config"));
|
|
190
|
-
const sourceId = readFlag(args, "source-id");
|
|
191
|
-
const channel = readFlag(args, "channel");
|
|
192
|
-
const source = config.sources.find((entry) => entry.id === sourceId);
|
|
193
|
-
if (!source) throw new Error(`manual pickup source is not configured: ${sourceId}`);
|
|
194
|
-
const distTag = source.distTags[channel];
|
|
195
|
-
if (!distTag) throw new Error("manual pickup channel must be alpha or release");
|
|
196
|
-
const packageMetadata = args.includes("--package-metadata")
|
|
197
|
-
? readJsonFlag(args, "package-metadata")
|
|
198
|
-
: JSON.parse(execFileSync("npm", ["view", `${source.package}@${distTag}`, "--json", "--registry=https://registry.npmjs.org/"], {
|
|
199
|
-
encoding: "utf8",
|
|
200
|
-
maxBuffer: 16 * 1024 * 1024,
|
|
201
|
-
}));
|
|
202
|
-
const attestationUrl = packageMetadata.dist?.attestations?.url;
|
|
203
|
-
if (!attestationUrl) throw new Error("published npm package does not expose an attestation URL");
|
|
204
|
-
let attestations;
|
|
205
|
-
if (args.includes("--attestations")) {
|
|
206
|
-
attestations = readJsonFlag(args, "attestations");
|
|
207
|
-
} else {
|
|
208
|
-
const response = await fetch(attestationUrl, { headers: { accept: "application/json" } });
|
|
209
|
-
if (!response.ok) throw new Error(`npm attestation lookup failed: HTTP ${response.status}`);
|
|
210
|
-
attestations = await response.json();
|
|
211
|
-
}
|
|
212
|
-
const upstreamRelease = resolveNpmRegistryRelease({ source, channel, packageMetadata, attestations });
|
|
213
|
-
return createManualUpstreamPickupPlan({
|
|
214
|
-
config,
|
|
215
|
-
sourceId,
|
|
216
|
-
channel,
|
|
217
|
-
currentVersion: readFlag(args, "current-version"),
|
|
218
|
-
upstreamRelease,
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async function runPickupCli(args) {
|
|
223
|
-
const [mode = "", ...pickupArgs] = args;
|
|
224
|
-
if (!mode || mode === "--help" || mode === "-h") {
|
|
225
|
-
process.stdout.write(usage());
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
if (mode !== "plan" && mode !== "create") throw new Error(`unsupported release-propagation pickup command: ${mode}`);
|
|
229
|
-
const plan = await resolvePickupPlan(pickupArgs);
|
|
230
|
-
const result = mode === "create"
|
|
231
|
-
? createManualUpstreamPickupCapture({
|
|
232
|
-
plan,
|
|
233
|
-
expectedDownstreamBaseSha: readFlag(pickupArgs, "expected-downstream-base-sha"),
|
|
234
|
-
})
|
|
235
|
-
: plan;
|
|
236
|
-
writeOutput(readFlag(pickupArgs, "output", ""), result);
|
|
237
|
-
if (hasFlag(pickupArgs, "json")) printJson(result);
|
|
238
|
-
else if (mode === "plan") process.stdout.write(`manual upstream pickup: ${plan.source.id} ${plan.currentVersion} -> ${plan.resolvedVersion} (${plan.status})\n`);
|
|
239
|
-
else process.stdout.write(`manual upstream pickup next action: ${result.nextAction}\n`);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export async function runReleasePropagationCli(argv = process.argv.slice(2)) {
|
|
174
|
+
export function runReleasePropagationCli(argv = process.argv.slice(2)) {
|
|
243
175
|
const [mode = "", ...args] = argv;
|
|
244
176
|
if (!mode || mode === "--help" || mode === "-h") {
|
|
245
177
|
process.stdout.write(usage());
|
|
@@ -274,10 +206,6 @@ export async function runReleasePropagationCli(argv = process.argv.slice(2)) {
|
|
|
274
206
|
runWorkCli(args);
|
|
275
207
|
return;
|
|
276
208
|
}
|
|
277
|
-
if (mode === "pickup") {
|
|
278
|
-
await runPickupCli(args);
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
209
|
if (mode === "write-lock") {
|
|
282
210
|
const plan = readReleasePropagationJson(readFlag(args, "plan"), {
|
|
283
211
|
label: "--plan",
|
|
@@ -331,8 +259,5 @@ export async function runReleasePropagationCli(argv = process.argv.slice(2)) {
|
|
|
331
259
|
}
|
|
332
260
|
|
|
333
261
|
if (!process.env.BUILDCHAIN_EMBEDDED_ENTRYPOINT && process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
334
|
-
runReleasePropagationCli()
|
|
335
|
-
console.error(`buildchain release-propagation: ${error.message}`);
|
|
336
|
-
process.exitCode = 1;
|
|
337
|
-
});
|
|
262
|
+
runReleasePropagationCli();
|
|
338
263
|
}
|
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://buildchain.libkungfu.dev/contracts/auditable-demo-scenario-v1.schema.json",
|
|
4
|
-
"title": "Buildchain declarative binary auditable demo",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"additionalProperties": false,
|
|
7
|
-
"required": ["schema", "product", "artifact", "execution", "renditions", "demos", "publication", "authority"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"schema": {"const": "buildchain.declarative-binary-demo/v1"},
|
|
10
|
-
"product": {
|
|
11
|
-
"type": "object",
|
|
12
|
-
"additionalProperties": false,
|
|
13
|
-
"required": ["id", "displayName", "binaryName"],
|
|
14
|
-
"properties": {
|
|
15
|
-
"id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$"},
|
|
16
|
-
"displayName": {"type": "string", "minLength": 1, "maxLength": 80},
|
|
17
|
-
"binaryName": {"type": "string", "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$"}
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
|
-
"artifact": {
|
|
21
|
-
"type": "object",
|
|
22
|
-
"additionalProperties": false,
|
|
23
|
-
"required": ["platformId", "binaryPath", "metadataPath", "metadataContract", "runtimeDependencies"],
|
|
24
|
-
"properties": {
|
|
25
|
-
"platformId": {"const": "linux-x64"},
|
|
26
|
-
"binaryPath": {"type": "string", "minLength": 1},
|
|
27
|
-
"metadataPath": {"type": "string", "minLength": 1},
|
|
28
|
-
"metadataContract": {"type": "string", "minLength": 1},
|
|
29
|
-
"runtimeDependencies": {"type": "array", "maxItems": 0}
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
"execution": {
|
|
33
|
-
"type": "object",
|
|
34
|
-
"additionalProperties": false,
|
|
35
|
-
"required": ["deterministic", "network", "secrets", "totalTimeoutSeconds", "environment"],
|
|
36
|
-
"properties": {
|
|
37
|
-
"deterministic": {"const": true},
|
|
38
|
-
"network": {"const": "none"},
|
|
39
|
-
"secrets": {"const": "none"},
|
|
40
|
-
"durationClass": {"type": "string", "enum": ["standard", "long-form"]},
|
|
41
|
-
"totalTimeoutSeconds": {"type": "integer", "minimum": 1},
|
|
42
|
-
"environment": {
|
|
43
|
-
"type": "object",
|
|
44
|
-
"propertyNames": {"pattern": "^[A-Z][A-Z0-9_]{0,63}$"},
|
|
45
|
-
"additionalProperties": {"type": "string", "maxLength": 256}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
},
|
|
49
|
-
"renditions": {
|
|
50
|
-
"const": [
|
|
51
|
-
{"id": "1080p", "role": "primary", "columns": 150, "rows": 36, "width": 1920, "height": 1080},
|
|
52
|
-
{"id": "720p", "role": "responsive", "columns": 100, "rows": 28, "width": 1280, "height": 720}
|
|
53
|
-
]
|
|
54
|
-
},
|
|
55
|
-
"demos": {
|
|
56
|
-
"type": "array",
|
|
57
|
-
"minItems": 1,
|
|
58
|
-
"maxItems": 8,
|
|
59
|
-
"items": {
|
|
60
|
-
"type": "object",
|
|
61
|
-
"additionalProperties": false,
|
|
62
|
-
"required": ["id", "title", "claimBoundary", "steps"],
|
|
63
|
-
"properties": {
|
|
64
|
-
"id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$"},
|
|
65
|
-
"title": {"type": "string", "minLength": 1, "maxLength": 120},
|
|
66
|
-
"claimBoundary": {"type": "string", "minLength": 1, "maxLength": 500},
|
|
67
|
-
"steps": {
|
|
68
|
-
"type": "array",
|
|
69
|
-
"minItems": 1,
|
|
70
|
-
"maxItems": 12,
|
|
71
|
-
"items": {
|
|
72
|
-
"type": "object",
|
|
73
|
-
"additionalProperties": false,
|
|
74
|
-
"required": ["id", "argv", "timeoutSeconds", "expectedExitCodes", "stdoutIncludes", "fileAssertions"],
|
|
75
|
-
"properties": {
|
|
76
|
-
"id": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$"},
|
|
77
|
-
"argv": {"type": "array", "minItems": 1, "maxItems": 64, "items": {"type": "string", "maxLength": 512}},
|
|
78
|
-
"timeoutSeconds": {"type": "integer", "minimum": 1, "maximum": 180},
|
|
79
|
-
"expectedExitCodes": {"type": "array", "minItems": 1, "maxItems": 4, "items": {"type": "integer", "minimum": 0, "maximum": 255}},
|
|
80
|
-
"stdoutIncludes": {"type": "array", "maxItems": 32, "items": {"type": "string", "minLength": 1, "maxLength": 256}},
|
|
81
|
-
"fileAssertions": {
|
|
82
|
-
"type": "array",
|
|
83
|
-
"maxItems": 32,
|
|
84
|
-
"items": {
|
|
85
|
-
"type": "object",
|
|
86
|
-
"additionalProperties": false,
|
|
87
|
-
"required": ["path", "jsonEquals"],
|
|
88
|
-
"properties": {
|
|
89
|
-
"path": {"type": "string", "minLength": 1},
|
|
90
|
-
"jsonEquals": {"type": "object"}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
"publication": {
|
|
101
|
-
"type": "object",
|
|
102
|
-
"additionalProperties": false,
|
|
103
|
-
"required": ["evidencePath", "readmePath", "marker"],
|
|
104
|
-
"properties": {
|
|
105
|
-
"evidencePath": {"type": "string", "minLength": 1},
|
|
106
|
-
"readmePath": {"type": "string", "minLength": 1},
|
|
107
|
-
"marker": {"type": "string", "pattern": "^[a-z0-9][a-z0-9._:-]{0,79}$"}
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
"authority": {
|
|
111
|
-
"type": "object",
|
|
112
|
-
"additionalProperties": false,
|
|
113
|
-
"required": ["grants", "nonAuthorities"],
|
|
114
|
-
"properties": {
|
|
115
|
-
"grants": {"type": "array", "maxItems": 0},
|
|
116
|
-
"nonAuthorities": {"type": "array", "minItems": 8, "uniqueItems": true, "items": {"type": "string"}}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
"allOf": [
|
|
121
|
-
{
|
|
122
|
-
"if": {
|
|
123
|
-
"properties": {
|
|
124
|
-
"execution": {
|
|
125
|
-
"required": ["durationClass"],
|
|
126
|
-
"properties": {"durationClass": {"const": "long-form"}}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
},
|
|
130
|
-
"then": {
|
|
131
|
-
"properties": {
|
|
132
|
-
"execution": {"properties": {"totalTimeoutSeconds": {"maximum": 180}}}
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
"else": {
|
|
136
|
-
"properties": {
|
|
137
|
-
"execution": {"properties": {"totalTimeoutSeconds": {"maximum": 60}}},
|
|
138
|
-
"demos": {
|
|
139
|
-
"items": {
|
|
140
|
-
"properties": {
|
|
141
|
-
"steps": {
|
|
142
|
-
"items": {
|
|
143
|
-
"properties": {"timeoutSeconds": {"maximum": 60}}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
]
|
|
153
|
-
}
|