[eas-cli] Add observe namespace and commands#3564
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3564 +/- ##
==========================================
+ Coverage 54.27% 54.64% +0.37%
==========================================
Files 820 833 +13
Lines 35055 35443 +388
Branches 7260 7335 +75
==========================================
+ Hits 19024 19364 +340
- Misses 15944 15992 +48
Partials 87 87 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
5cd183a to
3b1dfa6
Compare
Add new observe:versions subcommand that queries the appVersions resolver to display app version hierarchy with build numbers, updates, and event/user counts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b84ba0e to
9a4a75c
Compare
Switch timeSeries query from deprecated versionMarkers to appVersionMarkers, which uses the new app version hierarchy with buildNumbers, updates, and easBuilds. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e17f0fb to
4a2bed0
Compare
Update test mocks to use timeSeriesAsync and the new AppObserveTimeSeriesResult shape with appVersionMarkers and aggregate statistics. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| if (flags['days-from-now']) { | ||
| endTime = new Date().toISOString(); | ||
| startTime = new Date(Date.now() - flags['days-from-now'] * 24 * 60 * 60 * 1000).toISOString(); | ||
| } else { | ||
| endTime = flags.end ?? new Date().toISOString(); | ||
| startTime = | ||
| flags.start ?? new Date(Date.now() - DEFAULT_DAYS_BACK * 24 * 60 * 60 * 1000).toISOString(); | ||
| } |
There was a problem hiding this comment.
This is duplicated in events, metrics and versions - could we pull it out to a util?
| - [eas-cli] Add `--non-interactive` flag to `metadata:push` and `metadata:pull` commands with ASC API Key auth support. ([#3548](https://github.com/expo/eas-cli/pull/3548) by [@EvanBacon](https://github.com/EvanBacon)) | ||
| - Add `eas observe:metrics` command for monitoring app performance metrics. ([#3401](https://github.com/expo/eas-cli/pull/3401) by [@ubax](https://github.com/ubax)) | ||
| - Add `eas observe:events` command for monitoring app performance metrics. ([#3401](https://github.com/expo/eas-cli/pull/3401) by [@ubax](https://github.com/ubax)) | ||
|
|
There was a problem hiding this comment.
Should update the changelog to add eas observe:versions command
| })(), | ||
| sort: Flags.option({ | ||
| description: 'Sort order for events', | ||
| options: Object.values(EventsOrderPreset).map(s => s.toLowerCase()), |
There was a problem hiding this comment.
The --sort flag doesn't work at all, because we're inputting in lowercase and comparing against UPPERCASE in resolveOrderBy
|
|
||
| if (flags.json) { | ||
| const stats: StatisticKey[] = argumentsStat ?? DEFAULT_STATS_JSON; | ||
| printJsonOnlyOutput(buildObserveMetricsJson(metricsMap, metricNames, stats)); |
There was a problem hiding this comment.
I think the default table we get is just way too wide and will wrap in most terminals, making it hard to understand.
I suggest we:
- show ios and android separately (so we can skip the platform column)
- merge the value (event count)
- say at top what the user is looking at, e.g. "Median values (event count) for the last 60 days"
| 1.2.0 iOS 0.35s 110 1.32s 90 | ||
| 1.1.0 Android 0.25s 120 1.12s 100 " |
There was a problem hiding this comment.
The app version should always include the build number, so e.g. if we get the following back as releases:
[
{
"appVersion": "1.3.0", // <--- top level, everything starts with app version
"firstSeenAt": "2026-03-31T00:16:32.687Z",
"eventCount": 1280,
"uniqueUserCount": 20,
"buildNumbers": [
{
"appBuildNumber": "47", // <--- every app version can have one or many builds
"firstSeenAt": "2026-03-31T00:16:32.687Z",
"eventCount": 1280,
"uniqueUserCount": 20,
"easBuilds": [
{
"easBuildId": "e1a2b3c4-1300-4001-a000-100000000003", // <--- every build can have 0 to or many EAS Builds
"firstSeenAt": "2026-03-31T00:16:32.687Z",
"eventCount": 1280,
"uniqueUserCount": 20
}
]
}
],
"updates": [
{
"appUpdateId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", // <--- every app version can have one or many updates
"firstSeenAt": "2026-04-02T03:52:43.860Z",
"eventCount": 592,
"uniqueUserCount": 20,
"easBuilds": [
{
"easBuildId": "e1a2b3c4-1300-4001-a000-100000000003", // <--- every update should really only be used on one build at a time, but it's possible that it's on more than one
"firstSeenAt": "2026-04-02T03:52:43.860Z",
"eventCount": 592,
"uniqueUserCount": 20
}
]
}
]
}
]
Then the app version we use should be:
1.3.0 (47)
Plus, it has one update:
b2c3d4e5-f6a7-8901-bcde-f12345678901
| required: true, | ||
| options: [ | ||
| ...Object.keys(METRIC_ALIASES), | ||
| ...Object.keys(METRIC_ALIASES).map(key => METRIC_ALIASES[key]), |
There was a problem hiding this comment.
I think we should NOT accept the values here, let's only accept tti, ttr, cold_launch, warm_launch, bundle_load (same as the observe:events) - so, remove the second line.
|
✅ Thank you for adding the changelog entry! |

This is a merge of @Ubax 's changes from #3431 and #3432 , with refactoring to align with the recent OCLIF upgrade and some other adjustments:
observe:versionsto query statistics for app versions after the www change in https://github.com/expo/universe/pull/26373observe:metricsto use the new app versions, following the www change in https://github.com/expo/universe/pull/26391Why
Provide CLI commands to display Observe metrics and events.
How
New commands and GraphQL queries.
Test Plan
New unit tests added in
fetchEvents-test.ts