diff --git a/src/utils/deploy/hash-fns.ts b/src/utils/deploy/hash-fns.ts index c9edc6379a3..44aae22c14b 100644 --- a/src/utils/deploy/hash-fns.ts +++ b/src/utils/deploy/hash-fns.ts @@ -153,6 +153,18 @@ const hashFns = async ( statusCb, tmpDir, }) + + // ZISI's in-memory FunctionResult only nests bootstrap/runtime version into + // buildData when writing the manifest cache. Reconstruct it for direct-zip paths. + for (const func of functionZips) { + if (!func.buildData) { + func.buildData = { + bootstrapVersion: func.bootstrapVersion, + runtimeAPIVersion: func.runtimeAPIVersion, + } + } + } + const fileObjs = functionZips.map( ({ buildData, diff --git a/tests/unit/utils/deploy/hash-fns.test.ts b/tests/unit/utils/deploy/hash-fns.test.ts index d58a5bea0e3..7b10c21c640 100644 --- a/tests/unit/utils/deploy/hash-fns.test.ts +++ b/tests/unit/utils/deploy/hash-fns.test.ts @@ -46,3 +46,31 @@ test('Hashes files in a folder', async (t) => { }) }) }) + +test('Populates build_data.bootstrapVersion for v2 functions on direct-zip path', async (t) => { + await withSiteBuilder(t, async (builder) => { + await builder + .withNetlifyToml({ config: { functions: { directory: 'functions' } } }) + .withFunction({ + path: 'hello.js', + runtimeAPIVersion: 2, + handler: (_req: Request) => new Response('Hello'), + }) + .build() + + const { fnConfig } = await hashFns(new BaseCommand(), [path.join(builder.directory, 'functions')], { + tmpDir: temporaryDirectory(), + concurrentHash: DEFAULT_CONCURRENT_HASH, + statusCb() {}, + }) + + expect(fnConfig).toBeDefined() + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- covered by expectation above + const helloConfig = fnConfig!.hello as { build_data?: { bootstrapVersion?: string; runtimeAPIVersion?: number } } + expect(helloConfig).toBeDefined() + expect(helloConfig.build_data).toBeDefined() + expect(helloConfig.build_data?.runtimeAPIVersion).toBe(2) + expect(helloConfig.build_data?.bootstrapVersion).toEqual(expect.any(String)) + expect(helloConfig.build_data?.bootstrapVersion).not.toBe('') + }) +})