From 076217574d25cf927bf4b1563ea231886b4b9a86 Mon Sep 17 00:00:00 2001 From: Kadi Kraman Date: Mon, 27 Jul 2026 07:37:11 -0700 Subject: [PATCH 1/5] Update pre-build message to improve phrasing --- .../src/utils/usage/__tests__/checkForOverages-test.ts | 8 ++++---- packages/eas-cli/src/utils/usage/checkForOverages.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/eas-cli/src/utils/usage/__tests__/checkForOverages-test.ts b/packages/eas-cli/src/utils/usage/__tests__/checkForOverages-test.ts index a5f09acbb2..b3ec6c9592 100644 --- a/packages/eas-cli/src/utils/usage/__tests__/checkForOverages-test.ts +++ b/packages/eas-cli/src/utils/usage/__tests__/checkForOverages-test.ts @@ -245,7 +245,7 @@ describe('maybeWarnAboutUsageOveragesAsync', () => { expect(mockWarn).toHaveBeenCalledWith( expect.stringContaining( - "You've used 10 builds beyond your included credits this billing period ($15.00 in overages so far)." + "You've used 10 builds beyond your included credits this billing period ($15.00 in additional usage so far)." ) ); expect(mockWarn).toHaveBeenCalledWith( @@ -289,7 +289,7 @@ describe('maybeWarnAboutUsageOveragesAsync', () => { expect(mockWarn).toHaveBeenCalledWith( expect.stringContaining( - "You've used 3 builds beyond your included credits this billing period ($4.50 in overages so far)." + "You've used 3 builds beyond your included credits this billing period ($4.50 in additional usage so far)." ) ); }); @@ -558,7 +558,7 @@ describe('displayOverageWarning', () => { expect(mockWarn).toHaveBeenCalledWith( expect.stringContaining( - "You've used 10 builds beyond your included credits this billing period ($15.00 in overages so far)." + "You've used 10 builds beyond your included credits this billing period ($15.00 in additional usage so far)." ) ); expect(mockWarn).toHaveBeenCalledWith( @@ -579,7 +579,7 @@ describe('displayOverageWarning', () => { expect(mockWarn).toHaveBeenCalledWith( expect.stringContaining( - "You've used 1 build beyond your included credits this billing period ($1.50 in overages so far)." + "You've used 1 build beyond your included credits this billing period ($1.50 in additional usage so far)." ) ); }); diff --git a/packages/eas-cli/src/utils/usage/checkForOverages.ts b/packages/eas-cli/src/utils/usage/checkForOverages.ts index 7c2cd9459f..4d352e0d93 100644 --- a/packages/eas-cli/src/utils/usage/checkForOverages.ts +++ b/packages/eas-cli/src/utils/usage/checkForOverages.ts @@ -173,7 +173,7 @@ export function displayOverageWarning({ // tier === 'over' && paid plan Log.warn( chalk.bold( - `You've used ${overageCount} build${overageCount === 1 ? '' : 's'} beyond your included credits this billing period (${formatCents(overageCostCents)} in overages so far).` + `You've used ${overageCount} build${overageCount === 1 ? '' : 's'} beyond your included credits this billing period (${formatCents(overageCostCents)} in additional usage so far).` ) ); Log.warn( From ed0c1abed30621a1828d0f105a430f7429ce15b8 Mon Sep 17 00:00:00 2001 From: Kadi Kraman Date: Mon, 27 Jul 2026 07:38:09 -0700 Subject: [PATCH 2/5] Update usage message to improve phrasing --- packages/eas-cli/src/commands/account/usage.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/eas-cli/src/commands/account/usage.ts b/packages/eas-cli/src/commands/account/usage.ts index 9fde0e8018..90736f542e 100644 --- a/packages/eas-cli/src/commands/account/usage.ts +++ b/packages/eas-cli/src/commands/account/usage.ts @@ -58,7 +58,7 @@ function displayBandwidthMetric(metric: UsageMetricDisplay, indent: string = ' if (metric.overageValue > 0) { Log.log( - `${indent}${metric.name} (overage): ${chalk.red( + `${indent}${metric.name} (additional usage): ${chalk.red( formatBytesDisplay(metric.overageValue) )} (${formatCurrency(metric.overageCost)})` ); @@ -84,7 +84,7 @@ function displayMetric(metric: UsageMetricDisplay, indent: string = ' '): void if (metric.overageValue > 0) { Log.log( - `${indent}${metric.name} (overage): ${chalk.red( + `${indent}${metric.name} (additional usage): ${chalk.red( `${formatNumber(metric.overageValue)} ${metric.unit ?? ''}` )} (${formatCurrency(metric.overageCost)})` ); @@ -172,9 +172,9 @@ function displayUsage(data: UsageDisplayData, usageData: AccountFullUsageData): } if (data.totalOverageCostCents > 0) { - Log.log(` Current overages: ${chalk.yellow(formatCurrency(data.totalOverageCostCents))}`); + Log.log(` Additional usage: ${chalk.yellow(formatCurrency(data.totalOverageCostCents))}`); if (data.builds.overageCostCents > 0) { - Log.log(` Build overages: ${formatCurrency(data.builds.overageCostCents)}`); + Log.log(` Builds: ${formatCurrency(data.builds.overageCostCents)}`); // Show breakdown by worker size for (const overage of data.builds.overagesByWorkerSize) { const platformName = overage.platform === AppPlatform.Ios ? 'iOS' : 'Android'; @@ -188,7 +188,7 @@ function displayUsage(data: UsageDisplayData, usageData: AccountFullUsageData): } } if (data.updates.overageCostCents > 0) { - Log.log(` Update overages: ${formatCurrency(data.updates.overageCostCents)}`); + Log.log(` Updates: ${formatCurrency(data.updates.overageCostCents)}`); } } From 3b488e460eed07b999c38d434e3df9d697a9d5f4 Mon Sep 17 00:00:00 2001 From: Kadi Kraman Date: Mon, 27 Jul 2026 07:47:17 -0700 Subject: [PATCH 3/5] Add test for usage printout --- .../commands/account/__tests__/usage.test.ts | 42 +++++++++++++++++++ .../eas-cli/src/commands/account/usage.ts | 2 +- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/eas-cli/src/commands/account/__tests__/usage.test.ts b/packages/eas-cli/src/commands/account/__tests__/usage.test.ts index 240b325f1e..05e8edcadc 100644 --- a/packages/eas-cli/src/commands/account/__tests__/usage.test.ts +++ b/packages/eas-cli/src/commands/account/__tests__/usage.test.ts @@ -1,4 +1,5 @@ import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient'; +import { extractUsageData } from '../../../commandUtils/usageUtils'; import { AccountFullUsageQuery as AccountFullUsageQueryType, EasService, @@ -6,9 +7,17 @@ import { UsageMetricType, } from '../../../graphql/generated'; import { AccountQuery } from '../../../graphql/queries/AccountQuery'; +import Log from '../../../log'; import { calculatePercentUsed, createProgressBar } from '../../../utils/usage/checkForOverages'; +import { displayUsage } from '../usage'; jest.mock('../../../graphql/queries/AccountQuery'); +jest.mock('../../../log', () => ({ + ...jest.requireActual('../../../log'), + log: jest.fn(), + newLine: jest.fn(), + link: jest.fn((url: string, opts?: { text?: string }) => opts?.text ?? url), +})); function createMockFullUsageData( overrides: Partial<{ @@ -206,6 +215,39 @@ describe('AccountQuery', () => { }); }); +describe('displayUsage', () => { + const mockLog = jest.mocked(Log.log); + + beforeEach(() => { + mockLog.mockClear(); + }); + + it('labels usage beyond included credits as "additional usage"', () => { + const usageData = createMockFullUsageData({ + buildValue: 55, + buildLimit: 50, + mauValue: 3500, + mauLimit: 3000, + buildOverageCost: 1500, + updateOverageCost: 250, + }); + const displayData = extractUsageData(usageData); + + displayUsage(displayData, usageData); + + // eslint-disable-next-line no-control-regex + const output = mockLog.mock.calls + .flat() + .join('\n') + .replace(/\u001b\[\d+m/g, ''); + expect(output).toContain('Unique Updaters (additional usage): 500 users ($2.50)'); + expect(output).toContain('Additional usage: $17.50'); + expect(output).toContain('Builds: $15.00'); + expect(output).toContain('Updates: $2.50'); + expect(output.toLowerCase()).not.toContain('overage'); + }); +}); + describe('calculatePercentUsed', () => { it('calculates correct percentage', () => { expect(calculatePercentUsed(50, 100)).toBe(50); diff --git a/packages/eas-cli/src/commands/account/usage.ts b/packages/eas-cli/src/commands/account/usage.ts index 90736f542e..4f2a8448e6 100644 --- a/packages/eas-cli/src/commands/account/usage.ts +++ b/packages/eas-cli/src/commands/account/usage.ts @@ -95,7 +95,7 @@ function billingUrl(accountName: string): string { return `https://expo.dev/accounts/${accountName}/settings/billing`; } -function displayUsage(data: UsageDisplayData, usageData: AccountFullUsageData): void { +export function displayUsage(data: UsageDisplayData, usageData: AccountFullUsageData): void { const subscription = usageData.subscription; Log.newLine(); From f5cce1347427c3581cd53e837e423309e9b5141d Mon Sep 17 00:00:00 2001 From: Kadi Kraman Date: Mon, 27 Jul 2026 07:53:00 -0700 Subject: [PATCH 4/5] Add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e262bae884..54642bd7d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This is the log of notable changes to EAS CLI and related packages. - [eas-cli] Refresh README as an EAS product landing page. ([#3844](https://github.com/expo/eas-cli/pull/3844) by [@szdziedzic](https://github.com/szdziedzic)) - [eas-cli] Fix the EAS logo not rendering in the repository root README. ([#4093](https://github.com/expo/eas-cli/pull/4093) by [@szdziedzic](https://github.com/szdziedzic)) +- [eas-cli] Improve wording for usage printouts. ([#4094](https://github.com/expo/eas-cli/pull/4094) by [@kadikraman](https://github.com/kadikraman)) ## [21.3.0](https://github.com/expo/eas-cli/releases/tag/v21.3.0) - 2026-07-27 From 6c15548b965723b3a804d4dd9b47a730dc76ccb9 Mon Sep 17 00:00:00 2001 From: Kadi Kraman Date: Mon, 27 Jul 2026 11:58:13 -0700 Subject: [PATCH 5/5] Fix Log mock in usage test to explicitly mock default export --- .../eas-cli/src/commands/account/__tests__/usage.test.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/eas-cli/src/commands/account/__tests__/usage.test.ts b/packages/eas-cli/src/commands/account/__tests__/usage.test.ts index 05e8edcadc..b0dda600c5 100644 --- a/packages/eas-cli/src/commands/account/__tests__/usage.test.ts +++ b/packages/eas-cli/src/commands/account/__tests__/usage.test.ts @@ -13,9 +13,12 @@ import { displayUsage } from '../usage'; jest.mock('../../../graphql/queries/AccountQuery'); jest.mock('../../../log', () => ({ + __esModule: true, ...jest.requireActual('../../../log'), - log: jest.fn(), - newLine: jest.fn(), + default: { + log: jest.fn(), + newLine: jest.fn(), + }, link: jest.fn((url: string, opts?: { text?: string }) => opts?.text ?? url), }));