Skip to content

[Phase 1] Track auto-upgrade metrics in Monorail#7001

Draft
alfonso-noriega wants to merge 5 commits into03-12-port_auto_upgrade_poc_to_mainfrom
03-12-observe-auto-upgrade-metrics
Draft

[Phase 1] Track auto-upgrade metrics in Monorail#7001
alfonso-noriega wants to merge 5 commits into03-12-port_auto_upgrade_poc_to_mainfrom
03-12-observe-auto-upgrade-metrics

Conversation

@alfonso-noriega
Copy link
Contributor

Summary

  • Adds Monorail tracking for auto-upgrade events (resolves shop/issues-develop#22365)
  • Stacks on [Phase 1] Port auto-upgrade POC to main #6999 (Phase 1: auto-upgrade system)
  • Tracked metrics:
    • cmd_all_auto_upgrade_triggered: whether auto-upgrade was attempted
    • cmd_all_auto_upgrade_package_manager: which package manager was used (npm, yarn, pnpm, brew, etc.)
    • cmd_all_auto_upgrade_skipped_reason: why upgrade was skipped (major_version)
    • cmd_all_auto_upgrade_success: whether the upgrade succeeded or failed

Changes

  • packages/cli-kit/src/public/node/monorail.ts: Added 4 new fields to the public section of Schemas[MONORAIL_COMMAND_TOPIC]
  • packages/cli-kit/src/public/node/hooks/postrun.ts: Updated autoUpgradeIfNeeded() to call addPublicMetadata at each decision point (major bump skip, trigger with package manager, success/failure)
  • packages/cli-kit/src/public/node/hooks/postrun.test.ts: Added 4 new test cases covering metrics recording scenarios

Test plan

  • pnpm vitest run src/public/node/hooks/postrun.test.ts — all 8 tests pass
  • Verify Monorail schema changes are compatible with the pipeline

🤖 Generated with Claude Code

@github-actions
Copy link
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/private/node/conf-store.d.ts
@@ -24,6 +24,7 @@ export interface ConfSchema {
     devSessionStore?: string;
     currentDevSessionId?: string;
     cache?: Cache;
+    autoUpgradeEnabled?: boolean;
 }
 /**
  * Get session.
@@ -125,6 +126,18 @@ interface RunWithRateLimitOptions {
  * @returns true, or undefined if the task was not run.
  */
 export declare function runWithRateLimit(options: RunWithRateLimitOptions, config?: LocalStorage<ConfSchema>): Promise<boolean>;
+/**
+ * Get auto-upgrade preference.
+ *
+ * @returns Whether auto-upgrade is enabled, or undefined if not set.
+ */
+export declare function getAutoUpgradeEnabled(config?: LocalStorage<ConfSchema>): boolean | undefined;
+/**
+ * Set auto-upgrade preference.
+ *
+ * @param enabled - Whether auto-upgrade should be enabled.
+ */
+export declare function setAutoUpgradeEnabled(enabled: boolean, config?: LocalStorage<ConfSchema>): void;
 export declare function getConfigStoreForPartnerStatus(): LocalStorage<Record<string, {
     status: true;
     checkedAt: string;
packages/cli-kit/dist/public/node/fs.d.ts
@@ -1,6 +1,6 @@
 import { OverloadParameters } from '../../private/common/ts/overloaded-parameters.js';
 import { RandomNameFamily } from '../common/string.js';
-import { findUp as internalFindUp } from 'find-up';
+import { findUp as internalFindUp, findUpSync as internalFindUpSync } from 'find-up';
 import { ReadStream, WriteStream } from 'fs';
 import type { Pattern, Options as GlobOptions } from 'fast-glob';
 /**
@@ -335,6 +335,7 @@ export declare function defaultEOL(): EOL;
  * @returns The first path found that matches or  if none could be found.
  */
 export declare function findPathUp(matcher: OverloadParameters<typeof internalFindUp>[0], options: OverloadParameters<typeof internalFindUp>[1]): ReturnType<typeof internalFindUp>;
+export declare function findPathUpSync(matcher: OverloadParameters<typeof internalFindUp>[0], options: OverloadParameters<typeof internalFindUp>[1]): ReturnType<typeof internalFindUpSync>;
 export interface MatchGlobOptions {
     matchBase: boolean;
     noglobstar: boolean;
packages/cli-kit/dist/public/node/is-global.d.ts
@@ -26,6 +26,14 @@ export declare function installGlobalCLIPrompt(): Promise<InstallGlobalCLIPrompt
  * Infers the package manager used by the global CLI.
  *
  * @param argv - The arguments passed to the process.
+ * @param env - The environment variables of the process.
  * @returns The package manager used by the global CLI.
  */
-export declare function inferPackageManagerForGlobalCLI(argv?: string[]): PackageManager;
\ No newline at end of file
+export declare function inferPackageManagerForGlobalCLI(argv?: string[], env?: NodeJS.ProcessEnv): PackageManager;
+/**
+ * Returns the project directory for the given path.
+ *
+ * @param directory - The path to the directory to get the project directory for.
+ * @returns The project directory for the given path.
+ */
+export declare function getProjectDir(directory: string): string | undefined;
\ No newline at end of file
packages/cli-kit/dist/public/node/monorail.d.ts
@@ -46,6 +46,10 @@ export interface Schemas {
             cmd_all_timing_network_ms?: Optional<number>;
             cmd_all_timing_prompts_ms?: Optional<number>;
             cmd_all_timing_active_ms?: Optional<number>;
+            cmd_all_auto_upgrade_triggered?: Optional<boolean>;
+            cmd_all_auto_upgrade_skipped_reason?: Optional<string>;
+            cmd_all_auto_upgrade_success?: Optional<boolean>;
+            cmd_all_auto_upgrade_package_manager?: Optional<string>;
             cmd_extensions_binary_from_source?: Optional<boolean>;
             cmd_scaffold_required_auth?: Optional<boolean>;
             cmd_scaffold_template_custom?: Optional<boolean>;
packages/cli-kit/dist/public/node/node-package-manager.d.ts
@@ -25,7 +25,7 @@ export type DependencyType = 'dev' | 'prod' | 'peer';
 /**
  * A union that represents the package managers available.
  */
-export declare const packageManager: readonly ["yarn", "npm", "pnpm", "bun", "unknown"];
+export declare const packageManager: readonly ["yarn", "npm", "pnpm", "bun", "unknown", "homebrew"];
 export type PackageManager = (typeof packageManager)[number];
 /**
  * Returns an abort error that's thrown when the package manager can't be determined.
packages/cli-kit/dist/public/node/upgrade.d.ts
@@ -2,13 +2,34 @@
  * Utility function for generating an install command for the user to run
  * to install an updated version of Shopify CLI.
  *
- * @returns A string with the command to run.
+ * @returns A string with the command to run, or undefined if the package manager cannot be determined.
  */
-export declare function cliInstallCommand(): string;
+export declare function cliInstallCommand(): string | undefined;
+/**
+ * Runs the CLI upgrade using the appropriate package manager.
+ * Determines the install command and executes it.
+ *
+ * @throws Error if the package manager or command cannot be determined.
+ */
+export declare function runCLIUpgrade(): Promise<void>;
+/**
+ * Returns the version to auto-upgrade to, or undefined if auto-upgrade should be skipped.
+ * Auto-upgrade is disabled by default and must be enabled via .
+ * Also skips for CI, pre-release versions, or when no newer version is available.
+ *
+ * @returns The version string to upgrade to, or undefined if no upgrade should happen.
+ */
+export declare function versionToAutoUpgrade(): string | undefined;
 /**
  * Generates a message to remind the user to update the CLI.
  *
  * @param version - The version to update to.
  * @returns The message to remind the user to update the CLI.
  */
-export declare function getOutputUpdateCLIReminder(version: string): string;
\ No newline at end of file
+export declare function getOutputUpdateCLIReminder(version: string): string;
+/**
+ * Prompts the user to enable or disable automatic upgrades, then persists their choice.
+ *
+ * @returns Whether the user chose to enable auto-upgrade.
+ */
+export declare function promptAutoUpgrade(): Promise<boolean>;
\ No newline at end of file
packages/cli-kit/dist/public/node/version.d.ts
@@ -18,4 +18,13 @@ export declare function globalCLIVersion(): Promise<string | undefined>;
  * @param version - The version to check.
  * @returns True if the version is a pre-release version.
  */
-export declare function isPreReleaseVersion(version: string): boolean;
\ No newline at end of file
+export declare function isPreReleaseVersion(version: string): boolean;
+/**
+ * Checks if there is a major version change between two versions.
+ * Pre-release versions (0.0.0-*) are treated as not having a major version change.
+ *
+ * @param currentVersion - The current version.
+ * @param newerVersion - The newer version to compare against.
+ * @returns True if there is a major version change.
+ */
+export declare function isMajorVersionChange(currentVersion: string, newerVersion: string): boolean;
\ No newline at end of file
packages/cli-kit/dist/public/node/hooks/postrun.d.ts
@@ -5,4 +5,10 @@ import { Hook } from '@oclif/core';
  * @returns Whether post run hook has completed.
  */
 export declare function postRunHookHasCompleted(): boolean;
-export declare const hook: Hook.Postrun;
\ No newline at end of file
+export declare const hook: Hook.Postrun;
+/**
+ * Auto-upgrades the CLI after a command completes, if a newer version is available.
+ *
+ * @returns Resolves when the upgrade attempt (or fallback warning) is complete.
+ */
+export declare function autoUpgradeIfNeeded(): Promise<void>;
\ No newline at end of file
packages/cli-kit/dist/public/node/hooks/prerun.d.ts
@@ -11,6 +11,7 @@ export declare function parseCommandContent(cmdInfo: {
     pluginAlias?: string;
 }): CommandContent;
 /**
- * Warns the user if there is a new version of the CLI available
+ * Triggers a background check for a newer CLI version (non-blocking).
+ * The result is cached and consumed by the postrun hook for auto-upgrade.
  */
-export declare function warnOnAvailableUpgrade(): Promise<void>;
\ No newline at end of file
+export declare function checkForNewVersionInBackground(): void;
\ No newline at end of file

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