Skip to content

Separate telemetry handling between CLI and the app#2780

Merged
fredrikekelund merged 54 commits intotrunkfrom
stu-1365-standalone-cli-telemetry
Mar 17, 2026
Merged

Separate telemetry handling between CLI and the app#2780
fredrikekelund merged 54 commits intotrunkfrom
stu-1365-standalone-cli-telemetry

Conversation

@fredrikekelund
Copy link
Copy Markdown
Contributor

@fredrikekelund fredrikekelund commented Mar 12, 2026

Related issues

How AI was used in this PR

For executing smaller subtasks of the refactor and for planning parts of it.

Proposed Changes

This PR makes a few updates to the telemetry handling in the CLI, in anticipation of distributing the CLI through npm:

  • Separate the StatsGroup and StatsMetric definitions between the CLI and the app so that they're not shared.
  • Maintain the shared bumpStat and bumpAggregatedUniqueStat logic.
  • Create type-safe wrappers for those functions in apps/cli and apps/studio.
  • Tweak the ConfigFileProvider interface in tools/common/lib/bump-stat.ts to prepare for the separation of CLI and app config files (happening in Move CLI site data to dedicated config file #2731 and related PRs).
  • Added two new bump stats (anonymized, as always): studio-cli-weekly-unq-npm and studio-cli-weekly-unq-app. These two stats report usage per platform.
  • Added a __ENABLE_CLI_TELEMETRY__ constant definition that makes it so the regular npm run cli:build output disables telemetry altogether. Only npm run cli:package and npm run cli:build:prod will enable telemetry.

Testing Instructions

  1. Apply the following diff
diff --git a/tools/common/lib/bump-stat.ts b/tools/common/lib/bump-stat.ts
index 105a5324..4ec9683e 100644
--- a/tools/common/lib/bump-stat.ts
+++ b/tools/common/lib/bump-stat.ts
@@ -23,7 +23,7 @@ export function __bumpStat( group: string, stat: string, bumpInDev = false ) {
                return false;
        }

-       if ( process.env.E2E || ( process.env.NODE_ENV === 'development' && ! bumpInDev ) ) {
+       if ( true ) {
                console.info( `Would have bumped stat: ${ group }=${ stat }` );
                return false;
        }
  1. Run npm run cli:build:prod
  2. Run node apps/cli/dist/cli/main.js site list
  3. Ensure that the output contains Would have bumped stat: studio-cli-weekly-unq-app=darwin
  4. Ensure that the appdata file contains a studio-cli-weekly-unq-app key in lastBumpStats

Pre-merge Checklist

  • Have you checked for TypeScript, React or other console errors?

ivan-ottinger and others added 30 commits March 12, 2026 08:56
Add a separate Vite config (vite.config.npm.ts) that externalizes all
runtime dependencies and adds a Node.js shebang, producing a standalone
CLI package publishable to npm as @automattic/studio-cli.

The existing Electron-bundled build (vite.config.ts) is unchanged.
- Remove unused `main` field (CLI-only package)
- Include source maps in `files` whitelist
- Use `npx --no-install` for deterministic postinstall
Reverts the inline patch-package approach which breaks in CI
(patch-package errors on missing packages in workspace context).
The script detects monorepo workspaces and skips patching there.
The previous check for node_modules/ existence was unreliable because
npm can create the directory with hoisted leftovers even in workspaces.
Instead, check if the actual patched packages exist locally.
@fredrikekelund fredrikekelund self-assigned this Mar 12, 2026
Base automatically changed from stu-1362-cli-npm-build-pipeline to trunk March 17, 2026 08:18
@wpmobilebot
Copy link
Copy Markdown
Collaborator

wpmobilebot commented Mar 17, 2026

📊 Performance Test Results

Comparing 7b0a05a vs trunk

app-size

Metric trunk 7b0a05a Diff Change
App Size (Mac) 1236.39 MB 1236.37 MB 0.02 MB ⚪ 0.0%

site-editor

Metric trunk 7b0a05a Diff Change
load 1636 ms 1878 ms +242 ms 🔴 14.8%

site-startup

Metric trunk 7b0a05a Diff Change
siteCreation 7096 ms 7089 ms 7 ms ⚪ 0.0%
siteStartup 3927 ms 3931 ms +4 ms ⚪ 0.0%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

lastBumpStats: z
.record( z.string(), z.partialRecord( z.enum( StatsMetric ), z.number() ) )
.optional(),
lastBumpStats: z.record( z.string(), z.record( z.string(), z.number() ) ).optional(),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I previously advocated for the stricter schema here (#2394 (review)), but it actually causes more trouble than it fixes, given the other changes in this PR. Strictness in runtime types makes sense (i.e., for the function arguments to `bumpStat), but strictness in the appdata schema introduces the risk of runtime exceptions if the config file contains unknown bump stats. That isn't really needed, since we only use this object to check when we last bumped a particular stat.

Anyway, with this change, it's safe to land this PR to trunk even before the config file PR train (#2807 etc) has landed.

Copy link
Copy Markdown
Contributor

@bcotrim bcotrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed and works as expected!
Nice separation LGTM 👍

import { readFile, writeFile } from 'atomically';
import { z } from 'zod';
import { validateAccessToken } from 'cli/lib/api';
import { StatsMetric } from 'cli/lib/types/bump-stats';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import here, it should be safe to remove.

@fredrikekelund fredrikekelund merged commit 81d87fc into trunk Mar 17, 2026
10 checks passed
@fredrikekelund fredrikekelund deleted the stu-1365-standalone-cli-telemetry branch March 17, 2026 12:14
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.

4 participants