@kungfu-tech/buildchain 2.3.2-alpha.0 → 2.4.0-alpha.1
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/bin/buildchain.mjs +35 -1
- package/dist/site/artifact-schemas.json +5 -0
- package/dist/site/buildchain-site.json +7 -0
- package/dist/site/cli-registry.json +11 -1
- package/dist/site/site-manifest.json +7 -0
- package/docs/MAP.md +3 -0
- package/docs/cli.md +24 -2
- package/docs/infra-contract.md +208 -0
- package/docs/lifecycle-protocol.md +12 -0
- package/docs/versioning.md +1 -0
- package/fixtures/infra-contract-aws-cdk-shaped/README.md +8 -0
- package/fixtures/infra-contract-aws-cli-shaped/README.md +7 -0
- package/fixtures/infra-contract-cloudformation-shaped/README.md +7 -0
- package/fixtures/infra-contract-opentofu-shaped/README.md +7 -0
- package/fixtures/infra-contract-pulumi-shaped/README.md +7 -0
- package/fixtures/infra-contract-shaped/README.md +8 -0
- package/fixtures/infra-contract-terraform-shaped/README.md +5 -0
- package/package.json +2 -1
- package/packages/core/buildchain-config.js +139 -2
- package/scripts/generate-site-bundle.mjs +9 -1
- package/scripts/infra-contract-core.mjs +1032 -0
- package/scripts/infra-contract.mjs +345 -0
- package/scripts/init-repo.mjs +85 -4
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
import {
|
|
6
|
+
applyInfraContract,
|
|
7
|
+
applyInfraContractPropagation,
|
|
8
|
+
createInfraContractArtifact,
|
|
9
|
+
createInfraContractEvidenceBundle,
|
|
10
|
+
createInfraContractPlan,
|
|
11
|
+
createInfraContractPropagationPlan,
|
|
12
|
+
validateInfraContractProject,
|
|
13
|
+
verifyInfraContractEvidenceBundle,
|
|
14
|
+
} from "./infra-contract-core.mjs";
|
|
15
|
+
import { writeGitHubOutputs } from "./build-contract-core.mjs";
|
|
16
|
+
|
|
17
|
+
const INFRA_CONTRACT_CI_CONTRACT = "kungfu-buildchain-infra-contract-ci";
|
|
18
|
+
|
|
19
|
+
function readArg(name, fallback = "") {
|
|
20
|
+
const index = process.argv.indexOf(`--${name}`);
|
|
21
|
+
if (index === -1) {
|
|
22
|
+
return fallback;
|
|
23
|
+
}
|
|
24
|
+
return process.argv[index + 1] || "";
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readRepeatedArg(name) {
|
|
28
|
+
const values = [];
|
|
29
|
+
for (let index = 0; index < process.argv.length; index += 1) {
|
|
30
|
+
if (process.argv[index] === `--${name}` && process.argv[index + 1]) {
|
|
31
|
+
values.push(process.argv[index + 1]);
|
|
32
|
+
index += 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return values;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function readBooleanArg(name, fallback = true) {
|
|
39
|
+
const value = readArg(name, "");
|
|
40
|
+
if (!value) {
|
|
41
|
+
return fallback;
|
|
42
|
+
}
|
|
43
|
+
return value === "true" || value === "1";
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function readNumberArg(name, fallback) {
|
|
47
|
+
const value = readArg(name, "");
|
|
48
|
+
if (!value) {
|
|
49
|
+
return fallback;
|
|
50
|
+
}
|
|
51
|
+
const parsed = Number(value);
|
|
52
|
+
if (!Number.isFinite(parsed)) {
|
|
53
|
+
throw new Error(`--${name} must be a number`);
|
|
54
|
+
}
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function readNumberEnv(name, fallback) {
|
|
59
|
+
const value = process.env[name] || "";
|
|
60
|
+
if (!value) {
|
|
61
|
+
return fallback;
|
|
62
|
+
}
|
|
63
|
+
const parsed = Number(value);
|
|
64
|
+
if (!Number.isFinite(parsed)) {
|
|
65
|
+
throw new Error(`${name} must be a number`);
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function writeJson(result, outputPath) {
|
|
71
|
+
const json = `${JSON.stringify(result, null, 2)}\n`;
|
|
72
|
+
if (outputPath) {
|
|
73
|
+
fs.mkdirSync(path.dirname(path.resolve(outputPath)), { recursive: true });
|
|
74
|
+
fs.writeFileSync(outputPath, json);
|
|
75
|
+
} else {
|
|
76
|
+
process.stdout.write(json);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function writeJsonFile(result, filePath) {
|
|
81
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
82
|
+
fs.writeFileSync(filePath, `${JSON.stringify(result, null, 2)}\n`);
|
|
83
|
+
return filePath;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function posixRelative(cwd, filePath) {
|
|
87
|
+
return path.relative(cwd, filePath).split(path.sep).join("/");
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function readJsonFileArg(name) {
|
|
91
|
+
const value = readArg(name, "");
|
|
92
|
+
if (!value) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return JSON.parse(fs.readFileSync(path.resolve(value), "utf8"));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function readKeyValueMapArg(name) {
|
|
99
|
+
const entries = {};
|
|
100
|
+
for (const value of readRepeatedArg(name)) {
|
|
101
|
+
const separator = value.indexOf("=");
|
|
102
|
+
if (separator <= 0) {
|
|
103
|
+
throw new Error(`--${name} must use key=value`);
|
|
104
|
+
}
|
|
105
|
+
entries[value.slice(0, separator)] = value.slice(separator + 1);
|
|
106
|
+
}
|
|
107
|
+
return entries;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function infraContractCli() {
|
|
111
|
+
const mode = readArg("mode", process.env.BUILDCHAIN_INFRA_CONTRACT_MODE || "validate");
|
|
112
|
+
const cwd = readArg("cwd", process.env.BUILDCHAIN_WORKDIR || process.cwd());
|
|
113
|
+
const sourceSha = readArg("source-sha", process.env.BUILDCHAIN_SOURCE_SHA || process.env.GITHUB_SHA || "");
|
|
114
|
+
const output = readArg("output", process.env.BUILDCHAIN_INFRA_CONTRACT_OUTPUT || "");
|
|
115
|
+
|
|
116
|
+
if (mode === "validate") {
|
|
117
|
+
const result = validateInfraContractProject(cwd);
|
|
118
|
+
writeJson(result, output);
|
|
119
|
+
writeGitHubOutputs({
|
|
120
|
+
"project-type": result.project?.type || "",
|
|
121
|
+
"infra-adapter": result.infra?.adapter || "",
|
|
122
|
+
"infra-adoption-mode": result.infra?.adoptionMode || "",
|
|
123
|
+
"infra-apply-mode": result.infra?.applyMode || "",
|
|
124
|
+
});
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (mode === "ci") {
|
|
129
|
+
const outputDir = path.resolve(cwd, readArg("output-dir", process.env.BUILDCHAIN_INFRA_CONTRACT_OUTPUT_DIR || ".buildchain"));
|
|
130
|
+
const files = {
|
|
131
|
+
validation: path.join(outputDir, "infra-contract-validate.json"),
|
|
132
|
+
plan: path.join(outputDir, "infra-contract-plan.json"),
|
|
133
|
+
artifact: path.join(outputDir, "buildchain.infra-contract.json"),
|
|
134
|
+
propagationPlan: path.join(outputDir, "infra-contract-propagation.json"),
|
|
135
|
+
propagationResult: path.join(outputDir, "infra-contract-propagation-apply.json"),
|
|
136
|
+
applyResult: path.join(outputDir, "infra-contract-apply.json"),
|
|
137
|
+
evidenceBundle: path.join(outputDir, "infra-contract-evidence-bundle.json"),
|
|
138
|
+
verification: path.join(outputDir, "infra-contract-evidence-verification.json"),
|
|
139
|
+
};
|
|
140
|
+
const validation = validateInfraContractProject(cwd);
|
|
141
|
+
writeJsonFile(validation, files.validation);
|
|
142
|
+
const executeAdapterCommands = readBooleanArg("execute-adapter-commands", false);
|
|
143
|
+
const plan = createInfraContractPlan({
|
|
144
|
+
cwd,
|
|
145
|
+
sourceSha,
|
|
146
|
+
executeAdapterCommands,
|
|
147
|
+
});
|
|
148
|
+
writeJsonFile(plan, files.plan);
|
|
149
|
+
const artifact = createInfraContractArtifact({
|
|
150
|
+
cwd,
|
|
151
|
+
sourceSha,
|
|
152
|
+
plan,
|
|
153
|
+
approvedBy: readArg("approved-by", process.env.GITHUB_ACTOR || ""),
|
|
154
|
+
approvalId: readArg("approval-id", ""),
|
|
155
|
+
applyRunId: readArg("apply-run-id", process.env.GITHUB_RUN_ID || ""),
|
|
156
|
+
rollbackPointer: readArg("rollback-pointer", process.env.BUILDCHAIN_ROLLBACK_REF || ""),
|
|
157
|
+
executeAdapterCommands,
|
|
158
|
+
});
|
|
159
|
+
writeJsonFile(artifact, files.artifact);
|
|
160
|
+
const propagationPlan = createInfraContractPropagationPlan({
|
|
161
|
+
cwd,
|
|
162
|
+
artifact,
|
|
163
|
+
branchPrefix: readArg("branch-prefix", "buildchain/infra-contract"),
|
|
164
|
+
});
|
|
165
|
+
writeJsonFile(propagationPlan, files.propagationPlan);
|
|
166
|
+
const propagationResult = (artifact.consumers || []).length > 0
|
|
167
|
+
? applyInfraContractPropagation({
|
|
168
|
+
cwd,
|
|
169
|
+
artifact,
|
|
170
|
+
propagationPlan,
|
|
171
|
+
dryRun: true,
|
|
172
|
+
})
|
|
173
|
+
: null;
|
|
174
|
+
if (propagationResult) {
|
|
175
|
+
writeJsonFile(propagationResult, files.propagationResult);
|
|
176
|
+
}
|
|
177
|
+
let applyResult = null;
|
|
178
|
+
if (artifact.apply?.enabled) {
|
|
179
|
+
const approvalId = readArg("approval-id", "");
|
|
180
|
+
if (!approvalId) {
|
|
181
|
+
throw new Error("infra-contract ci requires --approval-id for apply-enabled contracts");
|
|
182
|
+
}
|
|
183
|
+
applyResult = applyInfraContract({
|
|
184
|
+
cwd,
|
|
185
|
+
sourceSha,
|
|
186
|
+
approvalId,
|
|
187
|
+
dryRun: true,
|
|
188
|
+
plan,
|
|
189
|
+
planMaxAgeMinutes: readNumberArg(
|
|
190
|
+
"plan-max-age-minutes",
|
|
191
|
+
readNumberEnv("BUILDCHAIN_INFRA_CONTRACT_PLAN_MAX_AGE_MINUTES", 60),
|
|
192
|
+
),
|
|
193
|
+
});
|
|
194
|
+
writeJsonFile(applyResult, files.applyResult);
|
|
195
|
+
}
|
|
196
|
+
const evidenceBundle = createInfraContractEvidenceBundle({
|
|
197
|
+
artifact,
|
|
198
|
+
applyResult,
|
|
199
|
+
propagationResult,
|
|
200
|
+
});
|
|
201
|
+
writeJsonFile(evidenceBundle, files.evidenceBundle);
|
|
202
|
+
const verification = verifyInfraContractEvidenceBundle(evidenceBundle);
|
|
203
|
+
writeJsonFile(verification, files.verification);
|
|
204
|
+
if (!verification.ok) {
|
|
205
|
+
throw new Error(`infra-contract ci evidence verification failed: ${verification.issues.map((issue) => issue.code).join(", ")}`);
|
|
206
|
+
}
|
|
207
|
+
const result = {
|
|
208
|
+
schemaVersion: 1,
|
|
209
|
+
contract: INFRA_CONTRACT_CI_CONTRACT,
|
|
210
|
+
cwd,
|
|
211
|
+
sourceSha,
|
|
212
|
+
artifactHash: artifact.artifactHash,
|
|
213
|
+
evidenceBundleHash: evidenceBundle.bundleHash,
|
|
214
|
+
verificationOk: verification.ok,
|
|
215
|
+
mutationAllowed: false,
|
|
216
|
+
mutationExecuted: false,
|
|
217
|
+
propagationPlanned: Boolean(propagationResult),
|
|
218
|
+
files: Object.fromEntries(
|
|
219
|
+
Object.entries(files)
|
|
220
|
+
.filter(([, filePath]) => fs.existsSync(filePath))
|
|
221
|
+
.map(([key, filePath]) => [key, posixRelative(cwd, filePath)]),
|
|
222
|
+
),
|
|
223
|
+
};
|
|
224
|
+
writeJson(result, output);
|
|
225
|
+
writeGitHubOutputs({
|
|
226
|
+
"infra-contract-hash": artifact.artifactHash,
|
|
227
|
+
"infra-evidence-bundle-hash": evidenceBundle.bundleHash,
|
|
228
|
+
"infra-evidence-verification-ok": String(verification.ok),
|
|
229
|
+
"infra-ci-json": JSON.stringify(result),
|
|
230
|
+
});
|
|
231
|
+
return result;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (mode === "plan") {
|
|
235
|
+
const result = createInfraContractPlan({
|
|
236
|
+
cwd,
|
|
237
|
+
sourceSha,
|
|
238
|
+
executeAdapterCommands: readBooleanArg("execute-adapter-commands", false),
|
|
239
|
+
});
|
|
240
|
+
writeJson(result, output);
|
|
241
|
+
writeGitHubOutputs({
|
|
242
|
+
"infra-plan-hash": result.planHash,
|
|
243
|
+
"infra-plan-json": JSON.stringify(result),
|
|
244
|
+
});
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (mode === "contract") {
|
|
249
|
+
const plan = readJsonFileArg("plan");
|
|
250
|
+
const result = createInfraContractArtifact({
|
|
251
|
+
cwd,
|
|
252
|
+
sourceSha,
|
|
253
|
+
plan,
|
|
254
|
+
approvedBy: readArg("approved-by", process.env.GITHUB_ACTOR || ""),
|
|
255
|
+
approvalId: readArg("approval-id", ""),
|
|
256
|
+
applyRunId: readArg("apply-run-id", process.env.GITHUB_RUN_ID || ""),
|
|
257
|
+
rollbackPointer: readArg("rollback-pointer", process.env.BUILDCHAIN_ROLLBACK_REF || ""),
|
|
258
|
+
executeAdapterCommands: readBooleanArg("execute-adapter-commands", false),
|
|
259
|
+
});
|
|
260
|
+
writeJson(result, output);
|
|
261
|
+
writeGitHubOutputs({
|
|
262
|
+
"infra-contract-hash": result.artifactHash,
|
|
263
|
+
"infra-contract-json": JSON.stringify(result),
|
|
264
|
+
});
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (mode === "propagation-plan") {
|
|
269
|
+
const artifact = readJsonFileArg("artifact");
|
|
270
|
+
const result = createInfraContractPropagationPlan({
|
|
271
|
+
cwd,
|
|
272
|
+
artifact,
|
|
273
|
+
branchPrefix: readArg("branch-prefix", "buildchain/infra-contract"),
|
|
274
|
+
});
|
|
275
|
+
writeJson(result, output);
|
|
276
|
+
writeGitHubOutputs({
|
|
277
|
+
"infra-propagation-count": String(result.pullRequests.length),
|
|
278
|
+
"infra-propagation-plan-json": JSON.stringify(result),
|
|
279
|
+
});
|
|
280
|
+
return result;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (mode === "propagation-apply") {
|
|
284
|
+
const result = applyInfraContractPropagation({
|
|
285
|
+
cwd,
|
|
286
|
+
artifact: readJsonFileArg("artifact"),
|
|
287
|
+
propagationPlan: readJsonFileArg("propagation-plan"),
|
|
288
|
+
dryRun: readBooleanArg("dry-run", true),
|
|
289
|
+
approvalId: readArg("approval-id", ""),
|
|
290
|
+
consumerWorkspaces: readKeyValueMapArg("consumer-workspace"),
|
|
291
|
+
});
|
|
292
|
+
writeJson(result, output);
|
|
293
|
+
writeGitHubOutputs({
|
|
294
|
+
"infra-propagation-status": result.status,
|
|
295
|
+
"infra-propagation-result-json": JSON.stringify(result),
|
|
296
|
+
});
|
|
297
|
+
return result;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (mode === "evidence-bundle") {
|
|
301
|
+
const result = createInfraContractEvidenceBundle({
|
|
302
|
+
artifact: readJsonFileArg("artifact"),
|
|
303
|
+
applyResult: readJsonFileArg("apply-result"),
|
|
304
|
+
propagationResult: readJsonFileArg("propagation-result"),
|
|
305
|
+
});
|
|
306
|
+
writeJson(result, output);
|
|
307
|
+
writeGitHubOutputs({
|
|
308
|
+
"infra-evidence-bundle-hash": result.bundleHash,
|
|
309
|
+
"infra-evidence-bundle-json": JSON.stringify(result),
|
|
310
|
+
});
|
|
311
|
+
return result;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
if (mode === "apply") {
|
|
315
|
+
const result = applyInfraContract({
|
|
316
|
+
cwd,
|
|
317
|
+
sourceSha,
|
|
318
|
+
approvalId: readArg("approval-id", ""),
|
|
319
|
+
dryRun: readBooleanArg("dry-run", true),
|
|
320
|
+
plan: readJsonFileArg("plan"),
|
|
321
|
+
planMaxAgeMinutes: readNumberArg(
|
|
322
|
+
"plan-max-age-minutes",
|
|
323
|
+
readNumberEnv("BUILDCHAIN_INFRA_CONTRACT_PLAN_MAX_AGE_MINUTES", 60),
|
|
324
|
+
),
|
|
325
|
+
executeAdapterCommands: readBooleanArg("execute-adapter-commands", false),
|
|
326
|
+
});
|
|
327
|
+
writeJson(result, output);
|
|
328
|
+
writeGitHubOutputs({
|
|
329
|
+
"infra-apply-status": result.status,
|
|
330
|
+
"infra-apply-result-json": JSON.stringify(result),
|
|
331
|
+
});
|
|
332
|
+
return result;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
throw new Error(`unsupported infra-contract mode: ${mode}`);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
339
|
+
try {
|
|
340
|
+
infraContractCli();
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error(`::error::${String(error.message || error).replace(/\r?\n/g, "%0A")}`);
|
|
343
|
+
process.exitCode = 1;
|
|
344
|
+
}
|
|
345
|
+
}
|
package/scripts/init-repo.mjs
CHANGED
|
@@ -212,7 +212,78 @@ command = "corepack pnpm run check"
|
|
|
212
212
|
`;
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
function
|
|
215
|
+
function infraContractToml(cwd) {
|
|
216
|
+
const name = repoName(cwd);
|
|
217
|
+
return `schema = 1
|
|
218
|
+
|
|
219
|
+
[project]
|
|
220
|
+
type = "infra-contract"
|
|
221
|
+
name = "${name}"
|
|
222
|
+
|
|
223
|
+
[infra]
|
|
224
|
+
adapter = "manual-observed"
|
|
225
|
+
adoption_mode = "manual-observed"
|
|
226
|
+
apply = "disabled"
|
|
227
|
+
environment = "staging"
|
|
228
|
+
desired = ["infra/desired.json"]
|
|
229
|
+
contract = ["infra/outputs.json"]
|
|
230
|
+
|
|
231
|
+
[[consumers]]
|
|
232
|
+
repo = "kungfu-systems/site-example"
|
|
233
|
+
path = "infra/outputs.json"
|
|
234
|
+
source = "infra/outputs.json"
|
|
235
|
+
|
|
236
|
+
[lifecycle.verify]
|
|
237
|
+
command = "buildchain infra-contract --mode ci"
|
|
238
|
+
`;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function infraContractDesiredJson(cwd) {
|
|
242
|
+
return `${JSON.stringify({
|
|
243
|
+
service: repoName(cwd),
|
|
244
|
+
environment: "staging",
|
|
245
|
+
resources: [
|
|
246
|
+
{
|
|
247
|
+
kind: "static-site",
|
|
248
|
+
name: repoName(cwd),
|
|
249
|
+
desiredState: {
|
|
250
|
+
hostname: "staging.example.com",
|
|
251
|
+
accessControl: "managed-network",
|
|
252
|
+
owner: "platform",
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
}, null, 2)}\n`;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
function infraContractOutputsJson(cwd) {
|
|
260
|
+
return `${JSON.stringify({
|
|
261
|
+
service: repoName(cwd),
|
|
262
|
+
environment: "staging",
|
|
263
|
+
observedMode: "manual-observed",
|
|
264
|
+
outputs: {
|
|
265
|
+
hostname: "staging.example.com",
|
|
266
|
+
distributionId: "observed-distribution-id",
|
|
267
|
+
bucket: "observed-bucket-name",
|
|
268
|
+
},
|
|
269
|
+
}, null, 2)}\n`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function workflowArtifactPaths(type) {
|
|
273
|
+
if (type === "infra-contract") {
|
|
274
|
+
return `.buildchain/infra-contract-validate.json
|
|
275
|
+
.buildchain/infra-contract-plan.json
|
|
276
|
+
.buildchain/buildchain.infra-contract.json
|
|
277
|
+
.buildchain/infra-contract-propagation.json
|
|
278
|
+
.buildchain/infra-contract-propagation-apply.json
|
|
279
|
+
.buildchain/infra-contract-evidence-bundle.json
|
|
280
|
+
.buildchain/infra-contract-evidence-verification.json`;
|
|
281
|
+
}
|
|
282
|
+
return `dist
|
|
283
|
+
build/stage`;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function workflowYaml({ type, runnerPreset, artifactName }) {
|
|
216
287
|
return `name: Build
|
|
217
288
|
|
|
218
289
|
on:
|
|
@@ -242,8 +313,7 @@ jobs:
|
|
|
242
313
|
runner-preset: "${runnerPreset}"
|
|
243
314
|
artifact-name-template: "${artifactName}"
|
|
244
315
|
artifact-paths: |
|
|
245
|
-
|
|
246
|
-
build/stage
|
|
316
|
+
${workflowArtifactPaths(type)}
|
|
247
317
|
`;
|
|
248
318
|
}
|
|
249
319
|
|
|
@@ -276,15 +346,19 @@ export function initBuildchainRepo({
|
|
|
276
346
|
if (type === "web-surface") {
|
|
277
347
|
return webSurfaceToml(resolvedCwd);
|
|
278
348
|
}
|
|
349
|
+
if (type === "infra-contract") {
|
|
350
|
+
return infraContractToml(resolvedCwd);
|
|
351
|
+
}
|
|
279
352
|
if (type === "anchored-package") {
|
|
280
353
|
return anchoredPackageToml(resolvedCwd, manager);
|
|
281
354
|
}
|
|
282
|
-
throw new Error("init --type must be one of package, native, web-surface, or anchored-package");
|
|
355
|
+
throw new Error("init --type must be one of package, native, web-surface, infra-contract, or anchored-package");
|
|
283
356
|
})();
|
|
284
357
|
|
|
285
358
|
const written = [
|
|
286
359
|
writeIfAllowed(path.join(resolvedCwd, "buildchain.toml"), toml, { force }),
|
|
287
360
|
writeIfAllowed(path.join(resolvedCwd, ".github", "workflows", "build.yml"), workflowYaml({
|
|
361
|
+
type,
|
|
288
362
|
runnerPreset,
|
|
289
363
|
artifactName,
|
|
290
364
|
}), { force }),
|
|
@@ -294,6 +368,13 @@ export function initBuildchainRepo({
|
|
|
294
368
|
written.push(writeIfAllowed(path.join(resolvedCwd, "release.json"), "{\n \"upstream\": \"\",\n \"version\": \"0.0.0\"\n}\n", { force }));
|
|
295
369
|
}
|
|
296
370
|
|
|
371
|
+
if (type === "infra-contract") {
|
|
372
|
+
written.push(
|
|
373
|
+
writeIfAllowed(path.join(resolvedCwd, "infra", "desired.json"), infraContractDesiredJson(resolvedCwd), { force }),
|
|
374
|
+
writeIfAllowed(path.join(resolvedCwd, "infra", "outputs.json"), infraContractOutputsJson(resolvedCwd), { force }),
|
|
375
|
+
);
|
|
376
|
+
}
|
|
377
|
+
|
|
297
378
|
return {
|
|
298
379
|
schemaVersion: 1,
|
|
299
380
|
type,
|