Skip to content

Commit

Permalink
Merge pull request #4429 from Shopify/ms.update-function-runner-to-us-ds
Browse files Browse the repository at this point in the history
[ShopifyVM] Update-function runner to use dynamic scaling
  • Loading branch information
mssalemi committed Sep 12, 2024
2 parents abf7ccc + a822359 commit b86bc88
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 6 deletions.
5 changes: 5 additions & 0 deletions .changeset/sixty-mangos-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/app': minor
---

Bumps function-runner version to include details on dynamic resource limits.
10 changes: 8 additions & 2 deletions packages/app/src/cli/commands/app/function/run.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {functionFlags, inFunctionContext} from '../../../services/function/common.js'
import {functionFlags, inFunctionContext, getOrGenerateSchemaPath} from '../../../services/function/common.js'
import {runFunction} from '../../../services/function/runner.js'
import {appFlags} from '../../../flags.js'
import Command from '@shopify/cli-kit/node/base-command'
Expand Down Expand Up @@ -44,7 +44,7 @@ export default class FunctionRun extends Command {
await inFunctionContext({
path: flags.path,
userProvidedConfigName: flags.config,
callback: async (_app, ourFunction) => {
callback: async (app, ourFunction) => {
let functionExport = DEFAULT_FUNCTION_EXPORT

if (flags.export !== undefined) {
Expand Down Expand Up @@ -78,12 +78,18 @@ export default class FunctionRun extends Command {
)
}

const inputQueryPath = ourFunction?.configuration.targeting?.[0]?.input_query
const queryPath = inputQueryPath && `${ourFunction?.directory}/${inputQueryPath}`
const schemaPath = await getOrGenerateSchemaPath(ourFunction, app)

await runFunction({
functionExtension: ourFunction,
json: flags.json,
inputPath: flags.input,
export: functionExport,
stdin: 'inherit',
schemaPath,
queryPath,
})
},
})
Expand Down
2 changes: 1 addition & 1 deletion packages/app/src/cli/services/function/binaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import * as gzip from 'node:zlib'
import {fileURLToPath} from 'node:url'

const JAVY_VERSION = 'v3.0.1'
const FUNCTION_RUNNER_VERSION = 'v6.0.0'
const FUNCTION_RUNNER_VERSION = 'v6.2.0'

// The logic for determining the download URL and what to do with the response stream is _coincidentally_ the same for
// Javy and function-runner for now. Those methods may not continue to have the same logic in the future. If they
Expand Down
50 changes: 49 additions & 1 deletion packages/app/src/cli/services/function/common.test.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import {inFunctionContext} from './common.js'
import {getOrGenerateSchemaPath, inFunctionContext} from './common.js'
import {loadApp} from '../../models/app/loader.js'
import {testApp, testFunctionExtension} from '../../models/app/app.test-data.js'
import {AppInterface} from '../../models/app/app.js'
import {ExtensionInstance} from '../../models/extensions/extension-instance.js'
import {FunctionConfigType} from '../../models/extensions/specifications/function.js'
import {generateSchemaService} from '../generate-schema.js'
import {describe, vi, expect, beforeEach, test} from 'vitest'
import {renderAutocompletePrompt, renderFatalError} from '@shopify/cli-kit/node/ui'
import {joinPath} from '@shopify/cli-kit/node/path'
import {isTerminalInteractive} from '@shopify/cli-kit/node/context/local'
import {fileExists} from '@shopify/cli-kit/node/fs'

vi.mock('../../models/app/loader.js')
vi.mock('@shopify/cli-kit/node/ui')
vi.mock('@shopify/cli-kit/node/context/local')
vi.mock('@shopify/cli-kit/node/fs')
vi.mock('../generate-schema.js')

let app: AppInterface
let ourFunction: ExtensionInstance
Expand Down Expand Up @@ -73,6 +78,49 @@ describe('ensure we are within a function context', () => {
}),
).rejects.toThrowError()

// Then
expect(ranCallback).toBe(false)
})
})

describe('getOrGenerateSchemaPath', () => {
let extension: ExtensionInstance<FunctionConfigType>
let app: AppInterface

beforeEach(() => {
extension = {
directory: '/path/to/function',
configuration: {},
} as ExtensionInstance<FunctionConfigType>

app = {} as AppInterface
})

test('returns the path if the schema file exists', async () => {
// Given
const expectedPath = joinPath(extension.directory, 'schema.graphql')
vi.mocked(fileExists).mockResolvedValue(true)

// When
const result = await getOrGenerateSchemaPath(extension, app)

// Then
expect(result).toBe(expectedPath)
expect(fileExists).toHaveBeenCalledWith(expectedPath)
})

test('generates the schema file if it does not exist', async () => {
// Given
const expectedPath = joinPath(extension.directory, 'schema.graphql')
vi.mocked(fileExists).mockResolvedValue(false)
vi.mocked(generateSchemaService).mockResolvedValueOnce()
vi.mocked(fileExists).mockResolvedValueOnce(true)

// When
const result = await getOrGenerateSchemaPath(extension, app)

// Then
expect(result).toBe(expectedPath)
expect(fileExists).toHaveBeenCalledWith(expectedPath)
})
})
23 changes: 22 additions & 1 deletion packages/app/src/cli/services/function/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import {loadApp} from '../../models/app/loader.js'
import {loadLocalExtensionsSpecifications} from '../../models/extensions/load-specifications.js'
import {ExtensionInstance} from '../../models/extensions/extension-instance.js'
import {FunctionConfigType} from '../../models/extensions/specifications/function.js'
import {resolvePath, cwd} from '@shopify/cli-kit/node/path'
import {generateSchemaService} from '../generate-schema.js'
import {resolvePath, cwd, joinPath} from '@shopify/cli-kit/node/path'
import {AbortError} from '@shopify/cli-kit/node/error'
import {Flags} from '@oclif/core'
import {isTerminalInteractive} from '@shopify/cli-kit/node/context/local'
import {renderAutocompletePrompt} from '@shopify/cli-kit/node/ui'
import {fileExists} from '@shopify/cli-kit/node/fs'

export const functionFlags = {
path: Flags.string({
Expand Down Expand Up @@ -50,3 +52,22 @@ export async function inFunctionContext({
throw new AbortError('Run this command from a function directory or use `--path` to specify a function directory.')
}
}

export async function getOrGenerateSchemaPath(
extension: ExtensionInstance<FunctionConfigType>,
app: AppInterface,
): Promise<string | undefined> {
const path = joinPath(extension.directory, 'schema.graphql')
if (await fileExists(path)) {
return path
}

await generateSchemaService({
app,
extension,
stdout: false,
path: extension.directory,
})

return (await fileExists(path)) ? path : undefined
}
16 changes: 15 additions & 1 deletion packages/app/src/cli/services/function/runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ describe('runFunction', () => {
stdin: new Readable(),
stdout: new Writable(),
stderr: new Writable(),
schemaPath: 'schemaPath',
queryPath: 'src/queryPath',
}

// When
Expand All @@ -47,7 +49,19 @@ describe('runFunction', () => {
// Then
expect(exec).toHaveBeenCalledWith(
functionRunnerBinary().path,
['-f', functionExtension.outputPath, '--input', options.inputPath, '--export', options.export, '--json'],
[
'-f',
functionExtension.outputPath,
'--input',
options.inputPath,
'--export',
options.export,
'--json',
'--schema-path',
options.schemaPath,
'--query-path',
options.queryPath,
],
{
cwd: functionExtension.directory,
stdin: options.stdin,
Expand Down
6 changes: 6 additions & 0 deletions packages/app/src/cli/services/function/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ interface FunctionRunnerOptions {
inputPath?: string
export?: string
json?: boolean
schemaPath?: string
queryPath?: string
stdin?: Readable | 'inherit'
stdout?: Writable | 'inherit'
stderr?: Writable | 'inherit'
Expand All @@ -29,6 +31,10 @@ export async function runFunction(options: FunctionRunnerOptions) {
if (options.json) {
args.push('--json')
}
if (options.schemaPath && options.queryPath) {
args.push('--schema-path', options.schemaPath)
args.push('--query-path', options.queryPath)
}

return exec(functionRunner.path, ['-f', options.functionExtension.outputPath, ...args], {
cwd: options.functionExtension.directory,
Expand Down

0 comments on commit b86bc88

Please sign in to comment.