Skip to content

Commit b3553de

Browse files
authored
Add metadata to angular bundle.yaml (#246)
Add a framework metadata section to Angular adapter's bundle.yaml output: - adapter name - adapter version - framework name - framework version
1 parent ce2b276 commit b3553de

File tree

4 files changed

+64
-23
lines changed

4 files changed

+64
-23
lines changed

packages/@apphosting/adapter-angular/src/bin/build.spec.ts

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { OutputBundleOptions } from "../interface.js";
99
describe("build commands", () => {
1010
let tmpDir: string;
1111
let outputBundleOptions: OutputBundleOptions;
12+
let defaultAngularVersion: string;
1213
beforeEach(() => {
1314
tmpDir = generateTmpDir();
1415
outputBundleOptions = {
@@ -20,16 +21,18 @@ describe("build commands", () => {
2021
serverFilePath: resolve(tmpDir, ".apphosting", "dist", "server", "server.mjs"),
2122
needsServerGenerated: false,
2223
};
24+
defaultAngularVersion = "17.3.8";
2325
});
2426

2527
it("expects all output bundle files to be generated", async () => {
26-
const { generateOutputDirectory, validateOutputDirectory } = await importUtils;
28+
const { generateOutputDirectory, validateOutputDirectory, createMetadata } = await importUtils;
2729
const files = {
2830
"dist/test/browser/browserfile": "",
2931
"dist/test/server/server.mjs": "",
3032
};
33+
const packageVersion = createMetadata(defaultAngularVersion).adapterVersion;
3134
generateTestFiles(tmpDir, files);
32-
await generateOutputDirectory(tmpDir, outputBundleOptions);
35+
await generateOutputDirectory(tmpDir, outputBundleOptions, defaultAngularVersion);
3336
await validateOutputDirectory(outputBundleOptions);
3437

3538
const expectedFiles = {
@@ -42,6 +45,11 @@ neededDirs:
4245
staticAssets:
4346
- .apphosting/dist/browser
4447
env: []
48+
metadata:
49+
adapterPackageName: "@apphosting/adapter-angular"
50+
adapterVersion: ${packageVersion}
51+
framework: angular
52+
frameworkVersion: 17.3.8
4553
`,
4654
};
4755
validateTestFiles(tmpDir, expectedFiles);
@@ -56,22 +64,12 @@ env: []
5664
generateTestFiles(tmpDir, files);
5765
await generateOutputDirectory(tmpDir, outputBundleOptions, "17.3.2");
5866

59-
const expectedFiles = {
60-
".apphosting/dist/browser/browserfile": "",
61-
".apphosting/dist/server/server.mjs": "",
62-
".apphosting/bundle.yaml": `
63-
runCommand: node .apphosting/dist/server/server.mjs
64-
neededDirs:
65-
- .apphosting
66-
staticAssets:
67-
- .apphosting/dist/browser
68-
env:
67+
const expectedContents = `env:
6968
- variable: SSR_PORT
7069
value: "8080"
7170
availability: RUNTIME
72-
`,
73-
};
74-
validateTestFiles(tmpDir, expectedFiles);
71+
`;
72+
validateFileExistsAndContains(tmpDir, ".apphosting/bundle.yaml", expectedContents);
7573
});
7674

7775
it("test failed validateOutputDirectory", async () => {
@@ -81,7 +79,7 @@ env:
8179
"dist/test/server/notserver.mjs": "",
8280
};
8381
generateTestFiles(tmpDir, files);
84-
await generateOutputDirectory(tmpDir, outputBundleOptions);
82+
await generateOutputDirectory(tmpDir, outputBundleOptions, defaultAngularVersion);
8583
assert.rejects(async () => await validateOutputDirectory(outputBundleOptions));
8684
});
8785

@@ -134,3 +132,17 @@ function validateTestFiles(baseDir: string, expectedFiles: Object): void {
134132
assert.deepEqual(ignoreBlankLines(contents), ignoreBlankLines(expectedContents));
135133
});
136134
}
135+
136+
function validateFileExistsAndContains(
137+
baseDir: string,
138+
expectedFileName: string,
139+
expectedContents: string,
140+
): void {
141+
const fileToRead = path.join(baseDir, expectedFileName);
142+
assert.ok(fs.existsSync(fileToRead), `File '${fileToRead}' does not exist.`);
143+
const contents = fs.readFileSync(fileToRead).toString();
144+
assert.ok(
145+
contents.includes(expectedContents),
146+
`Actual contents do not contain expected contents.\nExpected contained contents:\n${expectedContents}\nActual:\n${contents}`,
147+
);
148+
}

packages/@apphosting/adapter-angular/src/bin/build.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const opts = getBuildOptions();
1212

1313
// Check build conditions, which vary depending on your project structure (standalone or monorepo)
1414
await checkBuildConditions(opts);
15+
if (!process.env.FRAMEWORK_VERSION) {
16+
throw new Error("Could not find the angular version of the application");
17+
}
1518

1619
// enable JSON build logs for application builder
1720
process.env.NG_BUILD_LOGS_JSON = "1";

packages/@apphosting/adapter-angular/src/interface.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ export enum Availability {
2525
Runtime = "RUNTIME",
2626
}
2727

28+
// Metadata schema for bundle.yaml outputted by angular adapter
29+
export interface Metadata {
30+
adapterPackageName: string;
31+
adapterVersion: string;
32+
framework: string;
33+
frameworkVersion: string;
34+
}
35+
2836
// valid manifest schema
2937
export interface ValidManifest {
3038
errors: string[];

packages/@apphosting/adapter-angular/src/utils.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { stringify as yamlStringify } from "yaml";
88
import {
99
Availability,
1010
EnvironmentVariable,
11+
Metadata,
1112
OutputBundleOptions,
1213
OutputPaths,
1314
buildManifestSchema,
@@ -17,7 +18,7 @@ import stripAnsi from "strip-ansi";
1718
import { BuildOptions } from "@apphosting/common";
1819

1920
// fs-extra is CJS, readJson can't be imported using shorthand
20-
export const { writeFile, move, readJson, mkdir, copyFile } = fsExtra;
21+
export const { writeFile, move, readJson, mkdir, copyFile, readFileSync, existsSync } = fsExtra;
2122

2223
const require = createRequire(import.meta.url);
2324
const __filename = fileURLToPath(import.meta.url);
@@ -142,14 +143,31 @@ function extractManifestOutput(output: string): string {
142143
return stripAnsi(output.substring(start, end + 1));
143144
}
144145

146+
/**
147+
* Create metadata needed for outputting adapter and framework metrics in bundle.yaml.
148+
*/
149+
export function createMetadata(angularVersion: string): Metadata {
150+
const packageJsonPath = `${__dirname}/../package.json`;
151+
if (!existsSync(packageJsonPath)) {
152+
throw new Error(`Angular adapter package.json file does not exist at ${packageJsonPath}`);
153+
}
154+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
155+
return {
156+
adapterPackageName: packageJson.name,
157+
adapterVersion: packageJson.version,
158+
framework: "angular",
159+
frameworkVersion: angularVersion,
160+
};
161+
}
162+
145163
/**
146164
* Move the base output directory, which contains the server and browser bundle directory, and prerendered routes
147165
* as well as generating bundle.yaml.
148166
*/
149167
export async function generateOutputDirectory(
150168
cwd: string,
151169
outputBundleOptions: OutputBundleOptions,
152-
angularVersion?: string,
170+
angularVersion: string,
153171
): Promise<void> {
154172
await move(outputBundleOptions.baseDirectory, outputBundleOptions.outputBaseDirectory, {
155173
overwrite: true,
@@ -161,10 +179,10 @@ export async function generateOutputDirectory(
161179
}
162180

163181
// add environment variable to bundle.yaml if needed for specific versions
164-
function addBundleYamlEnvVar(angularVersion?: string): EnvironmentVariable[] {
182+
function generateEnvVars(angularVersion: string): EnvironmentVariable[] {
165183
const runtimeEnvVars: EnvironmentVariable[] = [];
166184
// add env var to solve angular port issue, existing only for Angular v17.3.2 (b/332896115)
167-
if (angularVersion && angularVersion === "17.3.2") {
185+
if (angularVersion === "17.3.2") {
168186
const ssrPortEnvVar: EnvironmentVariable = {
169187
variable: "SSR_PORT",
170188
value: "8080",
@@ -179,16 +197,16 @@ function addBundleYamlEnvVar(angularVersion?: string): EnvironmentVariable[] {
179197
async function generateBundleYaml(
180198
outputBundleOptions: OutputBundleOptions,
181199
cwd: string,
182-
angularVersion?: string,
200+
angularVersion: string,
183201
): Promise<void> {
184-
const runtimeEnvVars = addBundleYamlEnvVar(angularVersion);
185202
await writeFile(
186203
outputBundleOptions.bundleYamlPath,
187204
yamlStringify({
188205
runCommand: `node ${normalize(relative(cwd, outputBundleOptions.serverFilePath))}`,
189206
neededDirs: [normalize(relative(cwd, outputBundleOptions.outputDirectory))],
190207
staticAssets: [normalize(relative(cwd, outputBundleOptions.browserDirectory))],
191-
env: runtimeEnvVars,
208+
env: generateEnvVars(angularVersion),
209+
metadata: createMetadata(angularVersion),
192210
}),
193211
);
194212
}

0 commit comments

Comments
 (0)