Skip to content

feat(source-pylon): true incremental sync via POST /issues/search on updated_at#76083

Open
Henry Bogardus (usbogie) wants to merge 7 commits intoairbytehq:masterfrom
usbogie:source-pylon/incremental-sync-updated-at
Open

feat(source-pylon): true incremental sync via POST /issues/search on updated_at#76083
Henry Bogardus (usbogie) wants to merge 7 commits intoairbytehq:masterfrom
usbogie:source-pylon/incremental-sync-updated-at

Conversation

@usbogie
Copy link
Copy Markdown

@usbogie Henry Bogardus (usbogie) commented Apr 3, 2026

Summary

Closes #76084

  • Switch the issues stream from GET /issues (filtered by created_at) to POST /issues/search (filtered by updated_at) for true incremental sync
  • Previously, updates to existing issues (status changes, reassignments, new messages) were never captured in incremental syncs — only newly created issues were picked up
  • Pylon's new POST /issues/search endpoint supports filtering on updated_at, so incremental syncs now capture all issue modifications
  • Add cursor_paginator_body to handle pagination via POST request body (the search endpoint accepts cursor/limit in the body, not query params)
  • Add updated_at to the issues schema
  • Add CustomStateMigration to rename created_atupdated_at in existing connection state, preventing a full re-sync on upgrade
  • Add unit tests for the state migration component
  • Bump connector version to 0.0.6

Test plan

  • source-declarative-manifest check passes with valid Pylon API token
  • source-declarative-manifest read on the issues stream returns records with updated_at populated
  • Incremental state correctly tracks updated_at cursor
  • 30-day time slicing works correctly with the search endpoint
  • State migration tested locally: old {"created_at": "..."} state correctly migrated, records resume from cursor position
  • Unit tests pass for state migration component (6/6)
  • Full connector test suite via airbyte-cdk connector test

AI PR Review Justification

Forwards Compatibility

A CustomStateMigration (MigrateIssuesCursorFromCreatedAtToUpdatedAt) handles the cursor field rename from created_at to updated_at. When existing connections upgrade from v0.0.5, the migration detects created_at in state and renames it to updated_at, so connections resume from their last cursor position without a full re-sync. Unit tests cover all edge cases (old state, new state, empty state, both keys present).

Behavioral Changes

The endpoint change from GET /issues to POST /issues/search and the cursor field change from created_at to updated_at are intentional. The previous endpoint only supported filtering by creation time, which made "incremental" sync miss all modifications to existing issues. The new search endpoint supports updated_at filtering, enabling true incremental sync. The response format (data array, pagination object) is identical between both endpoints. Tested locally against a production Pylon instance with ~120k issues.

…dated_at

The issues stream previously used GET /issues with start_time/end_time
query parameters, which filtered by created_at. This meant updates to
existing issues (status changes, reassignments, new messages, etc.)
were never captured in incremental syncs.

Pylon's new POST /issues/search endpoint supports filtering on
updated_at, enabling true incremental sync that captures all issue
modifications.

Changes:
- Switch issues stream from GET /issues to POST /issues/search
- Change incremental cursor from created_at to updated_at
- Add request_body_json with updated_at time filter
- Add cursor_paginator_body for POST body pagination
- Add updated_at to issues schema
- Update test fixtures to reflect new cursor field
- Bump connector version to 0.0.6
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 3, 2026

CLA assistant check
All committers have signed the CLA.

@octavia-bot
Copy link
Copy Markdown
Contributor

octavia-bot bot commented Apr 3, 2026

Note

📝 PR Converted to Draft

More info...

Thank you for creating this PR. As a policy to protect our engineers' time, Airbyte requires all PRs to be created first in draft status. Your PR has been automatically converted to draft status in respect for this policy.

As soon as your PR is ready for formal review, you can proceed to convert the PR to "ready for review" status by clicking the "Ready for review" button at the bottom of the PR page.

To skip draft status in future PRs, please include [ready] in your PR title or add the skip-draft-status label when creating your PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

👋 Welcome to Airbyte!

Thank you for your contribution from usbogie/airbyte! We're excited to have you in the Airbyte community.

If you have any questions, feel free to ask in the PR comments or join our Slack community.

💡 Show Tips and Tricks

PR Slash Commands

As needed or by request, Airbyte Maintainers can execute the following slash commands on your PR:

  • /format-fix - Fixes most formatting issues.
  • /bump-version - Bumps connector versions.
  • /run-connector-tests - Runs connector tests.
  • /run-cat-tests - Runs CAT tests.
  • /run-regression-tests - Runs regression tests for the modified connector(s).
  • /build-connector-images - Builds and publishes a pre-release docker image for the modified connector(s).
  • /publish-connectors-prerelease - Publishes pre-release connector builds (tagged as {version}-preview.{git-sha}) for all modified connectors in the PR.
  • /ai-review - AI-powered PR review for connector safety and quality gates.
  • /force-merge reason="<A_GOOD_REASON>" - Force merges the PR using admin privileges, bypassing CI checks. Requires a reason.

Tips for Working with CI

  1. Pre-Release Checks. Please pay attention to these, as they contain standard checks on the metadata.yaml file, docs requirements, etc. If you need help resolving a pre-release check, please ask a maintainer.
    • Note: If you are creating a new connector, please be sure to replace the default logo.svg file with a suitable icon.
  2. Connector CI Tests. Some failures here may be expected if your tests require credentials. Please review these results to ensure (1) unit tests are passing, if applicable, and (2) integration tests pass to the degree possible and expected.
  3. (Optional.) BYO Connector Credentials for tests in your fork. You can optionally set up your fork with BYO credentials for your connector. This can significantly speed up your review, ensuring your changes are fully tested before the maintainers begin their review.
📚 Show Repo Guidance

Helpful Resources

📝 Edit this welcome message.

@usbogie Henry Bogardus (usbogie) changed the title source-pylon: true incremental sync via POST /issues/search on updated_at feat(source-pylon): true incremental sync via POST /issues/search on updated_at Apr 3, 2026
@usbogie Henry Bogardus (usbogie) marked this pull request as ready for review April 3, 2026 23:06
@devin-ai-integration
Copy link
Copy Markdown
Contributor

↪️ Triggering /ai-prove-fix per Hands-Free AI Triage Project triage next step.

Reason: CI is green (33 passed, 0 failed). Human-authored fix for true incremental sync on issues stream using POST /issues/search with updated_at cursor. Preferred candidate over competing Devin-authored PR airbytehq/airbyte#76085.
Linked issue: https://github.com/airbytehq/oncall/issues/11880


Devin session

@octavia-bot
Copy link
Copy Markdown
Contributor

octavia-bot bot commented Apr 4, 2026

🔍 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
Copy Markdown
Contributor

devin-ai-integration bot commented Apr 4, 2026

Prove-Fix Report: source-pylon v0.0.6

Detail Value
Connector source-pylon
Version 0.0.6
PR #76083
Oncall Issue airbytehq/oncall#11880
Session Devin Session

Outcome: Could Not Run Live Tests (Blocked on Approval)

Live connection testing is blocked pending HITL approval (escalated to PR author and fallback approver, no response after 1.5 hours). Regression tests are blocked due to missing GSM credentials (alpha connector). All pre-flight checks passed and code analysis strongly supports the fix.

Pre-flight Checks

  • Viability: Code changes address the reported issue (switches from GET /issues with created_at to POST /issues/search with updated_at)
  • Safety: No malicious code, no credential harvesting, no suspicious patterns
  • Breaking change: NOT breaking (alpha connector, cursor field change, new POST endpoint with pagination)
  • Reversibility: Version bump follows semver (0.0.5 -> 0.0.6), state format compatible

Pre-release

  • Published: 0.0.6-preview.6cc204b (workflow)

Regression Tests

  • Triggered comparison mode regression tests (workflow)
  • Result: FAILED due to missing GSM credentials (no integration test config exists for source-pylon in GSM)
  • This is an infrastructure limitation for this alpha connector, not a code issue

Connection Investigation

  • 8 active connections found, all TIER_2, all actively syncing and succeeding
  • Identified 1 internal (Airbyte-hosted) connection as best test candidate
  • Current version: v0.0.5 (not pinned), healthy baseline (approximately 786 records per sync)

Live Connection Tests

Evidence Analysis

Code analysis supports the fix:

  1. The issues stream correctly uses POST /issues/search with updated_at cursor filter
  2. DatetimeBasedCursor configured with cursor_field: updated_at and proper datetime formats
  3. Request body uses subfilters with time_is_after / time_is_before operators on updated_at
  4. Pagination uses cursor_paginator_body (body-based cursor pagination for POST requests)
  5. Step size of P30D with PT1S granularity is appropriate for incremental sync
  6. Schema includes updated_at field in the inline schema definition

Risk assessment:

  • Low risk: alpha connector, 8 total connections, all TIER_2
  • Non-breaking: no schema type changes, no field removals, no PK changes
  • Reversible: standard semver bump, state format compatible
Next Steps

To complete live testing (when approval is received):

  1. Pin the internal connection source actor to 0.0.6-preview.6cc204b
  2. Trigger sync and monitor results
  3. Verify: issues stream returns records, updated_at cursor works, sync completes successfully
  4. Unpin connection after testing
  5. Update this report with results

For merge decision without live testing:

  • All pre-flight checks passed
  • Code analysis confirms the fix correctly implements POST /issues/search with updated_at cursor
  • Non-breaking change on an alpha connector with low blast radius (8 connections)
  • All existing connections are healthy and succeeding on v0.0.5

Report finalized: 2026-04-04T13:25 UTC | Devin Session

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 4, 2026

Pre-release Connector Publish Started

Publishing pre-release build for connector source-pylon.
PR: #76083

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

View workflow run
Pre-release Publish: SUCCESS

Docker image (pre-release):
airbyte/source-pylon:0.0.6-preview.6cc204b

Docker Hub: https://hub.docker.com/layers/airbyte/source-pylon/0.0.6-preview.6cc204b

Registry JSON:

@devin-ai-integration
Copy link
Copy Markdown
Contributor

↪️ Triggering /ai-review per Hands-Free AI Triage Project triage next step.

Reason: CI is green (33 passed, 0 failed). Prove-fix report complete (pre-flight checks passed, pre-release published, live testing pending approval). Next pipeline step is AI review.
Linked issue: https://github.com/airbytehq/oncall/issues/11880

Devin session

@octavia-bot
Copy link
Copy Markdown
Contributor

octavia-bot bot commented Apr 5, 2026

AI PR Review starting...

Reviewing PR for connector safety and quality.
View playbook

Devin AI session created successfully!

@devin-ai-integration
Copy link
Copy Markdown
Contributor

devin-ai-integration bot commented Apr 5, 2026

AI PR Review Report

Review Action: NO ACTION (NOT ELIGIBLE)

Gate Status
PR Hygiene PASS
Code Hygiene WARNING
Test Coverage PASS
Code Security PASS
Per-Record Performance PASS
Breaking Dependencies PASS
Backwards Compatibility PASS
Forwards Compatibility FAIL
Behavioral Changes FAIL
Out-of-Scope Changes PASS
CI Checks PASS
Live / E2E Tests UNKNOWN

📋 PR Details & Eligibility

Connector & PR Info

Connector(s): source-pylon
PR: #76083
HEAD SHA: 6cc204b40f494b62aa2ae7dc300296d01d650419
Session: https://app.devin.ai/sessions/a2eb4edf180141e5a418a90ae66c2fba

Auto-Approve Eligibility

Eligible: No
Category: not-eligible
Reason: PR contains functional code changes to manifest.yaml (stream endpoint, HTTP method, cursor field, pagination, request body). This is not docs-only, additive-spec, patch/minor-deps, or comment/whitespace-only.

Review Action Details

NO ACTION (NOT ELIGIBLE) — Anti-Pattern gates (Forwards Compatibility, Behavioral Changes) are flagged and require human sign-off. The PR is not eligible for auto-approval due to functional code changes. 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 other types of changes require human review even if all gates pass.

🔍 Gate Evaluation Details

Gate-by-Gate Analysis

Gate Status Enforced? Details
PR Hygiene PASS Yes Description present (>50 chars visible content), changelog updated, no unresolved peer feedback
Code Hygiene WARNING WARNING Source code modified (manifest.yaml) but no unit test files modified
Test Coverage PASS Yes PR matches behavioral indicators (title: "feat") but is a manifest-only declarative connector change; integration test files modified (configured_catalog.json, sample_state.json)
Code Security PASS Yes No security-sensitive file paths matched; no auth/credential keywords in diff hunks
Per-Record Performance PASS WARNING No per-record performance concerns identified
Breaking Dependencies PASS WARNING No dependency version changes (only metadata.yaml dockerImageTag bump)
Backwards Compatibility PASS Blocks Auto-Approve Spec required unchanged: ["api_token"] in both master and PR; no properties removed; new updated_at field added to schema (additive)
Forwards Compatibility FAIL Blocks Auto-Approve Cursor field changed from created_at to updated_at; state format changed; paginator changed; incremental_sync modified
Behavioral Changes FAIL Blocks Auto-Approve HTTP method changed GET to POST; endpoint changed /issues to /issues/search; request_body_json added; time filtering moved from query params to body
Out-of-Scope Changes PASS Skip All changed files are within connector scope (airbyte-integrations/connectors/source-pylon/**, docs/integrations/sources/pylon.md)
CI Checks PASS Yes All core checks green: Lint, Test [No Creds], Build, Pre-Release Checks all passed
Live / E2E Tests UNKNOWN Yes Pre-release published successfully (0.0.6-preview.6cc204b). Live connection testing blocked on HITL approval per prove-fix report. No syncs verified on pre-release yet.

PR Hygiene — PASS

  • PR Body Length (raw): ~900 chars
  • PR Body Length (after stripping): ~850 chars
  • PR Body Length (visible content): ~700 chars
  • PR Body Preview: ## Summary Closes #76084 - Switch the issues stream from GET /issues (filtered by created_at) to POST /issues/search...
  • Docs Changelog: docs/integrations/sources/pylon.md updated with 0.0.6 changelog entry
  • Peer Feedback: No unresolved human reviewer comments

Code Hygiene — WARNING

  • Source Files Modified: manifest.yaml (functional changes to issues stream)
  • Test Files Modified: integration_tests/configured_catalog.json, integration_tests/sample_state.json (integration test fixtures updated)
  • Coverage Evidence: Integration test fixtures updated, but no unit test files added/modified
  • WARNING: No unit test files modified for source code changes. Note: Pre-release published and live validation pending (Live / E2E Tests gate) — risk partially mitigated but unit test coverage still recommended.

Test Coverage — PASS

  • Behavioral Change Detected: Yes
  • Indicators Found: Title contains "feat"; linked to issue source-pylon: issues stream incremental sync should use updated_at instead of created_at #76084
  • Test Files Modified: integration_tests/configured_catalog.json, integration_tests/sample_state.json
  • New Test Content Found: Yes — integration test fixtures updated with new cursor field (updated_at)
  • Test Content Evidence: "default_cursor_field": ["updated_at"] in configured_catalog.json
  • Note: This is a manifest-only (declarative) connector. The CDK framework handles the execution logic; the manifest defines the configuration. Integration test fixtures validating the new cursor field constitute appropriate test coverage for this change type.

Code Security — PASS

  • No changed files match security-sensitive path patterns
  • Diff hunks checked for keywords: no authenticator, OAuthAuthenticator, api_token, client_id, client_secret, refresh_token, access_token, api_key found in diff lines
  • metadata.yaml diff contains only dockerImageTag change — no allowedHosts, connectorBuildOptions, or dockerRepository keywords

Backwards Compatibility — PASS

Spec Comparison:

  • Master required: ["api_token"]
  • PR required: ["api_token"]
  • No new required fields, no properties removed

Schema Changes:

  • New optional field updated_at added to issues schema (additive, non-breaking)
  • No fields removed, no type changes

Stream Changes:

  • issues stream still present, not removed or renamed
  • Primary key unchanged

Note: Cursor field change from created_at to updated_at is evaluated under Forwards Compatibility (state format impact), not here. The spec itself is unchanged.

Forwards Compatibility — FAIL (Blocks Auto-Approve)

Keywords found in diff hunks of manifest.yaml:

  • cursor_field: updated_at (changed from created_at)
  • incremental_sync section modified
  • paginator reference changed (cursor_paginator to cursor_paginator_body)
  • DatetimeBasedCursor configuration altered
  • start_time_option / end_time_option removed (time filtering moved to request body)

Concerns:

  1. State format change: Existing connections have state with created_at cursor. After upgrade, the connector will look for updated_at in state. Old state will not contain this field, potentially causing a full re-sync.
  2. No state migration defined: No state_migrations entry to handle the transition from created_at to updated_at cursor.
  3. Rollback risk: If rolled back to v0.0.5, state written with updated_at cursor won't be understood.

Requires human sign-off to verify that the state transition is acceptable for this alpha connector (8 connections, all TIER_2).

Behavioral Changes — FAIL (Blocks Auto-Approve)

Keywords found in diff hunks of manifest.yaml:

  • http_method: POST (changed from GET)
  • request_body_json added with filter subfilters
  • path: issues/search (changed from issues)
  • page_size: 999 in new paginator definition

Concerns:

  1. Endpoint change: GET /issues to POST /issues/search is a fundamental API endpoint change
  2. Request body filtering: Time-based filtering moved from query parameters (start_time, end_time) to POST body (subfilters with time_is_after/time_is_before)
  3. Pagination change: Pagination moved from query params to body JSON (cursor_paginator_body)

These are intentional changes per the PR description — the new endpoint supports filtering on updated_at which enables true incremental sync. Requires human sign-off.

CI Checks — PASS

All core checks completed successfully:

  • Lint source-pylon Connector — passed
  • Test source-pylon Connector [No Creds] — passed
  • Build and Verify Artifacts (source-pylon) — passed
  • source-pylon Pre-Release Checks — passed (excluded from CI Checks, evaluated under Live / E2E Tests)
  • Format Check — passed
  • Validate PR Title — passed
  • Check Changelog Updated — passed
  • Build Airbyte Docs — passed

Community PR note: Test [No Creds] passed, indicating tests that don't require credentials are green.

Live / E2E Tests — UNKNOWN

Validation Required: Yes — this PR matches sync behavior changes (cursor field, incremental_sync, paginator, record_selector changes in manifest.yaml) and is linked to issue #76084.

Evidence Check (Priority 2 — CI/Labels fallback):

  • Pre-release published: 0.0.6-preview.6cc204b
  • Pre-Release Checks CI: PASSED
  • Live connection testing: Blocked on HITL approval per prove-fix report
  • No live-tests-passed, prerelease-validated, or equivalent labels present
  • No successful syncs verified on pre-release version yet

Result: UNKNOWN — pre-release exists and pre-release checks passed, but no live connection test results available yet. Live testing was attempted via /ai-prove-fix but blocked awaiting human approval to pin connections.

Recommendation: When HITL approval is granted, complete the live validation cycle. Alternatively, a maintainer can approve based on code analysis and the alpha connector's low blast radius (8 connections, all TIER_2).

📚 Evidence Consulted

Evidence

  • Changed files: 5 files
    • airbyte-integrations/connectors/source-pylon/manifest.yaml
    • airbyte-integrations/connectors/source-pylon/metadata.yaml
    • airbyte-integrations/connectors/source-pylon/integration_tests/configured_catalog.json
    • airbyte-integrations/connectors/source-pylon/integration_tests/sample_state.json
    • docs/integrations/sources/pylon.md
  • CI checks: 33 passed, 9 skipped, 0 failed — all core checks green
  • PR labels: community, connectors/source/pylon
  • PR description: Present with detailed summary, test plan, and linked issue
  • Existing bot reviews: None
  • Prove-fix report: Pre-release published, live testing pending HITL approval
❓ How to Respond

Providing Context or Justification

You can add explanations that the bot will see on the next review:

Option 1: PR Description (recommended)
Add a section to your PR description:

## AI PR Review Justification

### Forwards Compatibility
[Your explanation here — e.g., why the state migration from created_at to updated_at is acceptable]

### Behavioral Changes
[Your explanation here — e.g., confirming the endpoint change is intentional and tested]

Option 2: PR Comment
Add a comment starting with:

AI PR Review Justification:
[Your explanation here]

After adding your response, re-run /ai-review to have the bot evaluate it.

Note: For Anti-Pattern gates (Forwards Compatibility, Behavioral Changes), justifications provide context but still require human sign-off. These gates block auto-approval by design — a maintainer must review and approve the change.

State Migration Recommendation

The cursor field change from created_at to updated_at will affect existing connections' state. Consider adding a state_migrations entry to the manifest to handle the transition gracefully, or document that a state reset is expected for existing connections upgrading from v0.0.5.


Devin session

Existing connections have state with created_at as the cursor key.
Without migration, upgrading to 0.0.6 would cause a full re-sync.
This CustomStateMigration renames the state key so existing
connections resume from their last cursor position.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Development

Successfully merging this pull request may close these issues.

source-pylon: issues stream incremental sync should use updated_at instead of created_at

3 participants