Skip to content

Commit 5f8d6a6

Browse files
authored
Merge pull request #7244 from Shopify/04-10-fix_function_extension_build_path_and_info_output_path_resolution
Fix function extension build path and info output path resolution
2 parents fdfccd5 + 8283c0a commit 5f8d6a6

3 files changed

Lines changed: 82 additions & 8 deletions

File tree

packages/app/src/cli/services/build/extension.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,18 @@ export async function buildFunctionExtension(
161161
await runTrampoline(extension.outputPath)
162162
}
163163

164+
const projectOutputPath = joinPath(extension.directory, extension.outputRelativePath)
165+
164166
if (
165167
fileExistsSync(extension.outputPath) &&
166168
bundlePath !== extension.outputPath &&
169+
bundlePath !== projectOutputPath &&
167170
dirname(bundlePath) !== dirname(extension.outputPath)
168171
) {
172+
// Bundle build for deploy: base64-encode into the bundle directory
169173
await bundleFunctionExtension(extension.outputPath, bundlePath)
170174
}
175+
171176
// eslint-disable-next-line @typescript-eslint/no-explicit-any
172177
} catch (error: any) {
173178
// To avoid random user-code errors being reported as CLI bugs, we capture and rethrow them as AbortError.

packages/app/src/cli/services/function/info.test.ts

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,52 @@ describe('functionInfo', () => {
4949
expect(parsed).toHaveProperty('apiVersion')
5050
})
5151

52+
test('uses build.path from config for wasmPath when present', async () => {
53+
// Given
54+
const funcWithBuildPath = await testFunctionExtension({
55+
dir: '/path/to/function',
56+
config: {
57+
name: 'My Function',
58+
type: 'function',
59+
handle: 'my-function',
60+
api_version: '2024-01',
61+
configuration_ui: false,
62+
build: {
63+
path: 'custom/output.wasm',
64+
wasm_opt: false,
65+
},
66+
},
67+
})
68+
const options = {
69+
format: 'json' as const,
70+
functionRunnerPath: '/path/to/runner',
71+
schemaPath: '/path/to/schema.graphql',
72+
}
73+
74+
// When
75+
const result = functionInfo(funcWithBuildPath, options)
76+
77+
// Then
78+
const parsed = JSON.parse(result as string)
79+
expect(parsed.wasmPath).toBe('/path/to/function/custom/output.wasm')
80+
})
81+
82+
test('falls back to outputRelativePath when build.path is not set', async () => {
83+
// Given
84+
const options = {
85+
format: 'json' as const,
86+
functionRunnerPath: '/path/to/runner',
87+
schemaPath: '/path/to/schema.graphql',
88+
}
89+
90+
// When
91+
const result = functionInfo(ourFunction, options)
92+
93+
// Then
94+
const parsed = JSON.parse(result as string)
95+
expect(parsed.wasmPath).toBe(ourFunction.outputPath)
96+
})
97+
5298
test('returns AlertCustomSection array when format is text', async () => {
5399
// Given
54100
const options = {
@@ -174,7 +220,15 @@ describe('functionInfo', () => {
174220
}
175221

176222
// When
177-
const result = formatAsJson(testFunc, config, targeting, '/path/to/runner', '/path/to/schema.graphql')
223+
const functionOutputPath = '/path/to/function/output.wasm'
224+
const result = formatAsJson(
225+
testFunc,
226+
config,
227+
targeting,
228+
'/path/to/runner',
229+
functionOutputPath,
230+
'/path/to/schema.graphql',
231+
)
178232

179233
// Then
180234
const parsed = JSON.parse(result)
@@ -189,7 +243,7 @@ describe('functionInfo', () => {
189243
},
190244
},
191245
schemaPath: '/path/to/schema.graphql',
192-
wasmPath: testFunc.outputPath,
246+
wasmPath: functionOutputPath,
193247
functionRunnerPath: '/path/to/runner',
194248
})
195249
})
@@ -209,7 +263,7 @@ describe('functionInfo', () => {
209263
const targeting = {}
210264

211265
// When
212-
const result = formatAsJson(testFunc, config, targeting, '/path/to/runner')
266+
const result = formatAsJson(testFunc, config, targeting, '/path/to/runner', 'path/to/function.wasm', undefined)
213267

214268
// Then
215269
const parsed = JSON.parse(result)
@@ -362,7 +416,14 @@ describe('functionInfo', () => {
362416
}
363417

364418
// When
365-
const result = buildTextFormatSections(testFunc, config, targeting, '/path/to/runner', '/path/to/schema.graphql')
419+
const result = buildTextFormatSections(
420+
testFunc,
421+
config,
422+
targeting,
423+
'/path/to/runner',
424+
'/path/to/function/output.wasm',
425+
'/path/to/schema.graphql',
426+
)
366427

367428
// Then
368429
// configuration, targeting, build, function runner

packages/app/src/cli/services/function/info.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {ExtensionInstance} from '../../models/extensions/extension-instance.js'
22
import {outputContent, outputToken} from '@shopify/cli-kit/node/output'
3+
import {joinPath} from '@shopify/cli-kit/node/path'
34
import {InlineToken, AlertCustomSection} from '@shopify/cli-kit/node/ui'
45

56
type Format = 'json' | 'text'
@@ -14,6 +15,9 @@ interface FunctionConfiguration {
1415
handle?: string
1516
name?: string
1617
api_version?: string
18+
build?: {
19+
path?: string
20+
}
1721
targeting?: {
1822
target: string
1923
input_query?: string
@@ -42,6 +46,7 @@ export function formatAsJson(
4246
config: FunctionConfiguration,
4347
targeting: {[key: string]: {inputQueryPath?: string; export?: string}},
4448
functionRunnerPath: string,
49+
functionOutputPath: string,
4550
schemaPath?: string,
4651
): string {
4752
return JSON.stringify(
@@ -51,7 +56,7 @@ export function formatAsJson(
5156
apiVersion: config.api_version,
5257
targeting,
5358
schemaPath,
54-
wasmPath: ourFunction.outputPath,
59+
wasmPath: functionOutputPath,
5560
functionRunnerPath,
5661
},
5762
null,
@@ -127,6 +132,7 @@ export function buildTextFormatSections(
127132
config: FunctionConfiguration,
128133
targeting: {[key: string]: {inputQueryPath?: string; export?: string}},
129134
functionRunnerPath: string,
135+
functionOutputPath: string,
130136
schemaPath?: string,
131137
): AlertCustomSection[] {
132138
const sections: AlertCustomSection[] = [buildConfigurationSection(config, ourFunction.name)]
@@ -136,7 +142,7 @@ export function buildTextFormatSections(
136142
sections.push(targetingSection)
137143
}
138144

139-
sections.push(buildBuildSection(ourFunction.outputPath, schemaPath), buildFunctionRunnerSection(functionRunnerPath))
145+
sections.push(buildBuildSection(functionOutputPath, schemaPath), buildFunctionRunnerSection(functionRunnerPath))
140146

141147
return sections
142148
}
@@ -150,9 +156,11 @@ export function functionInfo(
150156

151157
const targeting = buildTargetingData(config, ourFunction.directory)
152158

159+
const functionOutputPath = joinPath(ourFunction.directory, config.build?.path ?? ourFunction.outputRelativePath)
160+
153161
if (format === 'json') {
154-
return formatAsJson(ourFunction, config, targeting, functionRunnerPath, schemaPath)
162+
return formatAsJson(ourFunction, config, targeting, functionRunnerPath, functionOutputPath, schemaPath)
155163
}
156164

157-
return buildTextFormatSections(ourFunction, config, targeting, functionRunnerPath, schemaPath)
165+
return buildTextFormatSections(ourFunction, config, targeting, functionRunnerPath, functionOutputPath, schemaPath)
158166
}

0 commit comments

Comments
 (0)