feat(data-warehouse): implement koyeb import source - #70718
Conversation
|
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 |
🦔 Hogbox preview · ✅ ready▶ Open the preview
commit |
🤖 CI report✅ Bundle size — no changeUncompressed size of every built Total: 64.77 MiB · no change No file changed by more than 1000 B. Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report ✅ Eager graph — within budgetHow much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy
🟢 Largest files eagerly shipped from
|
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 789 B | src/scenes/ChunkLoadErrorBoundary.tsx |
| 762 B | src/index.tsx |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 281.3 KiB | ../node_modules/.pnpm/posthog-js@1.402.2/node_modules/posthog-js/dist/rrweb.js |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 235.5 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 222.9 KiB | ../node_modules/.pnpm/posthog-js@1.402.2/node_modules/posthog-js/dist/module.js |
| 164.0 KiB | src/queries/validators.js |
| 154.3 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 105.8 KiB | src/lib/api.ts |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 92.7 KiB | ../packages/quill/packages/quill/dist/index.js |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Dist folder size — 🔺 +330 B (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1312.45 MiB · 🔺 +330 B (+0.0%)
⚠️ Backend coverage — 96.0% of changed backend lines covered — 12 uncovered
🧪 Backend test coverage
Patch coverage — changed backend lines (products + core): ███████████████████░ 96.0% (378 / 390)
| File | Patch | Uncovered changed lines |
|---|---|---|
products/warehouse_sources/backend/temporal/data_imports/sources/koyeb/koyeb.py |
91.1% | 61, 129, 134–135, 137–139, 141, 219–220 |
products/warehouse_sources/backend/temporal/data_imports/sources/koyeb/source.py |
92.6% | 76, 80 |
🤖 Agents: add a test covering the lines above, or note why under "How did you test this code?". Machine-readable gap list: the patch-coverage artifact on this run (gh run download 29452350474 -n patch-coverage), or the coverage-data block at the end of this comment.
Per-product line coverage (touched products)
| Product | Coverage | Lines |
|---|---|---|
demo |
███████████░░░░░░░░░ 56.2% |
1,497 / 2,663 |
tasks |
█████████████░░░░░░░ 67.4% |
25,560 / 37,895 |
signals |
████████████████░░░░ 79.1% |
19,037 / 24,073 |
data_modeling |
████████████████░░░░ 80.0% |
4,834 / 6,045 |
cdp |
████████████████░░░░ 80.7% |
3,118 / 3,864 |
notebooks |
█████████████████░░░ 84.3% |
6,343 / 7,520 |
agent_platform |
█████████████████░░░ 84.7% |
3,273 / 3,862 |
cohorts |
█████████████████░░░ 86.1% |
4,022 / 4,671 |
actions |
█████████████████░░░ 86.6% |
717 / 828 |
product_tours |
█████████████████░░░ 87.5% |
1,266 / 1,447 |
exports |
██████████████████░░ 88.3% |
6,891 / 7,800 |
conversations |
██████████████████░░ 88.9% |
16,129 / 18,133 |
dashboards |
██████████████████░░ 89.1% |
5,719 / 6,418 |
mcp_analytics |
██████████████████░░ 89.1% |
2,502 / 2,807 |
error_tracking |
██████████████████░░ 89.6% |
9,718 / 10,852 |
alerts |
██████████████████░░ 89.9% |
3,638 / 4,046 |
engineering_analytics |
██████████████████░░ 90.1% |
5,105 / 5,665 |
streamlit_apps |
██████████████████░░ 90.4% |
2,499 / 2,764 |
slack_app |
██████████████████░░ 90.6% |
9,511 / 10,503 |
marketing_analytics |
██████████████████░░ 90.8% |
11,514 / 12,684 |
product_analytics |
██████████████████░░ 91.1% |
5,599 / 6,143 |
data_warehouse |
██████████████████░░ 92.1% |
18,133 / 19,683 |
workflows |
██████████████████░░ 92.4% |
5,148 / 5,574 |
web_analytics |
███████████████████░ 92.7% |
13,624 / 14,691 |
ai_observability |
███████████████████░ 92.8% |
14,868 / 16,019 |
surveys |
███████████████████░ 92.9% |
5,660 / 6,094 |
posthog_ai |
███████████████████░ 93.2% |
1,322 / 1,418 |
approvals |
███████████████████░ 93.3% |
3,395 / 3,640 |
reminders |
███████████████████░ 93.4% |
468 / 501 |
early_access_features |
███████████████████░ 93.8% |
848 / 904 |
endpoints |
███████████████████░ 94.1% |
8,606 / 9,143 |
skills |
███████████████████░ 94.4% |
2,827 / 2,995 |
revenue_analytics |
███████████████████░ 94.5% |
3,598 / 3,809 |
review_hog |
███████████████████░ 94.6% |
6,529 / 6,902 |
logs |
███████████████████░ 95.3% |
9,528 / 9,994 |
experiments |
███████████████████░ 95.6% |
24,139 / 25,256 |
replay_vision |
███████████████████░ 95.7% |
13,337 / 13,935 |
annotations |
███████████████████░ 96.2% |
732 / 761 |
warehouse_sources |
███████████████████░ 96.2% |
225,964 / 234,879 |
feature_flags |
███████████████████░ 96.3% |
16,002 / 16,625 |
user_interviews |
███████████████████░ 96.4% |
2,242 / 2,325 |
data_catalog |
███████████████████░ 97.1% |
2,034 / 2,095 |
customer_analytics |
███████████████████░ 97.2% |
7,480 / 7,698 |
Report-only. Patch coverage = changed backend lines covered vs origin/master. Sorted lowest first.
Known gaps: lines covered only by Temporal tests show as uncovered; core line numbers may drift if master changed the same file.
PR overviewAll previously flagged issues have been addressed. No open security concerns remain on this pull request. Security reviewNo open security issues remain on this pull request. Fixed/addressed: 1 · PR risk: 0/10 |
|
Heads-up on the one red check: 🦉 via talyn.dev |
Implements the Koyeb warehouse source end-to-end: declarative endpoint catalog (16 tables), offset-based resumable pagination via the tracked HTTP transport, incremental sync for instances via the server-side starting_time filter, canonical table/column descriptions for docs enrichment, and full source + transport test suites. Generated-By: PostHog Code Task-Id: 4de80210-ae0f-4387-a2ad-9ef0b05cf6e6
Generated-By: PostHog Code Task-Id: 4de80210-ae0f-4387-a2ad-9ef0b05cf6e6
Deployment rows embed a `definition` whose `env[].value` and `config_files[].content` carry plaintext application secrets. Yielding them unchanged would let anyone with warehouse-query access read credentials they cannot see in Koyeb itself. Redact those values before persisting while keeping the surrounding structure (env keys, secret references, file paths) so the rows stay useful. Generated-By: PostHog Code Task-Id: a084024d-9dcd-4163-b9f2-7cf96735e008
Remove unreleasedSource=True so the finished source is visible in the connector catalog, and drop any test asserting the hidden state.
…le capture The definition scrub runs after _fetch_page returns, but opt-in HTTP sample capture stores the raw response body at the adapter layer, and its name-based scrubbers can't recognise plaintext env values or config-file content. Create the session with capture=False for secret-scrubbed endpoints (the documented seam, same as the OAuth token-exchange path) so those bodies never land in captured samples; requests stay metered and logged. Generated-By: PostHog Code Task-Id: 4de80210-ae0f-4387-a2ad-9ef0b05cf6e6
582df77 to
565bd31
Compare
Problem
The Koyeb data warehouse source existed only as a scaffolded stub (registered with
unreleasedSource=True, no fields, no sync logic). Users can't pull their Koyeb deployment and infrastructure data into the warehouse.Why: fill in the scaffolded Koyeb connector so engineering/DevOps data (apps, services, deployments, instances, event streams, usage) can be joined with product analytics in the warehouse.
Changes
Implements the Koyeb source end-to-end following the
source.py/settings.py/koyeb.pyarchitecture contract:settings.py:apps,services,deployments,regional_deployments,instances,domains,secrets(metadata only, values are never returned by Koyeb's list API),volumes,snapshots,organization_members,activities, the four per-entity event streams, andusage_details.ResumableSourcewith offset+limit pagination (Koyeb's single pagination model), terminating onhas_next=falseor a short page for the replies that don't carryhas_next. The offset checkpoints to Redis after each yielded page so interrupted syncs resume instead of restarting.instancesvia the documentedstarting_timeparam oncreated_at. Everything else is full refresh, since Koyeb exposes no updated-since filters and re-paging an offset list costs the same as a full refresh. Endpoints that acceptorderare always requestedascso offsets stay stable mid-sync.usage_detailsalways sends the requiredstarting_time/ending_timewindow (fixed floor to now, held constant across a run's pages) and uses a composite[instance_id, started_at]primary key since usage rows have no id.make_tracked_session(), with tenacity retries on 429/5xx andget_non_retryable_errors()stopping syncs on 401/403.canonical_descriptions.pydocuments every table/column from the Koyeb API reference, andlists_tables_without_credentials = Truelets the public docs render the table catalog.monthpartitioning on stable creation-time fields (created_at/when/started_at).frontend/public/services/koyeb.svg, built from the official Koyeb logomark.unreleasedSource=TruewithreleaseStatus=alphauntil exercised against a live account.Note
I had no Koyeb API credentials in this environment, so authenticated behaviors that the implementing-warehouse-sources skill asks to curl-verify (whether
order=ascandstarting_timeare honored rather than silently ignored) are taken from the public swagger spec (api.prod.koyeb.com/public.swagger.json) plus unauthenticated probes of the live API. The conservative consequences are documented in code comments: onlyinstancesis incremental, and the paginator never relies on the time filter for termination. Worth a smoke test against a real Koyeb org before de-flagging.How did you test this code?
pytest products/warehouse_sources/backend/temporal/data_imports/sources/koyeb/tests/(55 tests) plus the registry-wide suites insources/tests/(1606 passed): source categories, generated configs.tests/test_koyeb.py(transport): paginator termination across the three reply shapes (has_next, short page, exact-multiple + empty page) — catches the runaway/premature-stop regressions; resume-from-saved-offset and checkpoint-after-yield ordering — catches state saved before a page is yielded (data loss on resume); incrementalinstancessendingstarting_timeand full-refresh omitting it; RFC 3339 formatting of naive/aware/offset datetimes — Koyeb rejects non-RFC 3339 values; credential status mapping.tests/test_koyeb_source.py(source class): endpoint catalog and incremental flags, non-retryable 401/403 matching vs retryable 429/5xx/timeout, resumable manager binding, andsource_for_pipelineplumbing (including dropping a stale watermark when incremental is off).hogli ci:preflight --fixpasses;ruff check/ruff formatclean. I did not run a live sync (no credentials).Automatic notifications
Docs update
The posthog.com doc (
contents/docs/cdp/sources/koyeb.md) needs to land in the posthog.com repo — no checkout was available in this environment, soaudit_source_docscouldn't run.docsUrlis already set tohttps://posthog.com/docs/cdp/sources/koyebto match. Ready-to-commit doc content:contents/docs/cdp/sources/koyeb.md
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
implementing-warehouse-sources,documenting-warehouse-sources,writing-tests.usage_detailsas full refresh rather than incremental because its rows mutate while an instance is running (duration_secondsaccrues) and row identity under windowed queries couldn't be verified without credentials; skipped a partition key onorganization_membersbecausejoined_atcan move on re-invite; reverted an unrelated Stripe drift thatgenerate:source-configsproduced (the committed generated file predates current generator output for Stripe's auth block — left untouched for a separate fix).posthog-code/koyeb-warehouse-sourcebranch (no PR); it can be deleted once this lands.Created with PostHog Code