Skip to content

Commit 59336d4

Browse files
authored
gitignore .apphosting/ in nextjs builds (#378)
This is part of making adapter builds idempotent
1 parent 84a1be5 commit 59336d4

File tree

3 files changed

+98
-8
lines changed

3 files changed

+98
-8
lines changed

packages/@apphosting/adapter-nextjs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@apphosting/adapter-nextjs",
3-
"version": "14.0.17",
3+
"version": "14.0.18",
44
"main": "dist/index.js",
55
"description": "Experimental addon to the Firebase CLI to add web framework support",
66
"repository": {

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

Lines changed: 90 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,95 @@ outputFiles:
164164
async () => await validateOutputDirectory(outputBundleOptions, path.join(tmpDir, ".next")),
165165
);
166166
});
167+
it(".apphosting gitignored correctly in a monorepo setup", async () => {
168+
const { generateBuildOutput } = await importUtils;
169+
const files = {
170+
".next/standalone/apps/next-app/standalonefile": "",
171+
".next/static/staticfile": "",
172+
};
173+
generateTestFiles(tmpDir, files);
174+
const standaloneAppPath = path.join(tmpDir, ".next", "standalone", "apps", "next-app");
175+
await generateBuildOutput(
176+
tmpDir,
177+
"apps/next-app",
178+
{
179+
bundleYamlPath: path.join(tmpDir, ".apphosting", "bundle.yaml"),
180+
outputDirectoryBasePath: path.join(tmpDir, ".apphosting"),
181+
outputDirectoryAppPath: standaloneAppPath,
182+
outputPublicDirectoryPath: path.join(standaloneAppPath, "public"),
183+
outputStaticDirectoryPath: path.join(standaloneAppPath, ".next", "static"),
184+
serverFilePath: path.join(standaloneAppPath, "server.js"),
185+
},
186+
path.join(tmpDir, ".next"),
187+
defaultNextVersion,
188+
adapterMetadata,
189+
);
190+
191+
const expectedFiles = {
192+
".gitignore": "/.apphosting/",
193+
};
194+
const expectedPartialYaml = {
195+
version: "v1",
196+
runConfig: { runCommand: "node .next/standalone/apps/next-app/server.js" },
197+
};
198+
validateTestFiles(tmpDir, expectedFiles);
199+
validatePartialYamlContents(tmpDir, ".apphosting/bundle.yaml", expectedPartialYaml);
200+
});
201+
202+
it(".apphosting gitignored without existing .gitignore file", async () => {
203+
const { generateBuildOutput, validateOutputDirectory } = await importUtils;
204+
const files = {
205+
// .next/standalone/.next/ must be created beforehand otherwise
206+
// generateBuildOutput will attempt to copy
207+
// .next/ into .next/standalone/.next
208+
".next/standalone/.next/package.json": "",
209+
".next/static/staticfile": "",
210+
};
211+
generateTestFiles(tmpDir, files);
212+
await generateBuildOutput(
213+
tmpDir,
214+
tmpDir,
215+
outputBundleOptions,
216+
path.join(tmpDir, ".next"),
217+
defaultNextVersion,
218+
adapterMetadata,
219+
);
220+
await validateOutputDirectory(outputBundleOptions, path.join(tmpDir, ".next"));
221+
222+
const expectedFiles = {
223+
".gitignore": "/.apphosting/",
224+
};
225+
validateTestFiles(tmpDir, expectedFiles);
226+
});
227+
it(".apphosting gitignored in existing .gitignore file", async () => {
228+
const { generateBuildOutput, validateOutputDirectory } = await importUtils;
229+
const files = {
230+
// .next/standalone/.next/ must be created beforehand otherwise
231+
// generateBuildOutput will attempt to copy
232+
// .next/ into .next/standalone/.next
233+
".next/standalone/.next/package.json": "",
234+
".next/static/staticfile": "",
235+
".gitignore": "/.next/",
236+
};
237+
generateTestFiles(tmpDir, files);
238+
await generateBuildOutput(
239+
tmpDir,
240+
tmpDir,
241+
outputBundleOptions,
242+
path.join(tmpDir, ".next"),
243+
defaultNextVersion,
244+
{
245+
adapterPackageName: "@apphosting/adapter-nextjs",
246+
adapterVersion: "14.0.1",
247+
},
248+
);
249+
await validateOutputDirectory(outputBundleOptions, path.join(tmpDir, ".next"));
250+
251+
const expectedFiles = {
252+
".gitignore": "/.next/\n/.apphosting/",
253+
};
254+
validateTestFiles(tmpDir, expectedFiles);
255+
});
167256
it("expects directories and other files to be copied over", async () => {
168257
const { generateBuildOutput, validateOutputDirectory } = await importUtils;
169258
const files = {
@@ -188,10 +277,7 @@ outputFiles:
188277
outputBundleOptions,
189278
path.join(tmpDir, ".next"),
190279
defaultNextVersion,
191-
{
192-
adapterPackageName: "@apphosting/adapter-nextjs",
193-
adapterVersion: "14.0.1",
194-
},
280+
adapterMetadata,
195281
);
196282
await validateOutputDirectory(outputBundleOptions, path.join(tmpDir, ".next"));
197283

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ import {
1212
MiddlewareManifest,
1313
} from "./interfaces.js";
1414
import { NextConfigComplete } from "next/dist/server/config-shared.js";
15-
import { OutputBundleConfig } from "@apphosting/common";
15+
import { OutputBundleConfig, updateOrCreateGitignore } from "@apphosting/common";
1616

1717
// fs-extra is CJS, readJson can't be imported using shorthand
18-
export const { copy, exists, writeFile, readJson, readdir, readFileSync, existsSync, mkdir } =
18+
export const { copy, exists, writeFile, readJson, readdir, readFileSync, existsSync, ensureDir } =
1919
fsExtra;
2020

2121
// Loads the user's next.config.js file.
@@ -135,6 +135,10 @@ export async function generateBuildOutput(
135135
copyResources(appDir, opts.outputDirectoryAppPath, opts.bundleYamlPath),
136136
generateBundleYaml(opts, rootDir, nextVersion, adapterMetadata),
137137
]);
138+
// generateBundleYaml creates the output directory (if it does not already exist).
139+
// We need to make sure it is gitignored.
140+
const normalizedBundleDir = normalize(relative(rootDir, opts.outputDirectoryBasePath));
141+
updateOrCreateGitignore(rootDir, [`/${normalizedBundleDir}/`]);
138142
return;
139143
}
140144

@@ -181,7 +185,7 @@ async function generateBundleYaml(
181185
nextVersion: string,
182186
adapterMetadata: AdapterMetadata,
183187
): Promise<void> {
184-
await mkdir(opts.outputDirectoryBasePath);
188+
await ensureDir(opts.outputDirectoryBasePath);
185189
const outputBundle: OutputBundleConfig = {
186190
version: "v1",
187191
runConfig: {

0 commit comments

Comments
 (0)