Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Feb 4, 2026

What

Adds id and position fields to the options array in the product_variants stream schema. These fields come from Shopify's ProductOption API and are needed by users to:

  • Reference specific product options for API operations (using id)
  • Display options in the correct order on product pages (using position)

Resolves #72277
Related to airbytehq/oncall#11147

Requested by @pkozikow.

Link to Devin run: https://app.devin.ai/sessions/1d654c1925bc4ab789e40bc43a026e56

How

  1. Extended the GraphQL query to fetch product.options (with id, name, position) alongside the existing product.id
  2. Added _enrich_options_with_product_options() method that matches each selectedOption to its parent ProductOption by name and copies over the id and position values
  3. Updated the JSON schema to include the new id (integer) and position (integer) fields in the options array items

The matching is done by option name because Shopify's SelectedOption (what variants return) doesn't directly expose the parent ProductOption.id or ProductOption.position - these fields only exist on the ProductOption object at the product level.

Review guide

  1. source_shopify/shopify_graphql/bulk/query.py - GraphQL query extension and new enrichment method
  2. source_shopify/schemas/product_variants.json - Schema additions for id and position

Key areas to verify:

  • The name-matching logic between selectedOptions and ProductOption is correct for Shopify's API (assumes option names are unique per product)
  • The Bulk API query doesn't violate Shopify's 2-level nesting restriction (the product.options field is a simple array, not a connection)
  • The resolve_str_id conversion is appropriate for ProductOption IDs
  • The enrichment happens before the product field is removed from the record

User Impact

Users syncing the product_variants stream will now have access to id and position fields in each option object. This is an additive, non-breaking change - existing syncs will continue to work and will simply include the new fields.

Can this PR be safely reverted and rolled back?

  • YES 💚
  • NO ❌

Open with Devin

…options schema

Adds id and position fields to the options array in the product_variants stream schema.
These fields come from Shopify's ProductOption object and are needed by users to:
- Reference specific product options for API operations (using id)
- Display options in the correct order on product pages (using position)

Changes:
1. Extended GraphQL query to fetch product.options with id, name, position
2. Added _enrich_options_with_product_options() method to match options by name
   and copy id/position values from ProductOption to variant options
3. Updated JSON schema to include id (integer) and position (integer) fields

Resolves #72277
Related to airbytehq/oncall#11147

Co-Authored-By: unknown <>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

👋 Greetings, Airbyte Team Member!

Here are some helpful tips and reminders for your convenience.

💡 Show Tips and Tricks

PR Slash Commands

Airbyte Maintainers (that's you!) can execute the following slash commands on your PR:

  • 🛠️ Quick Fixes
    • /format-fix - Fixes most formatting issues.
    • /bump-version - Bumps connector versions, scraping changelog description from the PR title.
  • ❇️ AI Testing and Review:
    • /ai-docs-review - Provides AI-powered documentation recommendations for PRs with connector changes.
    • /ai-prove-fix - Runs prerelease readiness checks, including testing against customer connections.
    • /ai-canary-prerelease - Rolls out prerelease to 5-10 connections for canary testing.
    • /ai-review - AI-powered PR review for connector safety and quality gates.
  • 🚀 Connector Releases:
    • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
    • /bump-progressive-rollout-version - Bumps connector version with an RC suffix (2.16.10-rc.1) for progressive rollouts (enableProgressiveRollout: true).
      • Example: /bump-progressive-rollout-version changelog="Add new feature for progressive rollout"
  • ☕️ JVM connectors:
    • /update-connector-cdk-version connector=<CONNECTOR_NAME> - Updates the specified connector to the latest CDK version.
      Example: /update-connector-cdk-version connector=destination-bigquery
    • /bump-bulk-cdk-version bump=patch changelog='foo' - Bump the Bulk CDK's version. bump can be major/minor/patch.
  • 🐍 Python connectors:
    • /poe connector source-example lock - Run the Poe lock task on the source-example connector, committing the results back to the branch.
    • /poe source example lock - Alias for /poe connector source-example lock.
    • /poe source example use-cdk-branch my/branch - Pin the source-example CDK reference to the branch name specified.
    • /poe source example use-cdk-latest - Update the source-example CDK dependency to the latest available version.
  • ⚙️ Admin commands:
    • /force-merge reason="<REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.
      Example: /force-merge reason="CI is flaky, tests pass locally"
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

source-shopify Connector Test Results

211 tests   201 ✅  1m 59s ⏱️
  2 suites   10 💤
  2 files      0 ❌

Results for commit 77a0f43.

♻️ This comment has been updated with latest results.

@pkozikow
Copy link

pkozikow commented Feb 4, 2026

/ai-prove-fix

AI Prove Fix Started

Running readiness checks and testing against customer connections.
View workflow run
🔍 AI Prove Fix session starting... Running readiness checks and testing against customer connections. View playbook

Devin AI session created successfully!

@devin-ai-integration
Copy link
Contributor Author

devin-ai-integration bot commented Feb 4, 2026

Fix Validation Evidence

Outcome: Fix/Feature Proven Successfully

Evidence Summary

Tested on 1 internal Airbyte connection with the product_variants stream enabled. After pinning to pre-release version 3.2.0-preview.49b6b54, the sync completed successfully with 1 product_variants record (26 source fields populated) and no errors. The connector correctly fetches and enriches the new id and position fields in the options array.

Next Steps
  1. This PR appears ready for review and merge.
  2. For broader validation before release, consider running /ai-canary-prerelease to test on additional connections.
  3. The weekly /ai-release-manager will automatically monitor the release rollout after merge.

Connector & PR Details

Connector: source-shopify
PR: #72810
Pre-release Version Tested: airbyte/source-shopify:3.2.0-preview.49b6b54
Detailed Results: https://github.com/airbytehq/oncall/issues/11147#issuecomment-3844681347

Evidence Plan

Proving Criteria

A sync that successfully returns the new id and position fields in the options array with valid values, demonstrating the GraphQL query extension and enrichment logic work correctly.

Disproving Criteria

  • Sync fails with errors related to the new fields or GraphQL query changes
  • Schema validation errors for the options array
  • Fields remain null when they should have values from ProductOption

Cases Attempted

  1. Internal Airbyte test connection - Sync succeeded with product_variants stream, 26 source fields populated including the new schema fields
Pre-flight Checks
  • Viability: Fix addresses the reported issue (adds missing id and position fields to options schema)
  • Safety: No malicious code or dangerous patterns detected
  • Reversibility: Additive schema change, can be safely rolled back without breaking existing syncs
Detailed Evidence Log

Test Timeline (UTC):

  • 01:03 - Pinned source to pre-release version 3.2.0-preview.49b6b54
  • 01:05:04 - Triggered sync (Job ID: 69074090)
  • 01:11 - Sync completed successfully

Results:

  • Status: succeeded
  • Records synced: 43 total (1 from product_variants)
  • Bytes synced: 32,010
  • Failures: None

Note: Connection IDs and detailed logs are recorded in the linked private issue.


Session: https://app.devin.ai/sessions/3922f69d67ba4fdd9b6b58787c86601a

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

Pre-release Connector Publish Started

Publishing pre-release build for connector source-shopify.
PR: #72810

Pre-release versions will be tagged as {version}-preview.49b6b54
and are available for version pinning via the scoped_configuration API.

View workflow run
Pre-release Publish: SUCCESS

Docker image (pre-release):
airbyte/source-shopify:3.2.0-preview.49b6b54

Docker Hub: https://hub.docker.com/layers/airbyte/source-shopify/3.2.0-preview.49b6b54

Registry JSON:

@pkozikow pkozikow marked this pull request as ready for review February 4, 2026 01:25
@aldogonzalez8
Copy link
Contributor

aldogonzalez8 commented Feb 4, 2026

/bump-version

Bump Version job started... Check job output.

✅ Changes applied successfully. (77a0f43)

Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional flags.

Open in Devin Review

Comment on lines +2858 to +2873
for product_option in product_options:
if product_option:
name = product_option.get("name")
if name:
product_options_map[name] = {
"id": self.tools.resolve_str_id(product_option.get("id")),
"position": product_option.get("position"),
}

# Enrich each option with id and position from the matching ProductOption
for option in options:
if option:
option_name = option.get("name")
if option_name and option_name in product_options_map:
option["id"] = product_options_map[option_name]["id"]
option["position"] = product_options_map[option_name]["position"]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm somewhat worried about performance implications of enriching each record via additional calls x number of records.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good question! To clarify - this enrichment does not make any additional API calls. The product.options data is fetched in the same Bulk GraphQL query alongside the variant data (see the query_nodes change at line 2794-2800).

The enrichment is purely in-memory: we're just matching the variant's selectedOptions (which only have name and value) with the product's options (which have id, name, position) by name, then copying over the id and position values.

The performance impact is minimal - it's O(n*m) where n = number of options per variant (typically 1-3) and m = number of product options (also typically 1-3). In practice, this is a handful of dictionary lookups per record with no network overhead.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's a big help and that resolves my concern. Thanks for the clarification.

@aaronsteers
Copy link
Collaborator

aaronsteers commented Feb 4, 2026

/ai-review

PR AI Review Started

Evaluating connector PR for safety and quality.
View workflow run
AI PR Review starting...

Reviewing PR for connector safety and quality.
View playbook

Devin AI session created successfully!

@devin-ai-integration
Copy link
Contributor Author

AI PR Review in Progress

Reviewing PR #72810 for connector safety and quality gates.

Session: https://app.devin.ai/sessions/dad9aef3c161441582564138b3835761

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

Deploy preview for airbyte-docs ready!

✅ Preview
https://airbyte-docs-8s05jvegj-airbyte-growth.vercel.app

Built with commit 77a0f43.
This pull request is being automatically deployed with vercel-action

@devin-ai-integration
Copy link
Contributor Author

AI PR Review Report

Review Action: NO ACTION (NOT ELIGIBLE)

Gate Status
1. CI/Tests PASS
2. Security PASS
3. Safety PASS
4. Ops Risk PASS
5. Validation PASS
6. PR Quality PASS

📋 PR Details & Eligibility

Connector & PR Info

Connector(s): source-shopify
PR: #72810
HEAD SHA: 77a0f43cbc873bd75fef15593ece949d2f346f9b
Session: https://app.devin.ai/sessions/dad9aef3c161441582564138b3835761

Auto-Approve Eligibility

Eligible: No
Category: not-eligible
Reason: PR contains functional code changes (new enrichment method in query.py, new schema fields in product_variants.json). This is a feature addition, not docs-only, additive-spec-only, patch/minor-deps-only, or comment/whitespace-only.

Review Action Details

NO ACTION (NOT ELIGIBLE) - All gates pass but PR is not eligible for auto-approval. No PR review submitted. Human review required.

Note: This bot can approve PRs when all gates pass AND the PR is eligible for auto-approval (docs-only, additive spec changes, patch/minor dependency bumps, or comment/whitespace-only changes). PRs with functional code changes require human review even if all gates pass.

🔍 Gate Evaluation Details

Gate-by-Gate Analysis

Gate Status Enforced? Details
1. CI/Tests PASS Yes All core checks passed (211 tests, 201 passed, 10 skipped, 0 failed). WARNING: No test files modified for source code changes. Note: Live validation evidence present (Gate 5) - risk is mitigated but unit test coverage still recommended.
2. Security PASS Yes No security-sensitive patterns detected (no api_key, secret, password, token, credential, auth keywords in diff)
3. Safety/Reversibility PASS Yes Additive schema change only (adding id and position fields). No fields removed. PR confirms reversibility.
4. Operational Risk PASS Yes No rate limit, retry, timeout, or pagination changes. Enrichment is in-memory only (no additional API calls).
5. Pre-Release Validation PASS Yes /ai-prove-fix completed successfully. Pre-release 3.2.0-preview.49b6b54 tested on internal connection with product_variants stream.
6. PR Quality PASS Yes Description present with What/How/Review guide/User Impact sections. Changelog updated. Version bumped to 3.2.1.

Files Changed

  1. airbyte-integrations/connectors/source-shopify/metadata.yaml - version bump 3.2.0 → 3.2.1
  2. airbyte-integrations/connectors/source-shopify/pyproject.toml - version bump 3.2.0 → 3.2.1
  3. airbyte-integrations/connectors/source-shopify/source_shopify/schemas/product_variants.json - Added id and position fields to options array
  4. airbyte-integrations/connectors/source-shopify/source_shopify/shopify_graphql/bulk/query.py - Extended GraphQL query and added _enrich_options_with_product_options() method
  5. docs/integrations/sources/shopify.md - Changelog entry
📚 Evidence Consulted

Evidence

  • Changed files: 5 files (+51/-5 lines)
  • CI checks: 37 passed, 7 skipped, 0 failed
    • Test source-shopify Connector: PASS (211 tests, 201 passed, 10 skipped)
    • Lint source-shopify Connector: PASS
    • source-shopify Pre-Release Checks: PASS
    • Format Check: PASS
    • Check Changelog Updated: PASS
  • PR labels: area/connectors, connectors/source/shopify (auto-applied)
  • PR description: Present and detailed
  • Existing bot reviews: Devin Review (COMMENTED - no issues found)
  • Pre-release validation: /ai-prove-fix completed successfully with sync evidence

name="product",
fields=[
Field(name="id", alias="product_id"),
Field(name="options", alias="product_options", fields=["id", "name", "position"]),
Copy link
Contributor

Choose a reason for hiding this comment

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

dumb question, don't we need also value for what I see in the schema:

Image

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Great question! The value field is already present - it comes from the variant's selectedOptions (which we alias as options).

Here's how the data flows:

From variant's selectedOptions (already fetched):

  • name - e.g., "Color"
  • value - e.g., "Red" (the specific value selected for this variant)

From product.options (ProductOption) (added in this PR):

  • id - the ProductOption ID
  • position - display order

The key distinction is that ProductOption.values (plural) contains ALL possible values for an option (e.g., ["Red", "Blue", "Green"]), while SelectedOption.value (singular) is the specific value chosen for that variant.

We match by name and enrich with id and position - the value is already there from selectedOptions.

Copy link
Contributor

@aldogonzalez8 aldogonzalez8 left a comment

Choose a reason for hiding this comment

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

APPROVED

Copy link
Collaborator

@aaronsteers aaronsteers left a comment

Choose a reason for hiding this comment

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

Approved!

@pkozikow pkozikow merged commit 128da3e into master Feb 4, 2026
44 checks passed
@pkozikow pkozikow deleted the devin/1770163675-shopify-product-variants-options-id-position branch February 4, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

source-shopify: Add id and position fields to product_variants.options schema

4 participants