mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-14 10:08:06 -10:00
Compare commits
35
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82c222614b | ||
|
|
6c8431edf6 | ||
|
|
bc282b6262 | ||
|
|
17661d1cf0 | ||
|
|
8d35745124 | ||
|
|
3740ee4ef9 | ||
|
|
751d3d1287 | ||
|
|
1fd14c07e1 | ||
|
|
39ea1705d8 | ||
|
|
2c96b9929d | ||
|
|
0dae24ae47 | ||
|
|
a63efe01a1 | ||
|
|
803457b37a | ||
|
|
dcb1305501 | ||
|
|
97fe2d62d2 | ||
|
|
ca0850b82b | ||
|
|
039a7b408b | ||
|
|
68660ae845 | ||
|
|
34bb2c8a75 | ||
|
|
ac5cf3d7dd | ||
|
|
8d686b855b | ||
|
|
19973bb86f | ||
|
|
d132ac09de | ||
|
|
4c5e5d4ded | ||
|
|
44af16efe1 | ||
|
|
f34487cc8e | ||
|
|
7ea1c5de17 | ||
|
|
261f611770 | ||
|
|
f9337f419a | ||
|
|
4280e10836 | ||
|
|
a2fe99c97e | ||
|
|
868fd399a4 | ||
|
|
7d60ba2cea | ||
|
|
db7461a569 | ||
|
|
facffbdcd7 |
No files matched your search
+6
-12
@@ -3,24 +3,18 @@ commentConfiguration:
|
||||
epilogue: 'Generated by [CodeMention](https://github.com/expo/expo/actions/workflows/codemention.yaml)'
|
||||
rules:
|
||||
- patterns: ['**/*']
|
||||
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
|
||||
- patterns: ['packages/eas-cli/src/build/**']
|
||||
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
|
||||
- patterns: ['packages/eas-cli/src/commands/build/**']
|
||||
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
|
||||
- patterns: ['packages/eas-cli/src/submit/**']
|
||||
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
|
||||
- patterns: ['packages/eas-cli/src/commands/submit.ts']
|
||||
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela', 'radoslawkrzemien']
|
||||
- patterns: ['packages/eas-cli/src/update/**']
|
||||
mentions: ['EvanBacon', 'byCedric', 'wschurman']
|
||||
mentions: ['wschurman', 'quinlanj']
|
||||
- patterns: ['packages/eas-cli/src/commands/update/**']
|
||||
mentions: ['EvanBacon', 'byCedric', 'wschurman']
|
||||
mentions: ['wschurman', 'quinlanj']
|
||||
- patterns: ['packages/eas-cli/src/channel/**']
|
||||
mentions: ['wschurman', 'quinlanj']
|
||||
- patterns: ['packages/eas-cli/src/commands/channel/**']
|
||||
mentions: ['wschurman', 'quinlanj']
|
||||
- patterns: ['packages/eas-cli/schema/**']
|
||||
mentions: ['bycedric']
|
||||
- patterns: ['packages/eas-cli/src/metadata/**']
|
||||
mentions: ['bycedric']
|
||||
- patterns: ['packages/eas-cli/src/commands/metadata/**']
|
||||
mentions: ['bycedric']
|
||||
- patterns: ['packages/eas-json/**']
|
||||
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
|
||||
@@ -8,8 +8,71 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Add `eas deploy --dry-run` flag to output tarball. ([#2761](https://github.com/expo/eas-cli/pull/2761) by [@kitten](https://github.com/kitten))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
- Remove random branch name generation for --auto branch name non-vcs fallback. ([#2747](https://github.com/expo/eas-cli/pull/2747) by [@wschurman](https://github.com/wschurman))
|
||||
- Upgrade @expo/multipart-body-parser. ([#2751](https://github.com/expo/eas-cli/pull/2751) by [@wschurman](https://github.com/wschurman))
|
||||
- Pass env var flag to worker deployments. ([#2763](https://github.com/expo/eas-cli/pull/2763) by [@kadikraman](https://github.com/kadikraman))
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Fix provider account switching. ([#2767](https://github.com/expo/eas-cli/pull/2767) by [@EvanBacon](https://github.com/EvanBacon))
|
||||
|
||||
## [14.1.0](https://github.com/expo/eas-cli/releases/tag/v14.1.0) - 2024-12-10
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Add support for enabeling broadcast Push Notifications capability option, by setting `ios.usesBroadcastPushNotifications` to `true` in app config. ([#2748](https://github.com/expo/eas-cli/pull/2748) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Add link to FYI page mentioning the workaround for Apple SMS 2FA issue. ([#2752](https://github.com/expo/eas-cli/pull/2752) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
## [14.0.3](https://github.com/expo/eas-cli/releases/tag/v14.0.3) - 2024-12-09
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
- Bump `@expo/apple-utils` to fix sending two-factor authentication codes via SMS. ([#2750](https://github.com/expo/eas-cli/pull/2750) by [@EvanBacon](https://github.com/EvanBacon))
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Change update message to allow faster copy and paste. ([#2661](https://github.com/expo/eas-cli/pull/2661) by [@jonluca](https://github.com/jonluca))
|
||||
- Allow using `$schema` field in `eas.json`. ([#2624](https://github.com/expo/eas-cli/pull/2624) by [@saiichihashimoto](https://github.com/saiichihashimoto))
|
||||
|
||||
## [14.0.2](https://github.com/expo/eas-cli/releases/tag/v14.0.2) - 2024-12-06
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Print warning instead of throwing an error when validating `CFBundleShortVersionString` against App Store requirements. ([#2741](https://github.com/expo/eas-cli/pull/2741) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
## [14.0.1](https://github.com/expo/eas-cli/releases/tag/v14.0.1) - 2024-12-06
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Bump `@expo/apple-utils` to improve error handling and input validation and change auth headers. ([#2745](https://github.com/expo/eas-cli/pull/2745) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
## [14.0.0](https://github.com/expo/eas-cli/releases/tag/v14.0.0) - 2024-12-06
|
||||
|
||||
### 🛠 Breaking changes
|
||||
|
||||
- Change behavior of roll-back-to-embedded to not use current project state. ([#2722](https://github.com/expo/eas-cli/pull/2722) by [@wschurman](https://github.com/wschurman))
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Add hidden fingerprint:compare feature. ([#2736](https://github.com/expo/eas-cli/pull/2736) by [@quinlanj](https://github.com/quinlanj))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
- Update `@expo/config` and `@expo/config-plugins` to fix `eas build` command for bare iOS projects on Windows. ([#2744](https://github.com/expo/eas-cli/pull/2744) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Fix outdated gitignored Google services file warning. ([#2730](https://github.com/expo/eas-cli/pull/2730) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
## [13.4.2](https://github.com/expo/eas-cli/releases/tag/v13.4.2) - 2024-11-25
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Upgrade `@expo` packages to SDK 52 versions. ([#2706](https://github.com/expo/eas-cli/pull/2706) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"version": "13.4.2",
|
||||
"version": "14.1.0",
|
||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
|
||||
}
|
||||
+73
-73
@@ -153,7 +153,7 @@ ALIASES
|
||||
$ eas login
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/account/login.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/account/login.ts)_
|
||||
|
||||
## `eas account:logout`
|
||||
|
||||
@@ -170,7 +170,7 @@ ALIASES
|
||||
$ eas logout
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/account/logout.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/account/logout.ts)_
|
||||
|
||||
## `eas account:view`
|
||||
|
||||
@@ -187,7 +187,7 @@ ALIASES
|
||||
$ eas whoami
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/account/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/account/view.ts)_
|
||||
|
||||
## `eas analytics [STATUS]`
|
||||
|
||||
@@ -201,7 +201,7 @@ DESCRIPTION
|
||||
display or change analytics settings
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/analytics.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/analytics.ts)_
|
||||
|
||||
## `eas autocomplete [SHELL]`
|
||||
|
||||
@@ -253,7 +253,7 @@ DESCRIPTION
|
||||
create a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/branch/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/branch/create.ts)_
|
||||
|
||||
## `eas branch:delete [NAME]`
|
||||
|
||||
@@ -274,7 +274,7 @@ DESCRIPTION
|
||||
delete a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/branch/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/branch/delete.ts)_
|
||||
|
||||
## `eas branch:list`
|
||||
|
||||
@@ -294,7 +294,7 @@ DESCRIPTION
|
||||
list all branches
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/branch/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/branch/list.ts)_
|
||||
|
||||
## `eas branch:rename`
|
||||
|
||||
@@ -314,7 +314,7 @@ DESCRIPTION
|
||||
rename a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/branch/rename.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/branch/rename.ts)_
|
||||
|
||||
## `eas branch:view [NAME]`
|
||||
|
||||
@@ -337,7 +337,7 @@ DESCRIPTION
|
||||
view a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/branch/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/branch/view.ts)_
|
||||
|
||||
## `eas build`
|
||||
|
||||
@@ -374,7 +374,7 @@ DESCRIPTION
|
||||
start a build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/index.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/index.ts)_
|
||||
|
||||
## `eas build:cancel [BUILD_ID]`
|
||||
|
||||
@@ -393,7 +393,7 @@ DESCRIPTION
|
||||
cancel a build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/cancel.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/cancel.ts)_
|
||||
|
||||
## `eas build:configure`
|
||||
|
||||
@@ -410,7 +410,7 @@ DESCRIPTION
|
||||
configure the project to support EAS Build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/configure.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/configure.ts)_
|
||||
|
||||
## `eas build:delete [BUILD_ID]`
|
||||
|
||||
@@ -429,7 +429,7 @@ DESCRIPTION
|
||||
delete a build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/delete.ts)_
|
||||
|
||||
## `eas build:inspect`
|
||||
|
||||
@@ -464,7 +464,7 @@ DESCRIPTION
|
||||
inspect the state of the project at specific build stages, useful for troubleshooting
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/inspect.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/inspect.ts)_
|
||||
|
||||
## `eas build:list`
|
||||
|
||||
@@ -514,7 +514,7 @@ DESCRIPTION
|
||||
list all builds for your project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/list.ts)_
|
||||
|
||||
## `eas build:resign`
|
||||
|
||||
@@ -543,7 +543,7 @@ DESCRIPTION
|
||||
re-sign a build archive
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/resign.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/resign.ts)_
|
||||
|
||||
## `eas build:run`
|
||||
|
||||
@@ -569,7 +569,7 @@ DESCRIPTION
|
||||
run simulator/emulator builds from eas-cli
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/run.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/run.ts)_
|
||||
|
||||
## `eas build:submit`
|
||||
|
||||
@@ -619,7 +619,7 @@ DESCRIPTION
|
||||
get the latest version from EAS servers
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/version/get.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/version/get.ts)_
|
||||
|
||||
## `eas build:version:set`
|
||||
|
||||
@@ -638,7 +638,7 @@ DESCRIPTION
|
||||
update version of an app
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/version/set.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/version/set.ts)_
|
||||
|
||||
## `eas build:version:sync`
|
||||
|
||||
@@ -657,7 +657,7 @@ DESCRIPTION
|
||||
update a version in native code with a value stored on EAS servers
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/version/sync.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/version/sync.ts)_
|
||||
|
||||
## `eas build:view [BUILD_ID]`
|
||||
|
||||
@@ -674,7 +674,7 @@ DESCRIPTION
|
||||
view a build for your project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/build/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/build/view.ts)_
|
||||
|
||||
## `eas channel:create [NAME]`
|
||||
|
||||
@@ -695,7 +695,7 @@ DESCRIPTION
|
||||
create a channel
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/create.ts)_
|
||||
|
||||
## `eas channel:edit [NAME]`
|
||||
|
||||
@@ -717,7 +717,7 @@ DESCRIPTION
|
||||
point a channel at a new branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/edit.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/edit.ts)_
|
||||
|
||||
## `eas channel:list`
|
||||
|
||||
@@ -737,7 +737,7 @@ DESCRIPTION
|
||||
list all channels
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/list.ts)_
|
||||
|
||||
## `eas channel:pause [NAME]`
|
||||
|
||||
@@ -759,7 +759,7 @@ DESCRIPTION
|
||||
pause a channel to stop it from sending updates
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/pause.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/pause.ts)_
|
||||
|
||||
## `eas channel:resume [NAME]`
|
||||
|
||||
@@ -781,7 +781,7 @@ DESCRIPTION
|
||||
resume a channel to start sending updates
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/resume.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/resume.ts)_
|
||||
|
||||
## `eas channel:rollout [CHANNEL]`
|
||||
|
||||
@@ -814,7 +814,7 @@ DESCRIPTION
|
||||
Roll a new branch out on a channel incrementally.
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/rollout.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/rollout.ts)_
|
||||
|
||||
## `eas channel:view [NAME]`
|
||||
|
||||
@@ -837,7 +837,7 @@ DESCRIPTION
|
||||
view a channel
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/channel/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/channel/view.ts)_
|
||||
|
||||
## `eas config`
|
||||
|
||||
@@ -858,7 +858,7 @@ DESCRIPTION
|
||||
display project configuration (app.json + eas.json)
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/config.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/config.ts)_
|
||||
|
||||
## `eas credentials`
|
||||
|
||||
@@ -875,7 +875,7 @@ DESCRIPTION
|
||||
manage credentials
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/credentials/index.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/credentials/index.ts)_
|
||||
|
||||
## `eas credentials:configure-build`
|
||||
|
||||
@@ -893,7 +893,7 @@ DESCRIPTION
|
||||
Set up credentials for building your project.
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/credentials/configure-build.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/credentials/configure-build.ts)_
|
||||
|
||||
## `eas device:create`
|
||||
|
||||
@@ -907,7 +907,7 @@ DESCRIPTION
|
||||
register new Apple Devices to use for internal distribution
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/device/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/device/create.ts)_
|
||||
|
||||
## `eas device:delete`
|
||||
|
||||
@@ -927,7 +927,7 @@ DESCRIPTION
|
||||
remove a registered device from your account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/device/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/device/delete.ts)_
|
||||
|
||||
## `eas device:list`
|
||||
|
||||
@@ -948,7 +948,7 @@ DESCRIPTION
|
||||
list all registered devices for your account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/device/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/device/list.ts)_
|
||||
|
||||
## `eas device:rename`
|
||||
|
||||
@@ -969,7 +969,7 @@ DESCRIPTION
|
||||
rename a registered device
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/device/rename.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/device/rename.ts)_
|
||||
|
||||
## `eas device:view [UDID]`
|
||||
|
||||
@@ -983,7 +983,7 @@ DESCRIPTION
|
||||
view a device for your project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/device/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/device/view.ts)_
|
||||
|
||||
## `eas diagnostics`
|
||||
|
||||
@@ -997,7 +997,7 @@ DESCRIPTION
|
||||
display environment info
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/diagnostics.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/diagnostics.ts)_
|
||||
|
||||
## `eas env:create [ENVIRONMENT]`
|
||||
|
||||
@@ -1026,7 +1026,7 @@ DESCRIPTION
|
||||
create an environment variable for the current project or account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/create.ts)_
|
||||
|
||||
## `eas env:delete [ENVIRONMENT]`
|
||||
|
||||
@@ -1050,7 +1050,7 @@ DESCRIPTION
|
||||
delete an environment variable for the current project or account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/delete.ts)_
|
||||
|
||||
## `eas env:exec ENVIRONMENT BASH_COMMAND`
|
||||
|
||||
@@ -1071,7 +1071,7 @@ DESCRIPTION
|
||||
execute a command with environment variables from the selected environment
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/exec.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/exec.ts)_
|
||||
|
||||
## `eas env:get [ENVIRONMENT]`
|
||||
|
||||
@@ -1096,7 +1096,7 @@ DESCRIPTION
|
||||
view an environment variable for the current project or account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/get.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/get.ts)_
|
||||
|
||||
## `eas env:list [ENVIRONMENT]`
|
||||
|
||||
@@ -1121,7 +1121,7 @@ DESCRIPTION
|
||||
list environment variables for the current project or account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/list.ts)_
|
||||
|
||||
## `eas env:pull [ENVIRONMENT]`
|
||||
|
||||
@@ -1144,7 +1144,7 @@ DESCRIPTION
|
||||
pull environment variables for the selected environment to .env file
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/pull.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/pull.ts)_
|
||||
|
||||
## `eas env:push [ENVIRONMENT]`
|
||||
|
||||
@@ -1165,7 +1165,7 @@ DESCRIPTION
|
||||
push environment variables from .env file to the selected environment
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/push.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/push.ts)_
|
||||
|
||||
## `eas env:update [ENVIRONMENT]`
|
||||
|
||||
@@ -1196,7 +1196,7 @@ DESCRIPTION
|
||||
update an environment variable on the current project or account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/env/update.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/env/update.ts)_
|
||||
|
||||
## `eas help [COMMAND]`
|
||||
|
||||
@@ -1304,7 +1304,7 @@ DESCRIPTION
|
||||
validate the local store configuration
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/metadata/lint.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/metadata/lint.ts)_
|
||||
|
||||
## `eas metadata:pull`
|
||||
|
||||
@@ -1321,7 +1321,7 @@ DESCRIPTION
|
||||
generate the local store configuration from the app stores
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/metadata/pull.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/metadata/pull.ts)_
|
||||
|
||||
## `eas metadata:push`
|
||||
|
||||
@@ -1338,7 +1338,7 @@ DESCRIPTION
|
||||
sync the local store configuration to the app stores
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/metadata/push.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/metadata/push.ts)_
|
||||
|
||||
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
|
||||
|
||||
@@ -1368,7 +1368,7 @@ DESCRIPTION
|
||||
open the project page in a web browser
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/open.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/open.ts)_
|
||||
|
||||
## `eas project:info`
|
||||
|
||||
@@ -1382,7 +1382,7 @@ DESCRIPTION
|
||||
information about the current project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/project/info.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/project/info.ts)_
|
||||
|
||||
## `eas project:init`
|
||||
|
||||
@@ -1405,7 +1405,7 @@ ALIASES
|
||||
$ eas init
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/project/init.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/project/init.ts)_
|
||||
|
||||
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
|
||||
|
||||
@@ -1423,7 +1423,7 @@ ALIASES
|
||||
$ eas onboarding
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/project/onboarding.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/project/onboarding.ts)_
|
||||
|
||||
## `eas submit`
|
||||
|
||||
@@ -1454,7 +1454,7 @@ ALIASES
|
||||
$ eas build:submit
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/submit.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/submit.ts)_
|
||||
|
||||
## `eas update`
|
||||
|
||||
@@ -1496,7 +1496,7 @@ DESCRIPTION
|
||||
publish an update group
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/index.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/index.ts)_
|
||||
|
||||
## `eas update:configure`
|
||||
|
||||
@@ -1516,7 +1516,7 @@ DESCRIPTION
|
||||
configure the project to support EAS Update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/configure.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/configure.ts)_
|
||||
|
||||
## `eas update:delete GROUPID`
|
||||
|
||||
@@ -1537,7 +1537,7 @@ DESCRIPTION
|
||||
delete all the updates in an update group
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/delete.ts)_
|
||||
|
||||
## `eas update:edit [GROUPID]`
|
||||
|
||||
@@ -1561,7 +1561,7 @@ DESCRIPTION
|
||||
edit all the updates in an update group
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/edit.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/edit.ts)_
|
||||
|
||||
## `eas update:list`
|
||||
|
||||
@@ -1583,7 +1583,7 @@ DESCRIPTION
|
||||
view the recent updates
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/list.ts)_
|
||||
|
||||
## `eas update:republish`
|
||||
|
||||
@@ -1615,7 +1615,7 @@ DESCRIPTION
|
||||
roll back to an existing update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/republish.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/republish.ts)_
|
||||
|
||||
## `eas update:roll-back-to-embedded`
|
||||
|
||||
@@ -1623,12 +1623,11 @@ roll back to the embedded update
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas update:roll-back-to-embedded [--branch <value>] [--channel <value>] [--message <value>] [-p android|ios|all] [--auto]
|
||||
[--private-key-path <value>] [--json --non-interactive]
|
||||
$ eas update:roll-back-to-embedded [--branch <value>] [--channel <value>] [--runtime-version <value>] [--message <value>] [-p
|
||||
android|ios|all] [--private-key-path <value>] [--json --non-interactive]
|
||||
|
||||
FLAGS
|
||||
-p, --platform=(android|ios|all) [default: all]
|
||||
--auto Use the current git branch and commit message for the EAS branch and update message
|
||||
--branch=<value> Branch to publish the rollback to embedded update group on
|
||||
--channel=<value> Channel that the published rollback to embedded update should affect
|
||||
--json Enable JSON output, non-JSON messages will be printed to stderr.
|
||||
@@ -1638,12 +1637,13 @@ FLAGS
|
||||
expo-updates' configuration. Defaults to a file named "private-key.pem" in the
|
||||
certificate's directory. Only relevant if you are using code signing:
|
||||
https://docs.expo.dev/eas-update/code-signing/
|
||||
--runtime-version=<value> Runtime version that the rollback to embedded update should target
|
||||
|
||||
DESCRIPTION
|
||||
roll back to the embedded update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
|
||||
|
||||
## `eas update:rollback`
|
||||
|
||||
@@ -1663,7 +1663,7 @@ DESCRIPTION
|
||||
roll back to an embedded update or an existing update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/rollback.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/rollback.ts)_
|
||||
|
||||
## `eas update:view GROUPID`
|
||||
|
||||
@@ -1683,7 +1683,7 @@ DESCRIPTION
|
||||
update group details
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/update/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/update/view.ts)_
|
||||
|
||||
## `eas webhook:create`
|
||||
|
||||
@@ -1704,7 +1704,7 @@ DESCRIPTION
|
||||
create a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/webhook/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/webhook/create.ts)_
|
||||
|
||||
## `eas webhook:delete [ID]`
|
||||
|
||||
@@ -1724,7 +1724,7 @@ DESCRIPTION
|
||||
delete a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/webhook/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/webhook/delete.ts)_
|
||||
|
||||
## `eas webhook:list`
|
||||
|
||||
@@ -1742,7 +1742,7 @@ DESCRIPTION
|
||||
list webhooks
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/webhook/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/webhook/list.ts)_
|
||||
|
||||
## `eas webhook:update`
|
||||
|
||||
@@ -1764,7 +1764,7 @@ DESCRIPTION
|
||||
update a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/webhook/update.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/webhook/update.ts)_
|
||||
|
||||
## `eas webhook:view ID`
|
||||
|
||||
@@ -1781,7 +1781,7 @@ DESCRIPTION
|
||||
view a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/webhook/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/webhook/view.ts)_
|
||||
|
||||
## `eas whoami`
|
||||
|
||||
@@ -1816,7 +1816,7 @@ DESCRIPTION
|
||||
create a new workflow configuration YAML file
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/workflow/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/workflow/create.ts)_
|
||||
|
||||
## `eas workflow:run [FILE]`
|
||||
|
||||
@@ -1836,7 +1836,7 @@ DESCRIPTION
|
||||
Run an EAS workflow
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/workflow/run.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/workflow/run.ts)_
|
||||
|
||||
## `eas workflow:validate PATH`
|
||||
|
||||
@@ -1856,5 +1856,5 @@ DESCRIPTION
|
||||
validate a workflow configuration yaml file
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v13.4.2/packages/eas-cli/src/commands/workflow/validate.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v14.1.0/packages/eas-cli/src/commands/workflow/validate.ts)_
|
||||
<!-- commandsstop -->
|
||||
Generated
+96
@@ -4201,6 +4201,12 @@
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": [
|
||||
{
|
||||
"name": "PROFILE_IMAGE_UPLOAD",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "WORKFLOWS_PROJECT_SOURCES",
|
||||
"description": null,
|
||||
@@ -13381,6 +13387,23 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "ENUM",
|
||||
"name": "AppUploadSessionType",
|
||||
"description": null,
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": [
|
||||
{
|
||||
"name": "PROFILE_IMAGE_UPLOAD",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "AppVersion",
|
||||
@@ -19462,6 +19485,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "hasFingerprint",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "platform",
|
||||
"description": null,
|
||||
@@ -19577,6 +19612,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "hasFingerprint",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "platforms",
|
||||
"description": null,
|
||||
@@ -47717,6 +47764,55 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "createAppScopedUploadSession",
|
||||
"description": "Create an Upload Session for a specific app",
|
||||
"args": [
|
||||
{
|
||||
"name": "appID",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "ENUM",
|
||||
"name": "AppUploadSessionType",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "JSONObject",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "createUploadSession",
|
||||
"description": "Create an Upload Session",
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"name": "eas-cli",
|
||||
"description": "EAS command line tool",
|
||||
"version": "13.4.2",
|
||||
"version": "14.1.0",
|
||||
"author": "Expo <[email protected]>",
|
||||
"bin": {
|
||||
"eas": "./bin/run"
|
||||
},
|
||||
"bugs": "https://github.com/expo/eas-cli/issues",
|
||||
"dependencies": {
|
||||
"@expo/apple-utils": "2.1.0",
|
||||
"@expo/apple-utils": "2.1.5",
|
||||
"@expo/code-signing-certificates": "0.0.5",
|
||||
"@expo/config": "10.0.4",
|
||||
"@expo/config-plugins": "9.0.9",
|
||||
"@expo/eas-build-job": "1.0.149",
|
||||
"@expo/eas-json": "13.4.0",
|
||||
"@expo/config": "10.0.6",
|
||||
"@expo/config-plugins": "9.0.12",
|
||||
"@expo/eas-build-job": "1.0.151",
|
||||
"@expo/eas-json": "14.0.3",
|
||||
"@expo/env": "^0.4.0",
|
||||
"@expo/json-file": "8.3.3",
|
||||
"@expo/logger": "1.0.117",
|
||||
"@expo/multipart-body-parser": "1.1.0",
|
||||
"@expo/multipart-body-parser": "2.0.0",
|
||||
"@expo/osascript": "2.1.4",
|
||||
"@expo/package-manager": "1.6.1",
|
||||
"@expo/pkcs12": "0.1.3",
|
||||
@@ -28,7 +28,7 @@
|
||||
"@expo/results": "1.0.0",
|
||||
"@expo/rudder-sdk-node": "1.1.1",
|
||||
"@expo/spawn-async": "1.7.2",
|
||||
"@expo/steps": "1.0.150",
|
||||
"@expo/steps": "1.0.151",
|
||||
"@expo/timeago.js": "1.0.0",
|
||||
"@oclif/core": "^1.26.2",
|
||||
"@oclif/plugin-autocomplete": "^2.3.10",
|
||||
@@ -41,6 +41,7 @@
|
||||
"chalk": "4.1.2",
|
||||
"cli-progress": "3.12.0",
|
||||
"dateformat": "4.6.3",
|
||||
"diff": "7.0.0",
|
||||
"dotenv": "16.3.1",
|
||||
"env-paths": "2.2.0",
|
||||
"envinfo": "7.11.0",
|
||||
@@ -64,7 +65,7 @@
|
||||
"mime": "3.0.0",
|
||||
"minimatch": "5.1.2",
|
||||
"minizlib": "3.0.1",
|
||||
"nanoid": "3.3.4",
|
||||
"nanoid": "3.3.8",
|
||||
"node-fetch": "2.6.7",
|
||||
"node-forge": "1.3.1",
|
||||
"nullthrows": "1.1.1",
|
||||
@@ -96,6 +97,7 @@
|
||||
"@graphql-codegen/typescript-operations": "4.0.1",
|
||||
"@types/cli-progress": "3.11.5",
|
||||
"@types/dateformat": "3.0.1",
|
||||
"@types/diff": "6.0.0",
|
||||
"@types/envinfo": "7.8.3",
|
||||
"@types/express": "4.17.15",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
@@ -192,7 +194,7 @@
|
||||
},
|
||||
"warn-if-update-available": {
|
||||
"timeoutInDays": 0.5,
|
||||
"message": "<%= chalk('★') %> <%= chalk.bold(config.name + '@' + latest) %> <%= chalk.bold('is now available.') %>\n<%= chalk.dim('To upgrade, run ') %><%= chalk.dim(chalk.bold('npm install -g eas-cli')) %><%= chalk.dim('.') %>\n<%= chalk.dim('Proceeding with outdated version.') %>\n"
|
||||
"message": "<%= chalk('★') %> <%= chalk.bold(config.name + '@' + latest) %> <%= chalk.bold('is now available.') %>\n<%= chalk.dim('To upgrade, run:') %>\n<%= chalk.dim(chalk.bold('npm install -g eas-cli')) %>\n<%= chalk.dim('Proceeding with outdated version.') %>\n"
|
||||
},
|
||||
"update": {
|
||||
"node": {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import chalk from 'chalk';
|
||||
import { print } from 'graphql';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import { BranchNotFoundError } from './utils';
|
||||
@@ -8,10 +9,11 @@ import { withErrorHandlingAsync } from '../graphql/client';
|
||||
import {
|
||||
CreateUpdateBranchForAppMutation,
|
||||
CreateUpdateBranchForAppMutationVariables,
|
||||
UpdateBranch,
|
||||
UpdateBranchBasicInfoFragment,
|
||||
UpdateBranchFragment,
|
||||
} from '../graphql/generated';
|
||||
import { BranchQuery } from '../graphql/queries/BranchQuery';
|
||||
import { UpdateBranchBasicInfoFragmentNode } from '../graphql/types/UpdateBranchBasicInfo';
|
||||
import Log from '../log';
|
||||
import { formatBranch, getBranchDescription } from '../update/utils';
|
||||
import { printJsonOnlyOutput } from '../utils/json';
|
||||
@@ -126,7 +128,7 @@ function renderPageOfBranches(
|
||||
export async function createUpdateBranchOnAppAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
{ appId, name }: CreateUpdateBranchForAppMutationVariables
|
||||
): Promise<Pick<UpdateBranch, 'id' | 'name'>> {
|
||||
): Promise<UpdateBranchBasicInfoFragment> {
|
||||
const result = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<CreateUpdateBranchForAppMutation, CreateUpdateBranchForAppMutationVariables>(
|
||||
@@ -135,15 +137,17 @@ export async function createUpdateBranchOnAppAsync(
|
||||
updateBranch {
|
||||
createUpdateBranchForApp(appId: $appId, name: $name) {
|
||||
id
|
||||
name
|
||||
...UpdateBranchBasicInfoFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
${print(UpdateBranchBasicInfoFragmentNode)}
|
||||
`,
|
||||
{
|
||||
appId,
|
||||
name,
|
||||
}
|
||||
},
|
||||
{ additionalTypenames: ['UpdateBranch'] }
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
@@ -163,22 +167,21 @@ export async function ensureBranchExistsAsync(
|
||||
appId: string;
|
||||
branchName: string;
|
||||
}
|
||||
): Promise<{ branchId: string; createdBranch: boolean }> {
|
||||
): Promise<{ branch: UpdateBranchBasicInfoFragment; createdBranch: boolean }> {
|
||||
try {
|
||||
const updateBranch = await BranchQuery.getBranchByNameAsync(graphqlClient, {
|
||||
appId,
|
||||
name: branchName,
|
||||
});
|
||||
|
||||
const { id } = updateBranch;
|
||||
return { branchId: id, createdBranch: false };
|
||||
return { branch: updateBranch, createdBranch: false };
|
||||
} catch (error) {
|
||||
if (error instanceof BranchNotFoundError) {
|
||||
const newUpdateBranch = await createUpdateBranchOnAppAsync(graphqlClient, {
|
||||
appId,
|
||||
name: branchName,
|
||||
});
|
||||
return { branchId: newUpdateBranch.id, createdBranch: true };
|
||||
return { branch: newUpdateBranch, createdBranch: true };
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { Client } from '../vcs/vcs';
|
||||
|
||||
export async function getDefaultBranchNameAsync(vcsClient: Client): Promise<string> {
|
||||
return (
|
||||
(await vcsClient.getBranchNameAsync()) || `branch-${Math.random().toString(36).substring(2, 4)}`
|
||||
);
|
||||
export async function getDefaultBranchNameAsync(vcsClient: Client): Promise<string | null> {
|
||||
return await vcsClient.getBranchNameAsync();
|
||||
}
|
||||
|
||||
export class BranchNotFoundError extends Error {
|
||||
|
||||
@@ -5,7 +5,6 @@ import { vol } from 'memfs';
|
||||
import os from 'os';
|
||||
import type { XCBuildConfiguration } from 'xcode';
|
||||
|
||||
import { learnMore } from '../../../log';
|
||||
import { readPlistAsync } from '../../../utils/plist';
|
||||
import { resolveVcsClient } from '../../../vcs';
|
||||
import {
|
||||
@@ -301,27 +300,6 @@ describe(readShortVersionAsync, () => {
|
||||
);
|
||||
expect(buildNumber).toBe('1.0.0');
|
||||
});
|
||||
|
||||
it('fails when build number is invalid', async () => {
|
||||
const exp = initBareWorkflowProject({
|
||||
appVersion: '$(CURRENT_PROJECT_VERSION)',
|
||||
});
|
||||
|
||||
await expect(
|
||||
readShortVersionAsync(
|
||||
'/app',
|
||||
exp,
|
||||
{
|
||||
CURRENT_PROJECT_VERSION: '0.0.7.1.028',
|
||||
},
|
||||
vcsClient
|
||||
)
|
||||
).rejects.toThrowError(
|
||||
`The required format for "CFBundleShortVersionString" in Info.plist is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: 0.0.7.1.028. Edit the "CFBundleShortVersionString" in your Info.plist to match the required format. ${learnMore(
|
||||
'https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring'
|
||||
)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('managed project', () => {
|
||||
|
||||
@@ -109,14 +109,14 @@ function validateShortVersion({
|
||||
}): void {
|
||||
if (shortVersion && !SHORT_VERSION_REGEX.test(shortVersion)) {
|
||||
if (workflow === Workflow.MANAGED) {
|
||||
throw new Error(
|
||||
`The required format for "version" field from app.json/app.config.ts is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "version" field in your app.json/app.config.ts to match the required format. ${learnMore(
|
||||
Log.warn(
|
||||
`The required format for "version" field from app.json/app.config.ts for App Store iOS builds is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "version" field in your app.json/app.config.ts to match the format required by Apple. ${learnMore(
|
||||
'https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring'
|
||||
)}`
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
`The required format for "CFBundleShortVersionString" in Info.plist is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "CFBundleShortVersionString" in your Info.plist to match the required format. ${learnMore(
|
||||
Log.warn(
|
||||
`The required format for "CFBundleShortVersionString" in Info.plist for App Store iOS builds is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "CFBundleShortVersionString" in your Info.plist to match the format required by Apple. ${learnMore(
|
||||
'https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring'
|
||||
)}`
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ import Log from '../log';
|
||||
import { ora } from '../ora';
|
||||
|
||||
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
|
||||
const PLUGIN_PACKAGE_VERSION = '1.0.144';
|
||||
const PLUGIN_PACKAGE_VERSION = '1.0.152';
|
||||
|
||||
export enum LocalBuildMode {
|
||||
/**
|
||||
|
||||
@@ -27,24 +27,28 @@ export async function checkGoogleServicesFileAsync<T extends Platform>(
|
||||
if (!googleServicesFilePath) {
|
||||
return;
|
||||
}
|
||||
const googleServicesEnvVar =
|
||||
ctx.platform === Platform.ANDROID
|
||||
? ctx.env.GOOGLE_SERVICES_JSON
|
||||
: ctx.env.GOOGLE_SERVICES_INFO_PLIST;
|
||||
const rootDir = path.normalize(await ctx.vcsClient.getRootPathAsync());
|
||||
const absGoogleServicesFilePath = path.resolve(ctx.projectDir, googleServicesFilePath);
|
||||
if (
|
||||
(await fs.pathExists(absGoogleServicesFilePath)) &&
|
||||
(!isInsideDirectory(absGoogleServicesFilePath, rootDir) ||
|
||||
(await ctx.vcsClient.isFileIgnoredAsync(path.relative(rootDir, absGoogleServicesFilePath))))
|
||||
(await ctx.vcsClient.isFileIgnoredAsync(
|
||||
path.relative(rootDir, absGoogleServicesFilePath)
|
||||
))) &&
|
||||
!googleServicesEnvVar
|
||||
) {
|
||||
Log.warn(
|
||||
`File specified via "${ctx.platform}.googleServicesFile" field in your app.json is not checked in to your repository and won't be uploaded to the builder.`
|
||||
);
|
||||
Log.warn(
|
||||
`Use EAS Secret to pass all values that you don't want to include in your version control. ${learnMore(
|
||||
'https://docs.expo.dev/build-reference/variables/#using-secrets-in-environment-variables'
|
||||
`Use EAS file environment variables with secret or sensitive visibility to pass all values that you don't want to include in your version control to build process. ${learnMore(
|
||||
'https://docs.expo.dev/eas/environment-variables/#file-environment-variables'
|
||||
)}`
|
||||
);
|
||||
Log.warn(
|
||||
`If you are using that file for compatibility with the classic build service (expo build) you can silence this warning by setting your build profile's env.GOOGLE_SERVICES_FILE in eas.json to any non-empty string.`
|
||||
);
|
||||
Log.newLine();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
import { BranchQuery, UpdateBranchOnChannelObject } from '../graphql/queries/BranchQuery';
|
||||
import { ChannelQuery, UpdateChannelObject } from '../graphql/queries/ChannelQuery';
|
||||
import { UpdateChannelBasicInfoFragmentNode } from '../graphql/types/UpdateChannelBasicInfo';
|
||||
import Log from '../log';
|
||||
import Log, { learnMore } from '../log';
|
||||
import { getDisplayNameForProjectIdAsync } from '../project/projectUtils';
|
||||
import formatFields from '../utils/formatFields';
|
||||
import { printJsonOnlyOutput } from '../utils/json';
|
||||
@@ -303,7 +303,6 @@ export async function doesChannelExistAsync(
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Creates a channel and links it to a branch with the same name.
|
||||
*
|
||||
* @param appId the app ID, also known as the project ID
|
||||
@@ -319,7 +318,7 @@ export async function createAndLinkChannelAsync(
|
||||
}: { appId: string; channelName: string; shouldPrintJson?: boolean }
|
||||
): Promise<ChannelBasicInfo> {
|
||||
let branchId: string;
|
||||
let branchMessage: string;
|
||||
let hasCreatedBranch = false;
|
||||
|
||||
try {
|
||||
const branch = await BranchQuery.getBranchByNameAsync(graphqlClient, {
|
||||
@@ -327,7 +326,6 @@ export async function createAndLinkChannelAsync(
|
||||
name: channelName,
|
||||
});
|
||||
branchId = branch.id;
|
||||
branchMessage = `We found a branch with the same name`;
|
||||
} catch (error) {
|
||||
if (error instanceof BranchNotFoundError) {
|
||||
const newBranch = await createUpdateBranchOnAppAsync(graphqlClient, {
|
||||
@@ -335,7 +333,7 @@ export async function createAndLinkChannelAsync(
|
||||
name: channelName,
|
||||
});
|
||||
branchId = newBranch.id;
|
||||
branchMessage = `We also went ahead and made a branch with the same name`;
|
||||
hasCreatedBranch = true;
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
@@ -358,26 +356,25 @@ export async function createAndLinkChannelAsync(
|
||||
if (shouldPrintJson) {
|
||||
printJsonOnlyOutput(newChannel);
|
||||
} else {
|
||||
const projectDisplayName = await getDisplayNameForProjectIdAsync(graphqlClient, appId);
|
||||
const learnMoreLink = learnMore('https://docs.expo.dev/eas-update/eas-cli/');
|
||||
|
||||
Log.addNewLineIfNone();
|
||||
Log.withTick(
|
||||
`Created a new channel on project ${chalk.bold(
|
||||
await getDisplayNameForProjectIdAsync(graphqlClient, appId)
|
||||
)}`
|
||||
);
|
||||
Log.log(
|
||||
formatFields([
|
||||
{ label: 'Name', value: newChannel.name },
|
||||
{ label: 'ID', value: newChannel.id },
|
||||
])
|
||||
);
|
||||
Log.addNewLineIfNone();
|
||||
Log.withTick(`${branchMessage} and have pointed the channel at it.`);
|
||||
Log.log(
|
||||
formatFields([
|
||||
{ label: 'Name', value: newChannel.name },
|
||||
{ label: 'ID', value: branchId },
|
||||
])
|
||||
);
|
||||
if (hasCreatedBranch) {
|
||||
Log.withTick(
|
||||
`Created update channel ${chalk.bold(`"${newChannel.name}"`)} and branch ${chalk.bold(
|
||||
`"${newChannel.name}"`
|
||||
)} on ${chalk.bold(projectDisplayName)} project. ${learnMoreLink}`
|
||||
);
|
||||
} else {
|
||||
Log.withTick(
|
||||
`Created update channel ${chalk.bold(`"${newChannel.name}"`)} on ${chalk.bold(
|
||||
projectDisplayName
|
||||
)} project and connected it with existing ${chalk.bold(
|
||||
`"${newChannel.name}"`
|
||||
)} branch. ${learnMoreLink}`
|
||||
);
|
||||
}
|
||||
}
|
||||
return newChannel;
|
||||
}
|
||||
@@ -38,7 +38,12 @@ export async function fetchBuildsAsync({
|
||||
}: {
|
||||
graphqlClient: ExpoGraphqlClient;
|
||||
projectId: string;
|
||||
filters?: { statuses?: BuildStatus[]; platform?: RequestedPlatform; profile?: string };
|
||||
filters?: {
|
||||
statuses?: BuildStatus[];
|
||||
platform?: RequestedPlatform;
|
||||
profile?: string;
|
||||
hasFingerprint?: boolean;
|
||||
};
|
||||
}): Promise<BuildFragment[]> {
|
||||
let builds: BuildFragment[];
|
||||
const queryFilters: InputMaybe<BuildFilter> = {};
|
||||
@@ -48,6 +53,9 @@ export async function fetchBuildsAsync({
|
||||
if (filters?.profile) {
|
||||
queryFilters['buildProfile'] = filters.profile;
|
||||
}
|
||||
if (filters?.hasFingerprint) {
|
||||
queryFilters['hasFingerprint'] = filters.hasFingerprint;
|
||||
}
|
||||
if (!filters?.statuses) {
|
||||
builds = await BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
|
||||
@@ -58,7 +58,7 @@ export default class BranchCreate extends EasCommand {
|
||||
type: 'text',
|
||||
name: 'name',
|
||||
message: 'Provide a branch name:',
|
||||
initial: await getDefaultBranchNameAsync(vcsClient),
|
||||
initial: (await getDefaultBranchNameAsync(vcsClient)) ?? undefined,
|
||||
validate: value => (value ? true : validationMessage),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
import { Platform } from '@expo/eas-build-job';
|
||||
import { Flags } from '@oclif/core';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { fetchBuildsAsync, formatBuild } from '../../commandUtils/builds';
|
||||
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
|
||||
import { AppPlatform, BuildStatus } from '../../graphql/generated';
|
||||
import { BuildQuery } from '../../graphql/queries/BuildQuery';
|
||||
import Log from '../../log';
|
||||
import { ora } from '../../ora';
|
||||
import { RequestedPlatform } from '../../platform';
|
||||
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
|
||||
import { resolveWorkflowPerPlatformAsync } from '../../project/workflow';
|
||||
import { selectAsync } from '../../prompts';
|
||||
import { Fingerprint, FingerprintDiffItem } from '../../utils/fingerprint';
|
||||
import { createFingerprintAsync, diffFingerprint } from '../../utils/fingerprintCli';
|
||||
import { abridgedDiff } from '../../utils/fingerprintDiff';
|
||||
import formatFields, { FormatFieldsItem } from '../../utils/formatFields';
|
||||
import { enableJsonOutput } from '../../utils/json';
|
||||
|
||||
export default class FingerprintCompare extends EasCommand {
|
||||
static override description = 'compare fingerprints of the current project, builds and updates';
|
||||
static override hidden = true;
|
||||
|
||||
static override flags = {
|
||||
'build-id': Flags.string({
|
||||
aliases: ['buildId'],
|
||||
description: 'Compare the fingerprint with the build with the specified ID',
|
||||
}),
|
||||
...EasNonInteractiveAndJsonFlags,
|
||||
};
|
||||
|
||||
static override contextDefinition = {
|
||||
...this.ContextOptions.ProjectId,
|
||||
...this.ContextOptions.ProjectConfig,
|
||||
...this.ContextOptions.LoggedIn,
|
||||
...this.ContextOptions.Vcs,
|
||||
};
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = await this.parse(FingerprintCompare);
|
||||
const { json: jsonFlag, 'non-interactive': nonInteractive, buildId: buildIdFromArg } = flags;
|
||||
|
||||
const {
|
||||
projectId,
|
||||
privateProjectConfig: { projectDir },
|
||||
loggedIn: { graphqlClient },
|
||||
vcsClient,
|
||||
} = await this.getContextAsync(FingerprintCompare, {
|
||||
nonInteractive,
|
||||
withServerSideEnvironment: null,
|
||||
});
|
||||
if (jsonFlag) {
|
||||
enableJsonOutput();
|
||||
}
|
||||
|
||||
const displayName = await getDisplayNameForProjectIdAsync(graphqlClient, projectId);
|
||||
let buildId: string | null = buildIdFromArg;
|
||||
if (!buildId) {
|
||||
if (nonInteractive) {
|
||||
throw new Error('Build ID must be provided in non-interactive mode');
|
||||
}
|
||||
|
||||
buildId = await selectBuildToCompareAsync(graphqlClient, projectId, displayName, {
|
||||
filters: { hasFingerprint: true },
|
||||
});
|
||||
if (!buildId) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Log.log(`Comparing fingerprints of the current project and build ${buildId}…`);
|
||||
const buildWithFingerprint = await BuildQuery.withFingerprintByIdAsync(graphqlClient, buildId);
|
||||
const fingerprintDebugUrl = buildWithFingerprint.fingerprint?.debugInfoUrl;
|
||||
if (!fingerprintDebugUrl) {
|
||||
Log.error('A fingerprint for the build could not be found.');
|
||||
return;
|
||||
}
|
||||
const fingerprintResponse = await fetch(fingerprintDebugUrl);
|
||||
const fingerprint = (await fingerprintResponse.json()) as Fingerprint;
|
||||
const workflows = await resolveWorkflowPerPlatformAsync(projectDir, vcsClient);
|
||||
const buildPlatform = buildWithFingerprint.platform;
|
||||
const workflow = workflows[appPlatformToPlatform(buildPlatform)];
|
||||
|
||||
const projectFingerprint = await createFingerprintAsync(projectDir, {
|
||||
workflow,
|
||||
platforms: [appPlatformToString(buildPlatform)],
|
||||
debug: true,
|
||||
env: undefined,
|
||||
});
|
||||
if (!projectFingerprint) {
|
||||
Log.error('Project fingerprints can only be computed for projects with SDK 52 or higher');
|
||||
return;
|
||||
}
|
||||
if (fingerprint.hash === projectFingerprint.hash) {
|
||||
Log.log(`✅ Project fingerprint matches build`);
|
||||
return;
|
||||
} else {
|
||||
Log.log(`🔄 Project fingerprint differs from build`);
|
||||
}
|
||||
|
||||
const fingerprintDiffs = diffFingerprint(projectDir, fingerprint, projectFingerprint);
|
||||
if (!fingerprintDiffs) {
|
||||
Log.error('Fingerprint diffs can only be computed for projects with SDK 52 or higher');
|
||||
return;
|
||||
}
|
||||
|
||||
const filePathDiffs = fingerprintDiffs.filter(diff => {
|
||||
let sourceType;
|
||||
if (diff.op === 'added') {
|
||||
sourceType = diff.addedSource.type;
|
||||
} else if (diff.op === 'removed') {
|
||||
sourceType = diff.removedSource.type;
|
||||
} else if (diff.op === 'changed') {
|
||||
sourceType = diff.beforeSource.type;
|
||||
}
|
||||
return sourceType === 'dir' || sourceType === 'file';
|
||||
});
|
||||
if (filePathDiffs.length > 0) {
|
||||
Log.newLine();
|
||||
Log.log('📁 Paths with native dependencies:');
|
||||
}
|
||||
const fields = [];
|
||||
for (const diff of filePathDiffs) {
|
||||
const field = getDiffFilePathFields(diff);
|
||||
if (!field) {
|
||||
throw new Error(`Unsupported diff: ${JSON.stringify(diff)}`);
|
||||
}
|
||||
fields.push(field);
|
||||
}
|
||||
Log.log(
|
||||
formatFields(fields, {
|
||||
labelFormat: label => ` ${chalk.dim(label)}:`,
|
||||
})
|
||||
);
|
||||
|
||||
const contentDiffs = fingerprintDiffs.filter(diff => {
|
||||
let sourceType;
|
||||
if (diff.op === 'added') {
|
||||
sourceType = diff.addedSource.type;
|
||||
} else if (diff.op === 'removed') {
|
||||
sourceType = diff.removedSource.type;
|
||||
} else if (diff.op === 'changed') {
|
||||
sourceType = diff.beforeSource.type;
|
||||
}
|
||||
return sourceType === 'contents';
|
||||
});
|
||||
|
||||
for (const diff of contentDiffs) {
|
||||
printContentDiff(diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function printContentDiff(diff: FingerprintDiffItem): void {
|
||||
if (diff.op === 'added') {
|
||||
const sourceType = diff.addedSource.type;
|
||||
if (sourceType === 'contents') {
|
||||
printContentSource({
|
||||
op: diff.op,
|
||||
sourceType,
|
||||
contentsId: diff.addedSource.id,
|
||||
contentsAfter: diff.addedSource.contents,
|
||||
});
|
||||
}
|
||||
} else if (diff.op === 'removed') {
|
||||
const sourceType = diff.removedSource.type;
|
||||
if (sourceType === 'contents') {
|
||||
printContentSource({
|
||||
op: diff.op,
|
||||
sourceType,
|
||||
contentsId: diff.removedSource.id,
|
||||
contentsBefore: diff.removedSource.contents,
|
||||
});
|
||||
}
|
||||
} else if (diff.op === 'changed') {
|
||||
const sourceType = diff.beforeSource.type;
|
||||
if (sourceType === 'contents') {
|
||||
if (diff.afterSource.type !== 'contents') {
|
||||
throw new Error(
|
||||
`Changed fingerprint source types must be the same, received ${diff.beforeSource.type}, ${diff.afterSource.type}`
|
||||
);
|
||||
}
|
||||
printContentSource({
|
||||
op: diff.op,
|
||||
sourceType: diff.beforeSource.type, // before and after source types should be the same
|
||||
contentsId: diff.beforeSource.id, // before and after content ids should be the same
|
||||
contentsBefore: diff.beforeSource.contents,
|
||||
contentsAfter: diff.afterSource.contents,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getDiffFilePathFields(diff: FingerprintDiffItem): FormatFieldsItem | null {
|
||||
if (diff.op === 'added') {
|
||||
const sourceType = diff.addedSource.type;
|
||||
if (sourceType !== 'contents') {
|
||||
return getFilePathSourceFields({
|
||||
op: diff.op,
|
||||
sourceType,
|
||||
filePath: diff.addedSource.filePath,
|
||||
});
|
||||
}
|
||||
} else if (diff.op === 'removed') {
|
||||
const sourceType = diff.removedSource.type;
|
||||
if (sourceType !== 'contents') {
|
||||
return getFilePathSourceFields({
|
||||
op: diff.op,
|
||||
sourceType,
|
||||
filePath: diff.removedSource.filePath,
|
||||
});
|
||||
}
|
||||
} else if (diff.op === 'changed') {
|
||||
const sourceType = diff.beforeSource.type;
|
||||
if (sourceType !== 'contents') {
|
||||
return getFilePathSourceFields({
|
||||
op: diff.op,
|
||||
sourceType: diff.beforeSource.type, // before and after source types should be the same
|
||||
filePath: diff.beforeSource.filePath, // before and after filePaths should be the same
|
||||
});
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getFilePathSourceFields({
|
||||
op,
|
||||
sourceType,
|
||||
filePath,
|
||||
}: {
|
||||
op: 'added' | 'removed' | 'changed';
|
||||
sourceType: 'dir' | 'file';
|
||||
filePath: string;
|
||||
}): FormatFieldsItem {
|
||||
if (sourceType === 'dir') {
|
||||
if (op === 'added') {
|
||||
return { label: 'new directory', value: filePath };
|
||||
} else if (op === 'removed') {
|
||||
return { label: 'removed directory', value: filePath };
|
||||
} else if (op === 'changed') {
|
||||
return { label: 'modified directory', value: filePath };
|
||||
}
|
||||
} else if (sourceType === 'file') {
|
||||
if (op === 'added') {
|
||||
return { label: 'new file', value: filePath };
|
||||
} else if (op === 'removed') {
|
||||
return { label: 'removed file', value: filePath };
|
||||
} else if (op === 'changed') {
|
||||
return { label: 'modified file', value: filePath };
|
||||
}
|
||||
}
|
||||
throw new Error(`Unsupported source and op: ${sourceType}, ${op}`);
|
||||
}
|
||||
|
||||
const PRETTY_CONTENT_ID: Record<string, string> = {
|
||||
'expoAutolinkingConfig:ios': 'Expo autolinking config (iOS)',
|
||||
'expoAutolinkingConfig:android': 'Expo autolinking config (Android)',
|
||||
'packageJson:scripts': 'package.json scripts',
|
||||
expoConfig: 'Expo config',
|
||||
};
|
||||
|
||||
function printContentSource({
|
||||
op,
|
||||
contentsBefore,
|
||||
contentsAfter,
|
||||
contentsId,
|
||||
}: {
|
||||
op: 'added' | 'removed' | 'changed';
|
||||
sourceType: 'contents';
|
||||
contentsBefore?: string | Buffer;
|
||||
contentsAfter?: string | Buffer;
|
||||
contentsId: string;
|
||||
}): void {
|
||||
Log.newLine();
|
||||
const prettyContentId = PRETTY_CONTENT_ID[contentsId] ?? contentsId;
|
||||
if (op === 'added') {
|
||||
Log.log(`${chalk.dim('📝 New content')}: ${prettyContentId}`);
|
||||
} else if (op === 'removed') {
|
||||
Log.log(`${chalk.dim('📝 Removed content')}: ${prettyContentId}`);
|
||||
} else if (op === 'changed') {
|
||||
Log.log(`${chalk.dim('📝 Modified content')}: ${prettyContentId}`);
|
||||
}
|
||||
printContentsDiff(contentsBefore ?? '', contentsAfter ?? '');
|
||||
}
|
||||
|
||||
function printContentsDiff(contents1: string | Buffer, contents2: string | Buffer): void {
|
||||
const stringifiedContents1 = Buffer.isBuffer(contents1) ? contents1.toString() : contents1;
|
||||
const stringifiedContents2 = Buffer.isBuffer(contents2) ? contents2.toString() : contents2;
|
||||
|
||||
const isStr1JSON = isJSON(stringifiedContents1);
|
||||
const isStr2JSON = isJSON(stringifiedContents2);
|
||||
|
||||
const prettifiedContents1 = isStr1JSON
|
||||
? JSON.stringify(JSON.parse(stringifiedContents1), null, 2)
|
||||
: stringifiedContents1;
|
||||
const prettifiedContents2 = isStr2JSON
|
||||
? JSON.stringify(JSON.parse(stringifiedContents2), null, 2)
|
||||
: stringifiedContents2;
|
||||
|
||||
abridgedDiff(prettifiedContents1, prettifiedContents2, 0);
|
||||
}
|
||||
|
||||
function isJSON(str: string): boolean {
|
||||
try {
|
||||
JSON.parse(str);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function appPlatformToPlatform(platform: AppPlatform): Platform {
|
||||
switch (platform) {
|
||||
case AppPlatform.Android:
|
||||
return Platform.ANDROID;
|
||||
case AppPlatform.Ios:
|
||||
return Platform.IOS;
|
||||
default:
|
||||
throw new Error(`Unsupported platform: ${platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
function appPlatformToString(platform: AppPlatform): string {
|
||||
switch (platform) {
|
||||
case AppPlatform.Android:
|
||||
return 'android';
|
||||
case AppPlatform.Ios:
|
||||
return 'ios';
|
||||
default:
|
||||
throw new Error(`Unsupported platform: ${platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
export async function selectBuildToCompareAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
projectId: string,
|
||||
projectDisplayName: string,
|
||||
{
|
||||
filters,
|
||||
}: {
|
||||
filters?: {
|
||||
statuses?: BuildStatus[];
|
||||
platform?: RequestedPlatform;
|
||||
profile?: string;
|
||||
hasFingerprint?: boolean;
|
||||
};
|
||||
} = {}
|
||||
): Promise<string | null> {
|
||||
const spinner = ora().start('Fetching builds…');
|
||||
|
||||
let builds;
|
||||
try {
|
||||
builds = await fetchBuildsAsync({ graphqlClient, projectId, filters });
|
||||
spinner.stop();
|
||||
} catch (error) {
|
||||
spinner.fail(
|
||||
`Something went wrong and we couldn't fetch the builds for the project ${projectDisplayName}.`
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
if (builds.length === 0) {
|
||||
Log.warn(`No fingerprints have been computed for builds of project ${projectDisplayName}.`);
|
||||
return null;
|
||||
} else {
|
||||
const build = await selectAsync<string>(
|
||||
'Which build do you want to compare?',
|
||||
builds.map(build => ({
|
||||
title: formatBuild(build),
|
||||
value: build.id,
|
||||
}))
|
||||
);
|
||||
|
||||
return build;
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,10 @@ describe(UpdatePublish.name, () => {
|
||||
const { platforms, runtimeVersion } = mockTestExport();
|
||||
|
||||
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
|
||||
branchId: 'branch123',
|
||||
branch: {
|
||||
id: 'branch123',
|
||||
name: 'wat',
|
||||
},
|
||||
createdBranch: false,
|
||||
});
|
||||
|
||||
@@ -111,7 +114,10 @@ describe(UpdatePublish.name, () => {
|
||||
.mocked(getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync)
|
||||
.mockResolvedValue({ branchId: 'branch123', branchName: 'branchFromChannel' });
|
||||
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
|
||||
branchId: 'branch123',
|
||||
branch: {
|
||||
id: 'branch123',
|
||||
name: 'wat',
|
||||
},
|
||||
createdBranch: false,
|
||||
});
|
||||
|
||||
@@ -146,7 +152,10 @@ describe(UpdatePublish.name, () => {
|
||||
|
||||
// Mock an existing branch, so we don't create a new one
|
||||
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
|
||||
branchId: 'branch123',
|
||||
branch: {
|
||||
id: 'branch123',
|
||||
name: 'wat',
|
||||
},
|
||||
createdBranch: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { AppJSONConfig, ExpoConfig, PackageJSONConfig, getConfig } from '@expo/config';
|
||||
import { Updates } from '@expo/config-plugins';
|
||||
import { vol } from 'memfs';
|
||||
import nullthrows from 'nullthrows';
|
||||
import path from 'path';
|
||||
@@ -82,16 +81,23 @@ describe(UpdateRollBackToEmbedded.name, () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('creates a roll back to embedded with --non-interactive, --branch, and --message', async () => {
|
||||
const flags = ['--non-interactive', '--branch=branch123', '--message=abc'];
|
||||
it('creates a roll back to embedded with --non-interactive, --branch, --message, and --runtime-version', async () => {
|
||||
const flags = [
|
||||
'--non-interactive',
|
||||
'--branch=branch123',
|
||||
'--message=abc',
|
||||
'--runtime-version=exposdk:47.0.0',
|
||||
];
|
||||
|
||||
mockTestProject();
|
||||
const platforms = ['android', 'ios'];
|
||||
const runtimeVersion = 'exposdk:47.0.0';
|
||||
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
|
||||
|
||||
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
|
||||
branchId: 'branch123',
|
||||
branch: {
|
||||
id: 'branch123',
|
||||
name: 'wat',
|
||||
},
|
||||
createdBranch: false,
|
||||
});
|
||||
|
||||
@@ -104,19 +110,26 @@ describe(UpdateRollBackToEmbedded.name, () => {
|
||||
expect(PublishMutation.publishUpdateGroupAsync).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('creates a roll back to embedded with --non-interactive, --channel, and --message', async () => {
|
||||
const flags = ['--non-interactive', '--channel=channel123', '--message=abc'];
|
||||
it('creates a roll back to embedded with --non-interactive, --channel, --message, and --runtime-version', async () => {
|
||||
const flags = [
|
||||
'--non-interactive',
|
||||
'--channel=channel123',
|
||||
'--message=abc',
|
||||
'--runtime-version=exposdk:47.0.0',
|
||||
];
|
||||
|
||||
const { projectId } = mockTestProject();
|
||||
const platforms = ['android', 'ios'];
|
||||
const runtimeVersion = 'exposdk:47.0.0';
|
||||
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
|
||||
|
||||
jest
|
||||
.mocked(getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync)
|
||||
.mockResolvedValue({ branchId: updateStub.branch.id, branchName: 'branchFromChannel' });
|
||||
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
|
||||
branchId: 'branch123',
|
||||
branch: {
|
||||
id: 'branch123',
|
||||
name: 'wat',
|
||||
},
|
||||
createdBranch: false,
|
||||
});
|
||||
|
||||
@@ -142,18 +155,25 @@ describe(UpdateRollBackToEmbedded.name, () => {
|
||||
});
|
||||
|
||||
it('creates a roll back to embedded with the public expo config', async () => {
|
||||
const flags = ['--non-interactive', '--branch=branch123', '--message=abc'];
|
||||
const flags = [
|
||||
'--non-interactive',
|
||||
'--branch=branch123',
|
||||
'--message=abc',
|
||||
'--runtime-version=exposdk:47.0.0',
|
||||
];
|
||||
|
||||
// Add configuration to the project that should not be included in the update
|
||||
mockTestProject();
|
||||
|
||||
const platforms = ['ios'];
|
||||
const runtimeVersion = 'exposdk:47.0.0';
|
||||
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
|
||||
|
||||
// Mock an existing branch, so we don't create a new one
|
||||
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
|
||||
branchId: 'branch123',
|
||||
branch: {
|
||||
id: 'branch123',
|
||||
name: 'wat',
|
||||
},
|
||||
createdBranch: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -400,7 +400,7 @@ export default class UpdatePublish extends EasCommand {
|
||||
runtimeVersionInfoObjects
|
||||
);
|
||||
|
||||
const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
|
||||
const { branch } = await ensureBranchExistsAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
branchName,
|
||||
});
|
||||
@@ -482,7 +482,7 @@ export default class UpdatePublish extends EasCommand {
|
||||
);
|
||||
|
||||
return {
|
||||
branchId,
|
||||
branchId: branch.id,
|
||||
updateInfoGroup: localUpdateInfoGroup,
|
||||
rolloutInfoGroup: localRolloutInfoGroup,
|
||||
runtimeFingerprintSource: fingerprintSource
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Platform as PublishPlatform } from '@expo/config';
|
||||
import { Workflow } from '@expo/eas-build-job';
|
||||
import { Errors, Flags } from '@oclif/core';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
@@ -12,10 +11,12 @@ import { getPaginatedQueryOptions } from '../../commandUtils/pagination';
|
||||
import fetch from '../../fetch';
|
||||
import {
|
||||
PublishUpdateGroupInput,
|
||||
RuntimeFragment,
|
||||
StatuspageServiceName,
|
||||
UpdatePublishMutation,
|
||||
} from '../../graphql/generated';
|
||||
import { PublishMutation } from '../../graphql/mutations/PublishMutation';
|
||||
import { RuntimeQuery } from '../../graphql/queries/RuntimeQuery';
|
||||
import Log, { link } from '../../log';
|
||||
import { ora } from '../../ora';
|
||||
import { RequestedPlatform } from '../../platform';
|
||||
@@ -29,10 +30,8 @@ import {
|
||||
defaultPublishPlatforms,
|
||||
getBranchNameForCommandAsync,
|
||||
getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects,
|
||||
getRuntimeVersionInfoObjectsAsync,
|
||||
getUpdateMessageForCommandAsync,
|
||||
} from '../../project/publish';
|
||||
import { resolveWorkflowPerPlatformAsync } from '../../project/workflow';
|
||||
import { ensureEASUpdateIsConfiguredAsync } from '../../update/configure';
|
||||
import { getUpdateJsonInfosForUpdates } from '../../update/utils';
|
||||
import {
|
||||
@@ -45,12 +44,13 @@ import {
|
||||
import uniqBy from '../../utils/expodash/uniqBy';
|
||||
import formatFields from '../../utils/formatFields';
|
||||
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
|
||||
import { Connection, QueryParams, selectPaginatedAsync } from '../../utils/relay';
|
||||
import { maybeWarnAboutEasOutagesAsync } from '../../utils/statuspageService';
|
||||
|
||||
type RawUpdateFlags = {
|
||||
auto: boolean;
|
||||
branch?: string;
|
||||
channel?: string;
|
||||
'runtime-version'?: string;
|
||||
message?: string;
|
||||
platform: string;
|
||||
'private-key-path'?: string;
|
||||
@@ -59,10 +59,10 @@ type RawUpdateFlags = {
|
||||
};
|
||||
|
||||
type UpdateFlags = {
|
||||
auto: boolean;
|
||||
platform: RequestedPlatform;
|
||||
branchName?: string;
|
||||
channelName?: string;
|
||||
runtimeVersion?: string;
|
||||
updateMessage?: string;
|
||||
privateKeyPath?: string;
|
||||
json: boolean;
|
||||
@@ -81,6 +81,10 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
description: 'Channel that the published rollback to embedded update should affect',
|
||||
required: false,
|
||||
}),
|
||||
'runtime-version': Flags.string({
|
||||
description: 'Runtime version that the rollback to embedded update should target',
|
||||
required: false,
|
||||
}),
|
||||
message: Flags.string({
|
||||
description: 'A short message describing the rollback to embedded update',
|
||||
required: false,
|
||||
@@ -95,11 +99,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
default: 'all',
|
||||
required: false,
|
||||
}),
|
||||
auto: Flags.boolean({
|
||||
description:
|
||||
'Use the current git branch and commit message for the EAS branch and update message',
|
||||
default: false,
|
||||
}),
|
||||
'private-key-path': Flags.string({
|
||||
description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory. Only relevant if you are using code signing: https://docs.expo.dev/eas-update/code-signing/`,
|
||||
required: false,
|
||||
@@ -117,10 +116,10 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
const { flags: rawFlags } = await this.parse(UpdateRollBackToEmbedded);
|
||||
const paginatedQueryOptions = getPaginatedQueryOptions(rawFlags);
|
||||
const {
|
||||
auto: autoFlag,
|
||||
platform: platformFlag,
|
||||
channelName: channelNameArg,
|
||||
updateMessage: updateMessageArg,
|
||||
runtimeVersion: runtimeVersionArg,
|
||||
privateKeyPath,
|
||||
json: jsonFlag,
|
||||
nonInteractive,
|
||||
@@ -171,14 +170,14 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
projectId,
|
||||
channelNameArg,
|
||||
branchNameArg,
|
||||
autoFlag,
|
||||
autoFlag: false,
|
||||
nonInteractive,
|
||||
paginatedQueryOptions,
|
||||
});
|
||||
|
||||
const updateMessage = await getUpdateMessageForCommandAsync(vcsClient, {
|
||||
updateMessageArg,
|
||||
autoFlag,
|
||||
autoFlag: false,
|
||||
nonInteractive,
|
||||
jsonFlag,
|
||||
});
|
||||
@@ -186,28 +185,33 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
const realizedPlatforms: UpdatePublishPlatform[] =
|
||||
platformFlag === 'all' ? defaultPublishPlatforms : [platformFlag];
|
||||
|
||||
const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
|
||||
const { branch } = await ensureBranchExistsAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
branchName,
|
||||
});
|
||||
|
||||
const gitCommitHash = await vcsClient.getCommitHashAsync();
|
||||
const isGitWorkingTreeDirty = await vcsClient.hasUncommittedChangesAsync();
|
||||
const selectedRuntime =
|
||||
runtimeVersionArg ??
|
||||
(
|
||||
await UpdateRollBackToEmbedded.selectRuntimeAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
branchName,
|
||||
})
|
||||
)?.version;
|
||||
if (!selectedRuntime) {
|
||||
Errors.error('Must select a runtime or provide the --runtimeVersion flag', { exit: 1 });
|
||||
}
|
||||
|
||||
const workflows = await resolveWorkflowPerPlatformAsync(projectDir, vcsClient);
|
||||
const runtimeVersionInfoObjects = await getRuntimeVersionInfoObjectsAsync({
|
||||
exp,
|
||||
platforms: realizedPlatforms,
|
||||
projectDir,
|
||||
workflows: {
|
||||
...workflows,
|
||||
web: Workflow.UNKNOWN,
|
||||
},
|
||||
env: undefined,
|
||||
});
|
||||
const runtimeToPlatformsAndFingerprintInfoMapping =
|
||||
getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects(
|
||||
runtimeVersionInfoObjects
|
||||
realizedPlatforms.map(platform => ({
|
||||
platform,
|
||||
runtimeVersionInfo: {
|
||||
runtimeVersion: selectedRuntime,
|
||||
fingerprint: null,
|
||||
fingerprintHash: null,
|
||||
},
|
||||
}))
|
||||
);
|
||||
|
||||
let newUpdates: UpdatePublishMutation['updateBranch']['publishUpdateGroups'];
|
||||
@@ -215,10 +219,8 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
try {
|
||||
newUpdates = await this.publishRollbacksAsync({
|
||||
graphqlClient,
|
||||
isGitWorkingTreeDirty,
|
||||
gitCommitHash,
|
||||
updateMessage,
|
||||
branchId,
|
||||
branchId: branch.id,
|
||||
codeSigningInfo,
|
||||
runtimeToPlatformsAndFingerprintInfoMapping,
|
||||
realizedPlatforms,
|
||||
@@ -232,13 +234,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
if (jsonFlag) {
|
||||
printJsonOnlyOutput(getUpdateJsonInfosForUpdates(newUpdates));
|
||||
} else {
|
||||
if (new Set(newUpdates.map(update => update.group)).size > 1) {
|
||||
Log.addNewLineIfNone();
|
||||
Log.log(
|
||||
'👉 Since multiple runtime versions are defined, multiple update groups have been published.'
|
||||
);
|
||||
}
|
||||
|
||||
Log.addNewLineIfNone();
|
||||
|
||||
for (const runtime of uniqBy(
|
||||
@@ -276,14 +271,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
: []),
|
||||
...(newIosUpdate ? [{ label: 'iOS update ID', value: newIosUpdate.id }] : []),
|
||||
{ label: 'Message', value: updateMessage ?? '' },
|
||||
...(gitCommitHash
|
||||
? [
|
||||
{
|
||||
label: 'Commit',
|
||||
value: `${gitCommitHash}${isGitWorkingTreeDirty ? '*' : ''}`,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{ label: 'EAS Dashboard', value: updateGroupLink },
|
||||
])
|
||||
);
|
||||
@@ -294,8 +281,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
|
||||
private async publishRollbacksAsync({
|
||||
graphqlClient,
|
||||
isGitWorkingTreeDirty,
|
||||
gitCommitHash,
|
||||
updateMessage,
|
||||
branchId,
|
||||
codeSigningInfo,
|
||||
@@ -303,8 +288,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
realizedPlatforms,
|
||||
}: {
|
||||
graphqlClient: ExpoGraphqlClient;
|
||||
isGitWorkingTreeDirty: boolean | undefined;
|
||||
gitCommitHash: string | undefined;
|
||||
updateMessage: string | undefined;
|
||||
branchId: string;
|
||||
codeSigningInfo: CodeSigningInfo | undefined;
|
||||
@@ -329,8 +312,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
rollBackToEmbeddedInfoGroup: localRollbackInfoGroup,
|
||||
runtimeVersion,
|
||||
message: updateMessage,
|
||||
gitCommitHash,
|
||||
isGitWorkingTreeDirty,
|
||||
awaitingCodeSigningInfo: !!codeSigningInfo,
|
||||
};
|
||||
}
|
||||
@@ -381,22 +362,63 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
|
||||
return newUpdates;
|
||||
}
|
||||
|
||||
private static async selectRuntimeAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
{
|
||||
appId,
|
||||
branchName,
|
||||
batchSize = 5,
|
||||
}: {
|
||||
appId: string;
|
||||
branchName: string;
|
||||
batchSize?: number;
|
||||
}
|
||||
): Promise<RuntimeFragment | null> {
|
||||
const queryAsync = async (queryParams: QueryParams): Promise<Connection<RuntimeFragment>> => {
|
||||
return await RuntimeQuery.getRuntimesOnBranchAsync(graphqlClient, {
|
||||
appId,
|
||||
name: branchName,
|
||||
first: queryParams.first,
|
||||
after: queryParams.after,
|
||||
last: queryParams.last,
|
||||
before: queryParams.before,
|
||||
});
|
||||
};
|
||||
const getTitleAsync = async (runtime: RuntimeFragment): Promise<string> => {
|
||||
return runtime.version;
|
||||
};
|
||||
return await selectPaginatedAsync({
|
||||
queryAsync,
|
||||
getTitleAsync,
|
||||
printedType: 'target runtime',
|
||||
pageSize: batchSize,
|
||||
});
|
||||
}
|
||||
|
||||
private sanitizeFlags(flags: RawUpdateFlags): UpdateFlags {
|
||||
const nonInteractive = flags['non-interactive'] ?? false;
|
||||
|
||||
const { auto, branch: branchName, channel: channelName, message: updateMessage } = flags;
|
||||
if (nonInteractive && !auto && !(updateMessage && (branchName || channelName))) {
|
||||
const {
|
||||
branch: branchName,
|
||||
channel: channelName,
|
||||
message: updateMessage,
|
||||
'runtime-version': runtimeVersion,
|
||||
} = flags;
|
||||
if (nonInteractive && !(updateMessage && (branchName || channelName))) {
|
||||
Errors.error(
|
||||
'--branch and --message, or --channel and --message are required when updating in non-interactive mode unless --auto is specified',
|
||||
'--branch and --message, or --channel and --message are required in non-interactive mode',
|
||||
{ exit: 1 }
|
||||
);
|
||||
}
|
||||
if (nonInteractive && !runtimeVersion) {
|
||||
Errors.error('--runtimeVersion is required in non-interactive mode', { exit: 1 });
|
||||
}
|
||||
|
||||
return {
|
||||
auto,
|
||||
branchName,
|
||||
channelName,
|
||||
updateMessage,
|
||||
runtimeVersion,
|
||||
platform: flags.platform as RequestedPlatform,
|
||||
privateKeyPath: flags['private-key-path'],
|
||||
nonInteractive,
|
||||
|
||||
@@ -43,16 +43,18 @@ interface DeployFlags {
|
||||
environment?: EnvironmentVariableEnvironment;
|
||||
deploymentIdentifier?: string;
|
||||
exportDir: string;
|
||||
dryRun: boolean;
|
||||
}
|
||||
|
||||
interface RawDeployFlags {
|
||||
'non-interactive': boolean;
|
||||
environment?: string;
|
||||
environment?: EnvironmentVariableEnvironment;
|
||||
json: boolean;
|
||||
prod: boolean;
|
||||
alias?: string;
|
||||
id?: string;
|
||||
'export-dir': string;
|
||||
'dry-run': boolean;
|
||||
}
|
||||
|
||||
interface DeployInProgressParams {
|
||||
@@ -90,10 +92,11 @@ export default class WorkerDeploy extends EasCommand {
|
||||
helpValue: 'dir',
|
||||
default: 'dist',
|
||||
}),
|
||||
environment: {
|
||||
...EASEnvironmentFlag.environment,
|
||||
description: 'Deploy with EAS Environment Variables matching the specified environment.',
|
||||
},
|
||||
'dry-run': Flags.boolean({
|
||||
description: 'Outputs a tarball of the new deployment instead of uploading it.',
|
||||
default: false,
|
||||
}),
|
||||
...EASEnvironmentFlag,
|
||||
...EasNonInteractiveAndJsonFlags,
|
||||
};
|
||||
|
||||
@@ -268,6 +271,16 @@ export default class WorkerDeploy extends EasCommand {
|
||||
})
|
||||
);
|
||||
|
||||
if (flags.dryRun) {
|
||||
const DRY_RUN_OUTPUT_PATH = 'deploy.tar.gz';
|
||||
await fs.promises.copyFile(tarPath, DRY_RUN_OUTPUT_PATH);
|
||||
progress.succeed('Saved deploy.tar.gz tarball');
|
||||
if (flags.json) {
|
||||
printJsonOnlyOutput({ tarPath: DRY_RUN_OUTPUT_PATH });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const uploadUrl = await getSignedDeploymentUrlAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
deploymentIdentifier: flags.deploymentIdentifier,
|
||||
@@ -382,6 +395,8 @@ export default class WorkerDeploy extends EasCommand {
|
||||
aliasName: flags.alias?.trim().toLowerCase(),
|
||||
deploymentIdentifier: flags.id?.trim(),
|
||||
exportDir: flags['export-dir'],
|
||||
environment: flags['environment'],
|
||||
dryRun: flags['dry-run'],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ export class CredentialsContext {
|
||||
public readonly analytics: Analytics;
|
||||
public readonly vcsClient: Client;
|
||||
public readonly easJsonCliConfig?: EasJson['cli'];
|
||||
public readonly usesBroadcastPushNotifications: boolean;
|
||||
|
||||
private shouldAskAuthenticateAppStore: boolean = true;
|
||||
|
||||
@@ -61,6 +62,8 @@ export class CredentialsContext {
|
||||
this.nonInteractive = options.nonInteractive ?? false;
|
||||
this.projectInfo = options.projectInfo;
|
||||
this.freezeCredentials = options.freezeCredentials ?? false;
|
||||
this.usesBroadcastPushNotifications =
|
||||
options.projectInfo?.exp.ios?.usesBroadcastPushNotifications ?? false;
|
||||
}
|
||||
|
||||
get hasProjectContext(): boolean {
|
||||
|
||||
@@ -35,7 +35,7 @@ export class SetUpTargetBuildCredentials {
|
||||
bundleIdentifier: app.bundleIdentifier,
|
||||
projectName: app.projectName,
|
||||
},
|
||||
{ entitlements }
|
||||
{ entitlements, usesBroadcastPushNotifications: ctx.usesBroadcastPushNotifications }
|
||||
);
|
||||
}
|
||||
try {
|
||||
|
||||
+283
-73
@@ -45,7 +45,9 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
await syncCapabilitiesForEntitlementsAsync(bundleId, entitlements);
|
||||
await syncCapabilitiesForEntitlementsAsync(bundleId, entitlements, {
|
||||
usesBroadcastPushNotifications: false,
|
||||
});
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{
|
||||
@@ -62,63 +64,70 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
|
||||
'com.apple.developer.healthkit': true,
|
||||
// 'com.apple.developer.healthkit.access': [],
|
||||
'com.apple.developer.in-app-payments': ['merchant.com.example.development'],
|
||||
'com.apple.developer.icloud-container-identifiers': [],
|
||||
'com.apple.developer.ClassKit-environment': 'development',
|
||||
'com.apple.developer.default-data-protection':
|
||||
'NSFileProtectionCompleteUntilFirstUserAuthentication',
|
||||
'com.apple.developer.networking.networkextension': ['dns-proxy'],
|
||||
'com.apple.developer.networking.vpn.api': ['allow-vpn'],
|
||||
'com.apple.developer.networking.HotspotConfiguration': true,
|
||||
'com.apple.developer.kernel.extended-virtual-addressing': true,
|
||||
'com.apple.developer.homekit': true,
|
||||
'com.apple.developer.networking.multipath': true,
|
||||
'com.apple.external-accessory.wireless-configuration': true,
|
||||
'inter-app-audio': true,
|
||||
'com.apple.developer.pass-type-identifiers': ['$(TeamIdentifierPrefix)*'],
|
||||
'com.apple.developer.user-fonts': ['app-usage'],
|
||||
'com.apple.developer.devicecheck.appattest-environment': 'development',
|
||||
'com.apple.developer.nfc.readersession.formats': ['NDEF', 'TAG'],
|
||||
'com.apple.developer.applesignin': ['Default'],
|
||||
'com.apple.developer.siri': true,
|
||||
'com.apple.developer.networking.wifi-info': true,
|
||||
'com.apple.developer.usernotifications.communication': true,
|
||||
'com.apple.developer.usernotifications.time-sensitive': true,
|
||||
'com.apple.developer.group-session': true,
|
||||
'com.apple.developer.family-controls': true,
|
||||
'com.apple.developer.authentication-services.autofill-credential-provider': true,
|
||||
// 'com.apple.developer.game-center': true,
|
||||
'com.apple.security.application-groups': [
|
||||
'group.CY-A5149AC2-49FC-11E7-B3F3-0335A16FFB8D.com.cydia.Extender',
|
||||
],
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'com.apple.developer.healthkit': true,
|
||||
// 'com.apple.developer.healthkit.access': [],
|
||||
'com.apple.developer.in-app-payments': ['merchant.com.example.development'],
|
||||
'com.apple.developer.icloud-container-identifiers': [],
|
||||
'com.apple.developer.ClassKit-environment': 'development',
|
||||
'com.apple.developer.default-data-protection':
|
||||
'NSFileProtectionCompleteUntilFirstUserAuthentication',
|
||||
'com.apple.developer.networking.networkextension': ['dns-proxy'],
|
||||
'com.apple.developer.networking.vpn.api': ['allow-vpn'],
|
||||
'com.apple.developer.networking.HotspotConfiguration': true,
|
||||
'com.apple.developer.kernel.extended-virtual-addressing': true,
|
||||
'com.apple.developer.homekit': true,
|
||||
'com.apple.developer.networking.multipath': true,
|
||||
'com.apple.external-accessory.wireless-configuration': true,
|
||||
'inter-app-audio': true,
|
||||
'com.apple.developer.pass-type-identifiers': ['$(TeamIdentifierPrefix)*'],
|
||||
'com.apple.developer.user-fonts': ['app-usage'],
|
||||
'com.apple.developer.devicecheck.appattest-environment': 'development',
|
||||
'com.apple.developer.nfc.readersession.formats': ['NDEF', 'TAG'],
|
||||
'com.apple.developer.applesignin': ['Default'],
|
||||
'com.apple.developer.siri': true,
|
||||
'com.apple.developer.networking.wifi-info': true,
|
||||
'com.apple.developer.usernotifications.communication': true,
|
||||
'com.apple.developer.usernotifications.time-sensitive': true,
|
||||
'com.apple.developer.group-session': true,
|
||||
'com.apple.developer.family-controls': true,
|
||||
'com.apple.developer.authentication-services.autofill-credential-provider': true,
|
||||
// 'com.apple.developer.game-center': true,
|
||||
'com.apple.security.application-groups': [
|
||||
'group.CY-A5149AC2-49FC-11E7-B3F3-0335A16FFB8D.com.cydia.Extender',
|
||||
],
|
||||
|
||||
'com.apple.developer.fileprovider.testing-mode': true,
|
||||
'com.apple.developer.healthkit.recalibrate-estimates': true,
|
||||
'com.apple.developer.maps': true,
|
||||
'com.apple.developer.user-management': true,
|
||||
'com.apple.developer.networking.custom-protocol': true,
|
||||
'com.apple.developer.system-extension.install': true,
|
||||
'com.apple.developer.push-to-talk': true,
|
||||
'com.apple.developer.driverkit.transport.usb': true,
|
||||
'com.apple.developer.kernel.increased-memory-limit': true,
|
||||
'com.apple.developer.driverkit.communicates-with-drivers': true,
|
||||
'com.apple.developer.media-device-discovery-extension': true,
|
||||
'com.apple.developer.driverkit.allow-third-party-userclients': true,
|
||||
'com.apple.developer.weatherkit': true,
|
||||
'com.apple.developer.on-demand-install-capable': true,
|
||||
'com.apple.developer.driverkit.family.scsicontroller': true,
|
||||
'com.apple.developer.driverkit.family.serial': true,
|
||||
'com.apple.developer.driverkit.family.networking': true,
|
||||
'com.apple.developer.driverkit.family.hid.eventservice': true,
|
||||
'com.apple.developer.driverkit.family.hid.device': true,
|
||||
'com.apple.developer.driverkit': true,
|
||||
'com.apple.developer.driverkit.transport.hid': true,
|
||||
'com.apple.developer.driverkit.family.audio': true,
|
||||
'com.apple.developer.shared-with-you': true,
|
||||
});
|
||||
'com.apple.developer.fileprovider.testing-mode': true,
|
||||
'com.apple.developer.healthkit.recalibrate-estimates': true,
|
||||
'com.apple.developer.maps': true,
|
||||
'com.apple.developer.user-management': true,
|
||||
'com.apple.developer.networking.custom-protocol': true,
|
||||
'com.apple.developer.system-extension.install': true,
|
||||
'com.apple.developer.push-to-talk': true,
|
||||
'com.apple.developer.driverkit.transport.usb': true,
|
||||
'com.apple.developer.kernel.increased-memory-limit': true,
|
||||
'com.apple.developer.driverkit.communicates-with-drivers': true,
|
||||
'com.apple.developer.media-device-discovery-extension': true,
|
||||
'com.apple.developer.driverkit.allow-third-party-userclients': true,
|
||||
'com.apple.developer.weatherkit': true,
|
||||
'com.apple.developer.on-demand-install-capable': true,
|
||||
'com.apple.developer.driverkit.family.scsicontroller': true,
|
||||
'com.apple.developer.driverkit.family.serial': true,
|
||||
'com.apple.developer.driverkit.family.networking': true,
|
||||
'com.apple.developer.driverkit.family.hid.eventservice': true,
|
||||
'com.apple.developer.driverkit.family.hid.device': true,
|
||||
'com.apple.developer.driverkit': true,
|
||||
'com.apple.developer.driverkit.transport.hid': true,
|
||||
'com.apple.developer.driverkit.family.audio': true,
|
||||
'com.apple.developer.shared-with-you': true,
|
||||
'aps-environment': 'production',
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'HEALTHKIT', option: 'ON' },
|
||||
@@ -251,6 +260,10 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
capabilityType: 'SHARED_WITH_YOU',
|
||||
option: 'ON',
|
||||
},
|
||||
{
|
||||
capabilityType: 'PUSH_NOTIFICATIONS',
|
||||
option: 'ON',
|
||||
},
|
||||
]);
|
||||
|
||||
expect(results.enabled).toMatchInlineSnapshot(`
|
||||
@@ -304,6 +317,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
"DriverKit Transport HID (development)",
|
||||
"DriverKit Family Audio (development)",
|
||||
"Shared with You",
|
||||
"Push Notifications",
|
||||
]
|
||||
`);
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
@@ -318,9 +332,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
|
||||
'com.apple.developer.healthkit': true,
|
||||
});
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'com.apple.developer.healthkit': true,
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
|
||||
|
||||
@@ -344,9 +364,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
} as any;
|
||||
|
||||
await expect(
|
||||
syncCapabilitiesForEntitlementsAsync(bundleId, {
|
||||
'com.apple.developer.healthkit': true,
|
||||
})
|
||||
syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'com.apple.developer.healthkit': true,
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
)
|
||||
).rejects.toThrowError(
|
||||
`https://developer-mdn.apple.com/account/resources/identifiers/bundleId/edit/XXX333`
|
||||
);
|
||||
@@ -361,9 +387,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
|
||||
'com.apple.developer.healthkit': true,
|
||||
});
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'com.apple.developer.healthkit': true,
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'HEALTHKIT', option: 'ON' },
|
||||
@@ -382,9 +414,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
|
||||
'com.apple.developer.healthkit': true,
|
||||
});
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'com.apple.developer.healthkit': true,
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'HEALTHKIT', option: 'ON' },
|
||||
@@ -406,7 +444,13 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {});
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
|
||||
|
||||
@@ -423,9 +467,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
|
||||
'com.apple.developer.healthkit': true,
|
||||
});
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'com.apple.developer.healthkit': true,
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'HEALTHKIT', option: 'ON' },
|
||||
@@ -434,4 +484,164 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
|
||||
expect(results.enabled).toStrictEqual(['HealthKit']);
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('enables push notifications capability with broadcast option when the capability is disabled and usesBroadcastPushNotifications is true', async () => {
|
||||
const bundleId = {
|
||||
getBundleIdCapabilitiesAsync: jest.fn(() => []),
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'aps-environment': 'production',
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'PUSH_NOTIFICATION_FEATURE_BROADCAST' },
|
||||
]);
|
||||
|
||||
expect(results.enabled).toStrictEqual(['Push Notifications']);
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('updates push notifications capability with broadcast option when the capability is enabled without settings and usesBroadcastPushNotifications is true', async () => {
|
||||
const bundleId = {
|
||||
getBundleIdCapabilitiesAsync: jest.fn(() => [
|
||||
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', { settings: null }),
|
||||
]),
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'aps-environment': 'production',
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'PUSH_NOTIFICATION_FEATURE_BROADCAST' },
|
||||
]);
|
||||
|
||||
expect(results.enabled).toStrictEqual(['Push Notifications']);
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('disables push notifications capability', async () => {
|
||||
const bundleId = {
|
||||
getBundleIdCapabilitiesAsync: jest.fn(() => [
|
||||
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', { settings: null }),
|
||||
]),
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{},
|
||||
{
|
||||
usesBroadcastPushNotifications: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'OFF' },
|
||||
]);
|
||||
|
||||
expect(results.disabled).toStrictEqual(['Push Notifications']);
|
||||
expect(results.enabled).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('does nothing when push notifications capability is enabled with broadcast options and usesBroadcastPushNotifications is true', async () => {
|
||||
const bundleId = {
|
||||
getBundleIdCapabilitiesAsync: jest.fn(() => [
|
||||
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', {
|
||||
settings: [],
|
||||
}),
|
||||
]),
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'aps-environment': 'production',
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
|
||||
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
expect(results.enabled).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('does nothing when push notifications capability is enabled without broadcast options and usesBroadcastPushNotifications is false', async () => {
|
||||
const bundleId = {
|
||||
getBundleIdCapabilitiesAsync: jest.fn(() => [
|
||||
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', {
|
||||
settings: null,
|
||||
}),
|
||||
]),
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'aps-environment': 'production',
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
|
||||
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
expect(results.enabled).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('updates push notifications capability without broadcast options when it is enabled and usesBroadcastPushNotifications is false', async () => {
|
||||
const bundleId = {
|
||||
getBundleIdCapabilitiesAsync: jest.fn(() => [
|
||||
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', {
|
||||
settings: [],
|
||||
}),
|
||||
]),
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
id: 'XXX',
|
||||
} as any;
|
||||
|
||||
const results = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
{
|
||||
'aps-environment': 'production',
|
||||
},
|
||||
{
|
||||
usesBroadcastPushNotifications: false,
|
||||
}
|
||||
);
|
||||
|
||||
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
|
||||
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'ON' },
|
||||
]);
|
||||
|
||||
expect(results.disabled).toStrictEqual([]);
|
||||
expect(results.enabled).toStrictEqual(['Push Notifications']);
|
||||
});
|
||||
});
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
CapabilityType,
|
||||
CapabilityTypeDataProtectionOption,
|
||||
CapabilityTypeOption,
|
||||
CapabilityTypePushNotificationsOption,
|
||||
CloudContainer,
|
||||
MerchantId,
|
||||
} from '@expo/apple-utils';
|
||||
@@ -19,7 +20,10 @@ export const EXPO_NO_CAPABILITY_SYNC = getenv.boolish('EXPO_NO_CAPABILITY_SYNC',
|
||||
|
||||
type GetOptionsMethod<T extends CapabilityType = any> = (
|
||||
entitlement: JSONValue,
|
||||
entitlementsJson: JSONObject
|
||||
entitlementsJson: JSONObject,
|
||||
additionalOptions: {
|
||||
usesBroadcastPushNotifications?: boolean;
|
||||
}
|
||||
) => CapabilityOptionMap[T];
|
||||
|
||||
const validateBooleanOptions = (options: any): boolean => {
|
||||
@@ -78,7 +82,10 @@ const getDefinedOptions: GetOptionsMethod = entitlement => {
|
||||
*/
|
||||
export async function syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId: BundleId,
|
||||
entitlements: JSONObject = {}
|
||||
entitlements: JSONObject = {},
|
||||
additionalOptions: {
|
||||
usesBroadcastPushNotifications: boolean;
|
||||
}
|
||||
): Promise<{ enabled: string[]; disabled: string[] }> {
|
||||
if (EXPO_NO_CAPABILITY_SYNC) {
|
||||
return { enabled: [], disabled: [] };
|
||||
@@ -91,7 +98,8 @@ export async function syncCapabilitiesForEntitlementsAsync(
|
||||
|
||||
const { enabledCapabilityNames, request, remainingCapabilities } = getCapabilitiesToEnable(
|
||||
currentCapabilities,
|
||||
entitlements
|
||||
entitlements,
|
||||
additionalOptions
|
||||
);
|
||||
|
||||
const { disabledCapabilityNames, request: modifiedRequest } = getCapabilitiesToDisable(
|
||||
@@ -125,9 +133,25 @@ interface CapabilitiesRequest {
|
||||
option: any;
|
||||
}
|
||||
|
||||
function shouldSkipPushNotificationsCapabilityUpdate(
|
||||
existing: BundleIdCapability,
|
||||
additionalOptions: {
|
||||
usesBroadcastPushNotifications: boolean;
|
||||
}
|
||||
): boolean {
|
||||
// For push notifications, we should always update the capabaility if
|
||||
// - settings are not defined in the existing capability, but usesBroadcastPushNotifications is enabled (we want to add settings for this capability)
|
||||
// - settings are defined in the existing capability, but usesBroadcastPushNotifications is disabled (we want to remove settings for this capability)
|
||||
const noSettingsAttributes = existing.attributes.settings == null;
|
||||
return !noSettingsAttributes === additionalOptions.usesBroadcastPushNotifications;
|
||||
}
|
||||
|
||||
function getCapabilitiesToEnable(
|
||||
currentCapabilities: BundleIdCapability[],
|
||||
entitlements: JSONObject
|
||||
entitlements: JSONObject,
|
||||
additionalOptions: {
|
||||
usesBroadcastPushNotifications: boolean;
|
||||
}
|
||||
): {
|
||||
enabledCapabilityNames: string[];
|
||||
request: CapabilitiesRequest[];
|
||||
@@ -156,7 +180,17 @@ function getCapabilitiesToEnable(
|
||||
// Only skip if the existing capability is a simple boolean value,
|
||||
// if it has more complex settings then we should always update it.
|
||||
// If the `existing.attributes.settings` object is defined, then we can determine that it has extra configuration.
|
||||
if (existing && existing?.attributes.settings == null) {
|
||||
// For push notifications, we should always update the capabaility if
|
||||
// - settings are not defined in the existing capability, but usesBroadcastPushNotifications is enabled (we want to add settings for this capability)
|
||||
// - settings are defined in the existing capability, but usesBroadcastPushNotifications is disabled (we want to remove settings for this capability)
|
||||
const isPushNotificationsCapability =
|
||||
staticCapabilityInfo.capability === CapabilityType.PUSH_NOTIFICATIONS;
|
||||
if (
|
||||
existing &&
|
||||
((!isPushNotificationsCapability && existing.attributes.settings == null) ||
|
||||
(isPushNotificationsCapability &&
|
||||
shouldSkipPushNotificationsCapabilityUpdate(existing, additionalOptions)))
|
||||
) {
|
||||
// Remove the item from the list of capabilities so we don't disable it.
|
||||
remainingCapabilities.splice(existingIndex, 1);
|
||||
if (Log.isDebug) {
|
||||
@@ -173,7 +207,7 @@ function getCapabilitiesToEnable(
|
||||
|
||||
enabledCapabilityNames.push(staticCapabilityInfo.name);
|
||||
|
||||
const option = staticCapabilityInfo.getOptions(value, entitlements);
|
||||
const option = staticCapabilityInfo.getOptions(value, entitlements, additionalOptions);
|
||||
|
||||
request.push({
|
||||
capabilityType: staticCapabilityInfo.capability,
|
||||
@@ -488,7 +522,13 @@ export const CapabilityMapping: CapabilityClassifier[] = [
|
||||
entitlement: 'aps-environment',
|
||||
capability: CapabilityType.PUSH_NOTIFICATIONS,
|
||||
validateOptions: validateDevProdString,
|
||||
getOptions: getDefinedOptions,
|
||||
getOptions(entitlement, _entitlementsJson, { usesBroadcastPushNotifications }) {
|
||||
const option = entitlement ? CapabilityTypeOption.ON : CapabilityTypeOption.OFF;
|
||||
if (option === CapabilityTypeOption.ON && usesBroadcastPushNotifications) {
|
||||
return CapabilityTypePushNotificationsOption.PUSH_NOTIFICATION_FEATURE_BROADCAST;
|
||||
}
|
||||
return option;
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Wallet',
|
||||
|
||||
@@ -12,6 +12,7 @@ import { ora } from '../../../ora';
|
||||
|
||||
export interface IosCapabilitiesOptions {
|
||||
entitlements: JSONObject;
|
||||
usesBroadcastPushNotifications: boolean;
|
||||
}
|
||||
|
||||
export interface AppLookupParams {
|
||||
@@ -93,7 +94,7 @@ export async function ensureBundleIdExistsWithNameAsync(
|
||||
|
||||
export async function syncCapabilitiesAsync(
|
||||
bundleId: BundleId,
|
||||
{ entitlements }: IosCapabilitiesOptions
|
||||
{ entitlements, ...rest }: IosCapabilitiesOptions
|
||||
): Promise<void> {
|
||||
const spinner = ora(`Syncing capabilities`).start();
|
||||
|
||||
@@ -105,7 +106,8 @@ export async function syncCapabilitiesAsync(
|
||||
try {
|
||||
const { enabled, disabled } = await syncCapabilitiesForEntitlementsAsync(
|
||||
bundleId,
|
||||
entitlements
|
||||
entitlements,
|
||||
rest
|
||||
);
|
||||
const results =
|
||||
[buildMessage('Enabled', enabled), buildMessage('Disabled', disabled)]
|
||||
@@ -119,7 +121,7 @@ export async function syncCapabilitiesAsync(
|
||||
}
|
||||
|
||||
// Always run this after syncing the capabilities...
|
||||
await syncCapabilityIdentifiersAsync(bundleId, { entitlements });
|
||||
await syncCapabilityIdentifiersAsync(bundleId, { entitlements, ...rest });
|
||||
}
|
||||
|
||||
const buildMessage = (title: string, items: string[]): string =>
|
||||
|
||||
+26
@@ -711,6 +711,7 @@ export type AccountSsoConfigurationPublicDataQueryPublicDataByAccountNameArgs =
|
||||
};
|
||||
|
||||
export enum AccountUploadSessionType {
|
||||
ProfileImageUpload = 'PROFILE_IMAGE_UPLOAD',
|
||||
WorkflowsProjectSources = 'WORKFLOWS_PROJECT_SOURCES'
|
||||
}
|
||||
|
||||
@@ -2048,6 +2049,10 @@ export type AppUpdatesConnection = {
|
||||
pageInfo: PageInfo;
|
||||
};
|
||||
|
||||
export enum AppUploadSessionType {
|
||||
ProfileImageUpload = 'PROFILE_IMAGE_UPLOAD'
|
||||
}
|
||||
|
||||
/** Represents Play Store/App Store version of an application */
|
||||
export type AppVersion = {
|
||||
__typename?: 'AppVersion';
|
||||
@@ -2866,6 +2871,7 @@ export type BuildFilter = {
|
||||
channel?: InputMaybe<Scalars['String']['input']>;
|
||||
distribution?: InputMaybe<DistributionType>;
|
||||
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
|
||||
hasFingerprint?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
platform?: InputMaybe<AppPlatform>;
|
||||
runtimeVersion?: InputMaybe<Scalars['String']['input']>;
|
||||
sdkVersion?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -2877,6 +2883,7 @@ export type BuildFilterInput = {
|
||||
channel?: InputMaybe<Scalars['String']['input']>;
|
||||
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
distributions?: InputMaybe<Array<DistributionType>>;
|
||||
hasFingerprint?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
platforms?: InputMaybe<Array<AppPlatform>>;
|
||||
releaseChannel?: InputMaybe<Scalars['String']['input']>;
|
||||
runtimeVersion?: InputMaybe<Scalars['String']['input']>;
|
||||
@@ -6857,6 +6864,8 @@ export type UploadSession = {
|
||||
__typename?: 'UploadSession';
|
||||
/** Create an Upload Session for a specific account */
|
||||
createAccountScopedUploadSession: Scalars['JSONObject']['output'];
|
||||
/** Create an Upload Session for a specific app */
|
||||
createAppScopedUploadSession: Scalars['JSONObject']['output'];
|
||||
/** Create an Upload Session */
|
||||
createUploadSession: Scalars['JSONObject']['output'];
|
||||
};
|
||||
@@ -6868,6 +6877,12 @@ export type UploadSessionCreateAccountScopedUploadSessionArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type UploadSessionCreateAppScopedUploadSessionArgs = {
|
||||
appID: Scalars['ID']['input'];
|
||||
type: AppUploadSessionType;
|
||||
};
|
||||
|
||||
|
||||
export type UploadSessionCreateUploadSessionArgs = {
|
||||
type: UploadSessionType;
|
||||
};
|
||||
@@ -9120,6 +9135,13 @@ export type BuildsWithSubmissionsByIdQueryVariables = Exact<{
|
||||
|
||||
export type BuildsWithSubmissionsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } } } };
|
||||
|
||||
export type BuildsWithFingerprintByIdQueryVariables = Exact<{
|
||||
buildId: Scalars['ID']['input'];
|
||||
}>;
|
||||
|
||||
|
||||
export type BuildsWithFingerprintByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null } | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } } } };
|
||||
|
||||
export type ViewBuildsOnAppQueryVariables = Exact<{
|
||||
appId: Scalars['String']['input'];
|
||||
offset: Scalars['Int']['input'];
|
||||
@@ -9321,12 +9343,16 @@ export type BuildFragment = { __typename?: 'Build', id: string, status: BuildSta
|
||||
|
||||
export type BuildWithSubmissionsFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } };
|
||||
|
||||
export type BuildWithFingerprintFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null } | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } };
|
||||
|
||||
export type EnvironmentSecretFragment = { __typename?: 'EnvironmentSecret', id: string, name: string, type: EnvironmentSecretType, createdAt: any };
|
||||
|
||||
export type EnvironmentVariableFragment = { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType };
|
||||
|
||||
export type EnvironmentVariableWithSecretFragment = { __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType };
|
||||
|
||||
export type FingerprintFragment = { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null };
|
||||
|
||||
export type RuntimeFragment = { __typename?: 'Runtime', id: string, version: string };
|
||||
|
||||
export type StatuspageServiceFragment = { __typename?: 'StatuspageService', id: string, name: StatuspageServiceName, status: StatuspageServiceStatus, incidents: Array<{ __typename?: 'StatuspageIncident', id: string, status: StatuspageIncidentStatus, name: string, impact: StatuspageIncidentImpact, shortlink: string }> };
|
||||
|
||||
@@ -5,15 +5,22 @@ import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/creat
|
||||
import { withErrorHandlingAsync } from '../client';
|
||||
import {
|
||||
BuildFragment,
|
||||
BuildWithFingerprintFragment,
|
||||
BuildWithSubmissionsFragment,
|
||||
BuildsByIdQuery,
|
||||
BuildsByIdQueryVariables,
|
||||
BuildsWithFingerprintByIdQuery,
|
||||
BuildsWithFingerprintByIdQueryVariables,
|
||||
BuildsWithSubmissionsByIdQuery,
|
||||
BuildsWithSubmissionsByIdQueryVariables,
|
||||
ViewBuildsOnAppQuery,
|
||||
ViewBuildsOnAppQueryVariables,
|
||||
} from '../generated';
|
||||
import { BuildFragmentNode, BuildFragmentWithSubmissionsNode } from '../types/Build';
|
||||
import {
|
||||
BuildFragmentNode,
|
||||
BuildFragmentWithFingerprintNode,
|
||||
BuildFragmentWithSubmissionsNode,
|
||||
} from '../types/Build';
|
||||
|
||||
export const BuildQuery = {
|
||||
async byIdAsync(
|
||||
@@ -76,6 +83,36 @@ export const BuildQuery = {
|
||||
|
||||
return data.builds.byId;
|
||||
},
|
||||
async withFingerprintByIdAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
buildId: string,
|
||||
{ useCache = true }: { useCache?: boolean } = {}
|
||||
): Promise<BuildWithFingerprintFragment> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.query<BuildsWithFingerprintByIdQuery, BuildsWithFingerprintByIdQueryVariables>(
|
||||
gql`
|
||||
query BuildsWithFingerprintByIdQuery($buildId: ID!) {
|
||||
builds {
|
||||
byId(buildId: $buildId) {
|
||||
id
|
||||
...BuildWithFingerprintFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
${print(BuildFragmentWithFingerprintNode)}
|
||||
`,
|
||||
{ buildId },
|
||||
{
|
||||
requestPolicy: useCache ? 'cache-first' : 'network-only',
|
||||
additionalTypenames: ['Build'],
|
||||
}
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
|
||||
return data.builds.byId;
|
||||
},
|
||||
async viewBuildsOnAppAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
{ appId, limit, offset, filter }: ViewBuildsOnAppQueryVariables
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { print } from 'graphql';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import { FingerprintFragmentNode } from './Fingerprint';
|
||||
import { SubmissionFragmentNode } from './Submission';
|
||||
|
||||
export const BuildFragmentNode = gql`
|
||||
@@ -72,3 +73,17 @@ export const BuildFragmentWithSubmissionsNode = gql`
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export const BuildFragmentWithFingerprintNode = gql`
|
||||
${print(FingerprintFragmentNode)}
|
||||
${print(BuildFragmentNode)}
|
||||
|
||||
fragment BuildWithFingerprintFragment on Build {
|
||||
id
|
||||
...BuildFragment
|
||||
fingerprint {
|
||||
id
|
||||
...FingerprintFragment
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -0,0 +1,9 @@
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
export const FingerprintFragmentNode = gql`
|
||||
fragment FingerprintFragment on Fingerprint {
|
||||
id
|
||||
hash
|
||||
debugInfoUrl
|
||||
}
|
||||
`;
|
||||
@@ -634,7 +634,13 @@ export async function getBranchNameForCommandAsync({
|
||||
}
|
||||
|
||||
if (autoFlag) {
|
||||
return await getDefaultBranchNameAsync(vcsClient);
|
||||
const defaultBranchNameFromVcs = await getDefaultBranchNameAsync(vcsClient);
|
||||
if (!defaultBranchNameFromVcs) {
|
||||
throw new Error(
|
||||
'Must supply --branch or --channel for branch name as auto-detection of branch name via --auto is not supported when no VCS is present.'
|
||||
);
|
||||
}
|
||||
return defaultBranchNameFromVcs;
|
||||
} else if (nonInteractive) {
|
||||
throw new Error('Must supply --channel, --branch or --auto when in non-interactive mode.');
|
||||
} else {
|
||||
@@ -658,7 +664,7 @@ export async function getBranchNameForCommandAsync({
|
||||
type: 'text',
|
||||
name: 'name',
|
||||
message: 'No branches found. Provide a branch name:',
|
||||
initial: await getDefaultBranchNameAsync(vcsClient),
|
||||
initial: (await getDefaultBranchNameAsync(vcsClient)) ?? undefined,
|
||||
validate: value => (value ? true : 'Branch name may not be empty.'),
|
||||
});
|
||||
branchName = name;
|
||||
|
||||
@@ -149,7 +149,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
return newChannelInfo;
|
||||
}
|
||||
|
||||
async confirmCreationAsync(ctx: EASUpdateContext): Promise<boolean> {
|
||||
private async confirmCreationAsync(ctx: EASUpdateContext): Promise<boolean> {
|
||||
const { nonInteractive } = ctx;
|
||||
if (nonInteractive) {
|
||||
return true;
|
||||
@@ -159,7 +159,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
});
|
||||
}
|
||||
|
||||
async getChannelObjectAsync(
|
||||
private async getChannelObjectAsync(
|
||||
ctx: EASUpdateContext,
|
||||
runtimeVersion: string
|
||||
): Promise<UpdateChannelObject> {
|
||||
@@ -172,7 +172,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
});
|
||||
}
|
||||
|
||||
async getLatestUpdateGroupOnBranchAsync(
|
||||
private async getLatestUpdateGroupOnBranchAsync(
|
||||
ctx: EASUpdateContext,
|
||||
branchInfo: UpdateBranchBasicInfoFragment,
|
||||
runtimeVersion: string
|
||||
@@ -195,7 +195,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
return updateGroups[0] ?? null;
|
||||
}
|
||||
|
||||
async selectRuntimeVersionAsync(
|
||||
private async selectRuntimeVersionAsync(
|
||||
ctx: EASUpdateContext,
|
||||
branchToRollout: UpdateBranchBasicInfoFragment,
|
||||
defaultBranchId: string
|
||||
@@ -223,7 +223,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
);
|
||||
}
|
||||
|
||||
async selectRuntimeVersionFromAlternativeSourceAsync(
|
||||
private async selectRuntimeVersionFromAlternativeSourceAsync(
|
||||
ctx: EASUpdateContext,
|
||||
branchToRollout: UpdateBranchBasicInfoFragment,
|
||||
defaultBranch: UpdateBranchBasicInfoFragment
|
||||
@@ -271,7 +271,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
);
|
||||
}
|
||||
|
||||
async selectRuntimeVersionFromProjectConfigAsync(ctx: EASUpdateContext): Promise<string> {
|
||||
private async selectRuntimeVersionFromProjectConfigAsync(ctx: EASUpdateContext): Promise<string> {
|
||||
const platforms: ('ios' | 'android')[] = ['ios', 'android'];
|
||||
const workflows = await resolveWorkflowPerPlatformAsync(ctx.app.projectDir, ctx.vcsClient);
|
||||
const runtimes = (
|
||||
@@ -313,7 +313,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
return selectedRuntime;
|
||||
}
|
||||
|
||||
async selectBranchAsync(
|
||||
private async selectBranchAsync(
|
||||
ctx: EASUpdateContext,
|
||||
defaultBranchId: string
|
||||
): Promise<UpdateBranchBasicInfoFragment> {
|
||||
@@ -333,7 +333,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
|
||||
return branchInfo;
|
||||
}
|
||||
|
||||
async resolveBranchNameAsync(
|
||||
private async resolveBranchNameAsync(
|
||||
ctx: EASUpdateContext,
|
||||
branchName: string
|
||||
): Promise<UpdateBranchBasicInfoFragment> {
|
||||
|
||||
@@ -86,7 +86,7 @@ export class EditRollout implements EASUpdateAction<UpdateChannelBasicInfoFragme
|
||||
return newChannelInfo;
|
||||
}
|
||||
|
||||
async confirmEditAsync(ctx: EASUpdateContext): Promise<boolean> {
|
||||
private async confirmEditAsync(ctx: EASUpdateContext): Promise<boolean> {
|
||||
const { nonInteractive } = ctx;
|
||||
if (nonInteractive) {
|
||||
return true;
|
||||
@@ -96,7 +96,7 @@ export class EditRollout implements EASUpdateAction<UpdateChannelBasicInfoFragme
|
||||
});
|
||||
}
|
||||
|
||||
async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
|
||||
private async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
|
||||
const { graphqlClient, app } = ctx;
|
||||
const { projectId } = app;
|
||||
if (!isRollout(this.channelInfo)) {
|
||||
|
||||
@@ -87,7 +87,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
|
||||
return await this.performOutcomeAsync(ctx, rollout, outcome);
|
||||
}
|
||||
|
||||
async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
|
||||
private async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
|
||||
const { graphqlClient, app } = ctx;
|
||||
const { projectId } = app;
|
||||
if (!isRollout(this.channelInfo)) {
|
||||
@@ -107,7 +107,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
|
||||
});
|
||||
}
|
||||
|
||||
async selectOutcomeAsync(rollout: Rollout<UpdateBranchObject>): Promise<EndOutcome> {
|
||||
private async selectOutcomeAsync(rollout: Rollout<UpdateBranchObject>): Promise<EndOutcome> {
|
||||
const { rolledOutBranch, percentRolledOut, defaultBranch } = rollout;
|
||||
const rolledOutUpdateGroup = rolledOutBranch.updateGroups[0];
|
||||
const defaultUpdateGroup = defaultBranch.updateGroups[0];
|
||||
@@ -144,7 +144,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
|
||||
return selectedOutcome;
|
||||
}
|
||||
|
||||
async performOutcomeAsync(
|
||||
private async performOutcomeAsync(
|
||||
ctx: EASUpdateContext,
|
||||
rollout: Rollout<UpdateBranchObject>,
|
||||
outcome: EndOutcome
|
||||
@@ -185,7 +185,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
|
||||
return newChannelInfo;
|
||||
}
|
||||
|
||||
async confirmOutcomeAsync(
|
||||
private async confirmOutcomeAsync(
|
||||
ctx: EASUpdateContext,
|
||||
selectedOutcome: EndOutcome,
|
||||
rollout: Rollout<UpdateBranchObject>
|
||||
|
||||
@@ -61,7 +61,7 @@ export class ManageRollout implements EASUpdateAction<EASUpdateAction> {
|
||||
}
|
||||
}
|
||||
|
||||
async selectActionAsync(): Promise<ManageRolloutActions> {
|
||||
private async selectActionAsync(): Promise<ManageRolloutActions> {
|
||||
const manageOptions = [ManageRolloutActions.EDIT, ManageRolloutActions.END];
|
||||
if (this.options.callingAction) {
|
||||
manageOptions.push(ManageRolloutActions.GO_BACK);
|
||||
@@ -78,7 +78,7 @@ export class ManageRollout implements EASUpdateAction<EASUpdateAction> {
|
||||
return selectedManageOption;
|
||||
}
|
||||
|
||||
async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
|
||||
private async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
|
||||
const { graphqlClient, app } = ctx;
|
||||
const { projectId } = app;
|
||||
if (!isRollout(this.channelInfo)) {
|
||||
|
||||
@@ -91,7 +91,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async runActionAsync(
|
||||
private async runActionAsync(
|
||||
ctx: EASUpdateContext,
|
||||
action: RolloutActions,
|
||||
channelObject: UpdateChannelObject
|
||||
@@ -108,7 +108,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
|
||||
}
|
||||
}
|
||||
|
||||
viewRollout(channelObject: UpdateChannelObject): UpdateChannelObject {
|
||||
private viewRollout(channelObject: UpdateChannelObject): UpdateChannelObject {
|
||||
if (!this.options.json) {
|
||||
printRollout(channelObject);
|
||||
Log.warn('For formatted output, add the --json flag to your command.');
|
||||
@@ -116,7 +116,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
|
||||
return channelObject;
|
||||
}
|
||||
|
||||
async getJsonAsync({
|
||||
private async getJsonAsync({
|
||||
originalChannelObject,
|
||||
updatedChannelObject,
|
||||
}: {
|
||||
@@ -134,7 +134,9 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
|
||||
};
|
||||
}
|
||||
|
||||
async getRolloutJsonAsync(channelObject: UpdateChannelObject): Promise<JSONRolloutOutput> {
|
||||
private async getRolloutJsonAsync(
|
||||
channelObject: UpdateChannelObject
|
||||
): Promise<JSONRolloutOutput> {
|
||||
const rollout = getRollout(channelObject);
|
||||
return {
|
||||
defaultBranch: rollout.defaultBranch,
|
||||
@@ -145,7 +147,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
|
||||
};
|
||||
}
|
||||
|
||||
getRuntimeVersion(channelInfo: UpdateChannelBasicInfoFragment): string | undefined {
|
||||
private getRuntimeVersion(channelInfo: UpdateChannelBasicInfoFragment): string | undefined {
|
||||
if (isRollout(channelInfo)) {
|
||||
const updatedRolloutInfo = getRolloutInfo(channelInfo);
|
||||
if (isConstrainedRolloutInfo(updatedRolloutInfo)) {
|
||||
@@ -155,7 +157,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async getChannelObjectAsync(
|
||||
private async getChannelObjectAsync(
|
||||
ctx: EASUpdateContext,
|
||||
{ channelName, runtimeVersion }: { channelName: string; runtimeVersion?: string }
|
||||
): Promise<UpdateChannelObject> {
|
||||
|
||||
@@ -54,7 +54,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
|
||||
await this.runActionAsync(ctx, menuOption);
|
||||
}
|
||||
|
||||
async runActionAsync(ctx: EASUpdateContext, menuAction: MainMenuActions): Promise<null> {
|
||||
private async runActionAsync(ctx: EASUpdateContext, menuAction: MainMenuActions): Promise<null> {
|
||||
const { channelName } = this.options;
|
||||
switch (menuAction) {
|
||||
case MainMenuActions.CREATE_NEW: {
|
||||
@@ -87,13 +87,15 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async selectRolloutAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment | null> {
|
||||
private async selectRolloutAsync(
|
||||
ctx: EASUpdateContext
|
||||
): Promise<UpdateChannelBasicInfoFragment | null> {
|
||||
const selectRollout = new SelectRollout();
|
||||
const channelInfo = await selectRollout.runAsync(ctx);
|
||||
return channelInfo;
|
||||
}
|
||||
|
||||
async selectChannelToRolloutAsync(
|
||||
private async selectChannelToRolloutAsync(
|
||||
ctx: EASUpdateContext
|
||||
): Promise<UpdateChannelBasicInfoFragment> {
|
||||
let hasSomeChannel = false;
|
||||
@@ -113,7 +115,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
|
||||
return channelInfo;
|
||||
}
|
||||
|
||||
async resolveChannelNameAsync(
|
||||
private async resolveChannelNameAsync(
|
||||
ctx: EASUpdateContext,
|
||||
channelName: string
|
||||
): Promise<UpdateChannelBasicInfoFragment> {
|
||||
@@ -124,7 +126,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
|
||||
});
|
||||
}
|
||||
|
||||
toMainMenuAction(action: RolloutActions): MainMenuActions {
|
||||
private toMainMenuAction(action: RolloutActions): MainMenuActions {
|
||||
if (action === MainMenuActions.CREATE_NEW) {
|
||||
return MainMenuActions.CREATE_NEW;
|
||||
} else if (
|
||||
@@ -138,7 +140,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async promptMenuActionAsync(): Promise<MainMenuActions> {
|
||||
private async promptMenuActionAsync(): Promise<MainMenuActions> {
|
||||
const menuOptions = [MainMenuActions.CREATE_NEW, MainMenuActions.MANAGE_EXISTING];
|
||||
const { menuOption: selectedMenuOption } = await promptAsync({
|
||||
type: 'select',
|
||||
|
||||
@@ -27,7 +27,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
|
||||
: `runtime`;
|
||||
}
|
||||
|
||||
warnNoRuntime(): void {
|
||||
private warnNoRuntime(): void {
|
||||
if (this.options.anotherBranchToIntersectRuntimesBy) {
|
||||
const intersectBranchName = this.options.anotherBranchToIntersectRuntimesBy.name;
|
||||
Log.warn(
|
||||
@@ -42,7 +42,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
|
||||
}
|
||||
}
|
||||
|
||||
formatCantFindRuntime(): string {
|
||||
private formatCantFindRuntime(): string {
|
||||
return `🕵️ Not finding the update you were looking for? ${learnMore(
|
||||
'https://expo.fyi/eas-update-rollouts'
|
||||
)}`;
|
||||
@@ -104,7 +104,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
|
||||
return selectedRuntime.version;
|
||||
}
|
||||
|
||||
async getNewestRuntimeAsync(
|
||||
private async getNewestRuntimeAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
{
|
||||
appId,
|
||||
@@ -126,7 +126,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
|
||||
});
|
||||
}
|
||||
|
||||
async displayLatestUpdateGroupAsync({
|
||||
private async displayLatestUpdateGroupAsync({
|
||||
graphqlClient,
|
||||
appId,
|
||||
branchName,
|
||||
@@ -153,7 +153,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
|
||||
return formatRuntimeWithUpdateGroup(updateGroups[0], runtime, branchName);
|
||||
}
|
||||
|
||||
async selectRuntimesAsync(
|
||||
private async selectRuntimesAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
{
|
||||
appId,
|
||||
|
||||
+3
-3
@@ -34,7 +34,7 @@ export async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(
|
||||
throw error;
|
||||
}
|
||||
|
||||
const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
|
||||
const { branch } = await ensureBranchExistsAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
branchName: channelName,
|
||||
});
|
||||
@@ -43,7 +43,7 @@ export async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(
|
||||
} = await createChannelOnAppAsync(graphqlClient, {
|
||||
appId: projectId,
|
||||
channelName,
|
||||
branchId,
|
||||
branchId: branch.id,
|
||||
});
|
||||
|
||||
if (!newChannel) {
|
||||
@@ -52,7 +52,7 @@ export async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(
|
||||
);
|
||||
}
|
||||
|
||||
branchInfo = { branchId, branchName: channelName };
|
||||
branchInfo = { branchId: branch.id, branchName: channelName };
|
||||
}
|
||||
|
||||
return branchInfo;
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
import Log from '../../log';
|
||||
import { abridgedDiff } from '../fingerprintDiff';
|
||||
|
||||
jest.mock('chalk', () => ({
|
||||
red: jest.fn(text => `red(${text})`),
|
||||
green: jest.fn(text => `green(${text})`),
|
||||
gray: jest.fn(text => `gray(${text})`),
|
||||
cyan: jest.fn(text => `cyan(${text})`),
|
||||
}));
|
||||
|
||||
jest.spyOn(Log, 'log').mockImplementation(jest.fn());
|
||||
|
||||
describe('abridgedDiff', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should output the diff for added and removed lines with context', () => {
|
||||
const str1 = 'Line1\nLine2\nLine3';
|
||||
const str2 = 'Line1\nLineX\nLine3';
|
||||
|
||||
abridgedDiff(str1, str2, 1);
|
||||
|
||||
const expectedOutput = [
|
||||
'cyan(@@ -2,1 +2,1 @@)',
|
||||
' gray(Line1)',
|
||||
'red(-Line2)',
|
||||
'green(+LineX)',
|
||||
' gray(Line3)',
|
||||
].join('\n');
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
|
||||
});
|
||||
|
||||
it('should output the diff for completely different strings', () => {
|
||||
const str1 = 'LineA\nLineB';
|
||||
const str2 = 'LineC\nLineD';
|
||||
|
||||
abridgedDiff(str1, str2, 0);
|
||||
|
||||
const expectedOutput = [
|
||||
'cyan(@@ -1,2 +1,2 @@)',
|
||||
'red(-LineA)',
|
||||
'red(-LineB)',
|
||||
'green(+LineC)',
|
||||
'green(+LineD)',
|
||||
].join('\n');
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
|
||||
});
|
||||
|
||||
it('should not include context lines if contextLines is 0', () => {
|
||||
const str1 = 'Line1\nLine2\nLine3';
|
||||
const str2 = 'Line1\nLineX\nLine3';
|
||||
|
||||
abridgedDiff(str1, str2, 0);
|
||||
|
||||
const expectedOutput = ['cyan(@@ -2,1 +2,1 @@)', 'red(-Line2)', 'green(+LineX)'].join('\n');
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
|
||||
});
|
||||
|
||||
it('should handle strings with no differences', () => {
|
||||
const str1 = 'SameLine1\nSameLine2';
|
||||
const str2 = 'SameLine1\nSameLine2';
|
||||
|
||||
abridgedDiff(str1, str2, 1);
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith('');
|
||||
});
|
||||
|
||||
it('should handle empty input strings', () => {
|
||||
const str1 = '';
|
||||
const str2 = 'NewLine1\nNewLine2';
|
||||
|
||||
abridgedDiff(str1, str2, 1);
|
||||
|
||||
const expectedOutput = ['cyan(@@ -1,0 +1,2 @@)', 'green(+NewLine1)', 'green(+NewLine2)'].join(
|
||||
'\n'
|
||||
);
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
|
||||
});
|
||||
|
||||
it('should handle strings with only removed lines', () => {
|
||||
const str1 = 'OldLine1\nOldLine2';
|
||||
const str2 = '';
|
||||
|
||||
abridgedDiff(str1, str2, 1);
|
||||
|
||||
const expectedOutput = ['cyan(@@ -1,2 +1,0 @@)', 'red(-OldLine1)', 'red(-OldLine2)'].join('\n');
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
|
||||
});
|
||||
|
||||
it('should handle strings with mixed changes and context lines', () => {
|
||||
const str1 = 'Header\nLine1\nLine2\nFooter';
|
||||
const str2 = 'Header\nLine1\nLineX\nFooter';
|
||||
|
||||
abridgedDiff(str1, str2, 1);
|
||||
|
||||
const expectedOutput = [
|
||||
'cyan(@@ -3,1 +3,1 @@)',
|
||||
' gray(Line1)',
|
||||
'red(-Line2)',
|
||||
'green(+LineX)',
|
||||
' gray(Footer)',
|
||||
].join('\n');
|
||||
|
||||
expect(Log.log).toHaveBeenCalledTimes(1);
|
||||
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* DO NOT EDIT unless the same change is made in `@expo/fingerprint`
|
||||
*/
|
||||
|
||||
export interface HashSourceFile {
|
||||
type: 'file';
|
||||
filePath: string;
|
||||
|
||||
/**
|
||||
* Reasons of this source coming from
|
||||
*/
|
||||
reasons: string[];
|
||||
}
|
||||
|
||||
export interface HashSourceDir {
|
||||
type: 'dir';
|
||||
filePath: string;
|
||||
|
||||
/**
|
||||
* Reasons of this source coming from
|
||||
*/
|
||||
reasons: string[];
|
||||
}
|
||||
|
||||
export interface HashSourceContents {
|
||||
type: 'contents';
|
||||
id: string;
|
||||
contents: string | Buffer;
|
||||
|
||||
/**
|
||||
* Reasons of this source coming from
|
||||
*/
|
||||
reasons: string[];
|
||||
}
|
||||
|
||||
export type HashSource = HashSourceFile | HashSourceDir | HashSourceContents;
|
||||
|
||||
export interface Fingerprint {
|
||||
/**
|
||||
* Sources and their hash values to generate a fingerprint
|
||||
*/
|
||||
sources: FingerprintSource[];
|
||||
|
||||
/**
|
||||
* The final hash value of the whole fingerprint
|
||||
*/
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export interface DebugInfoFile {
|
||||
path: string;
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export interface DebugInfoDir {
|
||||
path: string;
|
||||
hash: string;
|
||||
children: (DebugInfoFile | DebugInfoDir | undefined)[];
|
||||
}
|
||||
|
||||
export interface DebugInfoContents {
|
||||
hash: string;
|
||||
}
|
||||
|
||||
export type DebugInfo = DebugInfoFile | DebugInfoDir | DebugInfoContents;
|
||||
|
||||
export type FingerprintSource = HashSource & {
|
||||
/**
|
||||
* Hash value of the `source`.
|
||||
* If the source is excluding by `Options.dirExcludes`, the value will be null.
|
||||
*/
|
||||
hash: string | null;
|
||||
/**
|
||||
* Debug info from the hashing process. Differs based on source type. Designed to be consumed by humans
|
||||
* as opposed to programmatically.
|
||||
*/
|
||||
debugInfo?: DebugInfo;
|
||||
};
|
||||
|
||||
export type FingerprintDiffItem =
|
||||
| {
|
||||
/**
|
||||
* The operation type of the diff item.
|
||||
*/
|
||||
op: 'added';
|
||||
/**
|
||||
* The added source.
|
||||
*/
|
||||
addedSource: FingerprintSource;
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* The operation type of the diff item.
|
||||
*/
|
||||
op: 'removed';
|
||||
/**
|
||||
* The removed source.
|
||||
*/
|
||||
removedSource: FingerprintSource;
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* The operation type of the diff item.
|
||||
*/
|
||||
op: 'changed';
|
||||
/**
|
||||
* The source before.
|
||||
*/
|
||||
beforeSource: FingerprintSource;
|
||||
/**
|
||||
* The source after.
|
||||
*/
|
||||
afterSource: FingerprintSource;
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import { Env, Workflow } from '@expo/eas-build-job';
|
||||
import { silent as silentResolveFrom } from 'resolve-from';
|
||||
|
||||
import mapMapAsync from './expodash/mapMapAsync';
|
||||
import { Fingerprint, FingerprintDiffItem } from './fingerprint';
|
||||
import Log from '../log';
|
||||
import { ora } from '../ora';
|
||||
|
||||
@@ -13,14 +14,30 @@ export type FingerprintOptions = {
|
||||
cwd?: string;
|
||||
};
|
||||
|
||||
export function diffFingerprint(
|
||||
projectDir: string,
|
||||
fingerprint1: Fingerprint,
|
||||
fingerprint2: Fingerprint
|
||||
): FingerprintDiffItem[] | null {
|
||||
// @expo/fingerprint is exported in the expo package for SDK 52+
|
||||
const fingerprintPath = silentResolveFrom(projectDir, 'expo/fingerprint');
|
||||
if (!fingerprintPath) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const Fingerprint = require(fingerprintPath);
|
||||
return Fingerprint.diffFingerprints(fingerprint1, fingerprint2);
|
||||
}
|
||||
|
||||
export async function createFingerprintAsync(
|
||||
projectDir: string,
|
||||
options: FingerprintOptions
|
||||
): Promise<{
|
||||
hash: string;
|
||||
sources: object[];
|
||||
isDebugSource: boolean;
|
||||
} | null> {
|
||||
): Promise<
|
||||
| (Fingerprint & {
|
||||
isDebugSource: boolean;
|
||||
})
|
||||
| null
|
||||
> {
|
||||
// @expo/fingerprint is exported in the expo package for SDK 52+
|
||||
const fingerprintPath = silentResolveFrom(projectDir, 'expo/fingerprint');
|
||||
if (!fingerprintPath) {
|
||||
@@ -61,11 +78,11 @@ async function createFingerprintWithoutLoggingAsync(
|
||||
projectDir: string,
|
||||
fingerprintPath: string,
|
||||
options: FingerprintOptions
|
||||
): Promise<{
|
||||
hash: string;
|
||||
sources: object[];
|
||||
isDebugSource: boolean;
|
||||
}> {
|
||||
): Promise<
|
||||
Fingerprint & {
|
||||
isDebugSource: boolean;
|
||||
}
|
||||
> {
|
||||
const Fingerprint = require(fingerprintPath);
|
||||
const fingerprintOptions: Record<string, any> = {};
|
||||
if (options.platforms) {
|
||||
@@ -99,9 +116,7 @@ export async function createFingerprintsByKeyAsync(
|
||||
): Promise<
|
||||
Map<
|
||||
string,
|
||||
{
|
||||
hash: string;
|
||||
sources: object[];
|
||||
Fingerprint & {
|
||||
isDebugSource: boolean;
|
||||
}
|
||||
>
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import chalk from 'chalk';
|
||||
import { diffLines } from 'diff';
|
||||
|
||||
import Log from '../log';
|
||||
|
||||
/**
|
||||
* Computes and prints a line-based diff between two strings, displaying changes as chunks.
|
||||
*
|
||||
* Each chunk contains lines that were added or removed, prefixed with contextual lines
|
||||
* from the unchanged parts of the strings. The output is styled similarly to `git diff`
|
||||
* with headers indicating line ranges for the changes in the original and modified strings.
|
||||
*
|
||||
* @param {string} str1 - The original string to compare.
|
||||
* @param {string} str2 - The modified string to compare against the original.
|
||||
* @param {number} [contextLines=2] - The number of unchanged lines to display before and after each chunk of changes.
|
||||
*
|
||||
* ### Output:
|
||||
* - Each chunk begins with a header in the format `@@ -<original range> +<modified range> @@`.
|
||||
* - Removed lines are prefixed with a red `-` and the original line number.
|
||||
* - Added lines are prefixed with a green `+` and the modified line number.
|
||||
* - Context lines are displayed in gray without a `+` or `-` prefix.
|
||||
*
|
||||
* ### Notes:
|
||||
* - Consecutive changes are grouped into a single chunk if separated by no more than the specified number of context lines.
|
||||
*
|
||||
* ### Example:
|
||||
* ```typescript
|
||||
* abridgedDiff("Line1\nLine2\nLine3", "Line1\nLineX\nLine3", 1);
|
||||
*
|
||||
* Output:
|
||||
* `@@ -2,1 +2,1 @@`
|
||||
* Line1
|
||||
* -Line2
|
||||
* +LineX
|
||||
* Line3
|
||||
* ```
|
||||
*/
|
||||
export function abridgedDiff(str1: string, str2: string, contextLines: number = 2): void {
|
||||
const changes = diffLines(str1, str2);
|
||||
|
||||
const output: string[] = [];
|
||||
let lineNumberOriginal = 1;
|
||||
let lineNumberModified = 1;
|
||||
|
||||
let currentChunk: string[] = [];
|
||||
let currentChunkPriorContext: string[] = [];
|
||||
let currentChunkAfterContext: string[] = [];
|
||||
let startOriginal: number | null = null; // Start line in the original for the current chunk
|
||||
let startModified: number | null = null; // Start line in the modified for the current chunk
|
||||
let addedLines = 0;
|
||||
let removedLines = 0;
|
||||
|
||||
const flushChunk = (): void => {
|
||||
if (currentChunk.length > 0) {
|
||||
const originalRange = `${startOriginal},${removedLines || 0}`;
|
||||
const modifiedRange = `${startModified},${addedLines || 0}`;
|
||||
// `git diff` style header
|
||||
output.push(chalk.cyan(`@@ -${originalRange} +${modifiedRange} @@`));
|
||||
output.push(...currentChunkPriorContext);
|
||||
output.push(...currentChunk);
|
||||
output.push(...currentChunkAfterContext);
|
||||
currentChunk = [];
|
||||
currentChunkPriorContext = [];
|
||||
currentChunkAfterContext = [];
|
||||
addedLines = 0;
|
||||
removedLines = 0;
|
||||
}
|
||||
};
|
||||
|
||||
for (const change of changes) {
|
||||
const lines = change.value.split('\n').filter(line => line);
|
||||
|
||||
if (change.added || change.removed) {
|
||||
// Initialize start lines for the chunk if not already set
|
||||
if (startOriginal === null) {
|
||||
startOriginal = lineNumberOriginal;
|
||||
}
|
||||
if (startModified === null) {
|
||||
startModified = lineNumberModified;
|
||||
}
|
||||
|
||||
if (change.removed) {
|
||||
lines.forEach(line => {
|
||||
currentChunk.push(`${chalk.red(`-${line}`)}`);
|
||||
lineNumberOriginal++;
|
||||
removedLines++;
|
||||
});
|
||||
}
|
||||
if (change.added) {
|
||||
lines.forEach(line => {
|
||||
currentChunk.push(`${chalk.green(`+${line}`)}`);
|
||||
lineNumberModified++;
|
||||
addedLines++;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Unchanged lines (context)
|
||||
lines.forEach((line, i) => {
|
||||
if (currentChunk.length > 0) {
|
||||
// Add leading context after a change
|
||||
if (i < contextLines) {
|
||||
currentChunkAfterContext.push(` ${chalk.gray(line)}`);
|
||||
}
|
||||
} else {
|
||||
// Add trailing context before a change
|
||||
if (lines.length - 1 - contextLines < i) {
|
||||
currentChunkPriorContext.push(` ${chalk.gray(line)}`);
|
||||
}
|
||||
}
|
||||
|
||||
const isFinalLineOfAfterContext = i === contextLines - 1 || i === lines.length - 1;
|
||||
|
||||
if (currentChunk.length > 0 && isFinalLineOfAfterContext) {
|
||||
flushChunk();
|
||||
}
|
||||
lineNumberOriginal++;
|
||||
lineNumberModified++;
|
||||
});
|
||||
|
||||
startOriginal = null;
|
||||
startModified = null;
|
||||
}
|
||||
}
|
||||
|
||||
flushChunk(); // Flush any remaining chunk
|
||||
Log.log(output.join('\n'));
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strict": true,
|
||||
"target": "ES2021",
|
||||
"target": "ES2022",
|
||||
"outDir": "build",
|
||||
"rootDir": "src",
|
||||
"typeRoots": ["../../ts-declarations", "../../node_modules/@types", "./node_modules/@types"]
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@expo/eas-json",
|
||||
"description": "A library for interacting with eas.json",
|
||||
"version": "13.4.0",
|
||||
"version": "14.0.3",
|
||||
"author": "Expo <[email protected]>",
|
||||
"bugs": "https://github.com/expo/eas-cli/issues",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "7.23.5",
|
||||
"@expo/eas-build-job": "1.0.149",
|
||||
"@expo/eas-build-job": "1.0.151",
|
||||
"chalk": "4.1.2",
|
||||
"env-string": "1.0.1",
|
||||
"fs-extra": "11.2.0",
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
"updatedAt": "2022-07-18T15:00:00.000Z"
|
||||
},
|
||||
"properties": {
|
||||
"$schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"cli": {
|
||||
"$ref": "#/definitions/Cli"
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ import { UnresolvedSubmitProfileSchema } from './submit/schema';
|
||||
import { AppVersionSource } from './types';
|
||||
|
||||
export const EasJsonSchema = Joi.object({
|
||||
$schema: Joi.string(),
|
||||
cli: Joi.object({
|
||||
version: Joi.string(),
|
||||
requireCommit: Joi.boolean(),
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"strict": true,
|
||||
"target": "ES2021",
|
||||
"target": "ES2022",
|
||||
"outDir": "build",
|
||||
"rootDir": "src",
|
||||
"typeRoots": ["../../node_modules/@types", "../../ts-declarations", "./node_modules/@types"]
|
||||
|
||||
@@ -1359,10 +1359,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b"
|
||||
integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==
|
||||
|
||||
"@expo/[email protected].0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-2.1.0.tgz#9cabfb9fc9dab5e7835b499804ecd6da289eb3fd"
|
||||
integrity sha512-RzZkPiPtdBuswnTM44LowiScej5M9J/OqTPjWTKSIXhB8veJwb1f5iAE1aqzsceXibOaz0F+4135XahRaPjVvw==
|
||||
"@expo/[email protected].5":
|
||||
version "2.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-2.1.5.tgz#a947697f10a7ab0f07f2d2fd075efdae9825e85e"
|
||||
integrity sha512-Yy4BWVoViYePwQk8rqvhosolS5MTTMgcsl9Aq3rzJrd1BH8C1V/h6N5xelqo+/V+ww2k8Bom7UTE1NlGcKHxRw==
|
||||
|
||||
"@expo/bunyan@^4.0.0":
|
||||
version "4.0.0"
|
||||
@@ -1382,7 +1382,27 @@
|
||||
node-forge "^1.2.1"
|
||||
nullthrows "^1.1.1"
|
||||
|
||||
"@expo/[email protected].9", "@expo/config-plugins@~9.0.0":
|
||||
"@expo/[email protected].12", "@expo/config-plugins@~9.0.10":
|
||||
version "9.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-9.0.12.tgz#f122b2dca22e135eadf6e73442da3ced0ce8aa0a"
|
||||
integrity sha512-/Ko/NM+GzvJyRkq8PITm8ms0KY5v0wmN1OQFYRMkcJqOi3PjlhndW+G6bHpJI9mkQXBaUnHwAiGLqIC3+MQ5Wg==
|
||||
dependencies:
|
||||
"@expo/config-types" "^52.0.0"
|
||||
"@expo/json-file" "~9.0.0"
|
||||
"@expo/plist" "^0.2.0"
|
||||
"@expo/sdk-runtime-versions" "^1.0.0"
|
||||
chalk "^4.1.2"
|
||||
debug "^4.3.5"
|
||||
getenv "^1.0.0"
|
||||
glob "^10.4.2"
|
||||
resolve-from "^5.0.0"
|
||||
semver "^7.5.4"
|
||||
slash "^3.0.0"
|
||||
slugify "^1.6.6"
|
||||
xcode "^3.0.1"
|
||||
xml2js "0.6.0"
|
||||
|
||||
"@expo/config-plugins@~9.0.0":
|
||||
version "9.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-9.0.9.tgz#3765c310c112e200c6715365d6023f6a05b001ed"
|
||||
integrity sha512-pbgbY3SwCMwkijhfe163J05BrTx4MqzeaV+nVgUMs7vRcjHY1tfM57Pdv6SPtgeDvZ8fvdXFXXzkJva+a7C9Bw==
|
||||
@@ -1407,7 +1427,26 @@
|
||||
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-52.0.1.tgz#327af1b72a3a9d4556f41e083e0e284dd8198b96"
|
||||
integrity sha512-vD8ZetyKV7U29lR6+NJohYeoLYTH+eNYXJeNiSOrWCz0witJYY11meMmEnpEaVbN89EfC6uauSUOa6wihtbyPQ==
|
||||
|
||||
"@expo/[email protected].4", "@expo/config@~10.0.4":
|
||||
"@expo/[email protected].6":
|
||||
version "10.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config/-/config-10.0.6.tgz#85830491bc8cce2af3f19276922a13f5578d2aa8"
|
||||
integrity sha512-xXkfPElrtxznkOZxFASJ7OPa6E9IHSjcZwj5BQ6XUF2dz5M7AFa2h5sXM8AalSaDU5tEBSgoUOjTh5957TlR8g==
|
||||
dependencies:
|
||||
"@babel/code-frame" "~7.10.4"
|
||||
"@expo/config-plugins" "~9.0.10"
|
||||
"@expo/config-types" "^52.0.0"
|
||||
"@expo/json-file" "^9.0.0"
|
||||
deepmerge "^4.3.1"
|
||||
getenv "^1.0.0"
|
||||
glob "^10.4.2"
|
||||
require-from-string "^2.0.2"
|
||||
resolve-from "^5.0.0"
|
||||
resolve-workspace-root "^2.0.0"
|
||||
semver "^7.6.0"
|
||||
slugify "^1.3.4"
|
||||
sucrase "3.35.0"
|
||||
|
||||
"@expo/config@~10.0.4":
|
||||
version "10.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@expo/config/-/config-10.0.4.tgz#a58ec3baef123e77584fbae769484bae2ee74f37"
|
||||
integrity sha512-pkvdPqKTaP6+Qvc8aTmDLQ9Dfwp98P1GO37MFKwsF5XormfN/9/eN8HfIRoM6d3uSIVKCcWW3X2yAEbNmOyfXw==
|
||||
@@ -1426,10 +1465,10 @@
|
||||
slugify "^1.3.4"
|
||||
sucrase "3.35.0"
|
||||
|
||||
"@expo/[email protected]49":
|
||||
version "1.0.149"
|
||||
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.149.tgz#5105f5083ecc9508fd419b6223c5c0b522743f97"
|
||||
integrity sha512-GW21oUHfX8gNEZYEH9PV2Zh7WpAXjrc6sHn9ycOGXCfnHMvdDzXp62j+Jv5KloIu4PnKul8lPzdxumPpfqPvRQ==
|
||||
"@expo/[email protected]51":
|
||||
version "1.0.151"
|
||||
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.151.tgz#25055a82a67b33b57b0c1308156dca967f9b1716"
|
||||
integrity sha512-9RsCCX5Sct23OzKqZ7adliBqm1sBl7sCBcdBvFAwyIUpWmQAaDhGFRm6hA+9ti7kvgJlHK+Mxm7n6BmVUMHjDg==
|
||||
dependencies:
|
||||
"@expo/logger" "1.0.117"
|
||||
joi "^17.13.1"
|
||||
@@ -1489,14 +1528,12 @@
|
||||
"@types/bunyan" "^1.8.11"
|
||||
bunyan "^1.8.15"
|
||||
|
||||
"@expo/multipart-body-parser@1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/multipart-body-parser/-/multipart-body-parser-1.1.0.tgz#ba402b3047cf14ef17b4d785ec030dd6474ae6e4"
|
||||
integrity sha512-XOaS79wFIJgx0J7oUzRb+kZsnZmFqGpisu0r8RPO3b0wjbW7xpWgiXmRR4RavKeGiVAPauZOi4vad7cJ3KCspg==
|
||||
"@expo/multipart-body-parser@2.0.0":
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@expo/multipart-body-parser/-/multipart-body-parser-2.0.0.tgz#dcd2034f3bbc29b9a6fa6ff31e5ba0caea0a2b38"
|
||||
integrity sha512-yS/wsqlj0d8ZKETEN7ro3dZtjdMhpte8wp+xUzjUQC3jizxcE0E62xgvGquJObiYUMGoCF5qRYr2t78STPEaSw==
|
||||
dependencies:
|
||||
dicer "^0.3.1"
|
||||
nullthrows "^1.1.1"
|
||||
structured-headers "^0.4.1"
|
||||
multipasta "^0.2.5"
|
||||
|
||||
"@expo/[email protected]":
|
||||
version "2.1.4"
|
||||
@@ -1608,12 +1645,12 @@
|
||||
dependencies:
|
||||
cross-spawn "^7.0.3"
|
||||
|
||||
"@expo/[email protected]0":
|
||||
version "1.0.150"
|
||||
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.150.tgz#ea148a186689575f2b33a83cd648ee2a60590aa8"
|
||||
integrity sha512-I9Urfph3e0tcIkZFlzYvMO8WBXJE5Fk3+PanbTvWkwY88aB5IMXrYM7ifHlLf0kpMK4/a9fP9arcVhbAaD/DMg==
|
||||
"@expo/[email protected]1":
|
||||
version "1.0.151"
|
||||
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.151.tgz#fde4655b87ace3add306ca81cf544de741ec56f4"
|
||||
integrity sha512-4DJD2DORbR6HPUB62tsz3W+CnO3X22Z61jui6iUrF1SjFLrYDkURmmVaiVv8tfbWhTrTvwMQR8cndN3rNqSBqQ==
|
||||
dependencies:
|
||||
"@expo/eas-build-job" "1.0.149"
|
||||
"@expo/eas-build-job" "1.0.151"
|
||||
"@expo/logger" "1.0.117"
|
||||
"@expo/spawn-async" "^1.7.2"
|
||||
arg "^5.0.2"
|
||||
@@ -3640,6 +3677,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
|
||||
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
|
||||
|
||||
"@types/[email protected]":
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/diff/-/diff-6.0.0.tgz#031f27cf57564f3cce825f38fb19fdd4349ad07a"
|
||||
integrity sha512-dhVCYGv3ZSbzmQaBSagrv1WJ6rXCdkyTcDyoNu1MD8JohI7pR7k8wdZEm+mvdxRKXyHVwckFzWU1vJc+Z29MlA==
|
||||
|
||||
"@types/[email protected]":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/envinfo/-/envinfo-7.8.3.tgz#6fccc3425e300ee377aad15423e555dc6fc12fa1"
|
||||
@@ -6080,13 +6122,6 @@ dezalgo@^1.0.0:
|
||||
asap "^2.0.0"
|
||||
wrappy "1"
|
||||
|
||||
dicer@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.1.tgz#abf28921e3475bc5e801e74e0159fd94f927ba97"
|
||||
integrity sha512-ObioMtXnmjYs3aRtpIJt9rgQSPCIhKVkFPip+E9GUDyWl8N435znUxK/JfNwGZJ2wnn5JKQ7Ly3vOK5Q5dylGA==
|
||||
dependencies:
|
||||
streamsearch "^1.1.0"
|
||||
|
||||
diff-sequences@^29.2.0:
|
||||
version "29.2.0"
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.2.0.tgz#4c55b5b40706c7b5d2c5c75999a50c56d214e8f6"
|
||||
@@ -6097,6 +6132,11 @@ diff-sequences@^29.6.3:
|
||||
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921"
|
||||
integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
|
||||
|
||||
[email protected]:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a"
|
||||
integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==
|
||||
|
||||
diff@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
@@ -10701,6 +10741,11 @@ [email protected], multimatch@^5.0.0:
|
||||
arrify "^2.0.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
multipasta@^0.2.5:
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/multipasta/-/multipasta-0.2.5.tgz#fb3564c4c619b73f98e72e2a4bbd4f7fba153edf"
|
||||
integrity sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==
|
||||
|
||||
[email protected]:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
@@ -10734,10 +10779,10 @@ nan@^2.14.0:
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
|
||||
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
|
||||
|
||||
[email protected].4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
[email protected].8:
|
||||
version "3.3.8"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
|
||||
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
@@ -13425,11 +13470,6 @@ [email protected], strong-log-transformer@^2.1.0:
|
||||
minimist "^1.2.0"
|
||||
through "^2.3.4"
|
||||
|
||||
structured-headers@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/structured-headers/-/structured-headers-0.4.1.tgz#77abd9410622c6926261c09b9d16cf10592694d1"
|
||||
integrity sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==
|
||||
|
||||
[email protected]:
|
||||
version "0.9.18"
|
||||
resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz#bcf02320c911fbadb054f7f928e51c6041a37b97"
|
||||
|
||||
Reference in new issue
Block a user