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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.0.42](https://github.com/theserverkid/reactapistack/compare/v0.0.41...v0.0.42) (2026-07-12)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **deploy:** bundle CFN templates in the rastack package so init/bootstrap work from any repo ([4b45ee3](https://github.com/theserverkid/reactapistack/commit/4b45ee3440aef0355bc06c5b40bb1fa4f02e496f))
|
|
11
|
+
|
|
5
12
|
### [0.0.41](https://github.com/theserverkid/reactapistack/compare/v0.0.40...v0.0.41) (2026-07-12)
|
|
6
13
|
|
|
7
14
|
### [0.0.40](https://github.com/theserverkid/reactapistack/compare/v0.0.39...v0.0.40) (2026-07-12)
|
package/dist/deploy/config.d.ts
CHANGED
|
@@ -136,17 +136,28 @@ export declare function cognitoAdvancedSecuritySupported(region: string): boolea
|
|
|
136
136
|
* the template's ENFORCED default stands).
|
|
137
137
|
*/
|
|
138
138
|
export declare function stackParameters(cfg: DeployConfig): StackParameter[];
|
|
139
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* The canonical repo-relative CloudFormation template paths. These are the paths
|
|
141
|
+
* in the *framework* repo (theserverkid/reactapistack) and the default the argv
|
|
142
|
+
* builders below embed. A **consumer** repo (the demo, any app) deliberately does
|
|
143
|
+
* NOT carry a copy of the framework IaC — the templates ship inside the `rastack`
|
|
144
|
+
* package instead — so `init`/`bootstrap` resolve the real on-disk path via
|
|
145
|
+
* `resolveDeployAsset` (io.ts) and pass it in as the `templateFile` override.
|
|
146
|
+
*/
|
|
140
147
|
export declare const APP_TEMPLATE_FILE = "deploy/cloudformation/app.yaml";
|
|
141
148
|
export declare const BOOTSTRAP_TEMPLATE_FILE = "deploy/cloudformation/bootstrap.yaml";
|
|
142
|
-
/**
|
|
143
|
-
|
|
149
|
+
/**
|
|
150
|
+
* The argv that creates the app's infrastructure (app.yaml). `templateFile`
|
|
151
|
+
* defaults to the canonical repo-relative path; `init` passes the resolved
|
|
152
|
+
* package-bundled path so it works from a consumer repo that carries no IaC.
|
|
153
|
+
*/
|
|
154
|
+
export declare function deployStackArgs(cfg: DeployConfig, templateFile?: string): string[];
|
|
144
155
|
/**
|
|
145
156
|
* The one-time `aws cloudformation deploy` command that creates the app's
|
|
146
157
|
* infrastructure (app.yaml), from the in-repo template. `rastack init` runs this
|
|
147
158
|
* for you; it is also printed by `--print` so it can be run by hand.
|
|
148
159
|
*/
|
|
149
|
-
export declare function deployStackCommand(cfg: DeployConfig): string;
|
|
160
|
+
export declare function deployStackCommand(cfg: DeployConfig, templateFile?: string): string;
|
|
150
161
|
/**
|
|
151
162
|
* The tier-0 bootstrap stack (bootstrap.yaml) — the S3 buckets that hold the
|
|
152
163
|
* Lambda placeholder + hosted templates, and the GitHub OIDC provider. One per
|
|
@@ -160,10 +171,15 @@ export declare function bootstrapStackName(cfg: DeployConfig): string;
|
|
|
160
171
|
* the template then derives the existing provider's ARN itself.
|
|
161
172
|
*/
|
|
162
173
|
export declare function bootstrapStackParameters(cfg: DeployConfig, reuseOidc?: boolean): StackParameter[];
|
|
163
|
-
/**
|
|
164
|
-
|
|
174
|
+
/**
|
|
175
|
+
* The argv that creates the bootstrap stack (bootstrap.yaml). `templateFile`
|
|
176
|
+
* defaults to the canonical repo-relative path; `init`/`bootstrap` pass the
|
|
177
|
+
* resolved package-bundled path so it works from a consumer repo that carries no
|
|
178
|
+
* IaC.
|
|
179
|
+
*/
|
|
180
|
+
export declare function bootstrapStackArgs(cfg: DeployConfig, reuseOidc?: boolean, templateFile?: string): string[];
|
|
165
181
|
/** The one-time `aws cloudformation deploy` command that creates the bootstrap stack. */
|
|
166
|
-
export declare function bootstrapStackCommand(cfg: DeployConfig, reuseOidc?: boolean): string;
|
|
182
|
+
export declare function bootstrapStackCommand(cfg: DeployConfig, reuseOidc?: boolean, templateFile?: string): string;
|
|
167
183
|
/** Stack Output keys `init` reads back off the bootstrap stack. */
|
|
168
184
|
export declare const BOOTSTRAP_ARTIFACTS_OUTPUT = "ArtifactsBucketName";
|
|
169
185
|
export declare const BOOTSTRAP_TEMPLATES_OUTPUT = "TemplatesBucketName";
|
package/dist/deploy/config.js
CHANGED
|
@@ -232,7 +232,14 @@ function stackParameters(cfg) {
|
|
|
232
232
|
params.push({ key: "AdvancedSecurity", value: "OFF" });
|
|
233
233
|
return params;
|
|
234
234
|
}
|
|
235
|
-
/**
|
|
235
|
+
/**
|
|
236
|
+
* The canonical repo-relative CloudFormation template paths. These are the paths
|
|
237
|
+
* in the *framework* repo (theserverkid/reactapistack) and the default the argv
|
|
238
|
+
* builders below embed. A **consumer** repo (the demo, any app) deliberately does
|
|
239
|
+
* NOT carry a copy of the framework IaC — the templates ship inside the `rastack`
|
|
240
|
+
* package instead — so `init`/`bootstrap` resolve the real on-disk path via
|
|
241
|
+
* `resolveDeployAsset` (io.ts) and pass it in as the `templateFile` override.
|
|
242
|
+
*/
|
|
236
243
|
exports.APP_TEMPLATE_FILE = "deploy/cloudformation/app.yaml";
|
|
237
244
|
exports.BOOTSTRAP_TEMPLATE_FILE = "deploy/cloudformation/bootstrap.yaml";
|
|
238
245
|
/**
|
|
@@ -244,7 +251,8 @@ exports.BOOTSTRAP_TEMPLATE_FILE = "deploy/cloudformation/bootstrap.yaml";
|
|
|
244
251
|
* accepts *only* a local template file. `--template-url` is exclusive to the
|
|
245
252
|
* low-level `create-stack`/`update-stack`/`create-change-set` commands, so
|
|
246
253
|
* pairing it with `deploy` fails with `the following arguments are required:
|
|
247
|
-
* --template-file`.
|
|
254
|
+
* --template-file`. The file is resolved from the `rastack` package (see
|
|
255
|
+
* `resolveDeployAsset`), so a consumer repo need not carry the framework IaC.
|
|
248
256
|
*/
|
|
249
257
|
function cfnDeployArgs(templateFile, stackName, region, params) {
|
|
250
258
|
return [
|
|
@@ -272,17 +280,21 @@ function cfnDeployArgs(templateFile, stackName, region, params) {
|
|
|
272
280
|
function awsCommand(args) {
|
|
273
281
|
return `aws ${args.join(" ")}`;
|
|
274
282
|
}
|
|
275
|
-
/**
|
|
276
|
-
|
|
277
|
-
|
|
283
|
+
/**
|
|
284
|
+
* The argv that creates the app's infrastructure (app.yaml). `templateFile`
|
|
285
|
+
* defaults to the canonical repo-relative path; `init` passes the resolved
|
|
286
|
+
* package-bundled path so it works from a consumer repo that carries no IaC.
|
|
287
|
+
*/
|
|
288
|
+
function deployStackArgs(cfg, templateFile = exports.APP_TEMPLATE_FILE) {
|
|
289
|
+
return cfnDeployArgs(templateFile, cfg.stackName, cfg.region, stackParameters(cfg));
|
|
278
290
|
}
|
|
279
291
|
/**
|
|
280
292
|
* The one-time `aws cloudformation deploy` command that creates the app's
|
|
281
293
|
* infrastructure (app.yaml), from the in-repo template. `rastack init` runs this
|
|
282
294
|
* for you; it is also printed by `--print` so it can be run by hand.
|
|
283
295
|
*/
|
|
284
|
-
function deployStackCommand(cfg) {
|
|
285
|
-
return awsCommand(deployStackArgs(cfg));
|
|
296
|
+
function deployStackCommand(cfg, templateFile = exports.APP_TEMPLATE_FILE) {
|
|
297
|
+
return awsCommand(deployStackArgs(cfg, templateFile));
|
|
286
298
|
}
|
|
287
299
|
/**
|
|
288
300
|
* The tier-0 bootstrap stack (bootstrap.yaml) — the S3 buckets that hold the
|
|
@@ -309,13 +321,18 @@ function bootstrapStackParameters(cfg, reuseOidc = false) {
|
|
|
309
321
|
params.push({ key: "CreateOIDCProvider", value: "false" });
|
|
310
322
|
return params;
|
|
311
323
|
}
|
|
312
|
-
/**
|
|
313
|
-
|
|
314
|
-
|
|
324
|
+
/**
|
|
325
|
+
* The argv that creates the bootstrap stack (bootstrap.yaml). `templateFile`
|
|
326
|
+
* defaults to the canonical repo-relative path; `init`/`bootstrap` pass the
|
|
327
|
+
* resolved package-bundled path so it works from a consumer repo that carries no
|
|
328
|
+
* IaC.
|
|
329
|
+
*/
|
|
330
|
+
function bootstrapStackArgs(cfg, reuseOidc = false, templateFile = exports.BOOTSTRAP_TEMPLATE_FILE) {
|
|
331
|
+
return cfnDeployArgs(templateFile, bootstrapStackName(cfg), cfg.region, bootstrapStackParameters(cfg, reuseOidc));
|
|
315
332
|
}
|
|
316
333
|
/** The one-time `aws cloudformation deploy` command that creates the bootstrap stack. */
|
|
317
|
-
function bootstrapStackCommand(cfg, reuseOidc = false) {
|
|
318
|
-
return awsCommand(bootstrapStackArgs(cfg, reuseOidc));
|
|
334
|
+
function bootstrapStackCommand(cfg, reuseOidc = false, templateFile = exports.BOOTSTRAP_TEMPLATE_FILE) {
|
|
335
|
+
return awsCommand(bootstrapStackArgs(cfg, reuseOidc, templateFile));
|
|
319
336
|
}
|
|
320
337
|
/** Stack Output keys `init` reads back off the bootstrap stack. */
|
|
321
338
|
exports.BOOTSTRAP_ARTIFACTS_OUTPUT = "ArtifactsBucketName";
|
package/dist/deploy/io.d.ts
CHANGED
|
@@ -7,6 +7,21 @@ import * as readline from "readline";
|
|
|
7
7
|
import { DeployConfig } from "./config";
|
|
8
8
|
/** Absolute path to the deploy config for a project root. */
|
|
9
9
|
export declare function configPath(cwd?: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a CloudFormation asset (`app.yaml`, `bootstrap.yaml`, or the
|
|
12
|
+
* `placeholder/bootstrap` Lambda bundle) to an absolute on-disk path.
|
|
13
|
+
*
|
|
14
|
+
* The templates are the **framework's** IaC, not the consumer's — the demo repo
|
|
15
|
+
* and every future app repo deliberately do not carry a copy (see
|
|
16
|
+
* deploy/cloudformation/README.md). So `init`/`bootstrap`, which run in those
|
|
17
|
+
* repos, cannot assume `deploy/cloudformation/<asset>` exists relative to the
|
|
18
|
+
* cwd — that is exactly the `Invalid template path deploy/cloudformation/…`
|
|
19
|
+
* failure. Instead the assets ship *inside* the `rastack` package (copied into
|
|
20
|
+
* `dist/templates/cloudformation/` at build time) and are resolved from the
|
|
21
|
+
* install location, with fallbacks so running from source or from the framework
|
|
22
|
+
* repo itself still works. Returns null when no candidate exists.
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveDeployAsset(relPath: string, cwd?: string): string | null;
|
|
10
25
|
/** Read + normalize the deploy config, or null when it does not exist yet. */
|
|
11
26
|
export declare function loadConfig(cwd?: string): DeployConfig | null;
|
|
12
27
|
/** Write the deploy config, creating `.rastack/` if needed. */
|
package/dist/deploy/io.js
CHANGED
|
@@ -39,6 +39,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
39
|
})();
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
41
|
exports.configPath = configPath;
|
|
42
|
+
exports.resolveDeployAsset = resolveDeployAsset;
|
|
42
43
|
exports.loadConfig = loadConfig;
|
|
43
44
|
exports.saveConfig = saveConfig;
|
|
44
45
|
exports.gitRemoteUrl = gitRemoteUrl;
|
|
@@ -66,6 +67,35 @@ const zip_1 = require("./zip");
|
|
|
66
67
|
function configPath(cwd = process.cwd()) {
|
|
67
68
|
return path.join(cwd, workflows_1.CONFIG_PATH);
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a CloudFormation asset (`app.yaml`, `bootstrap.yaml`, or the
|
|
72
|
+
* `placeholder/bootstrap` Lambda bundle) to an absolute on-disk path.
|
|
73
|
+
*
|
|
74
|
+
* The templates are the **framework's** IaC, not the consumer's — the demo repo
|
|
75
|
+
* and every future app repo deliberately do not carry a copy (see
|
|
76
|
+
* deploy/cloudformation/README.md). So `init`/`bootstrap`, which run in those
|
|
77
|
+
* repos, cannot assume `deploy/cloudformation/<asset>` exists relative to the
|
|
78
|
+
* cwd — that is exactly the `Invalid template path deploy/cloudformation/…`
|
|
79
|
+
* failure. Instead the assets ship *inside* the `rastack` package (copied into
|
|
80
|
+
* `dist/templates/cloudformation/` at build time) and are resolved from the
|
|
81
|
+
* install location, with fallbacks so running from source or from the framework
|
|
82
|
+
* repo itself still works. Returns null when no candidate exists.
|
|
83
|
+
*/
|
|
84
|
+
function resolveDeployAsset(relPath, cwd = process.cwd()) {
|
|
85
|
+
const candidates = [
|
|
86
|
+
// Installed package: dist/deploy/io.js → dist/templates/cloudformation/…
|
|
87
|
+
path.join(__dirname, "..", "templates", "cloudformation", relPath),
|
|
88
|
+
// Running from TS source: tools/src/deploy/io.ts → repo-root deploy/…
|
|
89
|
+
path.join(__dirname, "..", "..", "..", "deploy", "cloudformation", relPath),
|
|
90
|
+
// Invoked inside the framework repo itself (cwd is the repo root).
|
|
91
|
+
path.join(cwd, "deploy", "cloudformation", relPath),
|
|
92
|
+
];
|
|
93
|
+
for (const candidate of candidates) {
|
|
94
|
+
if (fs.existsSync(candidate))
|
|
95
|
+
return candidate;
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
69
99
|
/** Read + normalize the deploy config, or null when it does not exist yet. */
|
|
70
100
|
function loadConfig(cwd = process.cwd()) {
|
|
71
101
|
const file = configPath(cwd);
|
|
@@ -161,8 +191,8 @@ function stackOutput(stackName, key, region) {
|
|
|
161
191
|
* on every `init`. Returns false when the placeholder file is missing.
|
|
162
192
|
*/
|
|
163
193
|
function uploadPlaceholder(artifactsBucket, region, cwd = process.cwd()) {
|
|
164
|
-
const src =
|
|
165
|
-
if (!
|
|
194
|
+
const src = resolveDeployAsset("placeholder/bootstrap", cwd);
|
|
195
|
+
if (!src)
|
|
166
196
|
return false;
|
|
167
197
|
const zip = (0, zip_1.zipStore)([
|
|
168
198
|
{ name: "bootstrap", data: fs.readFileSync(src), mode: 0o755 },
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* [--region <r>] [--prefix <p>]
|
|
9
9
|
* [--reuse-oidc] [--print] [--yes]
|
|
10
10
|
*
|
|
11
|
-
* It deploys `
|
|
11
|
+
* It deploys the `bootstrap.yaml` template bundled with the `rastack` package
|
|
12
|
+
* (resolved by `resolveDeployAsset`, so it works from any repo), which creates:
|
|
12
13
|
* • the S3 buckets that hold the Lambda placeholder + hosted templates, and
|
|
13
14
|
* • the GitHub OIDC provider + trust that lets CI assume a deploy role.
|
|
14
15
|
* It then uploads the Lambda placeholder bundle to the artifacts bucket, so the
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
* [--region <r>] [--prefix <p>]
|
|
10
10
|
* [--reuse-oidc] [--print] [--yes]
|
|
11
11
|
*
|
|
12
|
-
* It deploys `
|
|
12
|
+
* It deploys the `bootstrap.yaml` template bundled with the `rastack` package
|
|
13
|
+
* (resolved by `resolveDeployAsset`, so it works from any repo), which creates:
|
|
13
14
|
* • the S3 buckets that hold the Lambda placeholder + hosted templates, and
|
|
14
15
|
* • the GitHub OIDC provider + trust that lets CI assume a deploy role.
|
|
15
16
|
* It then uploads the Lambda placeholder bundle to the artifacts bucket, so the
|
|
@@ -116,8 +117,9 @@ async function confirm(question) {
|
|
|
116
117
|
/** Print the exact command `bootstrap` would run, without touching the cloud. */
|
|
117
118
|
function printPlan(cfg, reuseOidc) {
|
|
118
119
|
console.log(`\n Bootstrap plan (${(0, config_1.bootstrapStackName)(cfg)} @ ${cfg.region})\n`);
|
|
120
|
+
const template = (0, io_1.resolveDeployAsset)("bootstrap.yaml") ?? undefined;
|
|
119
121
|
console.log(" ── Tier-0 bootstrap stack (bootstrap.yaml) ──");
|
|
120
|
-
console.log("\n " + (0, config_1.bootstrapStackCommand)(cfg, reuseOidc) + "\n");
|
|
122
|
+
console.log("\n " + (0, config_1.bootstrapStackCommand)(cfg, reuseOidc, template) + "\n");
|
|
121
123
|
console.log(" Then `rastack init` (or `rastack bootstrap` again) resolves this stack's\n" +
|
|
122
124
|
" ArtifactsBucket to create app backends. Nothing here is app-specific.\n");
|
|
123
125
|
}
|
|
@@ -127,8 +129,14 @@ function printPlan(cfg, reuseOidc) {
|
|
|
127
129
|
* already ask to reuse it.
|
|
128
130
|
*/
|
|
129
131
|
function deployBootstrap(cfg, reuseOidc) {
|
|
132
|
+
const template = (0, io_1.resolveDeployAsset)("bootstrap.yaml");
|
|
133
|
+
if (!template) {
|
|
134
|
+
console.error(" ✗ bootstrap.yaml template not found in the rastack package. Reinstall\n" +
|
|
135
|
+
" rastack (`npm i -g rastack`) or run from the framework repo.");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
130
138
|
try {
|
|
131
|
-
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, reuseOidc));
|
|
139
|
+
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, reuseOidc, template));
|
|
132
140
|
}
|
|
133
141
|
catch (err) {
|
|
134
142
|
if (reuseOidc) {
|
|
@@ -140,7 +148,7 @@ function deployBootstrap(cfg, reuseOidc) {
|
|
|
140
148
|
// second (which CloudFormation rejects).
|
|
141
149
|
console.log(" • retrying bootstrap, reusing the account's existing GitHub OIDC provider");
|
|
142
150
|
try {
|
|
143
|
-
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, true));
|
|
151
|
+
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, true, template));
|
|
144
152
|
}
|
|
145
153
|
catch (retryErr) {
|
|
146
154
|
console.error(`\n ✗ bootstrap stack deploy failed.\n ${retryErr.message}`);
|
|
@@ -177,8 +185,8 @@ function standUp(cfg, reuseOidc) {
|
|
|
177
185
|
// account is ready for `rastack init` without a second manual step.
|
|
178
186
|
console.log("\n▸ Uploading the Lambda placeholder bundle");
|
|
179
187
|
if (!(0, io_1.uploadPlaceholder)(artifactsBucket, cfg.region)) {
|
|
180
|
-
console.error(" ✗
|
|
181
|
-
" was not uploaded. `rastack init` will upload it on the first app deploy.");
|
|
188
|
+
console.error(" ✗ Lambda placeholder bundle not found in the rastack package — the\n" +
|
|
189
|
+
" placeholder was not uploaded. `rastack init` will upload it on the first app deploy.");
|
|
182
190
|
}
|
|
183
191
|
else {
|
|
184
192
|
console.log(" ✓ placeholder uploaded");
|
package/dist/rastack-init.js
CHANGED
|
@@ -187,11 +187,13 @@ function printPlan(cfg) {
|
|
|
187
187
|
const withBucket = (0, config_1.mergeConfig)(cfg, {
|
|
188
188
|
artifactsBucket: bucket ?? "<ArtifactsBucketName from bootstrap stack>",
|
|
189
189
|
});
|
|
190
|
+
const bootstrapTemplate = (0, io_1.resolveDeployAsset)("bootstrap.yaml") ?? undefined;
|
|
191
|
+
const appTemplate = (0, io_1.resolveDeployAsset)("app.yaml") ?? undefined;
|
|
190
192
|
console.log(`\n Deployment plan (${cfg.stackName} @ ${cfg.region})\n`);
|
|
191
193
|
console.log(` ── 1. Bootstrap stack (${(0, config_1.bootstrapStackName)(cfg)}) — run only if it does not exist ──`);
|
|
192
|
-
console.log("\n " + (0, config_1.bootstrapStackCommand)(cfg) + "\n");
|
|
194
|
+
console.log("\n " + (0, config_1.bootstrapStackCommand)(cfg, false, bootstrapTemplate) + "\n");
|
|
193
195
|
console.log(" ── 2. Per-app backend (app.yaml) ──");
|
|
194
|
-
console.log("\n " + (0, config_1.deployStackCommand)(withBucket) + "\n");
|
|
196
|
+
console.log("\n " + (0, config_1.deployStackCommand)(withBucket, appTemplate) + "\n");
|
|
195
197
|
console.log(" ── 3. Wire these GitHub repo Variables from the stack Outputs ──");
|
|
196
198
|
console.log(table((0, config_1.repoVariables)(cfg).map((v) => ({
|
|
197
199
|
key: v.name,
|
|
@@ -226,7 +228,7 @@ async function standUp(cfg, interactive) {
|
|
|
226
228
|
// 2. Upload the placeholder the function is created from.
|
|
227
229
|
console.log("\n▸ Uploading the Lambda placeholder bundle");
|
|
228
230
|
if (!(0, io_1.uploadPlaceholder)(artifactsBucket, cfg.region)) {
|
|
229
|
-
console.error(" ✗
|
|
231
|
+
console.error(" ✗ Lambda placeholder bundle not found in the rastack package — cannot create the function.");
|
|
230
232
|
process.exit(1);
|
|
231
233
|
}
|
|
232
234
|
// 3. Deploy the per-app backend with the resolved bucket wired in.
|
|
@@ -234,9 +236,15 @@ async function standUp(cfg, interactive) {
|
|
|
234
236
|
artifactsBucket,
|
|
235
237
|
templatesBucket: templatesBucket ?? undefined,
|
|
236
238
|
});
|
|
239
|
+
const appTemplate = (0, io_1.resolveDeployAsset)("app.yaml");
|
|
240
|
+
if (!appTemplate) {
|
|
241
|
+
console.error(" ✗ app.yaml template not found in the rastack package. Reinstall rastack\n" +
|
|
242
|
+
" (`npm i -g rastack`) or run from the framework repo.");
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
237
245
|
console.log(`\n▸ Deploying ${cfg.stackName}`);
|
|
238
246
|
try {
|
|
239
|
-
(0, io_1.awsRun)((0, config_1.deployStackArgs)(cfg));
|
|
247
|
+
(0, io_1.awsRun)((0, config_1.deployStackArgs)(cfg, appTemplate));
|
|
240
248
|
}
|
|
241
249
|
catch (err) {
|
|
242
250
|
console.error(`\n ✗ aws cloudformation deploy failed for ${cfg.stackName}.\n ${err.message}`);
|
|
@@ -299,8 +307,14 @@ function wireRepoVariables(cfg, interactive) {
|
|
|
299
307
|
}
|
|
300
308
|
/** Deploy the bootstrap stack, retrying once against an existing OIDC provider. */
|
|
301
309
|
function deployBootstrap(cfg) {
|
|
310
|
+
const template = (0, io_1.resolveDeployAsset)("bootstrap.yaml");
|
|
311
|
+
if (!template) {
|
|
312
|
+
console.error(" ✗ bootstrap.yaml template not found in the rastack package. Reinstall\n" +
|
|
313
|
+
" rastack (`npm i -g rastack`) or run from the framework repo.");
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
302
316
|
try {
|
|
303
|
-
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg));
|
|
317
|
+
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, false, template));
|
|
304
318
|
}
|
|
305
319
|
catch {
|
|
306
320
|
// The most common cause is an account that already has a GitHub OIDC
|
|
@@ -308,7 +322,7 @@ function deployBootstrap(cfg) {
|
|
|
308
322
|
// reuse it instead of creating a second.
|
|
309
323
|
console.log(" • retrying bootstrap, reusing the account's existing GitHub OIDC provider");
|
|
310
324
|
try {
|
|
311
|
-
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, true));
|
|
325
|
+
(0, io_1.awsRun)((0, config_1.bootstrapStackArgs)(cfg, true, template));
|
|
312
326
|
}
|
|
313
327
|
catch (err) {
|
|
314
328
|
console.error(`\n ✗ bootstrap stack deploy failed.\n ${err.message}`);
|