feat(data-warehouse): implement testrail import source - #69391
Merged
Conversation
Implements the TestRail warehouse source end-to-end: declarative endpoint catalog (projects, users, suites, sections, cases, milestones, runs, plans, tests, results, statuses, priorities, case_types), resumable limit/offset pagination with a deterministic parent-walk cursor, server-side incremental sync for cases/runs/plans/results, credential validation, canonical table descriptions, and transport + source tests. Generated-By: PostHog Code Task-Id: 7dc7b3fb-650d-459e-851d-bc5685ddac7d
Contributor
|
Hey @Gilbert09! 👋 It looks like your git author email on this PR isn't your
You can fix it for this repo with: git config user.email "you@posthog.com"Or set it globally with |
5 tasks
Contributor
|
Reviews (1): Last reviewed commit: "feat(data-warehouse): implement testrail..." | Re-trigger Greptile |
Use direct ["id"] access on the users primary key during per-project dedupe so a malformed response raises instead of silently collapsing keyless records onto the None sentinel. Generated-By: PostHog Code Task-Id: 7dc7b3fb-650d-459e-851d-bc5685ddac7d
Generated-By: PostHog Code Task-Id: 885588aa-0211-42ce-a13a-2b3bd4a223e8
MarconLP
approved these changes
Jul 9, 2026
MarconLP
approved these changes
Jul 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
TestRail was scaffolded as a warehouse source but had no sync logic, so users couldn't pull their test management data (projects, test cases, runs, results) into the PostHog Data warehouse to analyze QA activity alongside product data.
Changes
Implements the TestRail source end-to-end following the standard
source.py/settings.py/testrail.pysplit:projects,users,suites,sections,cases,milestones,runs,plans,tests,results, plus thestatuses/priorities/case_typesdictionaries for joining ids to labels.(parent, phase, offset)resume cursor saved after each yielded page, so Temporal restarts pick up where they left off and merge dedupes the boundary page.cases(updated_after),runs/plans/results(created_after). Incremental endpoints declaresort_mode="desc"since fan-out rows never arrive globally time-ordered, so the watermark commits only at end of sync.get_runsexcludes runs inside test plans, so therunstable (and the run enumeration behindtests/results) also walksget_plans→get_planentries. The incremental caveat (runs added later to a pre-watermark plan need a full refresh) is documented in the source and the docs page.has_morecomes exclusively from_links.nextso an endpoint that ignoreslimit/offsetcan't loop forever.make_tracked_session(), subdomain validated as a single DNS label and declared inconnection_host_fieldsso retargeting it re-requires the key, 401/403 mapped to non-retryable errors with TestRail's own error message surfaced (including the "API is disabled" case), 429/5xx retried with backoff.lists_tables_without_credentials = Trueso the public docs render the table catalog,SOURCES.mdmoved to Implemented.Kept behind
unreleasedSource=TruewithreleaseStatus=ALPHAfor now.Note
I couldn't curl-verify endpoint behavior against a live instance (no TestRail credentials available; the URL scheme and error shapes were verified against a live instance unauthenticated, the rest against the current API docs). Where the docs were ambiguous the code is conservative:
has_morenever relies on page-size heuristics, and unverified filters degrade to a full re-pull that merge dedupes rather than data loss.The user-facing doc (
contents/docs/cdp/sources/testrail.md) is written and needs to land in the posthog.com repo;manage.py audit_source_docspasses for testrail against that checkout.How did you test this code?
Automated tests only (no live TestRail instance available):
tests/test_testrail.py(transport): URL building (a second?would break TestRail's router), subdomain retargeting rejection, both payload shapes and the infinite-loop guard on_links.next, retryable vs terminal status mapping, pagination checkpointing after yield, suite fan-out withupdated_afteron every request, resume skipping completed suites, runs combining standalone + plan-entry runs, results keeping run enumeration unfiltered while filtering per-run requests (catches new results in old runs), admin → per-project users fallback with dedupe, and credential validation surfacing TestRail's error body.tests/test_testrail_source.py(source class): schema catalog incremental flags,connection_host_fields, non-retryable error matching, argument plumbing including dropping a stale watermark on full refresh.Ran the full
sources/tests/registry suite (1353 passed) plus the 77 new tests;ruff check/ruff formatclean;hogli ci:preflight --fixreports 0 failures.Automatic notifications
Docs update
Doc written per the documenting-warehouse-sources skill; it lives in the posthog.com repo (companion PR) since this repo doesn't carry source docs.
docsUrlmatches thetestrailslug.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Authored with Claude Code following the
/implementing-warehouse-sources,/writing-tests, and/documenting-warehouse-sourcesskills, using recent sources (ruddr, secoda, aha, github) as references. Notable decisions:ResumableSourcewith a deterministic parent-walk cursor over per-endpoint next-URL state because TestRail pagination is offset-based and fan-out heavy.runstable (and run enumeration) rather than mirroringget_runs's standalone-only semantics, since plan-driven QA teams would otherwise get emptytests/results.sort_mode="desc"on incremental endpoints after checking the pipeline's watermark checkpointing semantics;ascwould corrupt the watermark on mid-sync restarts given non-monotonic fan-out ordering.generate_source_configscurrently rewrites unrelated classes, so only theTestrailSourceConfigchange was spliced intogenerated_configs.py.Created with PostHog Code