rastack 0.0.41 → 0.0.42
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/CHANGELOG.md +7 -0
- package/dist/deploy/config.d.ts +23 -7
- package/dist/deploy/config.js +29 -12
- package/dist/deploy/io.d.ts +15 -0
- package/dist/deploy/io.js +32 -2
- package/dist/rastack-bootstrap.d.ts +2 -1
- package/dist/rastack-bootstrap.js +14 -6
- package/dist/rastack-init.js +20 -6
- package/dist/templates/cloudformation/app.yaml +635 -0
- package/dist/templates/cloudformation/bootstrap.yaml +342 -0
- package/dist/templates/cloudformation/placeholder/bootstrap +28 -0
- package/package.json +2 -2
- package/scripts/copy-templates.js +42 -0
- package/src/deploy/config.ts +35 -10
- package/src/deploy/io.ts +34 -2
- package/src/rastack-bootstrap.ts +17 -6
- package/src/rastack-init.ts +25 -6
- package/test/deploy.spec.ts +53 -0
package/src/rastack-init.ts
CHANGED
|
@@ -56,6 +56,7 @@ import {
|
|
|
56
56
|
ghAvailable,
|
|
57
57
|
gitRemoteUrl,
|
|
58
58
|
loadConfig,
|
|
59
|
+
resolveDeployAsset,
|
|
59
60
|
saveConfig,
|
|
60
61
|
setRepoVariable,
|
|
61
62
|
stackOutput,
|
|
@@ -209,13 +210,15 @@ function printPlan(cfg: DeployConfig): void {
|
|
|
209
210
|
const withBucket = mergeConfig(cfg, {
|
|
210
211
|
artifactsBucket: bucket ?? "<ArtifactsBucketName from bootstrap stack>",
|
|
211
212
|
});
|
|
213
|
+
const bootstrapTemplate = resolveDeployAsset("bootstrap.yaml") ?? undefined;
|
|
214
|
+
const appTemplate = resolveDeployAsset("app.yaml") ?? undefined;
|
|
212
215
|
console.log(`\n Deployment plan (${cfg.stackName} @ ${cfg.region})\n`);
|
|
213
216
|
console.log(
|
|
214
217
|
` ── 1. Bootstrap stack (${bootstrapStackName(cfg)}) — run only if it does not exist ──`,
|
|
215
218
|
);
|
|
216
|
-
console.log("\n " + bootstrapStackCommand(cfg) + "\n");
|
|
219
|
+
console.log("\n " + bootstrapStackCommand(cfg, false, bootstrapTemplate) + "\n");
|
|
217
220
|
console.log(" ── 2. Per-app backend (app.yaml) ──");
|
|
218
|
-
console.log("\n " + deployStackCommand(withBucket) + "\n");
|
|
221
|
+
console.log("\n " + deployStackCommand(withBucket, appTemplate) + "\n");
|
|
219
222
|
console.log(
|
|
220
223
|
" ── 3. Wire these GitHub repo Variables from the stack Outputs ──",
|
|
221
224
|
);
|
|
@@ -285,7 +288,7 @@ async function standUp(
|
|
|
285
288
|
console.log("\n▸ Uploading the Lambda placeholder bundle");
|
|
286
289
|
if (!uploadPlaceholder(artifactsBucket, cfg.region)) {
|
|
287
290
|
console.error(
|
|
288
|
-
" ✗
|
|
291
|
+
" ✗ Lambda placeholder bundle not found in the rastack package — cannot create the function.",
|
|
289
292
|
);
|
|
290
293
|
process.exit(1);
|
|
291
294
|
}
|
|
@@ -295,9 +298,17 @@ async function standUp(
|
|
|
295
298
|
artifactsBucket,
|
|
296
299
|
templatesBucket: templatesBucket ?? undefined,
|
|
297
300
|
});
|
|
301
|
+
const appTemplate = resolveDeployAsset("app.yaml");
|
|
302
|
+
if (!appTemplate) {
|
|
303
|
+
console.error(
|
|
304
|
+
" ✗ app.yaml template not found in the rastack package. Reinstall rastack\n" +
|
|
305
|
+
" (`npm i -g rastack`) or run from the framework repo.",
|
|
306
|
+
);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
298
309
|
console.log(`\n▸ Deploying ${cfg.stackName}`);
|
|
299
310
|
try {
|
|
300
|
-
awsRun(deployStackArgs(cfg));
|
|
311
|
+
awsRun(deployStackArgs(cfg, appTemplate));
|
|
301
312
|
} catch (err) {
|
|
302
313
|
console.error(
|
|
303
314
|
`\n ✗ aws cloudformation deploy failed for ${cfg.stackName}.\n ${(err as Error).message}`,
|
|
@@ -372,8 +383,16 @@ function wireRepoVariables(cfg: DeployConfig, interactive: boolean): void {
|
|
|
372
383
|
|
|
373
384
|
/** Deploy the bootstrap stack, retrying once against an existing OIDC provider. */
|
|
374
385
|
function deployBootstrap(cfg: DeployConfig): void {
|
|
386
|
+
const template = resolveDeployAsset("bootstrap.yaml");
|
|
387
|
+
if (!template) {
|
|
388
|
+
console.error(
|
|
389
|
+
" ✗ bootstrap.yaml template not found in the rastack package. Reinstall\n" +
|
|
390
|
+
" rastack (`npm i -g rastack`) or run from the framework repo.",
|
|
391
|
+
);
|
|
392
|
+
process.exit(1);
|
|
393
|
+
}
|
|
375
394
|
try {
|
|
376
|
-
awsRun(bootstrapStackArgs(cfg));
|
|
395
|
+
awsRun(bootstrapStackArgs(cfg, false, template));
|
|
377
396
|
} catch {
|
|
378
397
|
// The most common cause is an account that already has a GitHub OIDC
|
|
379
398
|
// provider (only one is allowed per URL). Retry telling the template to
|
|
@@ -382,7 +401,7 @@ function deployBootstrap(cfg: DeployConfig): void {
|
|
|
382
401
|
" • retrying bootstrap, reusing the account's existing GitHub OIDC provider",
|
|
383
402
|
);
|
|
384
403
|
try {
|
|
385
|
-
awsRun(bootstrapStackArgs(cfg, true));
|
|
404
|
+
awsRun(bootstrapStackArgs(cfg, true, template));
|
|
386
405
|
} catch (err) {
|
|
387
406
|
console.error(
|
|
388
407
|
`\n ✗ bootstrap stack deploy failed.\n ${(err as Error).message}`,
|
package/test/deploy.spec.ts
CHANGED
|
@@ -243,6 +243,19 @@ describe("stack parameters + launch command", () => {
|
|
|
243
243
|
"deploy",
|
|
244
244
|
]);
|
|
245
245
|
});
|
|
246
|
+
|
|
247
|
+
it("accepts a template-file override (the package-resolved path)", () => {
|
|
248
|
+
// `init` runs in a consumer repo that carries no framework IaC, so it passes
|
|
249
|
+
// the path the template was resolved to inside the `rastack` package.
|
|
250
|
+
const cfg = base({ artifactsBucket: "art" });
|
|
251
|
+
const abs = "/opt/rastack/dist/templates/cloudformation/app.yaml";
|
|
252
|
+
expect(deployStackArgs(cfg, abs)).toContain(abs);
|
|
253
|
+
expect(deployStackCommand(cfg, abs)).toContain(`--template-file ${abs}`);
|
|
254
|
+
// Default is unchanged when no override is given.
|
|
255
|
+
expect(deployStackCommand(cfg)).toContain(
|
|
256
|
+
"--template-file deploy/cloudformation/app.yaml",
|
|
257
|
+
);
|
|
258
|
+
});
|
|
246
259
|
});
|
|
247
260
|
|
|
248
261
|
describe("bootstrap stack", () => {
|
|
@@ -281,6 +294,21 @@ describe("bootstrap stack", () => {
|
|
|
281
294
|
expect(`aws ${bootstrapStackArgs(base()).join(" ")}`).toBe(cmd);
|
|
282
295
|
});
|
|
283
296
|
|
|
297
|
+
it("accepts a template-file override (the package-resolved path)", () => {
|
|
298
|
+
const abs = "/opt/rastack/dist/templates/cloudformation/bootstrap.yaml";
|
|
299
|
+
expect(bootstrapStackArgs(base(), false, abs)).toContain(abs);
|
|
300
|
+
expect(bootstrapStackCommand(base(), true, abs)).toContain(
|
|
301
|
+
`--template-file ${abs}`,
|
|
302
|
+
);
|
|
303
|
+
// Reuse-OIDC + override compose without disturbing the default path.
|
|
304
|
+
expect(bootstrapStackArgs(base(), true, abs)).toContain(
|
|
305
|
+
"CreateOIDCProvider=false",
|
|
306
|
+
);
|
|
307
|
+
expect(bootstrapStackCommand(base())).toContain(
|
|
308
|
+
"--template-file deploy/cloudformation/bootstrap.yaml",
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
|
|
284
312
|
it("validates only the account-level fields, not the per-app ones", () => {
|
|
285
313
|
// A config with no `app` is fine for bootstrap — it never touches app.yaml.
|
|
286
314
|
const cfg = normalizeConfig({
|
|
@@ -513,3 +541,28 @@ describe("scaffold", () => {
|
|
|
513
541
|
expect(files.map((f) => f.path)).toEqual([CONFIG_PATH]);
|
|
514
542
|
});
|
|
515
543
|
});
|
|
544
|
+
|
|
545
|
+
describe("resolveDeployAsset — bundled template resolution", () => {
|
|
546
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
547
|
+
const { resolveDeployAsset } = require("../src/deploy/io");
|
|
548
|
+
const path = require("path");
|
|
549
|
+
|
|
550
|
+
it("resolves the framework templates to an existing file", () => {
|
|
551
|
+
for (const name of ["app.yaml", "bootstrap.yaml"]) {
|
|
552
|
+
const resolved = resolveDeployAsset(name);
|
|
553
|
+
expect(resolved).not.toBeNull();
|
|
554
|
+
expect(path.isAbsolute(resolved)).toBe(true);
|
|
555
|
+
expect(resolved.endsWith(name)).toBe(true);
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
it("resolves the Lambda placeholder bundle", () => {
|
|
560
|
+
const resolved = resolveDeployAsset(path.join("placeholder", "bootstrap"));
|
|
561
|
+
expect(resolved).not.toBeNull();
|
|
562
|
+
expect(resolved.endsWith(path.join("placeholder", "bootstrap"))).toBe(true);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it("returns null for an asset that does not exist", () => {
|
|
566
|
+
expect(resolveDeployAsset("does-not-exist.yaml")).toBeNull();
|
|
567
|
+
});
|
|
568
|
+
});
|