Skip to content

chore(ci): run selective tests on all PRs, full suites in the merge queue - #72978

Draft
gantoine wants to merge 7 commits into
masterfrom
chore/trunk-merge-queue-ci
Draft

chore(ci): run selective tests on all PRs, full suites in the merge queue#72978
gantoine wants to merge 7 commits into
masterfrom
chore/trunk-merge-queue-ci

Conversation

@gantoine

@gantoine gantoine commented Jul 22, 2026

Copy link
Copy Markdown
Member

Problem

The Trunk merge queue is live on this repo, and master is restricted to it by branch ruleset. But CI still splits on draft vs ready, so every PR pays for the full suites twice: once when it is marked ready for review, and again in the queue on the trunk-merge/** test PR. The ready-PR run is no longer the merge gate, it is just an expensive dry run of one.

This flips the axis from draft vs ready to regular PR vs merge queue, so the full suites run once, where they actually gate.

Before:

flowchart LR
    D[Draft PR]:::phGray -->|narrowed selection| S[Selective CI]:::phBlue
    R[Ready PR]:::phYellow -->|full matrices| F[Full CI - not a gate]:::phGray
    R -->|enqueue| Q[Trunk queue: trunk-merge/** draft PR]:::phGray
    Q -->|full matrices again| G[Full CI - merge gate]:::phRed
    G --> M[master]:::phYellow
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
Loading

After:

flowchart LR
    P[PR, draft or ready]:::phYellow -->|narrowed selection| S[Selective CI]:::phBlue
    S -->|checks green, enqueue| Q[Trunk queue: trunk-merge/** draft PR]:::phGray
    Q -->|full matrices| F[Full CI - merge gate]:::phRed
    F -->|pass| M[master]:::phYellow
    F -->|fail| E[Eject PR from queue]:::phRed
    classDef phBlue fill:#1d4aff,stroke:#1d4aff,color:#fff;
    classDef phRed fill:#f54e00,stroke:#f54e00,color:#fff;
    classDef phYellow fill:#f9bd2b,stroke:#f9bd2b,color:#000;
    classDef phGray fill:#e5e7eb,stroke:#c7ccd1,color:#000;
Loading

Changes

Per workflow:

  • ci-backend: the snob-selected Django subset now runs on all regular PRs, not just drafts. The full Django matrices and turbo product tests run on trunk-merge/** PRs, master pushes, dispatch, and run-ci-backend labeled runs. The patch-coverage comment now only fires on labeled full runs, since selective runs would report false gaps.
  • ci-frontend: jest --findRelatedTests selection on all regular PRs, full FOSS×EE×chunk fanout in the queue.
  • ci-e2e-playwright: drafts still skip E2E entirely (unchanged). Ready PRs now get the narrowed spec selection on every run, not just synchronize. The full suite runs in the queue and on master.
  • ci-mcp: integration tests move from ready PRs to the queue. Build and unit tests still run on every PR.
  • ci-storybook: narrowed visual-regression matrix on all regular PRs, full chromium matrix in the queue.
  • .depot/workflows/ci-backend.yml: the hand-maintained depot shadow mirrors every canonical change, as ci-backend-shadow-drift requires.
  • Dropped ready_for_review from the trigger types of ci-backend, ci-frontend, ci-mcp, and ci-storybook, since draft to ready no longer changes behavior. That saves four dispatches per PR against GitHub's 500 runs/10s cap. Playwright keeps it because drafts still skip E2E.
  • Docs: updated the authoring-ci-workflows skill section that described the old draft/ready convention, and the AGENTS.md section on forcing a full matrix.

IS_DRAFT in the Django matrix builder becomes IS_SELECTIVE_PR. It carries the same trunk-merge/** carve-out for the same reason: select-tests deliberately does not run for a queue PR, and if the builder treated that PR as selective, the empty MODE would normalize to skip and the queue would merge having run no Django tests.

Warning

Ready PRs stop running the full suites. That is safe only because the queue is the gate and master is ruleset-restricted to it, both of which are already true. If the queue is ever turned off, this has to be reverted in the same change.

Note

A force label (run-ci-backend / run-ci-frontend) now only takes effect on the next push. labeled/unlabeled triggers were removed from these workflows separately, in #74017, and this PR removes the ready_for_review trigger that was the other way a label could take hold. An empty commit is enough: git commit --allow-empty -m "chore(ci): run the full matrix" && git push.

How did you test this code?

  • bin/hogli lint:workflows passes (7 checks, 106 workflows).
  • hogli ci:preflight --strict passes.
  • All seven touched YAML files parse.
  • actionlint was clean when this PR was first authored, apart from findings that were already there on untouched lines (job.check_run_id, the local node24 composite action). It is not installed in the worktree used for the master merge, so that pass ran in CI only.
  • Not runnable locally beyond linting: the trunk-merge/** paths only exercise inside a real queue run. The aggregator "... Tests Pass" jobs already treat skipped dependencies as success, and the skip combinations regular PRs now produce are exactly the ones drafts exercised before this change.

Automatic notifications

  • Publish to changelog?
  • Alert Sales and Marketing teams?

Docs update

Updated .agents/skills/authoring-ci-workflows/SKILL.md and AGENTS.md in this PR.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

I (well, Claude Code) made these changes after we compared this repo's CI against the Trunk merge queue setup on another PostHog repo. Skills invoked: /authoring-ci-workflows.

Decisions along the way: we considered forcing full CI on trunk-merge branches while keeping full ready-PR runs, but chose to swap selective testing onto ready PRs instead. The queue re-runs everything and ejects on failure, so paying for the full suites twice per PR buys nothing. Playwright keeps its draft skip because the per-push stack boot cost that motivated it is unchanged. The coverage comment was rescoped to labeled runs because selective runs would make patch coverage lie.

This branch sat while master moved, so it has since been merged up. Master landed the merge-queue rollout (#74065, #74367) and the label-trigger removal (#74017) in the meantime, and #74266 landed a far more developed version of the impacted-targets upload this PR had originally drafted: a workflow_call reusable with the compute and upload steps split into separate jobs so PR-controlled code never shares a runner with TRUNK_API_TOKEN, plus real lane computation instead of a hardcoded ALL. That file now matches master exactly and is no longer part of this PR, and neither is the TRUNK_API_TOKEN setup note that went with it. Where master and this branch had both edited the same line, the merge kept master's reasoning comments and lint markers on top of this branch's axis flip.

🤖 Generated with Claude Code

gantoine and others added 2 commits July 22, 2026 14:54
…ueue

Prepares CI for the Trunk merge queue. Regular PRs (draft or ready) now
run the selective paths (snob Django subset, jest --findRelatedTests,
narrowed Playwright specs, narrowed visual regression); the full suites
run on the queue's trunk-merge/** draft PRs, master pushes, dispatch,
and label-forced runs. Adds the impacted-targets upload workflow so PRs
(including forks) can enter parallel-queue lanes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gantoine gantoine self-assigned this Jul 22, 2026
@trunk-io

trunk-io Bot commented Jul 22, 2026

Copy link
Copy Markdown

Merging to master in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

🤖 CI report

Bundle size — no change

Uncompressed size of every built .js bundle, compared against the base branch.

Total: 65.30 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 budget

How 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 import() / React.lazy chunks are not counted.

Root Eager (shipped) Δ vs base Budget
entry (logged-out pages, app bootstrap)
src/index.tsx
1.25 MiB · 22 files no change ███░░░░░░░ 27.7% of 4.51 MiB
authenticated shell (every logged-in page)
src/scenes/AuthenticatedShell.tsx
8.11 MiB · 3,020 files no change ████████░░ 83.5% of 9.71 MiB

🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx

Largest files eagerly shipped from src/index.tsx
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
285.3 KiB ../node_modules/.pnpm/posthog-js@1.409.0/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
226.9 KiB ../node_modules/.pnpm/posthog-js@1.409.0/node_modules/posthog-js/dist/module.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.2 KiB src/lib/api.ts
94.7 KiB ../packages/quill/packages/quill/dist/index.js
93.3 KiB ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js
90.6 KiB ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/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

Toolbar bundle — eager 2.19 MiB within budget

What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.

Metric Size Δ vs base Budget
Eager (shipped)
entry + static imports
2.19 MiB · 17 files no change ████░░░░░░ 38.2% of 5.72 MiB
Deferred (lazy) 2.07 MiB · 33 files no change n/a — loads on demand
Loader dist/toolbar.js 1.1 KiB no change █░░░░░░░░░ 5.8% of 19.5 KiB
Largest eagerly-shipped chunks
Size File
717.7 KiB dist/toolbar/toolbar-app-NOGOCMN4.css
546.4 KiB dist/toolbar/chunk-chunk-O6Z3IPFM.js
484.4 KiB dist/toolbar/chunk-chunk-F4F6H6OV.js
133.6 KiB dist/toolbar/chunk-chunk-K3E7PHFY.js
131.8 KiB dist/toolbar/chunk-chunk-T5KY5WYR.js
71.0 KiB dist/toolbar/toolbar-app-LOCVUXOL.js
69.0 KiB dist/toolbar/chunk-chunk-27JL52RE.js
35.6 KiB dist/toolbar/chunk-chunk-IGTC7WBH.js
20.9 KiB dist/toolbar/chunk-chunk-PNWCE5T6.js
12.2 KiB dist/toolbar/chunk-chunk-PIK3PADE.js

Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile

Dist folder size — no change

Total size of the built frontend/dist folder (all assets), compared against the base branch.

Total: 1370.01 MiB · no change

tests-posthog Bot and others added 5 commits July 22, 2026 19:00
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ueue-ci

# Conflicts:
#	.depot/workflows/ci-backend.yml
#	.github/workflows/ci-backend.yml
#	.github/workflows/ci-frontend.yml
#	.github/workflows/ci-mcp.yml
#	.github/workflows/ci-storybook.yml
Master landed the merge-queue rollout (#74065, #74367) and the
impacted-targets upload (#74266) in the meantime, so:

- trunk-impacted-targets.yml now takes master's version wholesale; it
  supersedes this branch's standalone draft with a compute/upload split
  and real lane computation.
- Kept master's removal of the labeled/unlabeled triggers on top of this
  branch's removal of ready_for_review.
- Kept master's hogli-lint not-a-required-gate markers and the
  non-pytest-Python wording in ci-mcp.
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.

1 participant