quidproquo-cli 0.1.9 → 0.1.11
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/lib/commonjs/cli/commandRegistry.js +5 -0
- package/lib/commonjs/cli/commandRegistry.js.map +1 -1
- package/lib/commonjs/commands/checkCircular.d.ts +1 -0
- package/lib/commonjs/commands/checkCircular.js +70 -0
- package/lib/commonjs/commands/checkCircular.js.map +1 -0
- package/lib/commonjs/commands/synth.js +12 -1
- package/lib/commonjs/commands/synth.js.map +1 -1
- package/lib/commonjs/lib/circularImports.d.ts +3 -0
- package/lib/commonjs/lib/circularImports.js +79 -0
- package/lib/commonjs/lib/circularImports.js.map +1 -0
- package/lib/commonjs/lib/runCommand.d.ts +1 -0
- package/lib/commonjs/lib/runCommand.js +28 -3
- package/lib/commonjs/lib/runCommand.js.map +1 -1
- package/lib/commonjs/platforms/aws/goDocker.js +37 -35
- package/lib/commonjs/platforms/aws/goDocker.js.map +1 -1
- package/lib/commonjs/platforms/aws/viewsSync.d.ts +1 -0
- package/lib/commonjs/platforms/aws/viewsSync.js +31 -2
- package/lib/commonjs/platforms/aws/viewsSync.js.map +1 -1
- package/lib/esm/cli/commandRegistry.js +5 -0
- package/lib/esm/cli/commandRegistry.js.map +1 -1
- package/lib/esm/commands/checkCircular.d.ts +1 -0
- package/lib/esm/commands/checkCircular.js +55 -0
- package/lib/esm/commands/checkCircular.js.map +1 -0
- package/lib/esm/commands/synth.js +12 -1
- package/lib/esm/commands/synth.js.map +1 -1
- package/lib/esm/lib/circularImports.d.ts +3 -0
- package/lib/esm/lib/circularImports.js +61 -0
- package/lib/esm/lib/circularImports.js.map +1 -0
- package/lib/esm/lib/runCommand.d.ts +1 -0
- package/lib/esm/lib/runCommand.js +25 -2
- package/lib/esm/lib/runCommand.js.map +1 -1
- package/lib/esm/platforms/aws/goDocker.js +38 -36
- package/lib/esm/platforms/aws/goDocker.js.map +1 -1
- package/lib/esm/platforms/aws/viewsSync.d.ts +1 -0
- package/lib/esm/platforms/aws/viewsSync.js +27 -1
- package/lib/esm/platforms/aws/viewsSync.js.map +1 -1
- package/package.json +15 -14
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../../src/lib/runCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAYtC,2EAA2E;AAC3E,kDAAkD;AAClD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,IAAc,EAAE,UAA6B,EAAE,EAAiB,EAAE,CAC5G,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAE1C,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE;QACtC,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"runCommand.js","sourceRoot":"","sources":["../../../src/lib/runCommand.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from 'child_process';\nimport type { Readable } from 'stream';\n\nexport type RunCommandOptions = {\n // Extra environment variables merged over the parent process env.\n env?: Record<string, string>;\n // Working directory for the child (defaults to cwd).\n cwd?: string;\n // Echo the command before running it.\n logCommand?: boolean;\n};\n\n// Spawn a command, inheriting stdio, resolving on success. A non-zero exit\n// REJECTS so a failed build/deploy stops the run.\nexport const runCommand = (command: string, args: string[], options: RunCommandOptions = {}): Promise<void> =>\n new Promise((resolve, reject) => {\n const validArgs = args.filter((a) => !!a);\n\n if (options.logCommand) {\n console.log(`Running command: ${command} ${validArgs.join(' ')}`);\n }\n\n const child = spawn(command, validArgs, {\n stdio: 'inherit',\n // Shell only on Windows (to resolve npm/aws/cdk .cmd shims). On posix, run\n // without a shell so the already-array args are passed straight to the\n // program and can't be re-interpreted by `sh -c` — no command injection via\n // interpolated values (stack names, CI-supplied env, etc.).\n shell: process.platform === 'win32',\n cwd: options.cwd ?? process.cwd(),\n env: { ...process.env, ...(options.env ?? {}) },\n });\n\n child.on('error', (error) => reject(error));\n\n child.on('exit', (code, signal) => {\n if (signal) return reject(new Error(`${command} was killed with signal ${signal}`));\n if (code) return reject(new Error(`${command} ${validArgs.join(' ')} exited with code ${code}`));\n return resolve();\n });\n });\n\n// Run a command for its side effect only, swallowing both its output and its\n// exit code — for best-effort cleanup steps (e.g. `docker rm -f` of a container\n// that may not exist) that must never fail the run. Without a shell there's no\n// `>/dev/null 2>&1 || true`, so quieting and non-failing happen here instead.\nexport const runCommandBestEffort = (command: string, args: string[], options: RunCommandOptions = {}): Promise<void> =>\n new Promise((resolve) => {\n const validArgs = args.filter((a) => !!a);\n\n const child = spawn(command, validArgs, {\n stdio: 'ignore',\n shell: process.platform === 'win32',\n cwd: options.cwd ?? process.cwd(),\n env: { ...process.env, ...(options.env ?? {}) },\n });\n\n child.on('error', () => resolve());\n child.on('exit', () => resolve());\n });\n\nexport type RunCommandPrefixedOptions = {\n env?: Record<string, string>;\n cwd?: string;\n // ANSI color code for the prefix (see nextPrefixColor).\n color?: number;\n};\n\nconst PREFIX_COLORS = [36, 32, 33, 35, 34, 96, 92, 93, 95, 94];\nlet colorIndex = 0;\n\n// Hand each concurrent task a distinct prefix color so interleaved output is\n// scannable.\nexport const nextPrefixColor = (): number => {\n const color = PREFIX_COLORS[colorIndex % PREFIX_COLORS.length];\n colorIndex += 1;\n return color;\n};\n\n// Like runCommand, but pipes output and prefixes every line with a colored\n// [label] — for running many commands concurrently without unreadable\n// interleaving. Rejects on non-zero exit.\nexport const runCommandPrefixed = (label: string, command: string, args: string[], options: RunCommandPrefixedOptions = {}): Promise<void> =>\n new Promise((resolve, reject) => {\n const validArgs = args.filter((a) => !!a);\n const prefix = `\\x1b[${options.color ?? 36}m[${label}]\\x1b[0m `;\n\n const child = spawn(command, validArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n // Shell only on Windows (to resolve npm/aws/cdk .cmd shims). On posix, run\n // without a shell so the already-array args are passed straight to the\n // program and can't be re-interpreted by `sh -c` — no command injection via\n // interpolated values (stack names, CI-supplied env, etc.).\n shell: process.platform === 'win32',\n cwd: options.cwd ?? process.cwd(),\n env: { ...process.env, ...(options.env ?? {}) },\n });\n\n const attach = (stream: Readable, out: NodeJS.WriteStream): void => {\n let buffered = '';\n stream.on('data', (chunk: Buffer) => {\n buffered += chunk.toString();\n const lines = buffered.split('\\n');\n buffered = lines.pop() ?? '';\n lines.forEach((line) => out.write(`${prefix}${line}\\n`));\n });\n stream.on('end', () => {\n if (buffered) out.write(`${prefix}${buffered}\\n`);\n });\n };\n\n attach(child.stdout as Readable, process.stdout);\n attach(child.stderr as Readable, process.stderr);\n\n child.on('error', (error) => reject(error));\n\n child.on('exit', (code, signal) => {\n if (signal) return reject(new Error(`[${label}] ${command} was killed with signal ${signal}`));\n if (code) return reject(new Error(`[${label}] ${command} exited with code ${code}`));\n return resolve();\n });\n });\n"]}
|
|
@@ -34,7 +34,7 @@ import { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../li
|
|
|
34
34
|
import { runAppHook } from '../../lib/hooks';
|
|
35
35
|
import { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';
|
|
36
36
|
import { runRspack } from '../../lib/rspackRun';
|
|
37
|
-
import { nextPrefixColor, runCommand, runCommandPrefixed } from '../../lib/runCommand';
|
|
37
|
+
import { nextPrefixColor, runCommand, runCommandBestEffort, runCommandPrefixed } from '../../lib/runCommand';
|
|
38
38
|
import { assertNoFailures, runTasks } from '../../lib/runTasks';
|
|
39
39
|
import { logTimeEnd, logTimeStart } from '../../lib/timing';
|
|
40
40
|
import { bundleViews, getViewsDistDir } from '../../lib/views';
|
|
@@ -42,7 +42,7 @@ import { isAwsCredentialsValid } from './awsCredentials';
|
|
|
42
42
|
import { getCdkAppCommand, getDockerDir } from './cdkApp';
|
|
43
43
|
import { buildRemote, resolvePublishTarget } from './remote';
|
|
44
44
|
import { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';
|
|
45
|
-
import { getViewsS3Destinations } from './viewsSync';
|
|
45
|
+
import { getViewsS3Destinations, NO_CACHE_FILES } from './viewsSync';
|
|
46
46
|
const IMAGE_TAG = 'qpq-cdk-deployer';
|
|
47
47
|
const AWS_CLI_IMAGE = 'amazon/aws-cli';
|
|
48
48
|
const BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;
|
|
@@ -58,9 +58,14 @@ const AWS_ENV_PASSTHROUGH = [
|
|
|
58
58
|
'AWS_DEFAULT_ACCOUNT',
|
|
59
59
|
];
|
|
60
60
|
const assemblyDir = (appName, serviceName) => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);
|
|
61
|
+
// A container left behind by an interrupted run would block reusing its name.
|
|
62
|
+
// Clear it first, best-effort: a missing container (exit 1) must not fail the
|
|
63
|
+
// deploy. Was a `docker rm -f … >/dev/null 2>&1 ;` prefix on the run command,
|
|
64
|
+
// but that only worked under `shell: true`; as a separate call it's shell-free.
|
|
65
|
+
const removeContainer = (containerName) => runCommandBestEffort('docker', ['rm', '-f', containerName]);
|
|
61
66
|
const assertDockerRunning = async () => {
|
|
62
67
|
try {
|
|
63
|
-
await runCommand('docker', ['info', '--format', '
|
|
68
|
+
await runCommand('docker', ['info', '--format', 'docker daemon ok — server {{.ServerVersion}}']);
|
|
64
69
|
}
|
|
65
70
|
catch {
|
|
66
71
|
throw new Error('Docker daemon is not running (start Docker Desktop and retry).');
|
|
@@ -79,59 +84,62 @@ const buildDeployerImage = async () => {
|
|
|
79
84
|
// The assembly mounts read-only and is copied container-local first — the CDK
|
|
80
85
|
// CLI writes lock files next to the assembly it reads, and the copy keeps
|
|
81
86
|
// parallel api/web deploys of the same service fully isolated.
|
|
82
|
-
const dockerDeployStack = (color, appName, serviceName, stackType, stackName) => {
|
|
87
|
+
const dockerDeployStack = async (color, appName, serviceName, stackType, stackName) => {
|
|
83
88
|
const containerName = `${serviceName}-${stackType}`;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
// name — clear it quietly first.
|
|
87
|
-
'rm',
|
|
88
|
-
'-f',
|
|
89
|
-
containerName,
|
|
90
|
-
'>/dev/null',
|
|
91
|
-
'2>&1',
|
|
92
|
-
';',
|
|
93
|
-
'docker',
|
|
89
|
+
await removeContainer(containerName);
|
|
90
|
+
await runCommandPrefixed(`${stackType}:${serviceName}`, 'docker', [
|
|
94
91
|
'run',
|
|
95
92
|
'--rm',
|
|
96
93
|
'--name',
|
|
97
94
|
containerName,
|
|
98
95
|
'-v',
|
|
99
|
-
|
|
96
|
+
`${assemblyDir(appName, serviceName)}:/assembly:ro`,
|
|
100
97
|
...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),
|
|
101
98
|
IMAGE_TAG,
|
|
102
99
|
'bash',
|
|
103
100
|
'-c',
|
|
104
|
-
`
|
|
101
|
+
`cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events`,
|
|
105
102
|
], { color });
|
|
106
103
|
};
|
|
107
104
|
// Sync one service's pre-built views to S3 in a throwaway aws-cli container
|
|
108
105
|
// named <service>-views. The official image's entrypoint is `aws`. Multiple
|
|
109
106
|
// destinations (shell → website root + views prefix) run sequentially within
|
|
110
|
-
// the service, reusing the container name.
|
|
107
|
+
// the service, reusing the container name. Mirrors the host-side syncViewsToS3
|
|
108
|
+
// cache policy: hashed assets immutable, the fixed-name entry points re-uploaded
|
|
109
|
+
// with no-cache every deploy (see NO_CACHE_FILES).
|
|
111
110
|
const dockerSyncViews = async (color, appName, serviceName) => {
|
|
112
111
|
const containerName = `${serviceName}-views`;
|
|
113
|
-
|
|
112
|
+
const distDir = getViewsDistDir(appName, serviceName);
|
|
113
|
+
const runAwsCli = async (awsArgs) => {
|
|
114
|
+
await removeContainer(containerName);
|
|
114
115
|
await runCommandPrefixed(`views:${serviceName}`, 'docker', [
|
|
115
|
-
'rm',
|
|
116
|
-
'-f',
|
|
117
|
-
containerName,
|
|
118
|
-
'>/dev/null',
|
|
119
|
-
'2>&1',
|
|
120
|
-
';',
|
|
121
|
-
'docker',
|
|
122
116
|
'run',
|
|
123
117
|
'--rm',
|
|
124
118
|
'--name',
|
|
125
119
|
containerName,
|
|
126
120
|
'-v',
|
|
127
|
-
|
|
121
|
+
`${distDir}:/views:ro`,
|
|
128
122
|
...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),
|
|
129
123
|
AWS_CLI_IMAGE,
|
|
124
|
+
...awsArgs,
|
|
125
|
+
], { color });
|
|
126
|
+
};
|
|
127
|
+
for (const destination of getViewsS3Destinations(appName, serviceName)) {
|
|
128
|
+
await runAwsCli([
|
|
130
129
|
's3',
|
|
131
130
|
'sync',
|
|
132
131
|
'/views',
|
|
133
132
|
destination,
|
|
134
|
-
|
|
133
|
+
'--cache-control',
|
|
134
|
+
'public,max-age=31536000,immutable',
|
|
135
|
+
...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
|
|
136
|
+
]);
|
|
137
|
+
for (const file of NO_CACHE_FILES) {
|
|
138
|
+
if (!fs.existsSync(path.join(distDir, file))) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
await runAwsCli(['s3', 'cp', `/views/${file}`, `${destination}/${file}`, '--cache-control', 'no-cache']);
|
|
142
|
+
}
|
|
135
143
|
}
|
|
136
144
|
};
|
|
137
145
|
// Publish one service's already-built federated remote to S3 in a throwaway
|
|
@@ -150,20 +158,14 @@ const dockerPublishRemote = async (color, appName, serviceName) => {
|
|
|
150
158
|
['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],
|
|
151
159
|
];
|
|
152
160
|
for (const s3Operation of s3Operations) {
|
|
161
|
+
await removeContainer(containerName);
|
|
153
162
|
await runCommandPrefixed(`publish:${serviceName}`, 'docker', [
|
|
154
|
-
'rm',
|
|
155
|
-
'-f',
|
|
156
|
-
containerName,
|
|
157
|
-
'>/dev/null',
|
|
158
|
-
'2>&1',
|
|
159
|
-
';',
|
|
160
|
-
'docker',
|
|
161
163
|
'run',
|
|
162
164
|
'--rm',
|
|
163
165
|
'--name',
|
|
164
166
|
containerName,
|
|
165
167
|
'-v',
|
|
166
|
-
|
|
168
|
+
`${publishPath}:/publish:ro`,
|
|
167
169
|
...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),
|
|
168
170
|
AWS_CLI_IMAGE,
|
|
169
171
|
...s3Operation,
|
|
@@ -272,7 +274,7 @@ export const awsGoDocker = async (appName, plan) => {
|
|
|
272
274
|
run: async () => {
|
|
273
275
|
const outputDir = assemblyDir(appName, service);
|
|
274
276
|
fs.rmSync(outputDir, { recursive: true, force: true });
|
|
275
|
-
await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app',
|
|
277
|
+
await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app', getCdkAppCommand(), '--output', outputDir], {
|
|
276
278
|
cwd: getRoot(),
|
|
277
279
|
env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },
|
|
278
280
|
color: nextPrefixColor(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goDocker.js","sourceRoot":"","sources":["../../../../src/platforms/aws/goDocker.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:docker` — asks the same questions as `qpq go`, then deploys in\n// parallel via docker instead of sequentially:\n//\n// 1. Build everything locally first: QPQ config synth, rspack API bundles,\n// rspack view bundles, rspack federated-remote bundles, and one\n// self-contained CDK cloud assembly per service\n// (`cdk synth --output dist/qpq/cdk-docker/<app>/<service>`).\n// 2. Wave 1 (inf): one docker container per service deploys its inf stack,\n// all concurrently. Containers run only the CDK CLI against the mounted\n// pre-synthesized assembly — the workspace (and its npm-linked\n// quidproquo packages) never needs to exist inside the image.\n// 3. Wave 2 (api + web): once every inf stack is done, api and web stacks\n// for all services deploy concurrently (they depend only on inf, not on\n// each other).\n// 4. Views: the already-built bundles are synced to S3, one aws-cli\n// container per service, all concurrently.\n// 5. Publish: the already-built federated remotes (backends that opt in with\n// defineFederatedModuleStore(...)) are synced to S3 and their manifests\n// flipped, one aws-cli container per service, all concurrently.\n//\n// domain/bootstrap menu options deploy host-side exactly like `qpq go` —\n// a single stack gains nothing from docker.\n//\n// Requires the same env as `go` plus a running docker daemon. Knobs:\n// GO_DOCKER_BUILD_CONCURRENCY (default 4 — local builds are CPU-bound) and\n// GO_DOCKER_DEPLOY_CONCURRENCY (default unlimited — deploys just wait on\n// CloudFormation).\nimport { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\nimport { getServiceRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { synthCommand } from '../../commands/synth';\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runRspack } from '../../lib/rspackRun';\nimport { nextPrefixColor, runCommand, runCommandPrefixed } from '../../lib/runCommand';\nimport { assertNoFailures, runTasks } from '../../lib/runTasks';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { getCdkAppCommand, getDockerDir } from './cdkApp';\nimport { buildRemote, resolvePublishTarget } from './remote';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';\nimport { getViewsS3Destinations } from './viewsSync';\n\nconst IMAGE_TAG = 'qpq-cdk-deployer';\nconst AWS_CLI_IMAGE = 'amazon/aws-cli';\n\nconst BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;\nconst DEPLOY_CONCURRENCY = Number(process.env.GO_DOCKER_DEPLOY_CONCURRENCY) || Infinity;\n\n// Credentials/region reach the containers via `docker run -e NAME` (value\n// inherited from this process's env, never on the docker command line).\nconst AWS_ENV_PASSTHROUGH = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n 'AWS_DEFAULT_ACCOUNT',\n];\n\nconst assemblyDir = (appName: string, serviceName: string): string => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);\n\nconst assertDockerRunning = async (): Promise<void> => {\n try {\n await runCommand('docker', ['info', '--format', '\"docker daemon ok — server {{.ServerVersion}}\"']);\n } catch {\n throw new Error('Docker daemon is not running (start Docker Desktop and retry).');\n }\n};\n\nconst buildDeployerImage = async (): Promise<void> => {\n // Pin the image's CDK CLI to the CLI's own aws-cdk version so it can always\n // read the assembly schema the host synthesized.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cdkVersion = require('aws-cdk/package.json').version as string;\n console.log(`Building deployer image [${IMAGE_TAG}] (aws-cdk ${cdkVersion})`);\n await runCommand('docker', ['build', '-t', IMAGE_TAG, '--build-arg', `CDK_VERSION=${cdkVersion}`, getDockerDir()]);\n};\n\n// Deploy one stack from a pre-synthesized assembly in a throwaway container\n// named <service>-<stackType> (e.g. mini-web) so `docker ps` reads cleanly.\n// The assembly mounts read-only and is copied container-local first — the CDK\n// CLI writes lock files next to the assembly it reads, and the copy keeps\n// parallel api/web deploys of the same service fully isolated.\nconst dockerDeployStack = (\n color: number,\n appName: string,\n serviceName: string,\n stackType: 'inf' | 'api' | 'web',\n stackName: string,\n): Promise<void> => {\n const containerName = `${serviceName}-${stackType}`;\n return runCommandPrefixed(\n `${stackType}:${serviceName}`,\n 'docker',\n [\n // A container left behind by an interrupted run would block reusing the\n // name — clear it quietly first.\n 'rm',\n '-f',\n containerName,\n '>/dev/null',\n '2>&1',\n ';',\n 'docker',\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `\"${assemblyDir(appName, serviceName)}:/assembly:ro\"`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n IMAGE_TAG,\n 'bash',\n '-c',\n `\"cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events\"`,\n ],\n { color },\n );\n};\n\n// Sync one service's pre-built views to S3 in a throwaway aws-cli container\n// named <service>-views. The official image's entrypoint is `aws`. Multiple\n// destinations (shell → website root + views prefix) run sequentially within\n// the service, reusing the container name.\nconst dockerSyncViews = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const containerName = `${serviceName}-views`;\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n await runCommandPrefixed(\n `views:${serviceName}`,\n 'docker',\n [\n 'rm',\n '-f',\n containerName,\n '>/dev/null',\n '2>&1',\n ';',\n 'docker',\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `\"${getViewsDistDir(appName, serviceName)}:/views:ro\"`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n 's3',\n 'sync',\n '/views',\n destination,\n ],\n { color },\n );\n }\n};\n\n// Publish one service's already-built federated remote to S3 in a throwaway\n// aws-cli container named <service>-publish. The version dir (everything the\n// manifest references) syncs first, then the manifest.json is copied last —\n// same ordering guarantee as the host-side publish, so a reading lambda never\n// sees a manifest whose files aren't all present yet. resolvePublishTarget reads\n// the manifest hash + resolved bucket/prefix from the buildRemote output.\nconst dockerPublishRemote = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const { publishPath, manifestHash, bucketName, servicePrefix } = resolvePublishTarget(appName, serviceName);\n const containerName = `${serviceName}-publish`;\n\n // /publish is the service-remote-published dir; the hashed version subdir and\n // manifest.json both live directly under it.\n const s3Operations: string[][] = [\n ['s3', 'sync', `/publish/${manifestHash}`, `s3://${bucketName}/${servicePrefix}/${manifestHash}`],\n ['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],\n ];\n\n for (const s3Operation of s3Operations) {\n await runCommandPrefixed(\n `publish:${serviceName}`,\n 'docker',\n [\n 'rm',\n '-f',\n containerName,\n '>/dev/null',\n '2>&1',\n ';',\n 'docker',\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `\"${publishPath}:/publish:ro\"`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...s3Operation,\n ],\n { color },\n );\n }\n};\n\nexport const awsGoDocker = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n if (plan.kind === 'account') {\n await deployAccountStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n if (plan.kind === 'bootstrap') {\n if (plan.includeDomain) {\n await deployDomainStack(plan.appName);\n }\n await deployBootstrapStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n const { services, stacks } = plan;\n\n const allStacks = stacks === 'all';\n const needInf = allStacks || stacks === 'inf';\n const needApi = allStacks || stacks === 'api';\n const needWeb = allStacks || stacks === 'web';\n const needViews = allStacks || stacks === 'views';\n const needCdkDeploys = needInf || needApi || needWeb;\n\n const viewServices = needViews ? services.filter((s) => getServiceNamesWithViews(appName).includes(s)) : [];\n\n console.log('\\n\\nRunning dockerized deploy\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n // Federated publish needs the api stack (needApi ⇒ needCdkDeploys), so any\n // docker preflight it requires is already covered by these two checks.\n if (needCdkDeploys || viewServices.length > 0) {\n await assertDockerRunning();\n }\n if (needCdkDeploys) {\n await buildDeployerImage();\n }\n\n // ---- Phase 1: build everything locally ----\n console.log('\\n=== Phase 1: local builds ===\\n');\n\n await runAppHook(appName, 'predeploy');\n\n // Workspace packages resolve through their built dist/ (package.json main),\n // so bundles would ship stale code unless every lib is tsc'd first. npm runs\n // the workspaces in topological order; tsc -b is incremental, so this is\n // seconds when nothing changed.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // Synth QPQ configs (shell's config resolves the view bucket names).\n // In-process (no subprocess per service) — it's just config loads + JSON writes.\n const qpqSynthServices = [...new Set([...services, ...(needViews ? ['shell'] : [])])];\n for (const service of qpqSynthServices) {\n await synthCommand([service, '--app', appName]);\n }\n\n // Federated remotes are the backend story code, so republish them whenever the\n // api stack was (re)deployed. Skips services without defineFederatedModuleStore(...).\n // Detected here (after the workspace build) because it loads each service's config.\n const federatedServices = needApi ? getServiceNamesWithFederation(appName, services) : [];\n\n // The aws-cli image backs both the views sync (phase 4) and the federated\n // publish (phase 5) waves. Pull once now so those waves don't race N containers\n // into pulling the same image. Docker is already confirmed running above.\n if (viewServices.length > 0 || federatedServices.length > 0) {\n await runCommand('docker', ['pull', AWS_CLI_IMAGE]);\n }\n\n if (stacks !== 'views') {\n assertNoFailures(\n 'API bundling',\n await runTasks(\n services.map((service) => ({\n label: `bundle-api:${service}`,\n run: async () => {\n console.log(`Bundling api: [${service}]`);\n const qpqConfig = loadServiceQpqConfig(appName, service);\n await runRspack(getServiceRspackConfig(qpqConfig, path.join(getServiceDirectory(appName, service), 'service')));\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n assertNoFailures(\n 'Views bundling',\n await runTasks(\n viewServices.map((service) => ({\n label: `bundle-views:${service}`,\n run: async () => {\n console.log(`Bundling views: [${service}]`);\n await bundleViews(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n // Build the federated remotes locally now (rspack needs the workspace), so the\n // publish wave only has to sync the already-built output — mirroring how views\n // are bundled here and synced later.\n assertNoFailures(\n 'Remote bundling',\n await runTasks(\n federatedServices.map((service) => ({\n label: `bundle-remote:${service}`,\n run: async () => {\n console.log(`Bundling federated remote: [${service}]`);\n await buildRemote(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n if (needCdkDeploys) {\n // One self-contained cloud assembly per service (all its stacks + staged\n // assets) — separate --output dirs so synths can run in parallel and\n // containers never share mutable state.\n assertNoFailures(\n 'CDK synth',\n await runTasks(\n services.map((service) => ({\n label: `cdk-synth:${service}`,\n run: async () => {\n const outputDir = assemblyDir(appName, service);\n fs.rmSync(outputDir, { recursive: true, force: true });\n await runCommandPrefixed(\n `cdk-synth:${service}`,\n 'npx',\n ['cdk', 'synth', '--quiet', '--app', `'${getCdkAppCommand()}'`, '--output', `\"${outputDir}\"`],\n {\n cwd: getRoot(),\n env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },\n color: nextPrefixColor(),\n },\n );\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n // Stack names come from each service's live config, resolved once up front.\n const stackNames = new Map(\n services.map((service) => {\n const qpqConfig = loadServiceQpqConfig(appName, service);\n return [\n service,\n {\n inf: qpqDeployAwsCdkUtils.getInfStackName(qpqConfig),\n api: qpqDeployAwsCdkUtils.getApiStackName(qpqConfig),\n web: qpqDeployAwsCdkUtils.getWebStackName(qpqConfig),\n },\n ];\n }),\n );\n\n // ---- Phase 2: inf stacks, one container per service, all concurrent ----\n if (needInf) {\n console.log('\\n=== Phase 2: deploy inf stacks (docker) ===\\n');\n logTimeStart('infWave');\n assertNoFailures(\n 'Inf deploy',\n await runTasks(\n services.map((service) => ({\n label: `inf:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, 'inf', stackNames.get(service)!.inf),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('infWave');\n }\n\n // ---- Phase 3: api + web stacks, all concurrent ----\n if (needApi || needWeb) {\n console.log('\\n=== Phase 3: deploy api + web stacks (docker) ===\\n');\n logTimeStart('apiWebWave');\n assertNoFailures(\n 'Api/Web deploy',\n await runTasks(\n (['api', 'web'] as const)\n .filter((stackType) => (stackType === 'api' ? needApi : needWeb))\n .flatMap((stackType) =>\n services.map((service) => ({\n label: `${stackType}:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, stackType, stackNames.get(service)![stackType]),\n })),\n ),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('apiWebWave');\n }\n\n // ---- Phase 4: sync the pre-built views to S3, all concurrent ----\n if (viewServices.length > 0) {\n console.log('\\n=== Phase 4: sync views to S3 (docker) ===\\n');\n logTimeStart('viewsWave');\n assertNoFailures(\n 'Views sync',\n await runTasks(\n viewServices.map((service) => ({\n label: `views:${service}`,\n run: () => dockerSyncViews(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('viewsWave');\n }\n\n // ---- Phase 5: publish the pre-built federated remotes to S3, all concurrent ----\n if (federatedServices.length > 0) {\n console.log('\\n=== Phase 5: publish federated remotes to S3 (docker) ===\\n');\n logTimeStart('publishWave');\n assertNoFailures(\n 'Federated publish',\n await runTasks(\n federatedServices.map((service) => ({\n label: `publish:${service}`,\n run: () => dockerPublishRemote(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('publishWave');\n }\n\n logTimeEnd('totalTime');\n};\n"]}
|
|
1
|
+
{"version":3,"file":"goDocker.js","sourceRoot":"","sources":["../../../../src/platforms/aws/goDocker.ts"],"names":[],"mappings":"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","sourcesContent":["// `qpq go:docker` — asks the same questions as `qpq go`, then deploys in\n// parallel via docker instead of sequentially:\n//\n// 1. Build everything locally first: QPQ config synth, rspack API bundles,\n// rspack view bundles, rspack federated-remote bundles, and one\n// self-contained CDK cloud assembly per service\n// (`cdk synth --output dist/qpq/cdk-docker/<app>/<service>`).\n// 2. Wave 1 (inf): one docker container per service deploys its inf stack,\n// all concurrently. Containers run only the CDK CLI against the mounted\n// pre-synthesized assembly — the workspace (and its npm-linked\n// quidproquo packages) never needs to exist inside the image.\n// 3. Wave 2 (api + web): once every inf stack is done, api and web stacks\n// for all services deploy concurrently (they depend only on inf, not on\n// each other).\n// 4. Views: the already-built bundles are synced to S3, one aws-cli\n// container per service, all concurrently.\n// 5. Publish: the already-built federated remotes (backends that opt in with\n// defineFederatedModuleStore(...)) are synced to S3 and their manifests\n// flipped, one aws-cli container per service, all concurrently.\n//\n// domain/bootstrap menu options deploy host-side exactly like `qpq go` —\n// a single stack gains nothing from docker.\n//\n// Requires the same env as `go` plus a running docker daemon. Knobs:\n// GO_DOCKER_BUILD_CONCURRENCY (default 4 — local builds are CPU-bound) and\n// GO_DOCKER_DEPLOY_CONCURRENCY (default unlimited — deploys just wait on\n// CloudFormation).\nimport { qpqDeployAwsCdkUtils } from 'quidproquo-deploy-awscdk';\nimport { getServiceRspackConfig } from 'quidproquo-deploy-rspack';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { synthCommand } from '../../commands/synth';\nimport { DeployPlan } from '../../lib/deployPrompts';\nimport { getRoot, getServiceDirectory, getServiceNamesWithViews } from '../../lib/discovery';\nimport { runAppHook } from '../../lib/hooks';\nimport { getServiceNamesWithFederation, loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runRspack } from '../../lib/rspackRun';\nimport { nextPrefixColor, runCommand, runCommandBestEffort, runCommandPrefixed } from '../../lib/runCommand';\nimport { assertNoFailures, runTasks } from '../../lib/runTasks';\nimport { logTimeEnd, logTimeStart } from '../../lib/timing';\nimport { bundleViews, getViewsDistDir } from '../../lib/views';\nimport { isAwsCredentialsValid } from './awsCredentials';\nimport { getCdkAppCommand, getDockerDir } from './cdkApp';\nimport { buildRemote, resolvePublishTarget } from './remote';\nimport { deployAccountStack, deployBootstrapStack, deployDomainStack } from './stacks';\nimport { getViewsS3Destinations, NO_CACHE_FILES } from './viewsSync';\n\nconst IMAGE_TAG = 'qpq-cdk-deployer';\nconst AWS_CLI_IMAGE = 'amazon/aws-cli';\n\nconst BUILD_CONCURRENCY = Number(process.env.GO_DOCKER_BUILD_CONCURRENCY) || 4;\nconst DEPLOY_CONCURRENCY = Number(process.env.GO_DOCKER_DEPLOY_CONCURRENCY) || Infinity;\n\n// Credentials/region reach the containers via `docker run -e NAME` (value\n// inherited from this process's env, never on the docker command line).\nconst AWS_ENV_PASSTHROUGH = [\n 'AWS_ACCESS_KEY_ID',\n 'AWS_SECRET_ACCESS_KEY',\n 'AWS_SESSION_TOKEN',\n 'AWS_REGION',\n 'AWS_DEFAULT_REGION',\n 'AWS_DEFAULT_ACCOUNT',\n];\n\nconst assemblyDir = (appName: string, serviceName: string): string => path.join(getRoot(), 'dist', 'qpq', 'cdk-docker', appName, serviceName);\n\n// A container left behind by an interrupted run would block reusing its name.\n// Clear it first, best-effort: a missing container (exit 1) must not fail the\n// deploy. Was a `docker rm -f … >/dev/null 2>&1 ;` prefix on the run command,\n// but that only worked under `shell: true`; as a separate call it's shell-free.\nconst removeContainer = (containerName: string): Promise<void> => runCommandBestEffort('docker', ['rm', '-f', containerName]);\n\nconst assertDockerRunning = async (): Promise<void> => {\n try {\n await runCommand('docker', ['info', '--format', 'docker daemon ok — server {{.ServerVersion}}']);\n } catch {\n throw new Error('Docker daemon is not running (start Docker Desktop and retry).');\n }\n};\n\nconst buildDeployerImage = async (): Promise<void> => {\n // Pin the image's CDK CLI to the CLI's own aws-cdk version so it can always\n // read the assembly schema the host synthesized.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const cdkVersion = require('aws-cdk/package.json').version as string;\n console.log(`Building deployer image [${IMAGE_TAG}] (aws-cdk ${cdkVersion})`);\n await runCommand('docker', ['build', '-t', IMAGE_TAG, '--build-arg', `CDK_VERSION=${cdkVersion}`, getDockerDir()]);\n};\n\n// Deploy one stack from a pre-synthesized assembly in a throwaway container\n// named <service>-<stackType> (e.g. mini-web) so `docker ps` reads cleanly.\n// The assembly mounts read-only and is copied container-local first — the CDK\n// CLI writes lock files next to the assembly it reads, and the copy keeps\n// parallel api/web deploys of the same service fully isolated.\nconst dockerDeployStack = async (\n color: number,\n appName: string,\n serviceName: string,\n stackType: 'inf' | 'api' | 'web',\n stackName: string,\n): Promise<void> => {\n const containerName = `${serviceName}-${stackType}`;\n await removeContainer(containerName);\n await runCommandPrefixed(\n `${stackType}:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${assemblyDir(appName, serviceName)}:/assembly:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n IMAGE_TAG,\n 'bash',\n '-c',\n `cp -r /assembly /work/assembly && cdk deploy ${stackName} --app /work/assembly --require-approval never --progress events`,\n ],\n { color },\n );\n};\n\n// Sync one service's pre-built views to S3 in a throwaway aws-cli container\n// named <service>-views. The official image's entrypoint is `aws`. Multiple\n// destinations (shell → website root + views prefix) run sequentially within\n// the service, reusing the container name. Mirrors the host-side syncViewsToS3\n// cache policy: hashed assets immutable, the fixed-name entry points re-uploaded\n// with no-cache every deploy (see NO_CACHE_FILES).\nconst dockerSyncViews = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const containerName = `${serviceName}-views`;\n const distDir = getViewsDistDir(appName, serviceName);\n\n const runAwsCli = async (awsArgs: string[]): Promise<void> => {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `views:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${distDir}:/views:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...awsArgs,\n ],\n { color },\n );\n };\n\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n await runAwsCli([\n 's3',\n 'sync',\n '/views',\n destination,\n '--cache-control',\n 'public,max-age=31536000,immutable',\n ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),\n ]);\n\n for (const file of NO_CACHE_FILES) {\n if (!fs.existsSync(path.join(distDir, file))) {\n continue;\n }\n\n await runAwsCli(['s3', 'cp', `/views/${file}`, `${destination}/${file}`, '--cache-control', 'no-cache']);\n }\n }\n};\n\n// Publish one service's already-built federated remote to S3 in a throwaway\n// aws-cli container named <service>-publish. The version dir (everything the\n// manifest references) syncs first, then the manifest.json is copied last —\n// same ordering guarantee as the host-side publish, so a reading lambda never\n// sees a manifest whose files aren't all present yet. resolvePublishTarget reads\n// the manifest hash + resolved bucket/prefix from the buildRemote output.\nconst dockerPublishRemote = async (color: number, appName: string, serviceName: string): Promise<void> => {\n const { publishPath, manifestHash, bucketName, servicePrefix } = resolvePublishTarget(appName, serviceName);\n const containerName = `${serviceName}-publish`;\n\n // /publish is the service-remote-published dir; the hashed version subdir and\n // manifest.json both live directly under it.\n const s3Operations: string[][] = [\n ['s3', 'sync', `/publish/${manifestHash}`, `s3://${bucketName}/${servicePrefix}/${manifestHash}`],\n ['s3', 'cp', '/publish/manifest.json', `s3://${bucketName}/${servicePrefix}/manifest.json`],\n ];\n\n for (const s3Operation of s3Operations) {\n await removeContainer(containerName);\n await runCommandPrefixed(\n `publish:${serviceName}`,\n 'docker',\n [\n 'run',\n '--rm',\n '--name',\n containerName,\n '-v',\n `${publishPath}:/publish:ro`,\n ...AWS_ENV_PASSTHROUGH.flatMap((name) => ['-e', name]),\n AWS_CLI_IMAGE,\n ...s3Operation,\n ],\n { color },\n );\n }\n};\n\nexport const awsGoDocker = async (appName: string, plan: DeployPlan): Promise<void> => {\n if (plan.kind === 'cancelled') {\n return;\n }\n\n if ((await isAwsCredentialsValid()) === false) {\n console.log('Credentials are expired or invalid.');\n return;\n }\n\n logTimeStart('totalTime');\n\n if (plan.kind === 'account') {\n await deployAccountStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n if (plan.kind === 'bootstrap') {\n if (plan.includeDomain) {\n await deployDomainStack(plan.appName);\n }\n await deployBootstrapStack(plan.appName);\n logTimeEnd('totalTime');\n return;\n }\n\n const { services, stacks } = plan;\n\n const allStacks = stacks === 'all';\n const needInf = allStacks || stacks === 'inf';\n const needApi = allStacks || stacks === 'api';\n const needWeb = allStacks || stacks === 'web';\n const needViews = allStacks || stacks === 'views';\n const needCdkDeploys = needInf || needApi || needWeb;\n\n const viewServices = needViews ? services.filter((s) => getServiceNamesWithViews(appName).includes(s)) : [];\n\n console.log('\\n\\nRunning dockerized deploy\\n\\n');\n console.log('Executing for services');\n console.log(services.join(', '));\n\n // Federated publish needs the api stack (needApi ⇒ needCdkDeploys), so any\n // docker preflight it requires is already covered by these two checks.\n if (needCdkDeploys || viewServices.length > 0) {\n await assertDockerRunning();\n }\n if (needCdkDeploys) {\n await buildDeployerImage();\n }\n\n // ---- Phase 1: build everything locally ----\n console.log('\\n=== Phase 1: local builds ===\\n');\n\n await runAppHook(appName, 'predeploy');\n\n // Workspace packages resolve through their built dist/ (package.json main),\n // so bundles would ship stale code unless every lib is tsc'd first. npm runs\n // the workspaces in topological order; tsc -b is incremental, so this is\n // seconds when nothing changed.\n console.log('Building workspace packages');\n await runCommand('npm', ['run', 'build', '--workspaces', '--if-present']);\n\n // Synth QPQ configs (shell's config resolves the view bucket names).\n // In-process (no subprocess per service) — it's just config loads + JSON writes.\n const qpqSynthServices = [...new Set([...services, ...(needViews ? ['shell'] : [])])];\n for (const service of qpqSynthServices) {\n await synthCommand([service, '--app', appName]);\n }\n\n // Federated remotes are the backend story code, so republish them whenever the\n // api stack was (re)deployed. Skips services without defineFederatedModuleStore(...).\n // Detected here (after the workspace build) because it loads each service's config.\n const federatedServices = needApi ? getServiceNamesWithFederation(appName, services) : [];\n\n // The aws-cli image backs both the views sync (phase 4) and the federated\n // publish (phase 5) waves. Pull once now so those waves don't race N containers\n // into pulling the same image. Docker is already confirmed running above.\n if (viewServices.length > 0 || federatedServices.length > 0) {\n await runCommand('docker', ['pull', AWS_CLI_IMAGE]);\n }\n\n if (stacks !== 'views') {\n assertNoFailures(\n 'API bundling',\n await runTasks(\n services.map((service) => ({\n label: `bundle-api:${service}`,\n run: async () => {\n console.log(`Bundling api: [${service}]`);\n const qpqConfig = loadServiceQpqConfig(appName, service);\n await runRspack(getServiceRspackConfig(qpqConfig, path.join(getServiceDirectory(appName, service), 'service')));\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n assertNoFailures(\n 'Views bundling',\n await runTasks(\n viewServices.map((service) => ({\n label: `bundle-views:${service}`,\n run: async () => {\n console.log(`Bundling views: [${service}]`);\n await bundleViews(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n // Build the federated remotes locally now (rspack needs the workspace), so the\n // publish wave only has to sync the already-built output — mirroring how views\n // are bundled here and synced later.\n assertNoFailures(\n 'Remote bundling',\n await runTasks(\n federatedServices.map((service) => ({\n label: `bundle-remote:${service}`,\n run: async () => {\n console.log(`Bundling federated remote: [${service}]`);\n await buildRemote(appName, service);\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n\n if (needCdkDeploys) {\n // One self-contained cloud assembly per service (all its stacks + staged\n // assets) — separate --output dirs so synths can run in parallel and\n // containers never share mutable state.\n assertNoFailures(\n 'CDK synth',\n await runTasks(\n services.map((service) => ({\n label: `cdk-synth:${service}`,\n run: async () => {\n const outputDir = assemblyDir(appName, service);\n fs.rmSync(outputDir, { recursive: true, force: true });\n await runCommandPrefixed(`cdk-synth:${service}`, 'npx', ['cdk', 'synth', '--quiet', '--app', getCdkAppCommand(), '--output', outputDir], {\n cwd: getRoot(),\n env: { DEPLOY_SERVICE_NAME: service, DEPLOY_APP_NAME: appName },\n color: nextPrefixColor(),\n });\n },\n })),\n BUILD_CONCURRENCY,\n ),\n );\n }\n\n // Stack names come from each service's live config, resolved once up front.\n const stackNames = new Map(\n services.map((service) => {\n const qpqConfig = loadServiceQpqConfig(appName, service);\n return [\n service,\n {\n inf: qpqDeployAwsCdkUtils.getInfStackName(qpqConfig),\n api: qpqDeployAwsCdkUtils.getApiStackName(qpqConfig),\n web: qpqDeployAwsCdkUtils.getWebStackName(qpqConfig),\n },\n ];\n }),\n );\n\n // ---- Phase 2: inf stacks, one container per service, all concurrent ----\n if (needInf) {\n console.log('\\n=== Phase 2: deploy inf stacks (docker) ===\\n');\n logTimeStart('infWave');\n assertNoFailures(\n 'Inf deploy',\n await runTasks(\n services.map((service) => ({\n label: `inf:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, 'inf', stackNames.get(service)!.inf),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('infWave');\n }\n\n // ---- Phase 3: api + web stacks, all concurrent ----\n if (needApi || needWeb) {\n console.log('\\n=== Phase 3: deploy api + web stacks (docker) ===\\n');\n logTimeStart('apiWebWave');\n assertNoFailures(\n 'Api/Web deploy',\n await runTasks(\n (['api', 'web'] as const)\n .filter((stackType) => (stackType === 'api' ? needApi : needWeb))\n .flatMap((stackType) =>\n services.map((service) => ({\n label: `${stackType}:${service}`,\n run: () => dockerDeployStack(nextPrefixColor(), appName, service, stackType, stackNames.get(service)![stackType]),\n })),\n ),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('apiWebWave');\n }\n\n // ---- Phase 4: sync the pre-built views to S3, all concurrent ----\n if (viewServices.length > 0) {\n console.log('\\n=== Phase 4: sync views to S3 (docker) ===\\n');\n logTimeStart('viewsWave');\n assertNoFailures(\n 'Views sync',\n await runTasks(\n viewServices.map((service) => ({\n label: `views:${service}`,\n run: () => dockerSyncViews(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('viewsWave');\n }\n\n // ---- Phase 5: publish the pre-built federated remotes to S3, all concurrent ----\n if (federatedServices.length > 0) {\n console.log('\\n=== Phase 5: publish federated remotes to S3 (docker) ===\\n');\n logTimeStart('publishWave');\n assertNoFailures(\n 'Federated publish',\n await runTasks(\n federatedServices.map((service) => ({\n label: `publish:${service}`,\n run: () => dockerPublishRemote(nextPrefixColor(), appName, service),\n })),\n DEPLOY_CONCURRENCY,\n ),\n );\n logTimeEnd('publishWave');\n }\n\n logTimeEnd('totalTime');\n};\n"]}
|
|
@@ -3,9 +3,17 @@
|
|
|
3
3
|
// syncs to the 'website' bucket root AND to its prefix in the shared 'views'
|
|
4
4
|
// bucket (where every other service's views live).
|
|
5
5
|
import { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
6
8
|
import { loadServiceQpqConfig } from '../../lib/qpqConfigs';
|
|
7
9
|
import { runCommand } from '../../lib/runCommand';
|
|
8
10
|
import { getViewsDistDir } from '../../lib/views';
|
|
11
|
+
// The mutable entry points: fixed names whose CONTENT changes every deploy. They
|
|
12
|
+
// must never be cached without revalidation — a browser holding a stale
|
|
13
|
+
// mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle
|
|
14
|
+
// (the module-reload hot-swap and plain page refreshes both depend on these being
|
|
15
|
+
// fresh). Everything else in a views dist is content-hashed and safely immutable.
|
|
16
|
+
export const NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];
|
|
9
17
|
export const getViewsS3Destinations = (appName, serviceName) => {
|
|
10
18
|
const shellConfig = loadServiceQpqConfig(appName, 'shell');
|
|
11
19
|
const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);
|
|
@@ -17,9 +25,27 @@ export const getViewsS3Destinations = (appName, serviceName) => {
|
|
|
17
25
|
return destinations;
|
|
18
26
|
};
|
|
19
27
|
export const syncViewsToS3 = async (appName, serviceName) => {
|
|
28
|
+
const distDir = getViewsDistDir(appName, serviceName);
|
|
20
29
|
for (const destination of getViewsS3Destinations(appName, serviceName)) {
|
|
21
30
|
console.log(`Copying [${serviceName}] views to [${destination}]`);
|
|
22
|
-
|
|
31
|
+
// Content-hashed assets: cache forever.
|
|
32
|
+
await runCommand('aws', [
|
|
33
|
+
's3',
|
|
34
|
+
'sync',
|
|
35
|
+
distDir,
|
|
36
|
+
destination,
|
|
37
|
+
'--cache-control',
|
|
38
|
+
'public,max-age=31536000,immutable',
|
|
39
|
+
...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),
|
|
40
|
+
]);
|
|
41
|
+
// Entry points: cp (not sync) so the no-cache header is (re)applied on every
|
|
42
|
+
// deploy even when a body happens to be byte-identical.
|
|
43
|
+
for (const file of NO_CACHE_FILES) {
|
|
44
|
+
if (!fs.existsSync(path.join(distDir, file))) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
await runCommand('aws', ['s3', 'cp', path.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);
|
|
48
|
+
}
|
|
23
49
|
}
|
|
24
50
|
};
|
|
25
51
|
//# sourceMappingURL=viewsSync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,mDAAmD;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAY,EAAE;IACvF,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,cAAc,CAAC,sCAAsC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,YAAY,GAAG,CAAC,QAAQ,eAAe,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,cAAc,CAAC,sCAAsC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,YAAY,CAAC,IAAI,CAAC,QAAQ,iBAAiB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACzF,KAAK,MAAM,WAAW,IAAI,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,eAAe,WAAW,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"viewsSync.js","sourceRoot":"","sources":["../../../../src/platforms/aws/viewsSync.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,mDAAmD;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,iFAAiF;AACjF,wEAAwE;AACxE,gFAAgF;AAChF,kFAAkF;AAClF,kFAAkF;AAClF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,kBAAkB,EAAE,gBAAgB,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;AAElG,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,WAAmB,EAAY,EAAE;IACvF,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3D,MAAM,eAAe,GAAG,cAAc,CAAC,sCAAsC,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEpG,MAAM,YAAY,GAAG,CAAC,QAAQ,eAAe,IAAI,WAAW,EAAE,CAAC,CAAC;IAEhE,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,cAAc,CAAC,sCAAsC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QACxG,YAAY,CAAC,IAAI,CAAC,QAAQ,iBAAiB,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,OAAe,EAAE,WAAmB,EAAiB,EAAE;IACzF,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAEtD,KAAK,MAAM,WAAW,IAAI,sBAAsB,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,eAAe,WAAW,GAAG,CAAC,CAAC;QAElE,wCAAwC;QACxC,MAAM,UAAU,CAAC,KAAK,EAAE;YACtB,IAAI;YACJ,MAAM;YACN,OAAO;YACP,WAAW;YACX,iBAAiB;YACjB,mCAAmC;YACnC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;SACzD,CAAC,CAAC;QAEH,6EAA6E;QAC7E,wDAAwD;QACxD,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;gBAC7C,SAAS;YACX,CAAC;YAED,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,WAAW,IAAI,IAAI,EAAE,EAAE,iBAAiB,EAAE,UAAU,CAAC,CAAC,CAAC;QAC3H,CAAC;IACH,CAAC;AACH,CAAC,CAAC","sourcesContent":["// Views upload to S3. Bucket names resolve from the shell service's config.\n// shell is the module-federation host: its bundle is the root website, so it\n// syncs to the 'website' bucket root AND to its prefix in the shared 'views'\n// bucket (where every other service's views live).\nimport { awsNamingUtils } from 'quidproquo-actionprocessor-awslambda';\n\nimport fs from 'fs';\nimport path from 'path';\n\nimport { loadServiceQpqConfig } from '../../lib/qpqConfigs';\nimport { runCommand } from '../../lib/runCommand';\nimport { getViewsDistDir } from '../../lib/views';\n\n// The mutable entry points: fixed names whose CONTENT changes every deploy. They\n// must never be cached without revalidation — a browser holding a stale\n// mf-manifest.json or remoteEntry.js keeps running the previous deploy's bundle\n// (the module-reload hot-swap and plain page refreshes both depend on these being\n// fresh). Everything else in a views dist is content-hashed and safely immutable.\nexport const NO_CACHE_FILES = ['mf-manifest.json', 'remoteEntry.js', 'index.html', 'favicon.ico'];\n\nexport const getViewsS3Destinations = (appName: string, serviceName: string): string[] => {\n const shellConfig = loadServiceQpqConfig(appName, 'shell');\n const viewsBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('views', shellConfig);\n\n const destinations = [`s3://${viewsBucketName}/${serviceName}`];\n\n if (serviceName === 'shell') {\n const websiteBucketName = awsNamingUtils.getConfigRuntimeResourceNameFromConfig('website', shellConfig);\n destinations.push(`s3://${websiteBucketName}`);\n }\n\n return destinations;\n};\n\nexport const syncViewsToS3 = async (appName: string, serviceName: string): Promise<void> => {\n const distDir = getViewsDistDir(appName, serviceName);\n\n for (const destination of getViewsS3Destinations(appName, serviceName)) {\n console.log(`Copying [${serviceName}] views to [${destination}]`);\n\n // Content-hashed assets: cache forever.\n await runCommand('aws', [\n 's3',\n 'sync',\n distDir,\n destination,\n '--cache-control',\n 'public,max-age=31536000,immutable',\n ...NO_CACHE_FILES.flatMap((file) => ['--exclude', file]),\n ]);\n\n // Entry points: cp (not sync) so the no-cache header is (re)applied on every\n // deploy even when a body happens to be byte-identical.\n for (const file of NO_CACHE_FILES) {\n if (!fs.existsSync(path.join(distDir, file))) {\n continue;\n }\n\n await runCommand('aws', ['s3', 'cp', path.join(distDir, file), `${destination}/${file}`, '--cache-control', 'no-cache']);\n }\n }\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quidproquo-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "The qpq CLI — build, dev and deploy orchestration for QPQ apps",
|
|
5
5
|
"main": "./lib/commonjs/index.js",
|
|
6
6
|
"module": "./lib/esm/index.js",
|
|
@@ -34,27 +34,28 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/joe-coady/quidproquo#readme",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
38
|
-
"@aws-sdk/client-s3": "^3.
|
|
39
|
-
"@aws-sdk/client-sts": "^3.
|
|
37
|
+
"@aws-sdk/client-dynamodb": "^3.1093.0",
|
|
38
|
+
"@aws-sdk/client-s3": "^3.1093.0",
|
|
39
|
+
"@aws-sdk/client-sts": "^3.1093.0",
|
|
40
40
|
"@inquirer/prompts": "^8.5.2",
|
|
41
41
|
"@rspack/dev-server": "^2.1.0",
|
|
42
|
-
"aws-cdk": "^2.
|
|
43
|
-
"
|
|
44
|
-
"quidproquo
|
|
45
|
-
"quidproquo-
|
|
46
|
-
"quidproquo-
|
|
47
|
-
"quidproquo-
|
|
48
|
-
"quidproquo-deploy-
|
|
49
|
-
"quidproquo-
|
|
50
|
-
"quidproquo-
|
|
42
|
+
"aws-cdk": "^2.1132.1",
|
|
43
|
+
"madge": "^8.0.0",
|
|
44
|
+
"quidproquo": "0.1.11",
|
|
45
|
+
"quidproquo-actionprocessor-awslambda": "0.1.11",
|
|
46
|
+
"quidproquo-config-aws": "0.1.11",
|
|
47
|
+
"quidproquo-core": "0.1.11",
|
|
48
|
+
"quidproquo-deploy-awscdk": "0.1.11",
|
|
49
|
+
"quidproquo-deploy-rspack": "0.1.11",
|
|
50
|
+
"quidproquo-dev-server": "0.1.11",
|
|
51
|
+
"quidproquo-webserver": "0.1.11",
|
|
51
52
|
"ts-node": "^10.9.1",
|
|
52
53
|
"typescript": "^5.8.2"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@rspack/core": "^2.1.2",
|
|
56
57
|
"@types/node": "^22.13.13",
|
|
57
|
-
"quidproquo-tsconfig": "0.1.
|
|
58
|
+
"quidproquo-tsconfig": "0.1.11"
|
|
58
59
|
},
|
|
59
60
|
"bin": {
|
|
60
61
|
"qpq": "./lib/commonjs/bin/qpq.js"
|