Skip to content

Warn when schema.graphql api_version mismatches extension TOML#7098

Open
davejcameron wants to merge 1 commit intomainfrom
dc.warn-schema-version-mismatch
Open

Warn when schema.graphql api_version mismatches extension TOML#7098
davejcameron wants to merge 1 commit intomainfrom
dc.warn-schema-version-mismatch

Conversation

@davejcameron
Copy link
Copy Markdown
Contributor

@davejcameron davejcameron commented Mar 25, 2026

WHY are these changes introduced?

When a developer changes api_version in their shopify.extension.toml, the local schema.graphql becomes stale. The build then fails with cryptic type errors from typegen, with no indication that the schema simply needs to be re-fetched. This is a common failure case when working with Shopify Functions.

WHAT is this pull request doing?

Adds a lightweight check at the start of buildFunctionExtension that reads the first 512 bytes of schema.graphql looking for the server-stamped @apiVersion directive (e.g. schema @apiVersion(version: "2025-04") {). If present and it doesn't match the TOML's api_version, a warning is printed before the build runs:

schema.graphql was generated for API version 2025-01 but your extension targets 2025-04. Run shopify app function schema to update.

If the directive isn't present (legacy schema files, or server hasn't adopted stamping yet), the check is silently skipped — no false positives.

Depends on https://github.com/shop/world/pull/543227 for the server to stamp schemas with the @apiVersion directive.

How to test your changes?

  1. Create a function extension with api_version: "2025-01"
  2. Run shopify app function schema to fetch the schema (requires server-side directive stamping to be live, or manually add schema @apiVersion(version: "2025-01") { to the top of schema.graphql)
  3. Change api_version to "2025-04" in shopify.extension.toml
  4. Run shopify app function build
  5. Observe the warning before the build proceeds

Measuring impact

How do we know this change was effective? Please choose one:

  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix
  • Existing analytics will cater for this addition
  • PR includes analytics changes to measure impact

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 25, 2026

Coverage report

St.
Category Percentage Covered / Total
🟢 Statements 82.3% 14916/18125
🟡 Branches 74.83% 7364/9841
🟢 Functions 81.36% 3776/4641
🟢 Lines 82.68% 14098/17052

Test suite run success

3932 tests passing in 1513 suites.

Report generated by 🧪jest coverage report action from c185d02

@shivamkaravadra shivamkaravadra force-pushed the dc.warn-schema-version-mismatch branch from c185d02 to ff8c1cf Compare April 2, 2026 04:01
Copy link
Copy Markdown

This stack of pull requests is managed by Graphite. Learn more about stacking.

@shivamkaravadra shivamkaravadra force-pushed the dc.warn-schema-version-mismatch branch 4 times, most recently from 39dd7b8 to e993f17 Compare April 6, 2026 17:44
@shivamkaravadra shivamkaravadra force-pushed the dc.warn-schema-version-mismatch branch from e993f17 to a876b52 Compare April 6, 2026 17:54
@shivamkaravadra shivamkaravadra marked this pull request as ready for review April 6, 2026 19:39
@shivamkaravadra shivamkaravadra requested a review from a team as a code owner April 6, 2026 19:39
Copilot AI review requested due to automatic review settings April 6, 2026 19:39
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 6, 2026

We detected some changes at packages/*/src and there are no updates in the .changeset.
If the changes are user-facing, run pnpm changeset add to track your changes and include them in the next release CHANGELOG.

Caution

DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a pre-build warning to help developers notice when a function’s local schema.graphql was generated for a different API version than the extension’s api_version, avoiding confusing typegen/build errors caused by stale schemas.

Changes:

  • Adds a schema @apiVersion(version: "...") stamp check at the start of buildFunctionExtension and warns on mismatch.
  • Introduces unit tests covering match/mismatch/no-directive/missing-file scenarios.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
packages/app/src/cli/services/build/extension.ts Reads schema.graphql to detect stamped API version and emits a warning before building when mismatched.
packages/app/src/cli/services/build/extension.test.ts Adds tests validating the new warning behavior under several schema-file conditions.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

try {
content = await readFile(schemaPath)
} catch (error) {
if (error instanceof Error && 'code' in error) return
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handler in warnIfSchemaMismatch returns for any filesystem error that happens to have a code property (e.g. EACCES/EPERM), which can hide real problems reading schema.graphql and lead to more cryptic failures later in the build. Only ignore the expected “file not found” case (e.g. code === 'ENOENT') and rethrow other read errors.

Suggested change
if (error instanceof Error && 'code' in error) return
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') return

Copilot uses AI. Check for mistakes.
Comment on lines +232 to +237
async function warnIfSchemaMismatch(extension: ExtensionInstance<FunctionConfigType>) {
const schemaPath = joinPath(extension.directory, 'schema.graphql')
let content: string
try {
content = await readFile(schemaPath)
} catch (error) {
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check currently reads the entire schema.graphql into memory via readFile(schemaPath). The PR description calls out reading only the first ~512 bytes; doing that would keep the check lightweight even if schemas become large. Consider reading a small prefix (e.g. open + read / or readFile then slice) before applying the regex.

Copilot uses AI. Check for mistakes.
return runCommand(extension.buildCommand, extension, options)
}

const API_VERSION_DIRECTIVE_RE = /@apiVersion\(version:\s*"([^"]+)"\)/
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API_VERSION_DIRECTIVE_RE requires version: with no whitespace before the colon. If the server ever formats this as version : "YYYY-MM" (still valid GraphQL), the warning will be skipped. Making the regex tolerant of optional whitespace around the colon would make the check more robust.

Suggested change
const API_VERSION_DIRECTIVE_RE = /@apiVersion\(version:\s*"([^"]+)"\)/
const API_VERSION_DIRECTIVE_RE = /@apiVersion\(version\s*:\s*"([^"]+)"\)/

Copilot uses AI. Check for mistakes.
Comment on lines +450 to +454
function mockSchemaNotFound() {
const err = new Error('ENOENT') as NodeJS.ErrnoException
err.code = 'ENOENT'
vi.mocked(readFile).mockRejectedValueOnce(err)
}
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new tests cover ENOENT, match, mismatch, and “no directive”, but there’s no assertion for non-ENOENT read failures. Adding a test that readFile rejects with something like EACCES/EPERM and ensuring the error is propagated would prevent regressions (especially if warnIfSchemaMismatch is tightened to only ignore ENOENT).

Copilot uses AI. Check for mistakes.
@shivamkaravadra
Copy link
Copy Markdown

It seems as though the failing test may be flaky as it is timing out and another PR was merged with the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants