Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This is the log of notable changes to EAS CLI and related packages.
- [build-tools] Support an optional `package_version` input on `eas/start_serve_sim_remote_session`, so a simulator session can pin the `@expo/serve-sim` version instead of always running `latest`. ([#4253](https://github.com/expo/eas-cli/pull/4253) by [@gwdp](https://github.com/gwdp))
- [build-tools] Add composable custom build functions for downloading, installing, and launching application archives in simulator sessions. ([#4222](https://github.com/expo/eas-cli/pull/4222) by [@szdziedzic](https://github.com/szdziedzic))
- [eas-cli] Add `--build-id`, `--application-archive-url`, and `--expo-go` to `eas simulator` to install and launch an application before the session is ready. ([#4223](https://github.com/expo/eas-cli/pull/4223) by [@szdziedzic](https://github.com/szdziedzic))
- [eas-cli] Add `--environment` flag to the `eas observe:*` commands. ([#4275](https://github.com/expo/eas-cli/pull/4275) by [@kadikraman](https://github.com/kadikraman))

### 🐛 Bug fixes

Expand Down
19 changes: 19 additions & 0 deletions packages/eas-cli/src/commands/observe/__tests__/events.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,25 @@ describe(ObserveEvents, () => {
expect(mockCustomEventNamesAsync).not.toHaveBeenCalled();
});

it('passes --environment to the custom events filter', async () => {
mockFetchObserveCustomEventsAsync.mockResolvedValue({
events: [{ id: 'evt-1' } as any],
pageInfo: { hasNextPage: false, hasPreviousPage: false },
});
const command = createCommand(['my_event', '--environment', 'production']);
await command.runAsync();

const options = mockFetchObserveCustomEventsAsync.mock.calls[0][2];
expect(options.environment).toBe('production');
});

it('passes --environment to customEventNamesAsync when listing event names', async () => {
const command = createCommand(['--environment', 'production']);
await command.runAsync();

expect(mockCustomEventNamesAsync.mock.calls[0][1].environment).toBe('production');
});

it('routes to customEventNamesAsync when no positional arg is provided', async () => {
const command = createCommand([]);
await command.runAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ describe(ObserveMetricsSummary, () => {
expect(platforms).toEqual([AppPlatform.Ios]);
});

it('passes --environment through to fetchObserveMetricsAsync', async () => {
const command = createCommand(['--environment', 'production']);
await command.runAsync();

expect(mockFetchObserveMetricsSummaryAsync.mock.calls[0][6]).toBe('production');
});

it('resolves --metric aliases before passing to fetchObserveMetricsAsync', async () => {
const command = createCommand(['--metric', 'tti', '--metric', 'cold_launch']);
await command.runAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ describe(ObserveMetrics, () => {
expect(options.endTime).toBe('2025-02-01T00:00:00.000Z');
});

it('passes --environment to the events filter', async () => {
const command = createCommand(['tti', '--environment', 'production']);
await command.runAsync();

const options = mockFetchObserveEventsAsync.mock.calls[0][2];
expect(options.environment).toBe('production');
});

it('defaults endTime to now when only --start is provided', async () => {
const now = new Date('2025-06-15T12:00:00.000Z');
jest.useFakeTimers({ now });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ describe(ObserveRoutes, () => {
expect(options.buildNumber).toBe('42');
});

it('passes --environment through to the fetcher', async () => {
const command = createCommand(['--environment', 'production']);
await command.runAsync();

const options = mockFetchObserveNavigationRoutesAsync.mock.calls[0][2];
expect(options.environment).toBe('production');
});

it('passes --route-name flags through as routeNames array', async () => {
const command = createCommand(['--route-name', '/home', '--route-name', '/profile']);
await command.runAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,11 @@ describe(ObserveSession, () => {
await expect(command.runAsync()).rejects.toThrow(/picker flags/);
});

it('rejects --environment when a session ID is also provided', async () => {
const command = createCommand(['session-abc', '--environment', 'production']);
await expect(command.runAsync()).rejects.toThrow(/picker flags/);
});

it('picker mode with --event-name tti fetches metric events and threads selected sessionId', async () => {
mockFetchSessionMetricCandidatesAsync.mockResolvedValue([
makeMetricEvent({ sessionId: 'picked-session-1' }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ describe(ObserveVersions, () => {
expect(platforms).toEqual([AppPlatform.Ios]);
});

it('passes --environment through to fetchObserveVersionsAsync', async () => {
const command = createCommand(['--environment', 'production']);
await command.runAsync();

expect(mockFetchObserveVersionsAsync.mock.calls[0][5]).toBe('production');
});

it('uses default time range (60 days back) when no --start/--end flags', async () => {
const now = new Date('2025-06-15T12:00:00.000Z');
jest.useFakeTimers({ now });
Expand Down
5 changes: 5 additions & 0 deletions packages/eas-cli/src/commands/observe/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { fetchObserveCustomEventsAsync } from '../../observe/fetchCustomEvents';
import {
ObserveAfterFlag,
ObserveAppVersionFlag,
ObserveEnvironmentFlag,
ObservePlatformFlag,
ObserveProjectIdFlag,
ObserveTimeRangeFlags,
Expand Down Expand Up @@ -54,6 +55,7 @@ export default class ObserveEvents extends EasCommand {
...ObserveTimeRangeFlags,
...ObserveAppVersionFlag,
...ObserveUpdateIdFlag,
...ObserveEnvironmentFlag,
'session-id': Flags.string({
description:
'Filter by session ID. When no event name is given, lists the events in the session instead of the event-name summary.',
Expand Down Expand Up @@ -112,6 +114,7 @@ export default class ObserveEvents extends EasCommand {
startTime,
endTime,
platform,
environment: flags.environment,
})
);

Expand Down Expand Up @@ -142,6 +145,7 @@ export default class ObserveEvents extends EasCommand {
appVersion: flags['app-version'],
updateId: flags['update-id'],
sessionId: flags['session-id'],
environment: flags.environment,
})
);

Expand All @@ -151,6 +155,7 @@ export default class ObserveEvents extends EasCommand {
startTime,
endTime,
platform,
environment: flags.environment,
});

if (json) {
Expand Down
5 changes: 4 additions & 1 deletion packages/eas-cli/src/commands/observe/metrics-summary.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import Log from '../../log';
import { fetchObserveMetricsAsync } from '../../observe/fetchMetrics';
import {
ObserveEnvironmentFlag,
ObservePlatformFlag,
ObserveProjectIdFlag,
ObserveTimeRangeFlags,
Expand Down Expand Up @@ -62,6 +63,7 @@ export default class ObserveMetricsSummary extends EasCommand {
options: DEFAULT_STATS_JSON,
})(),
...ObserveTimeRangeFlags,
...ObserveEnvironmentFlag,
...ObserveProjectIdFlag,
...EasNonInteractiveAndJsonFlags,
};
Expand Down Expand Up @@ -107,7 +109,8 @@ export default class ObserveMetricsSummary extends EasCommand {
metricNames,
platforms,
startTime,
endTime
endTime,
flags.environment
)
);

Expand Down
6 changes: 5 additions & 1 deletion packages/eas-cli/src/commands/observe/metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import {
ObserveAfterFlag,
ObserveAppVersionFlag,
ObserveEnvironmentFlag,
ObservePlatformFlag,
ObserveProjectIdFlag,
ObserveTimeRangeFlags,
Expand Down Expand Up @@ -60,6 +61,7 @@ export default class ObserveMetrics extends EasCommand {
...ObserveTimeRangeFlags,
...ObserveAppVersionFlag,
...ObserveUpdateIdFlag,
...ObserveEnvironmentFlag,
...ObserveProjectIdFlag,
...EasNonInteractiveAndJsonFlags,
};
Expand Down Expand Up @@ -123,14 +125,16 @@ export default class ObserveMetrics extends EasCommand {
platform,
appVersion: flags['app-version'],
updateId: flags['update-id'],
environment: flags.environment,
}),
fetchTotalEventCountAsync(
graphqlClient,
projectId,
metricName,
platforms,
startTime,
endTime
endTime,
flags.environment
),
])
);
Expand Down
3 changes: 3 additions & 0 deletions packages/eas-cli/src/commands/observe/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { fetchObserveNavigationRoutesAsync } from '../../observe/fetchNavigation
import {
ObserveAfterFlag,
ObserveAppVersionFlag,
ObserveEnvironmentFlag,
ObservePlatformFlag,
ObserveProjectIdFlag,
ObserveTimeRangeFlags,
Expand Down Expand Up @@ -70,6 +71,7 @@ export default class ObserveRoutes extends EasCommand {
'Filter by route name (can be specified multiple times to include several routes)',
multiple: true,
}),
...ObserveEnvironmentFlag,
...ObserveProjectIdFlag,
...EasNonInteractiveAndJsonFlags,
};
Expand Down Expand Up @@ -125,6 +127,7 @@ export default class ObserveRoutes extends EasCommand {
updateId: flags['update-id'],
buildNumber: flags['build-number'],
routeNames,
environment: flags.environment,
})
);

Expand Down
22 changes: 18 additions & 4 deletions packages/eas-cli/src/commands/observe/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import {
fetchSessionMetricCandidatesAsync,
verifyObserveSessionAccessAsync,
} from '../../observe/fetchSessions';
import { ObserveProjectIdFlag, ObserveTimeRangeFlags } from '../../observe/flags';
import {
ObserveEnvironmentFlag,
ObserveProjectIdFlag,
ObserveTimeRangeFlags,
} from '../../observe/flags';
import { withObservePlanGateHandlingAsync } from '../../observe/planGating';
import {
buildObserveSessionEventsJson,
Expand Down Expand Up @@ -66,6 +70,7 @@ export default class ObserveSession extends EasCommand {
'Metric or log event name to pick candidate sessions by (e.g. tti, cold_launch, login_pressed). If omitted in interactive mode, you will be prompted.',
}),
...ObserveTimeRangeFlags,
...ObserveEnvironmentFlag,
...ObserveProjectIdFlag,
...EasNonInteractiveAndJsonFlags,
};
Expand Down Expand Up @@ -102,10 +107,11 @@ export default class ObserveSession extends EasCommand {
flags.sort !== undefined ||
flags.days !== undefined ||
flags.start !== undefined ||
flags.end !== undefined;
flags.end !== undefined ||
flags.environment !== undefined;
if (pickerFlagsProvided) {
throw new EasCommandError(
'The picker flags (--event-name, --sort, --days, --start, --end) describe how to find a session and cannot be combined with a session ID argument.'
'The picker flags (--event-name, --sort, --days, --start, --end, --environment) describe how to find a session and cannot be combined with a session ID argument.'
);
}
sessionId = args.sessionId;
Expand All @@ -127,6 +133,7 @@ export default class ObserveSession extends EasCommand {
eventNameFlag: flags['event-name'],
sort: flags.sort,
timeRangeFlags: { days: flags.days, start: flags.start, end: flags.end },
environment: flags.environment,
});
}

Expand Down Expand Up @@ -172,18 +179,20 @@ async function pickSessionIdInteractivelyAsync({
eventNameFlag,
sort,
timeRangeFlags,
environment,
}: {
graphqlClient: ExpoGraphqlClient;
projectId: string;
eventNameFlag: string | undefined;
sort: string | undefined;
timeRangeFlags: { days: number | undefined; start: string | undefined; end: string | undefined };
environment: string | undefined;
}): Promise<string> {
const { startTime, endTime } = resolveTimeRange(timeRangeFlags);

const eventNameChoice: EventNameChoice = eventNameFlag
? { name: eventNameFlag, isMetric: isKnownMetricName(eventNameFlag) }
: await promptForEventNameAsync({ graphqlClient, projectId, startTime, endTime });
: await promptForEventNameAsync({ graphqlClient, projectId, startTime, endTime, environment });

let sortValue: string;
if (sort) {
Expand All @@ -208,6 +217,7 @@ async function pickSessionIdInteractivelyAsync({
startTime,
endTime,
limit: PICKER_CANDIDATE_LIMIT,
environment,
})
).map(event => ({ sessionId: event.sessionId, title: formatMetricCandidateTitle(event) }))
: (
Expand All @@ -217,6 +227,7 @@ async function pickSessionIdInteractivelyAsync({
startTime,
endTime,
limit: PICKER_CANDIDATE_LIMIT,
environment,
})
).map(event => ({ sessionId: event.sessionId, title: formatLogCandidateTitle(event) }));

Expand Down Expand Up @@ -254,16 +265,19 @@ async function promptForEventNameAsync({
projectId,
startTime,
endTime,
environment,
}: {
graphqlClient: ExpoGraphqlClient;
projectId: string;
startTime: string;
endTime: string;
environment: string | undefined;
}): Promise<EventNameChoice> {
const { names: customEventNames } = await ObserveQuery.customEventNamesAsync(graphqlClient, {
appId: projectId,
startTime,
endTime,
environment,
});

const metricChoices: ExpoChoice<EventNameChoice>[] = Object.entries(METRIC_SHORT_NAMES).map(
Expand Down
5 changes: 4 additions & 1 deletion packages/eas-cli/src/commands/observe/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import Log from '../../log';
import { fetchObserveVersionsAsync } from '../../observe/fetchVersions';
import {
ObserveEnvironmentFlag,
ObservePlatformFlag,
ObserveProjectIdFlag,
ObserveTimeRangeFlags,
Expand All @@ -22,6 +23,7 @@ export default class ObserveVersions extends EasCommand {
static override flags = {
...ObservePlatformFlag,
...ObserveTimeRangeFlags,
...ObserveEnvironmentFlag,
...ObserveProjectIdFlag,
...EasNonInteractiveAndJsonFlags,
};
Expand Down Expand Up @@ -60,7 +62,8 @@ export default class ObserveVersions extends EasCommand {
projectId,
platforms,
startTime,
endTime
endTime,
flags.environment
);

if (json) {
Expand Down
10 changes: 9 additions & 1 deletion packages/eas-cli/src/graphql/queries/ObserveQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,14 @@ export const ObserveQuery = {
startTime,
endTime,
metricNames,
environment,
}: {
appId: string;
platform: AppObservePlatform;
startTime: string;
endTime: string;
metricNames?: string[];
environment?: string;
}
): Promise<AppObserveAppVersion[]> {
const data = await withErrorHandlingAsync(
Expand All @@ -252,7 +254,13 @@ export const ObserveQuery = {
`,
{
appId,
input: { platform, startTime, endTime, ...(metricNames && { metricNames }) },
input: {
platform,
startTime,
endTime,
...(metricNames && { metricNames }),
...(environment && { environment }),
},
}
)
.toPromise()
Expand Down
Loading
Loading