Skip to content

trunk-merge/pr-73758/a92328c6-8265-4923-baf5-49831183c4d6 - #85866

Closed
trunk-io[bot] wants to merge 482 commits into
masterfrom
trunk-merge/pr-73758/a92328c6-8265-4923-baf5-49831183c4d6
Closed

trunk-merge/pr-73758/a92328c6-8265-4923-baf5-49831183c4d6#85866
trunk-io[bot] wants to merge 482 commits into
masterfrom
trunk-merge/pr-73758/a92328c6-8265-4923-baf5-49831183c4d6

Conversation

@trunk-io

@trunk-io trunk-io Bot commented Aug 19, 2026

Copy link
Copy Markdown
Trunk Merge Pull Request Banner

This pull request was created and is being managed by Trunk Merge.

This pull request is based on the master branch at SHA 013921af19434fa91e43012b3dd21ef8c186856e.

See more details about each PR in the batch here:

When CI completes, this pull request will be closed automatically.

Pull Requests Being Tested

This pull request is testing a batch with the changes from pull requests 73758 and 84289 - batching documentation.

Dependencies

This pull request depends on the changes from pull requests 85236, 85514, 84617, 77555, 84373, 85235, 83909, 85530, 83139, 85108, 84348, 83858, 85681, 85597, 85612, 83976, 85322, 85743, 85682, 73764, 85716, 84345, 84453, 82973, 85646, 84531, 83323, 54933, 85529, 85084, 85793, and 83250.

webjunkie and others added 30 commits August 19, 2026 15:29
Test selection was wired to draft PRs only, and in practice it never
narrowed anything: select-tests treated any run_legacy=true from
turbo-discover as untrusted, but run_legacy is true for every diff that
touches posthog/ or ee/. Django only runs when run_legacy is true, so
"selected" mode and a running Django matrix were mutually exclusive. The
whole mechanism reduced to "drafts skip the heavy matrices".

Split the two things run_legacy conflates. A direct legacy edit is what
the selector is built for, so it is now trusted; an inferred
product->legacy cascade still is not. turbo-discover publishes
run_legacy_reason so the workflow reads the cause instead of
reconstructing it from two coarse booleans.

Ready PRs now narrow too. Untrusted selection runs the full matrices on
a ready PR and still skips them on a draft, which has its ready run as a
backstop. The merge queue's trunk-merge/** run and master pushes never
reach select-tests, so what actually gates master is unchanged.

Trusting legacy diffs exposed a hole: several entries in the `legacy`
paths filter are not Python, so the import graph reaches no test through
them and the selector returned nothing. A quarantine lift or a C++
parser change would have gated on zero Django tests. Added the missing
full-run patterns, plus a backstop that refuses to narrow to nothing
when legacy files changed, so a future paths-filter entry that nobody
teaches the selector about fails safe.

Compat is now carried through selection instead of dropped, driven by
the same env var the compat pytest run uses. It is inert until a second
ClickHouse version lands, since all entries currently match.

Also: select-tests decides trust before checking out, so an untrusted
PR no longer clones the repo in front of the full matrix it is about to
run; it moves to depot like every other pre-job on this critical path;
and coverage instrumentation is gated on full runs, matching the report
job that consumes it.

DISABLE_BACKEND_TEST_SELECTION puts every PR back on the full matrices
without a code change.
Generated-By: PostHog Desktop
Task-Id: ef95bb24-cf25-4bf8-bd81-189d422cfac3
Destinations created from the Python-era template (before Oct 2025,
including those bumped from 202409 by linked-api-version-update) build
body.user.userInfo in place with no guard line, so the replace key
bumped their header while leaving userInfo unguarded, trading the 426
for a 422 on any event without both names. The key now also rewrites
that legacy userInfo section into the collect-and-guard form, and a new
only_if_contains gate keeps those replacements off the deliberately
excluded 202409 destinations.
Generated-By: PostHog Desktop
Task-Id: 581b9408-d8ce-4150-9659-36c4c15f121d
Generated-By: PostHog Desktop
Task-Id: f9e0a97b-8c72-41cd-93ee-95989ea9d9c9
Generated-By: PostHog Desktop
Task-Id: f9e0a97b-8c72-41cd-93ee-95989ea9d9c9
Generated-By: PostHog Desktop
Task-Id: 581b9408-d8ce-4150-9659-36c4c15f121d
Generated-By: PostHog Desktop
Task-Id: f9e0a97b-8c72-41cd-93ee-95989ea9d9c9
… config instead of a custom session

The previous fix passed a hand-built `session` in the Clever resource's client config, which bypassed `RESTClient`'s own tracked-session construction — and broke the existing test suite, which drives the sync end-to-end by mocking `rest_client.make_tracked_session`.

Instead, add a `capture` option to `ClientConfig`/`RESTClient` that's threaded down to the default tracked session (`capture: bool = True`, backward compatible for every other source). Clever now sets `"capture": False` in its client config, keeping roster PII out of HTTP sample storage while leaving `RESTClient`'s normal session construction (and the existing tests that mock it) intact.
1 updated
Run: ad7969c6-da18-4e4e-b1e0-b8ad4c601796

Co-authored-by: GeneralistDev <1705096+GeneralistDev@users.noreply.github.com>
Generated-By: PostHog Desktop
Task-Id: 84d72519-5cb5-4c5e-af27-5b28a99e17cf
`get_resource()` returns `EndpointResource`, whose `endpoint` field is typed `str | Endpoint | None`. Indexing into it directly (`resource["endpoint"]["params"]`) doesn't type-check. Every other source's tests wrap the result in `cast(dict[str, Any], ...)` first (see `cast_ai`, `census`, etc.) — apply the same pattern here. This was the last cause of the "Python code quality (depot-ubuntu-24.04)" / "Check static typing" CI failure (10 mypy errors, all on these lines).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A release condition rollout percentage that is not a whole number fails to
parse on .NET before 2.13.3 and Java before 2.12.1, which stops local
evaluation for every flag in the project rather than just the edited flag.

Show a warning above the release conditions naming the offending percentages
and the minimum SDK versions. Skip client-only flags, which never run local
evaluation, and skip multivariate variant rollouts, which those SDKs have
always read as floats.

Generated-By: PostHog Desktop
Task-Id: b46f1d31-74ad-4a17-854c-4019b1e4e020
`BlueskyResumeConfig` used a bare `@dataclasses.dataclass` with no explicit
`frozen=` choice. That trips two CI guards for new (non-grandfathered)
dataclasses:

- `posthog/test/repo_invariants/test_dataclass_defaults.py`, run as part of
  the backend "Repo checks" job. Its failure is treated as a deterministic
  failure and cancels the rest of the backend CI matrix (explains the
  Django/Python-quality/cascading-cancellation failures on this PR).
- `.semgrep/rules/devex/prefer-frozen-dataclasses.yaml` (WARNING severity,
  but blocking on new findings via the "New warnings (blocking)" step in
  `semgrep-devex`), which feeds into "Semgrep Checks Pass".

Sibling resumable sources added since the guard existed (e.g. `firebase.py`)
use `@frozen` from `posthog.dataclasses` for their resume-config dataclass,
constructed with keyword args exactly like `BlueskyResumeConfig` already is.
Switched to the same pattern; no behavior change.
10 updated
Run: 5e107aca-9988-4e3b-b28a-c71472a31529

Co-authored-by: HaynesPostHog <181385999+HaynesPostHog@users.noreply.github.com>
…ike protocol

`VendrEndpointConfig` was a frozen dataclass but gets passed as `endpoint_configs: Mapping[str, FanoutEndpointLike]` to `build_dependent_resource`. mypy treats a frozen dataclass's fields as read-only, which doesn't structurally satisfy `FanoutEndpointLike`'s plain (read-write) attribute declarations - this is exactly the failure in the "Python code quality" CI check (`mypy`'s `arg-type` error on `build_dependent_resource`'s `endpoint_configs` argument).

Fixed by setting `frozen=False`, matching the identical, already-established fix + comment on `YocoEndpointConfig` (same fan-out pattern, same protocol).
…umeConfig dataclass

The bare `@dataclasses.dataclass` on `Dynamics365BusinessCentralResumeConfig` had no explicit `frozen=` choice, tripping the `prefer-frozen-dataclasses` repo-invariant guard (posthog/test/repo_invariants/test_dataclass_defaults.py) and the matching semgrep devex rule. Every sibling `*ResumeConfig` dataclass in this directory already declares `frozen=True`; this brings the new source in line with that convention. No behavior change — the config is only ever constructed with kwargs and never mutated after construction.
Generated-By: PostHog Desktop
Task-Id: 581b9408-d8ce-4150-9659-36c4c15f121d
…l "tests" module collision

CI's failure logs (surfaced via the Trunk Test Analytics PR comment) showed shopify's tests failing to import with "module 'tests.test_validate_credentials' could not be found" — not an asaas test failing directly. `asaas/tests/` and `shopify/tests/` are the only two source test dirs in the whole `sources/` tree that carry a `tests/__init__.py`; neither `asaas/` nor `shopify/` itself is a package (no `__init__.py`), so pytest's default import mode registers each as a top-level `tests` package rooted at its own vendor directory. With two vendors doing this, the second one collected shadows the first in `sys.modules["tests"]`, and the module actually imported wins — breaking the other vendor's test collection for the whole session, which is why every warehouse-sources CI shard failed identically.

Every other of the ~650 source test directories has no `__init__.py`; matching that convention (removing the file added in this PR) fixes the collision without touching shopify's pre-existing one.
Generated-By: PostHog Desktop
Task-Id: f9e0a97b-8c72-41cd-93ee-95989ea9d9c9
Slack linkifies a typed @PostHog even inside an org-scoped package or repo
path, so writing @PostHog/react-native-plugin fires a real app_mention and
starts an agent run against a prompt that is only the path's tail.

Drop the event when every mention in the text sits directly before a slash.
Requiring every mention to be glued leaves a message that also tags the app
properly untouched, which avoids a users.info round-trip in the hot path.

Generated-By: PostHog Desktop
Task-Id: 257aa657-55f4-4d72-84dd-8d8057ac5e13
Offset slicing loaded every matching insight id into memory up front and re-walked
the primary key index from the start on each batch. Keyset pagination scans forward
from the previous batch's last id instead, matching how the rest of the repo batches
(`hypercache_manager`, `resave_cohorts`, the dashboard tile backfill).

The cursor is safe here because nothing in the batch writes touch `id`, so it can
neither skip nor repeat a row.

Each batch now fetches `Insight` rows directly rather than ids that the batch helper
immediately refetched, so this drops a query per batch. Project scoping moves to the
source queryset, which the batches are sliced from, so it is unchanged.
`insights_considered` becomes a running counter, since there is no longer a full id
list to take a length from.

The test patches the batch size down to 2 over 5 insights. Nothing else in the class
exercises more than one batch, so a cursor that fails to advance or advances too far
would otherwise go uncaught.

Generated-By: PostHog Desktop
Task-Id: fbd7806c-cc0b-47a7-84ce-a5a26568f868
trunk-io Bot added 25 commits August 19, 2026 17:10
@github-actions

Copy link
Copy Markdown
Contributor

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit df7bd98.

@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

⚠️ Django migration SQL — 4 new migrations to review

We've detected new migrations on this PR. Review the SQL output for each migration:

products/dashboards/backend/migrations/0015_dashboard_customization.py

BEGIN;
--
-- Add field customization to dashboard
--
ALTER TABLE "posthog_dashboard" ADD COLUMN "customization" jsonb DEFAULT '{}'::jsonb NOT NULL;
COMMIT;

products/tasks/backend/migrations/0098_task_hog_flow_id_task_origin_key_and_more.py

BEGIN;
--
-- Add field hog_flow_id to task
--
ALTER TABLE "posthog_task" ADD COLUMN "hog_flow_id" uuid NULL;
--
-- Add field origin_key to task
--
ALTER TABLE "posthog_task" ADD COLUMN "origin_key" varchar(128) NULL;
COMMIT;

products/tasks/backend/migrations/0099_task_workflow_indexes.py

--
-- Concurrently create index posthog_task_hog_flow_idx on field(s) hog_flow_id, -created_at of model task
--
SET lock_timeout = 0;
SET statement_timeout = 0;
CREATE INDEX CONCURRENTLY "posthog_task_hog_flow_idx" ON "posthog_task" ("hog_flow_id", "created_at" DESC);
--
-- Custom state/database change combination
--
SET lock_timeout = 0;
SET statement_timeout = 0;
CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS "posthog_task_origin_key_uniq" ON "posthog_task" (team_id, origin_key) WHERE origin_key IS NOT NULL;

products/tasks/backend/migrations/0100_alter_loop_origin_product_and_more.py

BEGIN;
--
-- Alter field origin_product on loop
--
-- (no-op)
--
-- Alter field origin_product on sandboxsession
--
-- (no-op)
--
-- Alter field origin_product on task
--
-- (no-op)
COMMIT;

Last updated: 2026-08-19 17:23 UTC (df7bd98)

Django migration risk — migration analysis complete

We've analyzed your migrations for potential risks.

Summary: 2 Safe | 2 Needs Review | 0 Blocked

⚠️ Needs Review

May have performance impact

dashboards.0015_dashboard_customization
  └─ #1 ⚠️ AddField
     Adding NOT NULL field with callable default (dict) - verify it's stable
     model: dashboard, field: customization, default: dict
tasks.0100_alter_loop_origin_product_and_more
  └─ #1 ⚠️ AlterField
     Field alteration may cause table locks or data loss (check if changing type or constraints)
     model: loop, field: origin_product, field_type: CharField
  └─ #2 ⚠️ AlterField
     Field alteration may cause table locks or data loss (check if changing type or constraints)
     model: sandboxsession, field: origin_product, field_type: CharField
  └─ #3 ⚠️ AlterField
     Field alteration may cause table locks or data loss (check if changing type or constraints)
     model: task, field: origin_product, field_type: CharField

✅ Safe

Brief or no lock, backwards compatible

tasks.0098_task_hog_flow_id_task_origin_key_and_more
  └─ #1 ✅ AddField
     Adding nullable field requires brief lock
     model: task, field: hog_flow_id
  └─ #2 ✅ AddField
     Adding nullable field requires brief lock
     model: task, field: origin_key
tasks.0099_task_workflow_indexes
  └─ #1 ✅ SafeAddIndexConcurrently
     PostHog concurrent-index helper: idempotent (timeout disabling + invalid-leftover recovery)
     model: task, index: posthog_task_hog_flow_idx
  └─ #2 ✅ SeparateDatabaseAndState
     Wrapper operation - see nested operations for risk: CreateIndexConcurrently
     database_operations: CreateIndexConcurrently
     └─ #3 ✅ CreateIndexConcurrently
        PostHog concurrent-index helper: idempotent (timeout disabling + invalid-leftover recovery)
        model: None, index: posthog_task_origin_key_uniq

📚 How to Deploy These Changes Safely

AddField:

This operation acquires a brief lock but doesn't rewrite the table.

Deployment uses lock timeouts with automatic retries, so lock contention will cause retries rather than connection pile-up.

Last updated: 2026-08-19 17:24 UTC (df7bd98)

@trunk-io trunk-io Bot closed this Aug 19, 2026
@trunk-io
trunk-io Bot deleted the trunk-merge/pr-73758/a92328c6-8265-4923-baf5-49831183c4d6 branch August 19, 2026 17:25
@trunk-io

trunk-io Bot commented Aug 19, 2026

Copy link
Copy Markdown
Author

Static BadgeStatic BadgeStatic Badge

View Full Report ↗︎Docs

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.