Compare commits

..
Author SHA1 Message Date
Szymon Dziedzic bbf14e2ee8 v7.1.0 2024-01-26 10:53:35 +01:00
Szymon DziedzicandStanisław Chmiela 126c5627eb [eas-json] validate EAS Submit inputs better (#2198)
* [eas-json] sanitize EAS Submit inputs better

* add link to docs

* update CHANGELOG.md

* validate app specific password

* use Joi schema for validation

* fix typo

* minor improvements

* Update packages/eas-cli/src/submit/ios/__tests__/IosSubmitCommand-test.ts

Co-authored-by: Stanisław Chmiela <[email protected]>

* make uuid validation less strict

* apply suggested changes

* fix tests

---------

Co-authored-by: Stanisław Chmiela <[email protected]>
2024-01-26 10:48:01 +01:00
Will Schurman b5f2f5286a [eas-cli] Support requireCommit for EAS Update (#2196) 2024-01-22 10:38:13 -08:00
Will Schurman 8ea05793dd [eas-cli] Remove support for classic updates release channel in 50+ (#2189) 2024-01-19 10:53:52 -08:00
Expo CI 02c8dcaa5b update CHANGELOG.md 2024-01-19 14:57:46 +00:00
Szymon Dziedzic fe1a1f14d1 v7.0.0 2024-01-19 15:51:27 +01:00
Szymon Dziedzic df7b18ca03 upgrade eas-cli-local-build-plugin to 1.0.60 2024-01-19 15:46:42 +01:00
Quinlan Jung 41142a9486 [eas-cli] Revert "[1/1][eas-cli] generate eas-update-metadata.json on publish … (#2187)
* Revert "[1/1][eas-cli] generate eas-update-metadata.json  on publish (#2158)"

This reverts commit 183fe8712b.

* lint

* update CHANGELOG.md
2024-01-18 13:59:19 -08:00
Quinlan Jung 72c28d4259 [eas-cli] use branch mapping utility fn (#2186)
* [eas-cli] use branch mapping utility fn

* update CHANGELOG.md
2024-01-18 13:58:43 -08:00
Expo CI da42962151 update CHANGELOG.md 2024-01-18 21:28:12 +00:00
Brent Vatne bbebe90876 v6.1.0 2024-01-18 13:21:18 -08:00
Will Schurman ea57d6383a [eas-cli] Upgrade packages from the expo/expo repo (#2145) 2024-01-18 11:01:00 -08:00
Szymon Dziedzic f5a99cea6b [ENG-11092][eas-json] update eas.schema.json to add support for Xcode 15.2 image (#2184)
* [eas-json] update `eas.schema.json` to add support for Xcode 15.2 image

* update CHANGELOG.md
2024-01-18 17:57:31 +01:00
44 changed files with 701 additions and 489 deletions

No files matched your search

+25 -3
View File
@@ -8,17 +8,39 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Add `build:delete` command. ([#2178](https://github.com/expo/eas-cli/pull/2178) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
- Add filter flags for `platform` and `profile` to `build:cancel` and `build:delete` commands. ([#2178](https://github.com/expo/eas-cli/pull/2178) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
- Support requireCommit for EAS Update. ([#2196](https://github.com/expo/eas-cli/pull/2196) by [@wschurman](https://github.com/wschurman))
### 🐛 Bug fixes
### 🧹 Chores
- Remove support for classic updates release channel in 50+. ([#2189](https://github.com/expo/eas-cli/pull/2189) by [@wschurman](https://github.com/wschurman))
- Validate EAS Submit inputs better. ([#2198](https://github.com/expo/eas-cli/pull/2198) by [@szdziedzic](https://github.com/szdziedzic))
## [7.0.0](https://github.com/expo/eas-cli/releases/tag/v7.0.0) - 2024-01-19
### 🛠 Breaking changes
- Stop generating eas-update-metadata.json on publish. ([#2187](https://github.com/expo/eas-cli/pull/2187) by [@quinlanj](https://github.com/quinlanj))
### 🧹 Chores
- Use branch mapping utility fn. ([#2186](https://github.com/expo/eas-cli/pull/2186) by [@quinlanj](https://github.com/quinlanj))
## [6.1.0](https://github.com/expo/eas-cli/releases/tag/v6.1.0) - 2024-01-18
### 🎉 New features
- Add `build:delete` command. ([#2178](https://github.com/expo/eas-cli/pull/2178) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
- Add filter flags for `platform` and `profile` to `build:cancel` and `build:delete` commands. ([#2178](https://github.com/expo/eas-cli/pull/2178) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
### 🧹 Chores
- Remove "bare"-specific **eas.json** template. ([#2179](https://github.com/expo/eas-cli/pull/2179) by [@sjchmiela](https://github.com/sjchmiela))
- Prompt users if they want to continue if EAS CLI fails to provision the devices. ([#2181](https://github.com/expo/eas-cli/pull/2181) by [@szdziedzic](https://github.com/szdziedzic))
- Update `eas-cli` and `@expo/eas-json` dependencies. ([#2176](https://github.com/expo/eas-cli/pull/2176) by [@szdziedzic](https://github.com/szdziedzic))
- Prompt user to map channel on update if unmapped. ([#2185](https://github.com/expo/eas-cli/pull/2185) by [@quinlanj](https://github.com/quinlanj))
- Update `eas.schema.json` to after adding Xcode 15.2 image. ([#2184](https://github.com/expo/eas-cli/pull/2184) by [@szdziedzic](https://github.com/szdziedzic))
- Upgrade packages from the expo/expo repo. ([#2145](https://github.com/expo/eas-cli/pull/2145) by [@wschurman](https://github.com/wschurman))
## [6.0.0](https://github.com/expo/eas-cli/releases/tag/v6.0.0) - 2024-01-12
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "6.0.0",
"version": "7.1.0",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+81 -59
View File
@@ -68,6 +68,7 @@ eas --help COMMAND
* [`eas build`](#eas-build)
* [`eas build:cancel [BUILD_ID]`](#eas-buildcancel-build_id)
* [`eas build:configure`](#eas-buildconfigure)
* [`eas build:delete [BUILD_ID]`](#eas-builddelete-build_id)
* [`eas build:inspect`](#eas-buildinspect)
* [`eas build:list`](#eas-buildlist)
* [`eas build:resign`](#eas-buildresign)
@@ -135,7 +136,7 @@ ALIASES
$ eas login
```
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/account/login.ts)_
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/account/login.ts)_
## `eas account:logout`
@@ -152,7 +153,7 @@ ALIASES
$ eas logout
```
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/account/logout.ts)_
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/account/logout.ts)_
## `eas account:view`
@@ -169,7 +170,7 @@ ALIASES
$ eas whoami
```
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/account/view.ts)_
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -183,7 +184,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/analytics.ts)_
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -235,7 +236,7 @@ DESCRIPTION
create a branch
```
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/branch/create.ts)_
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -256,7 +257,7 @@ DESCRIPTION
delete a branch
```
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/branch/delete.ts)_
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -276,7 +277,7 @@ DESCRIPTION
list all branches
```
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/branch/list.ts)_
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -296,7 +297,7 @@ DESCRIPTION
rename a branch
```
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/branch/rename.ts)_
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -319,7 +320,7 @@ DESCRIPTION
view a branch
```
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/branch/view.ts)_
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/branch/view.ts)_
## `eas build`
@@ -349,7 +350,7 @@ DESCRIPTION
start a build
```
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/index.ts)_
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -357,16 +358,18 @@ cancel a build
```
USAGE
$ eas build:cancel [BUILD_ID] [--non-interactive]
$ eas build:cancel [BUILD_ID] [--non-interactive] [-p android|ios|all] [-e <value>]
FLAGS
--non-interactive Run the command in non-interactive mode.
-e, --profile=PROFILE_NAME Filter builds by build profile if build ID is not provided
-p, --platform=(android|ios|all) Filter builds by the platform if build ID is not provided
--non-interactive Run the command in non-interactive mode.
DESCRIPTION
cancel a build
```
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/cancel.ts)_
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -383,7 +386,26 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/configure.ts)_
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
delete a build
```
USAGE
$ eas build:delete [BUILD_ID] [--non-interactive] [-p android|ios|all] [-e <value>]
FLAGS
-e, --profile=PROFILE_NAME Filter builds by build profile if build ID is not provided
-p, --platform=(android|ios|all) Filter builds by the platform if build ID is not provided
--non-interactive Run the command in non-interactive mode.
DESCRIPTION
delete a build
```
_See code: [src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/delete.ts)_
## `eas build:inspect`
@@ -418,7 +440,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/inspect.ts)_
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -456,7 +478,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/list.ts)_
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/list.ts)_
## `eas build:resign`
@@ -482,7 +504,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/resign.ts)_
_See code: [src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/resign.ts)_
## `eas build:run`
@@ -508,7 +530,7 @@ DESCRIPTION
run simulator/emulator builds from eas-cli
```
_See code: [src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/run.ts)_
_See code: [src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/run.ts)_
## `eas build:submit`
@@ -557,7 +579,7 @@ DESCRIPTION
get the latest version from EAS servers
```
_See code: [src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/version/get.ts)_
_See code: [src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -576,7 +598,7 @@ DESCRIPTION
update version of an app
```
_See code: [src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/version/set.ts)_
_See code: [src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -595,7 +617,7 @@ DESCRIPTION
update a version in native code with a value stored on EAS servers
```
_See code: [src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/version/sync.ts)_
_See code: [src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -612,7 +634,7 @@ DESCRIPTION
view a build for your project
```
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/build/view.ts)_
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -633,7 +655,7 @@ DESCRIPTION
create a channel
```
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/channel/create.ts)_
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -655,7 +677,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/channel/edit.ts)_
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -675,7 +697,7 @@ DESCRIPTION
list all channels
```
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/channel/list.ts)_
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/channel/list.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -707,7 +729,7 @@ DESCRIPTION
Roll a new branch out on a channel incrementally.
```
_See code: [src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/channel/rollout.ts)_
_See code: [src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -730,7 +752,7 @@ DESCRIPTION
view a channel
```
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/channel/view.ts)_
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/channel/view.ts)_
## `eas config`
@@ -751,7 +773,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/config.ts)_
## `eas credentials`
@@ -768,7 +790,7 @@ DESCRIPTION
manage credentials
```
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/credentials.ts)_
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/credentials.ts)_
## `eas device:create`
@@ -782,7 +804,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/device/create.ts)_
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/device/create.ts)_
## `eas device:delete`
@@ -802,7 +824,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/device/delete.ts)_
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/device/delete.ts)_
## `eas device:list`
@@ -823,7 +845,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/device/list.ts)_
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/device/list.ts)_
## `eas device:rename`
@@ -844,7 +866,7 @@ DESCRIPTION
rename a registered device
```
_See code: [src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/device/rename.ts)_
_See code: [src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -858,7 +880,7 @@ DESCRIPTION
view a device for your project
```
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/device/view.ts)_
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -872,7 +894,7 @@ DESCRIPTION
display environment info
```
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/diagnostics.ts)_
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -960,7 +982,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/metadata/lint.ts)_
_See code: [src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -977,7 +999,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/metadata/pull.ts)_
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -994,7 +1016,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/metadata/push.ts)_
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/metadata/push.ts)_
## `eas open`
@@ -1008,7 +1030,7 @@ DESCRIPTION
open the project page in a web browser
```
_See code: [src/commands/open.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/open.ts)_
_See code: [src/commands/open.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/open.ts)_
## `eas project:info`
@@ -1022,7 +1044,7 @@ DESCRIPTION
information about the current project
```
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/project/info.ts)_
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/project/info.ts)_
## `eas project:init`
@@ -1044,7 +1066,7 @@ ALIASES
$ eas init
```
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/project/init.ts)_
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/project/init.ts)_
## `eas secret:create`
@@ -1067,7 +1089,7 @@ DESCRIPTION
create an environment secret on the current project or owner account
```
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/secret/create.ts)_
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/secret/create.ts)_
## `eas secret:delete`
@@ -1085,7 +1107,7 @@ DESCRIPTION
delete an environment secret by ID
```
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/secret/delete.ts)_
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/secret/delete.ts)_
## `eas secret:list`
@@ -1099,7 +1121,7 @@ DESCRIPTION
list environment secrets available for your current app
```
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/secret/list.ts)_
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/secret/list.ts)_
## `eas secret:push`
@@ -1119,7 +1141,7 @@ DESCRIPTION
read environment secrets from env file and store on the server
```
_See code: [src/commands/secret/push.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/secret/push.ts)_
_See code: [src/commands/secret/push.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/secret/push.ts)_
## `eas submit`
@@ -1149,7 +1171,7 @@ ALIASES
$ eas build:submit
```
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/submit.ts)_
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/submit.ts)_
## `eas update`
@@ -1183,7 +1205,7 @@ DESCRIPTION
publish an update group
```
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/index.ts)_
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1201,7 +1223,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/configure.ts)_
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1222,7 +1244,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/delete.ts)_
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/delete.ts)_
## `eas update:list`
@@ -1244,7 +1266,7 @@ DESCRIPTION
view the recent updates
```
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/list.ts)_
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1271,7 +1293,7 @@ DESCRIPTION
roll back to an existing update
```
_See code: [src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/republish.ts)_
_See code: [src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/republish.ts)_
## `eas update:roll-back-to-embedded`
@@ -1298,7 +1320,7 @@ DESCRIPTION
roll back to the embedded update
```
_See code: [src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/roll-back-to-embedded.ts)_
_See code: [src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
@@ -1317,7 +1339,7 @@ DESCRIPTION
roll back to an embedded update or an existing update
```
_See code: [src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/rollback.ts)_
_See code: [src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -1337,7 +1359,7 @@ DESCRIPTION
update group details
```
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/update/view.ts)_
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1358,7 +1380,7 @@ DESCRIPTION
create a webhook
```
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/webhook/create.ts)_
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1378,7 +1400,7 @@ DESCRIPTION
delete a webhook
```
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/webhook/delete.ts)_
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1396,7 +1418,7 @@ DESCRIPTION
list webhooks
```
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/webhook/list.ts)_
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1418,7 +1440,7 @@ DESCRIPTION
update a webhook
```
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/webhook/update.ts)_
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1435,7 +1457,7 @@ DESCRIPTION
view a webhook
```
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v6.0.0/src/commands/webhook/view.ts)_
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v7.1.0/src/commands/webhook/view.ts)_
## `eas whoami`
+7 -7
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "6.0.0",
"version": "7.1.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -10,11 +10,11 @@
"dependencies": {
"@expo/apple-utils": "1.3.2",
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "8.1.2",
"@expo/config-plugins": "7.2.4",
"@expo/config-types": "49.0.0",
"@expo/eas-build-job": "1.0.56",
"@expo/eas-json": "6.0.0",
"@expo/config": "8.5.4",
"@expo/config-plugins": "7.8.4",
"@expo/config-types": "50.0.0",
"@expo/eas-build-job": "1.0.59",
"@expo/eas-json": "7.1.0",
"@expo/json-file": "8.2.37",
"@expo/multipart-body-parser": "1.1.0",
"@expo/osascript": "2.0.33",
@@ -23,7 +23,7 @@
"@expo/plist": "0.0.20",
"@expo/plugin-help": "5.1.23",
"@expo/plugin-warn-if-update-available": "2.5.1",
"@expo/prebuild-config": "6.2.5",
"@expo/prebuild-config": "6.7.3",
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.7.0",
+1 -2
View File
@@ -99,14 +99,13 @@ export async function prepareAndroidBuildAsync(
return await ensureAndroidCredentialsAsync(ctx);
},
syncProjectConfigurationAsync: async () => {
await syncProjectConfigurationAsync(ctx.graphqlClient, {
await syncProjectConfigurationAsync({
projectDir: ctx.projectDir,
exp: ctx.exp,
localAutoIncrement:
ctx.easJsonCliConfig?.appVersionSource === AppVersionSource.REMOTE
? false
: ctx.buildProfile.autoIncrement,
projectId: ctx.projectId,
vcsClient: ctx.vcsClient,
});
},
@@ -7,36 +7,30 @@ import fs from 'fs-extra';
import path from 'path';
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import Log from '../../log';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { syncUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
import { Client } from '../../vcs/vcs';
export async function syncProjectConfigurationAsync(
graphqlClient: ExpoGraphqlClient,
{
projectDir,
exp,
localAutoIncrement,
projectId,
vcsClient,
}: {
projectDir: string;
exp: ExpoConfig;
localAutoIncrement?: AndroidVersionAutoIncrement;
projectId: string;
vcsClient: Client;
}
): Promise<void> {
export async function syncProjectConfigurationAsync({
projectDir,
exp,
localAutoIncrement,
vcsClient,
}: {
projectDir: string;
exp: ExpoConfig;
localAutoIncrement?: AndroidVersionAutoIncrement;
vcsClient: Client;
}): Promise<void> {
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID, vcsClient);
const versionBumpStrategy = resolveVersionBumpStrategy(localAutoIncrement ?? false);
if (workflow === Workflow.GENERIC) {
await cleanUpOldEasBuildGradleScriptAsync(projectDir);
if (isExpoUpdatesInstalled(projectDir)) {
await syncUpdatesConfigurationAsync(graphqlClient, projectDir, exp, projectId);
await syncUpdatesConfigurationAsync(projectDir, exp);
}
await bumpVersionAsync({ projectDir, exp, bumpStrategy: versionBumpStrategy });
} else {
@@ -232,7 +232,9 @@ export async function resolveRemoteVersionCodeAsync(
applicationIdentifier: applicationId,
storeVersion: localVersions.appVersion ?? exp.version ?? '1.0.0',
buildVersion: currentBuildVersion,
runtimeVersion: Updates.getRuntimeVersionNullable(exp, Platform.ANDROID) ?? undefined,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.ANDROID)) ??
undefined,
});
spinner.succeed(`Initialized versionCode with ${chalk.bold(currentBuildVersion)}.`);
} catch (err) {
@@ -254,7 +256,9 @@ export async function resolveRemoteVersionCodeAsync(
applicationIdentifier: applicationId,
storeVersion: localVersions.appVersion ?? exp.version ?? '1.0.0',
buildVersion: String(nextBuildVersion),
runtimeVersion: Updates.getRuntimeVersionNullable(exp, Platform.ANDROID) ?? undefined,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.ANDROID)) ??
undefined,
});
spinner.succeed(
`Incremented versionCode from ${chalk.bold(currentBuildVersion)} to ${chalk.bold(
+1 -2
View File
@@ -80,7 +80,7 @@ export async function prepareIosBuildAsync(
return ensureIosCredentialsAsync(ctx, ctx.ios.targets);
},
syncProjectConfigurationAsync: async () => {
await syncProjectConfigurationAsync(ctx.graphqlClient, {
await syncProjectConfigurationAsync({
projectDir: ctx.projectDir,
exp: ctx.exp,
targets: ctx.ios.targets,
@@ -88,7 +88,6 @@ export async function prepareIosBuildAsync(
ctx.easJsonCliConfig?.appVersionSource === AppVersionSource.REMOTE
? false
: ctx.buildProfile.autoIncrement,
projectId: ctx.projectId,
vcsClient: ctx.vcsClient,
});
},
@@ -3,37 +3,31 @@ import { Platform, Workflow } from '@expo/eas-build-job';
import { IosVersionAutoIncrement } from '@expo/eas-json';
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { Target } from '../../credentials/ios/types';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { syncUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
import { Client } from '../../vcs/vcs';
export async function syncProjectConfigurationAsync(
graphqlClient: ExpoGraphqlClient,
{
projectDir,
exp,
targets,
localAutoIncrement,
projectId,
vcsClient,
}: {
projectDir: string;
exp: ExpoConfig;
targets: Target[];
localAutoIncrement?: IosVersionAutoIncrement;
projectId: string;
vcsClient: Client;
}
): Promise<void> {
export async function syncProjectConfigurationAsync({
projectDir,
exp,
targets,
localAutoIncrement,
vcsClient,
}: {
projectDir: string;
exp: ExpoConfig;
targets: Target[];
localAutoIncrement?: IosVersionAutoIncrement;
vcsClient: Client;
}): Promise<void> {
const workflow = await resolveWorkflowAsync(projectDir, Platform.IOS, vcsClient);
const versionBumpStrategy = resolveVersionBumpStrategy(localAutoIncrement ?? false);
if (workflow === Workflow.GENERIC) {
if (isExpoUpdatesInstalled(projectDir)) {
await syncUpdatesConfigurationAsync(graphqlClient, vcsClient, projectDir, exp, projectId);
await syncUpdatesConfigurationAsync(vcsClient, projectDir, exp);
}
await bumpVersionAsync({ projectDir, exp, bumpStrategy: versionBumpStrategy, targets });
} else {
+6 -2
View File
@@ -342,7 +342,9 @@ export async function resolveRemoteBuildNumberAsync(
applicationIdentifier: applicationTarget.bundleIdentifier,
storeVersion: localShortVersion ?? '1.0.0',
buildVersion: currentBuildVersion,
runtimeVersion: Updates.getRuntimeVersionNullable(exp, Platform.IOS) ?? undefined,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.IOS)) ??
undefined,
});
spinner.succeed(`Initialized buildNumber with ${chalk.bold(currentBuildVersion)}.`);
} catch (err) {
@@ -364,7 +366,9 @@ export async function resolveRemoteBuildNumberAsync(
applicationIdentifier: applicationTarget.bundleIdentifier,
storeVersion: localShortVersion ?? '1.0.0',
buildVersion: nextBuildVersion,
runtimeVersion: Updates.getRuntimeVersionNullable(exp, Platform.IOS) ?? undefined,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.IOS)) ??
undefined,
});
spinner.succeed(
`Incremented buildNumber from ${chalk.bold(currentBuildVersion)} to ${chalk.bold(
+1 -1
View File
@@ -6,7 +6,7 @@ import semver from 'semver';
import { ora } from '../ora';
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
const PLUGIN_PACKAGE_VERSION = '1.0.56';
const PLUGIN_PACKAGE_VERSION = '1.0.60';
export enum LocalBuildMode {
/**
+17 -5
View File
@@ -9,7 +9,11 @@ import { BuildContext } from './context';
import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios/version';
import { LocalBuildMode } from './local';
import Log from '../log';
import { getUsername, isExpoUpdatesInstalled } from '../project/projectUtils';
import {
getUsername,
isClassicUpdatesSupportedAsync,
isExpoUpdatesInstalled,
} from '../project/projectUtils';
import {
readChannelSafelyAsync as readAndroidChannelSafelyAsync,
readReleaseChannelSafelyAsync as readAndroidReleaseChannelSafelyAsync,
@@ -35,7 +39,9 @@ export async function collectMetadataAsync<T extends Platform>(
workflow: ctx.workflow,
credentialsSource: ctx.buildProfile.credentialsSource,
sdkVersion: ctx.exp.sdkVersion,
runtimeVersion: Updates.getRuntimeVersionNullable(ctx.exp, ctx.platform) ?? undefined,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(ctx.projectDir, ctx.exp, ctx.platform)) ??
undefined,
reactNativeVersion: await getReactNativeVersionAsync(ctx.projectDir),
...channelOrReleaseChannel,
distribution,
@@ -123,13 +129,19 @@ async function resolveChannelOrReleaseChannelAsync<T extends Platform>(
if (ctx.buildProfile.channel) {
return { channel: ctx.buildProfile.channel };
}
if (ctx.buildProfile.releaseChannel) {
return { releaseChannel: ctx.buildProfile.releaseChannel };
}
const channel = await getNativeChannelAsync(ctx);
if (channel) {
return { channel };
}
if (!(await isClassicUpdatesSupportedAsync(ctx.projectDir))) {
return null;
}
if (ctx.buildProfile.releaseChannel) {
return { releaseChannel: ctx.buildProfile.releaseChannel };
}
const releaseChannel = await getNativeReleaseChannelAsync(ctx);
return { releaseChannel };
}
@@ -334,7 +334,6 @@ async function prepareAndStartBuildAsync({
);
if (buildProfile.profile.channel) {
await validateExpoUpdatesInstalledAsProjectDependencyAsync({
graphqlClient,
exp: buildCtx.exp,
projectId: buildCtx.projectId,
projectDir,
@@ -479,7 +478,6 @@ async function maybeDownloadAndRunSimulatorBuildsAsync(
async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
exp,
graphqlClient,
projectId,
projectDir,
vcsClient,
@@ -487,7 +485,6 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
nonInteractive,
sdkVersion,
}: {
graphqlClient: ExpoGraphqlClient;
exp: ExpoConfig;
projectId: string;
projectDir: string;
@@ -516,7 +513,7 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
message: `Would you like to install the "expo-updates" package and configure EAS Update now?`,
});
if (installExpoUpdates) {
await ensureEASUpdateIsConfiguredAsync(graphqlClient, {
await ensureEASUpdateIsConfiguredAsync({
exp,
projectId,
projectDir,
@@ -11,10 +11,7 @@ import { isExpoUpdatesInstalled, isUsingEASUpdate } from '../../project/projectU
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync } from '../../prompts';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
import {
ensureEASUpdateIsConfiguredInEasJsonAsync,
ensureUseClassicUpdatesIsRemovedAsync,
} from '../../update/configure';
import { ensureEASUpdateIsConfiguredInEasJsonAsync } from '../../update/configure';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
export default class BuildConfigure extends EasCommand {
@@ -38,7 +35,6 @@ export default class BuildConfigure extends EasCommand {
const { flags } = await this.parse(BuildConfigure);
const {
privateProjectConfig: { exp, projectId, projectDir },
loggedIn: { graphqlClient },
vcsClient,
} = await this.getContextAsync(BuildConfigure, {
nonInteractive: false,
@@ -70,12 +66,6 @@ export default class BuildConfigure extends EasCommand {
vcsClient,
});
if (didCreateEasJson && isUsingEASUpdate(exp, projectId)) {
if (exp.updates?.useClassicUpdates) {
// NOTE: this method modifies the Expo config; be sure to use this function's return value
// if the config object is used later in the future
await ensureUseClassicUpdatesIsRemovedAsync({ exp, projectDir });
}
await ensureEASUpdateIsConfiguredInEasJsonAsync(projectDir);
}
@@ -84,20 +74,14 @@ export default class BuildConfigure extends EasCommand {
if ([RequestedPlatform.Android, RequestedPlatform.All].includes(platform)) {
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID, vcsClient);
if (workflow === Workflow.GENERIC) {
await syncAndroidUpdatesConfigurationAsync(graphqlClient, projectDir, exp, projectId);
await syncAndroidUpdatesConfigurationAsync(projectDir, exp);
}
}
if ([RequestedPlatform.Ios, RequestedPlatform.All].includes(platform)) {
const workflow = await resolveWorkflowAsync(projectDir, Platform.IOS, vcsClient);
if (workflow === Workflow.GENERIC) {
await syncIosUpdatesConfigurationAsync(
graphqlClient,
vcsClient,
projectDir,
exp,
projectId
);
await syncIosUpdatesConfigurationAsync(vcsClient, projectDir, exp);
}
}
}
@@ -1,4 +1,4 @@
import { getRuntimeVersionNullable } from '@expo/config-plugins/build/utils/Updates';
import { getRuntimeVersionNullableAsync } from '@expo/config-plugins/build/utils/Updates';
import { Platform } from '@expo/eas-build-job';
import { EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import { Flags } from '@oclif/core';
@@ -116,7 +116,8 @@ export default class BuildVersionSetView extends EasCommand {
applicationIdentifier,
storeVersion: exp.version ?? '1.0.0',
buildVersion: String(version),
runtimeVersion: getRuntimeVersionNullable(exp, platform) ?? undefined,
runtimeVersion:
(await getRuntimeVersionNullableAsync(projectDir, exp, platform)) ?? undefined,
});
}
}
@@ -4,7 +4,11 @@ import { print } from 'graphql';
import gql from 'graphql-tag';
import { selectBranchOnAppAsync } from '../../branch/queries';
import { hasEmptyBranchMap, hasStandardBranchMap } from '../../channel/branch-mapping';
import {
getAlwaysTrueBranchMapping,
hasEmptyBranchMap,
hasStandardBranchMap,
} from '../../channel/branch-mapping';
import { selectChannelOnAppAsync } from '../../channel/queries';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
@@ -124,11 +128,7 @@ export default class ChannelEdit extends EasCommand {
const channel = await updateChannelBranchMappingAsync(graphqlClient, {
channelId: existingChannel.id,
// todo: move branch mapping logic to utility
branchMapping: JSON.stringify({
data: [{ branchId: branch.id, branchMappingLogic: 'true' }],
version: 0,
}),
branchMapping: JSON.stringify(getAlwaysTrueBranchMapping(branch.id)),
});
if (json) {
@@ -132,7 +132,7 @@ export default class ChannelRollout extends EasCommand {
const { args, flags } = await this.parse(ChannelRollout);
const argsAndFlags = this.sanitizeArgsAndFlags({ ...flags, ...args });
const {
privateProjectConfig: { exp, projectId },
privateProjectConfig: { exp, projectId, projectDir },
loggedIn: { graphqlClient },
} = await this.getContextAsync(ChannelRollout, {
nonInteractive: argsAndFlags.nonInteractive,
@@ -141,9 +141,8 @@ export default class ChannelRollout extends EasCommand {
enableJsonOutput();
}
const app = { projectId, exp };
const app = { projectId, exp, projectDir };
const ctx = {
projectId,
nonInteractive: argsAndFlags.nonInteractive,
graphqlClient,
app,
@@ -1,30 +0,0 @@
import { ExpoConfig } from '@expo/config';
import { instance, mock } from 'ts-mockito';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { ensureEASUpdateIsConfiguredAsync } from '../../../update/configure';
import { Client } from '../../../vcs/vcs';
describe(ensureEASUpdateIsConfiguredAsync, () => {
it('errors with "useClassicUpdates" set and no app.json', async () => {
const graphqlClient = instance(mock<ExpoGraphqlClient>({}));
const vcsClient = instance(mock<Client>({}));
const exp: ExpoConfig = {
name: 'test',
slug: 'test',
updates: { useClassicUpdates: true },
};
await expect(async () => {
await ensureEASUpdateIsConfiguredAsync(graphqlClient, {
exp,
projectId: 'test',
projectDir: '/tmp/test',
platform: null,
vcsClient,
});
}).rejects.toThrow(
`Your app config sets "updates.useClassicUpdates" but EAS Update does not support classic updates. Remove "useClassicUpdates" from your app config and run this command again.`
);
});
});
@@ -324,7 +324,7 @@ function mockTestExport({
uniqueUploadedAssetPaths: [],
});
jest.mocked(Updates.getRuntimeVersion).mockReturnValue(runtimeVersion);
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
return { inputDir: exportDir, platforms, runtimeVersion };
}
@@ -84,7 +84,7 @@ describe(UpdateRollBackToEmbedded.name, () => {
mockTestProject();
const platforms = ['android', 'ios'];
const runtimeVersion = 'exposdk:47.0.0';
jest.mocked(Updates.getRuntimeVersion).mockReturnValue(runtimeVersion);
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
@@ -106,7 +106,7 @@ describe(UpdateRollBackToEmbedded.name, () => {
const { projectId } = mockTestProject();
const platforms = ['android', 'ios'];
const runtimeVersion = 'exposdk:47.0.0';
jest.mocked(Updates.getRuntimeVersion).mockReturnValue(runtimeVersion);
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
jest.mocked(getBranchNameFromChannelNameAsync).mockResolvedValue('branchFromChannel');
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
@@ -154,7 +154,7 @@ describe(UpdateRollBackToEmbedded.name, () => {
const platforms = ['ios'];
const runtimeVersion = 'exposdk:47.0.0';
jest.mocked(Updates.getRuntimeVersion).mockReturnValue(runtimeVersion);
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
// Mock an existing branch, so we don't create a new one
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
@@ -35,7 +35,6 @@ export default class UpdateConfigure extends EasCommand {
const platform = flags.platform as RequestedPlatform;
const {
privateProjectConfig: { projectId, exp, projectDir },
loggedIn: { graphqlClient },
vcsClient,
} = await this.getContextAsync(UpdateConfigure, {
nonInteractive: flags['non-interactive'],
@@ -47,7 +46,7 @@ export default class UpdateConfigure extends EasCommand {
await vcsClient.ensureRepoExistsAsync();
await ensureEASUpdateIsConfiguredAsync(graphqlClient, {
await ensureEASUpdateIsConfiguredAsync({
exp,
projectId,
projectDir,
@@ -4,6 +4,7 @@ import chalk from 'chalk';
import nullthrows from 'nullthrows';
import { ensureBranchExistsAsync } from '../../branch/queries';
import { ensureRepoIsCleanAsync } from '../../build/utils/repository';
import { getUpdateGroupUrl } from '../../build/utils/url';
import { ensureChannelExistsAsync } from '../../channel/queries';
import EasCommand from '../../commandUtils/EasCommand';
@@ -29,7 +30,6 @@ import {
collectAssetsAsync,
defaultPublishPlatforms,
filterExportedPlatformsByFlag,
generateEasMetadataAsync,
getBranchNameForCommandAsync,
getRequestedPlatform,
getRuntimeToPlatformMappingFromRuntimeVersions,
@@ -189,6 +189,9 @@ export default class UpdatePublish extends EasCommand {
enableJsonOutput();
}
await vcsClient.ensureRepoExistsAsync();
await ensureRepoIsCleanAsync(vcsClient, nonInteractive);
const {
exp: expPossiblyWithoutEasUpdateConfigured,
projectId,
@@ -197,7 +200,7 @@ export default class UpdatePublish extends EasCommand {
await maybeWarnAboutEasOutagesAsync(graphqlClient, [StatuspageServiceName.EasUpdate]);
await ensureEASUpdateIsConfiguredAsync(graphqlClient, {
await ensureEASUpdateIsConfiguredAsync({
exp: expPossiblyWithoutEasUpdateConfigured,
platform: getRequestedPlatform(platformFlag),
projectDir,
@@ -469,9 +472,6 @@ export default class UpdatePublish extends EasCommand {
throw e;
}
if (!skipBundler) {
await generateEasMetadataAsync(distRoot, getUpdateJsonInfosForUpdates(newUpdates));
}
if (jsonFlag) {
printJsonOnlyOutput(getUpdateJsonInfosForUpdates(newUpdates));
} else {
@@ -293,12 +293,7 @@ async function askUpdatesFromChannelNameAsync(
nonInteractive,
}: { projectId: string; channelName: string; json: boolean; nonInteractive: boolean }
): Promise<UpdateToRepublish[]> {
const branchName = await getBranchNameFromChannelNameAsync(
graphqlClient,
projectId,
channelName,
{ json, nonInteractive, offset: 0 }
);
const branchName = await getBranchNameFromChannelNameAsync(graphqlClient, projectId, channelName);
return await askUpdatesFromBranchNameAsync(graphqlClient, {
projectId,
@@ -148,7 +148,7 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
await maybeWarnAboutEasOutagesAsync(graphqlClient, [StatuspageServiceName.EasUpdate]);
await ensureEASUpdateIsConfiguredAsync(graphqlClient, {
await ensureEASUpdateIsConfiguredAsync({
exp: expPossiblyWithoutEasUpdateConfigured,
platform: getRequestedPlatform(platformFlag),
projectDir,
@@ -5,6 +5,6 @@ export function createCtxMock(options: { nonInteractive?: boolean } = {}): EASUp
return {
graphqlClient: jest.fn() as any,
nonInteractive: options.nonInteractive ?? false,
app: { exp: testAppJson, projectId: 'test-project-id' },
app: { exp: testAppJson, projectId: 'test-project-id', projectDir: '/' },
};
}
+1 -1
View File
@@ -5,7 +5,7 @@ import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGr
export type EASUpdateContext = {
graphqlClient: ExpoGraphqlClient;
nonInteractive: boolean;
app: { exp: ExpoConfig; projectId: string };
app: { exp: ExpoConfig; projectId: string; projectDir: string };
};
export interface EASUpdateAction<T = any> {
+26 -13
View File
@@ -88,6 +88,17 @@ export function isUsingEASUpdate(exp: ExpoConfig, projectId: string): boolean {
return exp.updates?.url === getEASUpdateURL(projectId);
}
async function getExpoUpdatesPackageVersionIfInstalledAsync(
projectDir: string
): Promise<string | null> {
const maybePackageJson = resolveFrom.silent(projectDir, 'expo-updates/package.json');
if (!maybePackageJson) {
return null;
}
const { version } = await fs.readJson(maybePackageJson);
return version ?? null;
}
export async function validateAppVersionRuntimePolicySupportAsync(
projectDir: string,
exp: ExpoConfig
@@ -96,12 +107,9 @@ export async function validateAppVersionRuntimePolicySupportAsync(
return;
}
const maybePackageJson = resolveFrom.silent(projectDir, 'expo-updates/package.json');
if (maybePackageJson) {
const { version } = await fs.readJson(maybePackageJson);
if (semver.gte(version, '0.14.4')) {
return;
}
const expoUpdatesPackageVersion = await getExpoUpdatesPackageVersionIfInstalledAsync(projectDir);
if (expoUpdatesPackageVersion !== null && semver.gte(expoUpdatesPackageVersion, '0.14.4')) {
return;
}
Log.warn(
@@ -112,13 +120,9 @@ export async function validateAppVersionRuntimePolicySupportAsync(
export async function enforceRollBackToEmbeddedUpdateSupportAsync(
projectDir: string
): Promise<void> {
const maybePackageJson = resolveFrom.silent(projectDir, 'expo-updates/package.json');
if (maybePackageJson) {
const { version } = await fs.readJson(maybePackageJson);
if (semver.gte(version, '0.19.0')) {
return;
}
const expoUpdatesPackageVersion = await getExpoUpdatesPackageVersionIfInstalledAsync(projectDir);
if (expoUpdatesPackageVersion !== null && semver.gte(expoUpdatesPackageVersion, '0.19.0')) {
return;
}
throw new Error(
@@ -128,6 +132,15 @@ export async function enforceRollBackToEmbeddedUpdateSupportAsync(
);
}
export async function isClassicUpdatesSupportedAsync(projectDir: string): Promise<boolean> {
const expoUpdatesPackageVersion = await getExpoUpdatesPackageVersionIfInstalledAsync(projectDir);
if (expoUpdatesPackageVersion === null) {
return false;
}
return semver.lt(expoUpdatesPackageVersion, '0.19.0');
}
export async function installExpoUpdatesAsync(
projectDir: string,
options?: { silent: boolean }
+18 -33
View File
@@ -24,11 +24,7 @@ import Log, { learnMore } from '../log';
import { RequestedPlatform, requestedPlatformDisplayNames } from '../platform';
import { promptAsync } from '../prompts';
import { getBranchNameFromChannelNameAsync } from '../update/getBranchNameFromChannelNameAsync';
import {
UpdateJsonInfo,
formatUpdateMessage,
truncateString as truncateUpdateMessage,
} from '../update/utils';
import { formatUpdateMessage, truncateString as truncateUpdateMessage } from '../update/utils';
import { PresignedPost, uploadWithPresignedPostWithRetryAsync } from '../uploads';
import {
expoCommandAsync,
@@ -298,14 +294,6 @@ export function loadMetadata(distRoot: string): Metadata {
return metadata;
}
export async function generateEasMetadataAsync(
distRoot: string,
metadata: UpdateJsonInfo[]
): Promise<void> {
const easMetadataPath = path.join(distRoot, 'eas-update-metadata.json');
await JsonFile.writeAsync(easMetadataPath, { updates: metadata });
}
export function filterExportedPlatformsByFlag<T extends Partial<Record<Platform, any>>>(
record: T,
platformFlag: ExpoCLIExportPlatformFlag
@@ -575,12 +563,7 @@ export async function getBranchNameForCommandAsync({
}
if (channelNameArg) {
return await getBranchNameFromChannelNameAsync(
graphqlClient,
projectId,
channelNameArg,
paginatedQueryOptions
);
return await getBranchNameFromChannelNameAsync(graphqlClient, projectId, channelNameArg);
}
if (branchNameArg) {
@@ -722,20 +705,22 @@ export async function getRuntimeVersionObjectAsync(
}
}
return [...new Set(platforms)].map(platform => {
if (platform === 'web') {
return { platform: 'web', runtimeVersion: 'UNVERSIONED' };
}
return {
platform,
runtimeVersion: nullthrows(
Updates.getRuntimeVersion(exp, platform),
`Unable to determine runtime version for ${
requestedPlatformDisplayNames[platform]
}. ${learnMore('https://docs.expo.dev/eas-update/runtime-versions/')}`
),
};
});
return await Promise.all(
[...new Set(platforms)].map(async platform => {
if (platform === 'web') {
return { platform: 'web', runtimeVersion: 'UNVERSIONED' };
}
return {
platform,
runtimeVersion: nullthrows(
await Updates.getRuntimeVersionAsync(projectDir, exp, platform),
`Unable to determine runtime version for ${
requestedPlatformDisplayNames[platform]
}. ${learnMore('https://docs.expo.dev/eas-update/runtime-versions/')}`
),
};
})
);
}
export function getRuntimeToPlatformMappingFromRuntimeVersions(
@@ -272,9 +272,13 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
async selectRuntimeVersionFromProjectConfigAsync(ctx: EASUpdateContext): Promise<string> {
const platforms: ('ios' | 'android')[] = ['ios', 'android'];
const runtimes = platforms
.map(platform => Updates.getRuntimeVersion(ctx.app.exp, platform))
.filter(truthy);
const runtimes = (
await Promise.all(
platforms.map(platform =>
Updates.getRuntimeVersionAsync(ctx.app.projectDir, ctx.app.exp, platform)
)
)
).filter(truthy);
const dedupedRuntimes = [...new Set(runtimes)];
if (dedupedRuntimes.length === 0) {
@@ -111,6 +111,11 @@ export default class IosSubmitCommand {
const envAppSpecificPassword = getenv.string('EXPO_APPLE_APP_SPECIFIC_PASSWORD', '');
if (envAppSpecificPassword) {
if (!/^[a-z]{4}-[a-z]{4}-[a-z]{4}-[a-z]{4}$/.test(envAppSpecificPassword)) {
throw new Error(
'EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format XXXX-XXXX-XXXX-XXXX, where X is a lowercase letter.'
);
}
return result({
sourceType: AppSpecificPasswordSourceType.userDefined,
appSpecificPassword: envAppSpecificPassword,
@@ -78,6 +78,43 @@ describe(IosSubmitCommand, () => {
jest.mocked(getOwnerAccountForProjectIdAsync).mockResolvedValue(mockJester.accounts[0]);
});
it('throws an error if using app specific password in invalid format', async () => {
const projectId = uuidv4();
const graphqlClient = {} as any as ExpoGraphqlClient;
const analytics = instance(mock<Analytics>());
jest
.mocked(getArchiveAsync)
.mockImplementation(jest.requireActual('../../ArchiveSource').getArchiveAsync);
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'ls -la';
const ctx = await createSubmissionContextAsync({
platform: Platform.IOS,
projectDir: testProject.projectRoot,
archiveFlags: {
url: 'http://expo.dev/fake.ipa',
},
profile: {
language: 'en-US',
appleId: '[email protected]',
ascAppId: '12345678',
},
nonInteractive: false,
actor: mockJester,
graphqlClient,
analytics,
exp: testProject.appJSON.expo,
projectId,
vcsClient,
});
const command = new IosSubmitCommand(ctx);
await expect(command.runAsync()).rejects.toThrow(
'EXPO_APPLE_APP_SPECIFIC_PASSWORD must be in the format XXXX-XXXX-XXXX-XXXX, where X is a lowercase letter.'
);
delete process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD;
});
describe('non-interactive mode', () => {
it("throws error if didn't provide appleId and ascAppId in the submit profile", async () => {
const projectId = uuidv4();
@@ -118,7 +155,7 @@ describe(IosSubmitCommand, () => {
.mocked(getArchiveAsync)
.mockImplementation(jest.requireActual('../../ArchiveSource').getArchiveAsync);
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'supersecret';
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'abcd-abcd-abcd-abcd';
const ctx = await createSubmissionContextAsync({
platform: Platform.IOS,
@@ -147,7 +184,7 @@ describe(IosSubmitCommand, () => {
archiveSource: { type: SubmissionArchiveSourceType.Url, url: 'http://expo.dev/fake.ipa' },
config: {
appleIdUsername: '[email protected]',
appleAppSpecificPassword: 'supersecret',
appleAppSpecificPassword: 'abcd-abcd-abcd-abcd',
ascAppIdentifier: '12345678',
},
});
@@ -182,7 +219,7 @@ describe(IosSubmitCommand, () => {
return ctx;
});
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'supersecret';
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'abcd-abcd-abcd-abcd';
const ctx = await createSubmissionContextAsync({
platform: Platform.IOS,
@@ -209,7 +246,7 @@ describe(IosSubmitCommand, () => {
submittedBuildId: selectedBuild.id,
config: {
appleIdUsername: '[email protected]',
appleAppSpecificPassword: 'supersecret',
appleAppSpecificPassword: 'abcd-abcd-abcd-abcd',
ascAppIdentifier: '87654321',
},
archiveSource: undefined,
@@ -239,7 +276,7 @@ describe(IosSubmitCommand, () => {
return ctx;
});
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'supersecret';
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'abcd-abcd-abcd-abcd';
const ctx = await createSubmissionContextAsync({
platform: Platform.IOS,
@@ -266,7 +303,7 @@ describe(IosSubmitCommand, () => {
submittedBuildId: selectedBuild.id,
config: {
appleIdUsername: '[email protected]',
appleAppSpecificPassword: 'supersecret',
appleAppSpecificPassword: 'abcd-abcd-abcd-abcd',
ascAppIdentifier: '12345678',
},
archiveSource: undefined,
@@ -301,7 +338,7 @@ describe(IosSubmitCommand, () => {
return ctx;
});
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'supersecret';
process.env.EXPO_APPLE_APP_SPECIFIC_PASSWORD = 'abcd-abcd-abcd-abcd';
const ctx = await createSubmissionContextAsync({
platform: Platform.IOS,
@@ -329,7 +366,7 @@ describe(IosSubmitCommand, () => {
submittedBuildId: selectedBuild.id,
config: {
appleIdUsername: '[email protected]',
appleAppSpecificPassword: 'supersecret',
appleAppSpecificPassword: 'abcd-abcd-abcd-abcd',
ascAppIdentifier: '12345678',
},
archiveSource: undefined,
@@ -1,22 +1,13 @@
import { instance, mock } from 'ts-mockito';
import { selectBranchOnAppAsync } from '../../branch/queries';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { updateChannelBranchMappingAsync } from '../../commands/channel/edit';
import { App, Runtime, UpdateBranch, UpdateChannel, UpdateInsights } from '../../graphql/generated';
import { ChannelQuery } from '../../graphql/queries/ChannelQuery';
import { getBranchNameFromChannelNameAsync } from '../getBranchNameFromChannelNameAsync';
jest.mock('../../graphql/queries/ChannelQuery');
jest.mock('../../graphql/queries/BranchQuery');
jest.mock('../../branch/queries');
jest.mock('../../commands/channel/edit');
const defaultPaginatedQueryOptions = {
json: false,
nonInteractive: false,
offset: 0,
};
describe(getBranchNameFromChannelNameAsync, () => {
beforeEach(() => {
jest.resetAllMocks();
@@ -35,14 +26,13 @@ describe(getBranchNameFromChannelNameAsync, () => {
const result = await getBranchNameFromChannelNameAsync(
graphqlClient,
'test-project-id',
'channel-name',
defaultPaginatedQueryOptions
'channel-name'
);
expect(result).toBe('test-branch-name');
});
test('prompts user to select a branch if no branch is connected to channel', async () => {
test('errors when no branch is connected to channel', async () => {
const graphqlClient = instance(mock<ExpoGraphqlClient>());
jest.mocked(ChannelQuery.viewUpdateChannelAsync).mockImplementationOnce(
async () =>
@@ -51,24 +41,11 @@ describe(getBranchNameFromChannelNameAsync, () => {
}) as any
);
jest
.mocked(selectBranchOnAppAsync)
.mockImplementationOnce(async () => mockUpdateBranches(['test-branch-name'])[0] as any);
jest.mocked(updateChannelBranchMappingAsync).mockImplementationOnce(
async () =>
mockUpdateChannel({
channelName: 'test-channel-name',
branchNames: ['test-branch-name'],
}) as any
expect(
getBranchNameFromChannelNameAsync(graphqlClient, 'test-project-id', 'test-channel-name')
).rejects.toThrow(
"Channel has no branches associated with it. Run 'eas channel:edit' to map a branch"
);
const result = await getBranchNameFromChannelNameAsync(
graphqlClient,
'test-project-id',
'test-channel-name',
defaultPaginatedQueryOptions
);
expect(result).toBe('test-branch-name');
});
test('errors when more than one branch is connected to channel', async () => {
@@ -82,12 +59,7 @@ describe(getBranchNameFromChannelNameAsync, () => {
);
expect(
getBranchNameFromChannelNameAsync(
graphqlClient,
'test-project-id',
'test-channel-name',
defaultPaginatedQueryOptions
)
getBranchNameFromChannelNameAsync(graphqlClient, 'test-project-id', 'test-channel-name')
).rejects.toThrow(
"Channel has multiple branches associated with it. Instead, use '--branch' instead of '--channel'"
);
@@ -106,8 +78,7 @@ describe(getBranchNameFromChannelNameAsync, () => {
const result = await getBranchNameFromChannelNameAsync(
graphqlClient,
'test-project-id',
'test-channel-name',
defaultPaginatedQueryOptions
'test-channel-name'
);
expect(result).toBe('test-branch-name');
@@ -1,31 +1,25 @@
import { ExpoConfig } from '@expo/config';
import { AndroidConfig, AndroidManifest, XML } from '@expo/config-plugins';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { RequestedPlatform } from '../../platform';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import { ensureValidVersions } from '../utils';
/**
* Synchronize updates configuration to native files. This needs to do essentially the same thing as `withUpdates`
*/
export async function syncUpdatesConfigurationAsync(
graphqlClient: ExpoGraphqlClient,
projectDir: string,
exp: ExpoConfig,
projectId: string
exp: ExpoConfig
): Promise<void> {
ensureValidVersions(exp, RequestedPlatform.Android);
const accountName = (await getOwnerAccountForProjectIdAsync(graphqlClient, projectId)).name;
// sync AndroidManifest.xml
const androidManifestPath = await AndroidConfig.Paths.getAndroidManifestAsync(projectDir);
const androidManifest = await getAndroidManifestAsync(projectDir);
const updatedAndroidManifest = AndroidConfig.Updates.setUpdatesConfig(
const updatedAndroidManifest = await AndroidConfig.Updates.setUpdatesConfigAsync(
projectDir,
exp,
androidManifest,
accountName
androidManifest
);
await AndroidConfig.Manifest.writeAndroidManifestAsync(
androidManifestPath,
@@ -37,10 +31,13 @@ export async function syncUpdatesConfigurationAsync(
const stringsResourceXML = await AndroidConfig.Resources.readResourcesXMLAsync({
path: stringsJSONPath,
});
const updatedStringsResourceXML = AndroidConfig.Updates.applyRuntimeVersionFromConfig(
exp,
stringsResourceXML
);
const updatedStringsResourceXML =
await AndroidConfig.Updates.applyRuntimeVersionFromConfigForProjectRootAsync(
projectDir,
exp,
stringsResourceXML
);
await XML.writeXMLAsync({ path: stringsJSONPath, xml: updatedStringsResourceXML });
}
+17 -80
View File
@@ -8,18 +8,16 @@ import semver from 'semver';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from './android/UpdatesModule';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from './ios/UpdatesModule';
import { getEASUpdateURL } from '../api';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AppPlatform } from '../graphql/generated';
import Log, { learnMore } from '../log';
import { RequestedPlatform, appPlatformDisplayNames } from '../platform';
import { createOrModifyExpoConfigAsync, isUsingStaticExpoConfig } from '../project/expoConfig';
import { createOrModifyExpoConfigAsync } from '../project/expoConfig';
import {
installExpoUpdatesAsync,
isExpoUpdatesInstalledAsDevDependency,
isExpoUpdatesInstalledOrAvailable,
} from '../project/projectUtils';
import { resolveWorkflowPerPlatformAsync } from '../project/workflow';
import { confirmAsync } from '../prompts';
import { Client } from '../vcs/vcs';
export const DEFAULT_MANAGED_RUNTIME_VERSION_GTE_SDK_49 = { policy: 'appVersion' } as const;
@@ -260,29 +258,26 @@ function warnEASUpdatesManualConfig({
* Make sure that the current `app.json` configuration for EAS Updates is set natively.
*/
async function ensureEASUpdateIsConfiguredNativelyAsync(
graphqlClient: ExpoGraphqlClient,
vcsClient: Client,
{
exp,
projectId,
projectDir,
platform,
workflows,
}: {
exp: ExpoConfig;
projectId: string;
projectDir: string;
platform: RequestedPlatform;
workflows: Record<Platform, Workflow>;
}
): Promise<void> {
if (['all', 'android'].includes(platform) && workflows.android === Workflow.GENERIC) {
await syncAndroidUpdatesConfigurationAsync(graphqlClient, projectDir, exp, projectId);
await syncAndroidUpdatesConfigurationAsync(projectDir, exp);
Log.withTick(`Configured ${chalk.bold('AndroidManifest.xml')} for EAS Update`);
}
if (['all', 'ios'].includes(platform) && workflows.ios === Workflow.GENERIC) {
await syncIosUpdatesConfigurationAsync(graphqlClient, vcsClient, projectDir, exp, projectId);
await syncIosUpdatesConfigurationAsync(vcsClient, projectDir, exp);
Log.withTick(`Configured ${chalk.bold('Expo.plist')} for EAS Update`);
}
}
@@ -356,30 +351,19 @@ export async function ensureEASUpdateIsConfiguredInEasJsonAsync(projectDir: stri
* - Sets `updates.url` if not set
* - Ensure latest changes are reflected in the native config, if any
*/
export async function ensureEASUpdateIsConfiguredAsync(
graphqlClient: ExpoGraphqlClient,
{
exp: expMaybeWithoutUpdates,
projectId,
projectDir,
vcsClient,
platform,
}: {
exp: ExpoConfig;
projectId: string;
projectDir: string;
vcsClient: Client;
platform: RequestedPlatform | null;
}
): Promise<void> {
// EAS Update and SDK 49's "useClassicUpdates" option are mutually exclusive
if (expMaybeWithoutUpdates.updates?.useClassicUpdates) {
expMaybeWithoutUpdates = await ensureUseClassicUpdatesIsRemovedAsync({
exp: expMaybeWithoutUpdates,
projectDir,
});
}
export async function ensureEASUpdateIsConfiguredAsync({
exp: expMaybeWithoutUpdates,
projectId,
projectDir,
vcsClient,
platform,
}: {
exp: ExpoConfig;
projectId: string;
projectDir: string;
vcsClient: Client;
platform: RequestedPlatform | null;
}): Promise<void> {
const hasExpoUpdates = isExpoUpdatesInstalledOrAvailable(
projectDir,
expMaybeWithoutUpdates.sdkVersion
@@ -411,10 +395,9 @@ export async function ensureEASUpdateIsConfiguredAsync(
});
if (projectChanged || !hasExpoUpdates) {
await ensureEASUpdateIsConfiguredNativelyAsync(graphqlClient, vcsClient, {
await ensureEASUpdateIsConfiguredNativelyAsync(vcsClient, {
exp: expWithUpdates,
projectDir,
projectId,
platform,
workflows,
});
@@ -428,49 +411,3 @@ export async function ensureEASUpdateIsConfiguredAsync(
Log.newLine();
}
}
export async function ensureUseClassicUpdatesIsRemovedAsync({
exp: expMaybeWithoutUpdates,
projectDir,
}: {
exp: ExpoConfig;
projectDir: string;
}): Promise<ExpoConfig> {
if (!isUsingStaticExpoConfig(projectDir)) {
throw new Error(
`Your app config sets "updates.useClassicUpdates" but EAS Update does not support classic updates. Remove "useClassicUpdates" from your app config and run this command again.`
);
}
const shouldEditConfig = await confirmAsync({
message: `Your app config sets "updates.useClassicUpdates" but EAS Update does not support classic updates. Remove "updates.useClassicUpdates" from your app config?`,
});
if (!shouldEditConfig) {
throw new Error(
`Manually remove "updates.useClassicUpdates" from your app config and run this command again.`
);
}
const editedExpoConfig = mergeExpoConfig(expMaybeWithoutUpdates, {
updates: { useClassicUpdates: undefined },
}) as ExpoConfig;
const result = await createOrModifyExpoConfigAsync(projectDir, editedExpoConfig);
switch (result.type) {
case 'success':
Log.withTick(`Removed "updates.useClassicUpdates"`);
expMaybeWithoutUpdates = editedExpoConfig;
break;
case 'warn':
case 'fail':
throw new Error(result.message);
default:
throw new Error(
`Unexpected result type "${result.type}" received when modifying the project config.`
);
}
return editedExpoConfig;
}
@@ -1,18 +1,13 @@
import { ensureBranchExistsAsync, selectBranchOnAppAsync } from '../branch/queries';
import { getAlwaysTrueBranchMapping } from '../channel/branch-mapping';
import { ensureBranchExistsAsync } from '../branch/queries';
import { ChannelNotFoundError } from '../channel/errors';
import { createChannelOnAppAsync } from '../channel/queries';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { PaginatedQueryOptions } from '../commandUtils/pagination';
import { updateChannelBranchMappingAsync } from '../commands/channel/edit';
import { ChannelQuery } from '../graphql/queries/ChannelQuery';
import Log from '../log';
export async function getBranchNameFromChannelNameAsync(
graphqlClient: ExpoGraphqlClient,
projectId: string,
channelName: string,
paginatedQueryOptions: PaginatedQueryOptions
channelName: string
): Promise<string> {
let branchName;
@@ -25,19 +20,9 @@ export async function getBranchNameFromChannelNameAsync(
if (channel.updateBranches.length === 1) {
branchName = channel.updateBranches[0].name;
} else if (channel.updateBranches.length === 0) {
Log.log('Channel has no branches associated with it.');
const branch = await selectBranchOnAppAsync(graphqlClient, {
projectId,
promptTitle: `Which branch would you like ${channel.name} to point at?`,
displayTextForListItem: updateBranch => ({ title: updateBranch.name }),
paginatedQueryOptions,
});
await updateChannelBranchMappingAsync(graphqlClient, {
channelId: channel.id,
branchMapping: JSON.stringify(getAlwaysTrueBranchMapping(branch.id)),
});
return branch.name;
throw new Error(
"Channel has no branches associated with it. Run 'eas channel:edit' to map a branch"
);
} else {
throw new Error(
`Channel has multiple branches associated with it. Instead, use '--branch' instead of '--channel'`
@@ -1,28 +1,22 @@
import { ExpoConfig } from '@expo/config';
import { IOSConfig } from '@expo/config-plugins';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { RequestedPlatform } from '../../platform';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import { readPlistAsync, writePlistAsync } from '../../utils/plist';
import { Client } from '../../vcs/vcs';
import { ensureValidVersions } from '../utils';
export async function syncUpdatesConfigurationAsync(
graphqlClient: ExpoGraphqlClient,
vcsClient: Client,
projectDir: string,
exp: ExpoConfig,
projectId: string
exp: ExpoConfig
): Promise<void> {
ensureValidVersions(exp, RequestedPlatform.Ios);
const accountName = (await getOwnerAccountForProjectIdAsync(graphqlClient, projectId)).name;
const expoPlist = await readExpoPlistAsync(projectDir);
const updatedExpoPlist = IOSConfig.Updates.setUpdatesConfig(
const updatedExpoPlist = await IOSConfig.Updates.setUpdatesConfigAsync(
projectDir,
exp,
expoPlist,
accountName
expoPlist
);
await writeExpoPlistAsync(vcsClient, projectDir, updatedExpoPlist);
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "6.0.0",
"version": "7.1.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
+2 -1
View File
@@ -357,6 +357,7 @@
"enum": [
"default",
"latest",
"macos-ventura-13.6-xcode-15.2",
"macos-ventura-13.6-xcode-15.1",
"macos-ventura-13.6-xcode-15.0",
"macos-ventura-13.4-xcode-14.3.1",
@@ -367,7 +368,7 @@
],
"markdownEnumDescriptions": [
"`macos-ventura-13.4-xcode-14.3.1`",
"`macos-ventura-13.6-xcode-15.1`"
"`macos-ventura-13.6-xcode-15.2`"
]
},
{
@@ -107,10 +107,10 @@ test('ios config with all required values', async () => {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'QWERTY',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'abc-123-def-456',
ascApiKeyId: 'ABCD',
ascApiKeyIssuerId: 'b4d78f58-48c6-4f2c-96cb-94d8cd76970a',
ascApiKeyId: 'AB32CDE81F',
},
},
},
@@ -121,11 +121,11 @@ test('ios config with all required values', async () => {
expect(iosProfile).toEqual({
appleId: '[email protected]',
appleTeamId: 'QWERTY',
appleTeamId: 'AB32CDE81F',
ascAppId: '1223423523',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'abc-123-def-456',
ascApiKeyId: 'ABCD',
ascApiKeyIssuerId: 'b4d78f58-48c6-4f2c-96cb-94d8cd76970a',
ascApiKeyId: 'AB32CDE81F',
language: 'en-US',
});
});
@@ -137,7 +137,7 @@ test('ios config with ascApiKey fields set to env var', async () => {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'QWERTY',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: '$ASC_API_KEY_PATH',
ascApiKeyIssuerId: '$ASC_API_KEY_ISSUER_ID',
ascApiKeyId: '$ASC_API_KEY_ID',
@@ -148,18 +148,18 @@ test('ios config with ascApiKey fields set to env var', async () => {
try {
process.env.ASC_API_KEY_PATH = './path-ABCD.p8';
process.env.ASC_API_KEY_ISSUER_ID = 'abc-123-def-456';
process.env.ASC_API_KEY_ID = 'ABCD';
process.env.ASC_API_KEY_ISSUER_ID = 'b4d78f58-48c6-4f2c-96cb-94d8cd76970a';
process.env.ASC_API_KEY_ID = 'AB32CDE81F';
const accessor = EasJsonAccessor.fromProjectPath('/project');
const iosProfile = await EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'release');
expect(iosProfile).toEqual({
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'QWERTY',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'abc-123-def-456',
ascApiKeyId: 'ABCD',
ascApiKeyIssuerId: 'b4d78f58-48c6-4f2c-96cb-94d8cd76970a',
ascApiKeyId: 'AB32CDE81F',
language: 'en-US',
});
} finally {
@@ -176,16 +176,16 @@ test('valid profile extending other profile', async () => {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'QWERTY',
appleTeamId: 'AB32CDE81F',
},
},
extension: {
extends: 'base',
ios: {
appleTeamId: 'ABCDEF',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'abc-123-def-456',
ascApiKeyId: 'ABCD',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CDE81F',
},
},
},
@@ -202,19 +202,134 @@ test('valid profile extending other profile', async () => {
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'QWERTY',
appleTeamId: 'AB32CDE81F',
});
expect(extendedProfile).toEqual({
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'ABCDEF',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'abc-123-def-456',
ascApiKeyId: 'ABCD',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CDE81F',
});
});
test('ios config with with invalid appleId', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
release: {
ios: {
appleId: '| /bin/bash echo "hello"',
ascAppId: '1223423523',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CDE81F',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'release');
await expect(promise).rejects.toThrow(
'Invalid Apple ID was specified. It should be a valid email address. Example: "[email protected]".'
);
});
test('ios config with with invalid ascAppId', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
release: {
ios: {
appleId: '[email protected]',
ascAppId: 'othervalue',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CDE81F',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'release');
await expect(promise).rejects.toThrow(
'Invalid Apple App Store Connect App ID ("ascAppId") was specified. It should consist of 10 digits. Example: "1234567891". Learn more: https://expo.fyi/asc-app-id.md.'
);
});
test('ios config with with invalid appleTeamId', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
release: {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'ls -la',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CDE81F',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'release');
await expect(promise).rejects.toThrow(
'Invalid Apple Team ID was specified. It should consist of 10 uppercase letters or digits. Example: "AB32CDE81F".'
);
});
test('ios config with with invalid ascApiKeyIssuerId', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
release: {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'notanuuid',
ascApiKeyId: 'AB32CDE81F',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'release');
await expect(promise).rejects.toThrow(
'Invalid Apple App Store Connect API Key Issuer ID ("ascApiKeyIssuerId") was specified. It should be a valid UUID. Example: "b4d78f58-48c6-4f2c-96cb-94d8cd76970a". Learn more: https://expo.fyi/creating-asc-api-key.'
);
});
test('ios config with with invalid ascApiKeyId', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
release: {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'AB32CDE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: 'b4d78f58-48c6-4f2c-96cb-94d8cd76970a',
ascApiKeyId: 'wrong value',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const promise = EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'release');
await expect(promise).rejects.toThrow(
`Invalid Apple App Store Connect API Key ID ("ascApiKeyId") was specified. It should consist of 10 uppercase letters or digits. Example: "AB32CDE81F". Learn more: https://expo.fyi/creating-asc-api-key.`
);
});
test('get profile names', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
+2 -2
View File
@@ -1,7 +1,7 @@
import Joi from 'joi';
import { BuildProfileSchema } from './build/schema';
import { SubmitProfileSchema } from './submit/schema';
import { UnresolvedSubmitProfileSchema } from './submit/schema';
import { AppVersionSource } from './types';
export const EasJsonSchema = Joi.object({
@@ -12,5 +12,5 @@ export const EasJsonSchema = Joi.object({
promptToConfigurePushNotifications: Joi.boolean(),
}),
build: Joi.object().pattern(Joi.string(), BuildProfileSchema),
submit: Joi.object().pattern(Joi.string(), SubmitProfileSchema),
submit: Joi.object().pattern(Joi.string(), UnresolvedSubmitProfileSchema),
});
+2 -2
View File
@@ -1,7 +1,7 @@
import { Platform } from '@expo/eas-build-job';
import envString from 'env-string';
import { AndroidSubmitProfileSchema, IosSubmitProfileSchema } from './schema';
import { AndroidSubmitProfileSchema, ResolvedIosSubmitProfileSchema } from './schema';
import {
AndroidSubmitProfileFieldsToEvaluate,
IosSubmitProfileFieldsToEvaluate,
@@ -99,7 +99,7 @@ function mergeProfiles<T extends Platform>(
export function getDefaultProfile<T extends Platform>(platform: T): SubmitProfile<T> {
const Schema =
platform === Platform.ANDROID ? AndroidSubmitProfileSchema : IosSubmitProfileSchema;
platform === Platform.ANDROID ? AndroidSubmitProfileSchema : ResolvedIosSubmitProfileSchema;
return Schema.validate({}, { allowUnknown: false, abortEarly: false, convert: true }).value;
}
+41 -3
View File
@@ -19,7 +19,9 @@ export const AndroidSubmitProfileSchema = Joi.object({
}),
});
export const IosSubmitProfileSchema = Joi.object({
// it is less strict submission schema allowing for magic syntax like "$ASC_API_KEY_PATH"
// to read value from environment variable later on
export const UnresolvedIosSubmitProfileSchema = Joi.object({
ascApiKeyPath: Joi.string(),
ascApiKeyId: Joi.string(),
ascApiKeyIssuerId: Joi.string(),
@@ -34,8 +36,44 @@ export const IosSubmitProfileSchema = Joi.object({
metadataPath: Joi.string(),
});
export const SubmitProfileSchema = Joi.object({
// more strict version after resolving all of the values
export const ResolvedIosSubmitProfileSchema = Joi.object({
ascApiKeyPath: Joi.string(),
ascApiKeyId: Joi.string()
.regex(/^[\dA-Z]{10}$/)
.message(
'Invalid Apple App Store Connect API Key ID ("ascApiKeyId") was specified. It should consist of 10 uppercase letters or digits. Example: "AB32CDE81F". Learn more: https://expo.fyi/creating-asc-api-key.'
),
ascApiKeyIssuerId: Joi.string()
.uuid()
.message(
'Invalid Apple App Store Connect API Key Issuer ID ("ascApiKeyIssuerId") was specified. It should be a valid UUID. Example: "b4d78f58-48c6-4f2c-96cb-94d8cd76970a". Learn more: https://expo.fyi/creating-asc-api-key.'
),
appleId: Joi.string()
.email()
.message(
'Invalid Apple ID was specified. It should be a valid email address. Example: "[email protected]".'
),
ascAppId: Joi.string()
.regex(/^\d{10}$/)
.message(
'Invalid Apple App Store Connect App ID ("ascAppId") was specified. It should consist of 10 digits. Example: "1234567891". Learn more: https://expo.fyi/asc-app-id.md.'
),
appleTeamId: Joi.string()
.regex(/^[\dA-Z]{10}$/)
.message(
'Invalid Apple Team ID was specified. It should consist of 10 uppercase letters or digits. Example: "AB32CDE81F".'
),
sku: Joi.string(),
language: Joi.string().default('en-US'),
companyName: Joi.string(),
appName: Joi.string(),
bundleIdentifier: Joi.string(),
metadataPath: Joi.string(),
});
export const UnresolvedSubmitProfileSchema = Joi.object({
extends: Joi.string(),
android: AndroidSubmitProfileSchema,
ios: IosSubmitProfileSchema,
ios: UnresolvedIosSubmitProfileSchema,
});
+13 -1
View File
@@ -5,6 +5,7 @@ import { resolveBuildProfile } from './build/resolver';
import { BuildProfile } from './build/types';
import { MissingEasJsonError } from './errors';
import { resolveSubmitProfile } from './submit/resolver';
import { AndroidSubmitProfileSchema, ResolvedIosSubmitProfileSchema } from './submit/schema';
import { SubmitProfile } from './submit/types';
import { EasJson } from './types';
@@ -102,6 +103,17 @@ export class EasJsonUtils {
profileName?: string
): Promise<SubmitProfile<T>> {
const easJson = await accessor.readAsync();
return resolveSubmitProfile({ easJson, platform, profileName });
const profile = resolveSubmitProfile({ easJson, platform, profileName });
const Schema =
platform === Platform.ANDROID ? AndroidSubmitProfileSchema : ResolvedIosSubmitProfileSchema;
const { value, error } = Schema.validate(profile, {
allowUnknown: false,
abortEarly: false,
convert: true,
});
if (error) {
throw error;
}
return value;
}
}
Generated
+160 -37
View File
@@ -1377,14 +1377,15 @@
node-forge "^1.2.1"
nullthrows "^1.1.1"
"@expo/config-plugins@7.2.4", "@expo/config-plugins@~7.2.0":
version "7.2.4"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-7.2.4.tgz#c8d354348b746e53d70224f0bf7b87994f7c2936"
integrity sha512-TItGwmKH1GDjA5GlMkXo1A8pqeqppSK40aSVRVQaGZraUj+nuvtpWxNgEWZxWFumiatP2ocWwyWVjfmH+rJY6g==
"@expo/config-plugins@7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-7.8.4.tgz#533b5d536c1dc8b5544d64878b51bda28f2e1a1f"
integrity sha512-hv03HYxb/5kX8Gxv/BTI8TLc9L06WzqAfHRRXdbar4zkLcP2oTzvsLEF4/L/TIpD3rsnYa0KU42d0gWRxzPCJg==
dependencies:
"@expo/config-types" "^49.0.0-alpha.1"
"@expo/json-file" "~8.2.37"
"@expo/plist" "^0.0.20"
"@expo/config-types" "^50.0.0-alpha.1"
"@expo/fingerprint" "^0.6.0"
"@expo/json-file" "~8.3.0"
"@expo/plist" "^0.1.0"
"@expo/sdk-runtime-versions" "^1.0.0"
"@react-native/normalize-color" "^2.0.0"
chalk "^4.1.2"
@@ -1395,22 +1396,63 @@
resolve-from "^5.0.0"
semver "^7.5.3"
slash "^3.0.0"
slugify "^1.6.6"
xcode "^3.0.1"
xml2js "0.6.0"
"@expo/config-[email protected].0", "@expo/config-types@^49.0.0-alpha.1":
version "49.0.0"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-49.0.0.tgz#15ffef715285c06703f6fb7ec0cda853f645cc09"
integrity sha512-8eyREVi+K2acnMBe/rTIu1dOfyR2+AMnTLHlut+YpMV9OZPdeKV0Bs9BxAewGqBA2slslbQ9N39IS2CuTKpXkA==
"@expo/config-plugins@~7.8.0", "@expo/config-plugins@~7.8.2":
version "7.8.2"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-7.8.2.tgz#c00ce93c4d6c2cb9e345ed9cd56ceeea05ab8ddb"
integrity sha512-XM2eXA5EvcpmXFCui48+bVy8GTskYSjPf2yC+LliYv8PDcedu7+pdgmbnvH4eZCyHfTMO8/UiF+w8e5WgOEj5A==
dependencies:
"@expo/config-types" "^50.0.0-alpha.1"
"@expo/fingerprint" "^0.6.0"
"@expo/json-file" "~8.3.0"
"@expo/plist" "^0.1.0"
"@expo/sdk-runtime-versions" "^1.0.0"
"@react-native/normalize-color" "^2.0.0"
chalk "^4.1.2"
debug "^4.3.1"
find-up "~5.0.0"
getenv "^1.0.0"
glob "7.1.6"
resolve-from "^5.0.0"
semver "^7.5.3"
slash "^3.0.0"
slugify "^1.6.6"
xcode "^3.0.1"
xml2js "0.6.0"
"@expo/config@8.1.2", "@expo/config@~8.1.0":
version "8.1.2"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-8.1.2.tgz#7fff28b3acefe39702e9f3ce1c9fd896a52caa80"
integrity sha512-4e7hzPj50mQIlsrzOH6XZ36O094mPfPTIDIH4yv49bWNMc7GFLTofB/lcT+QyxiLaJuC0Wlk9yOLB8DIqmtwug==
"@expo/config[email protected]", "@expo/config-types@^50.0.0", "@expo/config-types@^50.0.0-alpha.1":
version "50.0.0"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-50.0.0.tgz#b534d3ec997ec60f8af24f6ad56244c8afc71a0b"
integrity sha512-0kkhIwXRT6EdFDwn+zTg9R2MZIAEYGn1MVkyRohAd+C9cXOb5RA8WLQi7vuxKF9m1SMtNAUrf0pO+ENK0+/KSw==
"@expo/[email protected]":
version "8.5.4"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-8.5.4.tgz#bb5eb06caa36e4e35dc8c7647fae63e147b830ca"
integrity sha512-ggOLJPHGzJSJHVBC1LzwXwR6qUn8Mw7hkc5zEKRIdhFRuIQ6s2FE4eOvP87LrNfDF7eZGa6tJQYsiHSmZKG+8Q==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "~7.2.0"
"@expo/config-types" "^49.0.0-alpha.1"
"@expo/config-plugins" "~7.8.2"
"@expo/config-types" "^50.0.0"
"@expo/json-file" "^8.2.37"
getenv "^1.0.0"
glob "7.1.6"
require-from-string "^2.0.2"
resolve-from "^5.0.0"
semver "7.5.3"
slugify "^1.3.4"
sucrase "3.34.0"
"@expo/config@~8.5.0":
version "8.5.2"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-8.5.2.tgz#4a0de82279337a37b5f1f0958711fe56e8ea31c2"
integrity sha512-UYy9kWxjQAEDwlX7gwLk0+8IxGPcHJMLnYRYtR5C5xGIV+ML7tCA+qFz1p4gHZRPkJD+k7iZyqBtyqt8xm+zXw==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "~7.8.2"
"@expo/config-types" "^50.0.0"
"@expo/json-file" "^8.2.37"
getenv "^1.0.0"
glob "7.1.6"
@@ -1428,24 +1470,44 @@
joi "^17.9.2"
semver "^7.5.4"
"@expo/[email protected]":
version "0.3.22"
resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.3.22.tgz#3a45fb2e268d20fcc761c87bca3aca7fd8e24260"
integrity sha512-uzq+RERAtkWypOFOLssFnXXqEqKjNj9eXN7e97d/EXUAojNcLDoXc0sL+F5B1I4qtlsnhX01kcpoIBBZD8wZNQ==
"@expo/[email protected]":
version "1.0.59"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.59.tgz#cd86ce33bebe1e7c60bef4754d798aff381e0ff3"
integrity sha512-oFOn8hbJbfpjrYM39yejnvlD9qMgK/zRuQ9PnzruIygOxDrBn1nnOAO9Jm0kWBGAPJVDAJRQ2exOgHVY+tAAEw==
dependencies:
joi "^17.11.0"
semver "^7.5.4"
"@expo/fingerprint@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.6.0.tgz#77366934673d4ecea37284109b4dd67f9e6a7487"
integrity sha512-KfpoVRTMwMNJ/Cf5o+Ou8M/Y0EGSTqK+rbi70M2Y0K2qgWNfMJ1gm6sYO9uc8lcTr7YSYM1Rme3dk7QXhpScNA==
dependencies:
"@expo/spawn-async" "^1.5.0"
chalk "^4.1.2"
debug "^4.3.4"
find-up "^5.0.0"
minimatch "^3.0.4"
p-limit "^3.1.0"
resolve-from "^5.0.0"
"@expo/image-utils@^0.4.0":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.4.1.tgz#78c54b8aaa974d0ac37fee5285683b54ff161b2c"
integrity sha512-EZb+VHSmw+a5s2hS9qksTcWylY0FDaIAVufcxoaRS9tHIXLjW5zcKW7Rhj9dSEbZbRVy9yXXdHKa3GQdUQIOFw==
dependencies:
"@expo/spawn-async" "1.5.0"
chalk "^4.0.0"
fs-extra "9.0.0"
getenv "^1.0.0"
jimp-compact "0.16.1"
mime "^2.4.4"
node-fetch "^2.6.0"
parse-png "^2.1.0"
resolve-from "^5.0.0"
semver "7.3.2"
tempy "0.3.0"
"@expo/[email protected]", "@expo/json-file@^8.2.37", "@expo/json-file@~8.2.37":
"@expo/[email protected]", "@expo/json-file@^8.2.37":
version "8.2.37"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.37.tgz#9c02d3b42134907c69cc0a027b18671b69344049"
integrity sha512-YaH6rVg11JoTS2P6LsW7ybS2CULjf40AbnAHw2F1eDPuheprNjARZMnyHFPkKv7GuxCy+B9GPcbOKgc4cgA80Q==
@@ -1454,6 +1516,15 @@
json5 "^2.2.2"
write-file-atomic "^2.3.0"
"@expo/json-file@~8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.3.0.tgz#fc84af77b532a4e9bfb5beafd0e3b7f692b6bd7e"
integrity sha512-yROUeXJXR5goagB8c3muFLCzLmdGOvoPpR5yDNaXrnTp4euNykr9yW0wWhJx4YVRTNOPtGBnEbbJBW+a9q+S6g==
dependencies:
"@babel/code-frame" "~7.10.4"
json5 "^2.2.2"
write-file-atomic "^2.3.0"
"@expo/[email protected]":
version "1.0.37"
resolved "https://registry.yarnpkg.com/@expo/logger/-/logger-1.0.37.tgz#79b2336d4e9ed70bd19a53168eb91d6a899f11d8"
@@ -1503,7 +1574,7 @@
dependencies:
node-forge "^1.2.1"
"@expo/[email protected]", "@expo/plist@^0.0.20":
"@expo/[email protected]":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.20.tgz#a6b3124438031c02b762bad5a47b70584d3c0072"
integrity sha512-UXQ4LXCfTZ580LDHGJ5q62jSTwJFFJ1GqBu8duQMThiHKWbMJ+gajJh6rsB6EJ3aLUr9wcauxneL5LVRFxwBEA==
@@ -1512,6 +1583,15 @@
base64-js "^1.2.3"
xmlbuilder "^14.0.0"
"@expo/plist@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.1.0.tgz#eabc95f951d14e10c87fd0443ee01d567371f058"
integrity sha512-xWD+8vIFif0wKyuqe3fmnmnSouXYucciZXFzS0ZD5OV9eSAS1RGQI5FaGGJ6zxJ4mpdy/4QzbLdBjnYE5vxA0g==
dependencies:
"@xmldom/xmldom" "~0.7.7"
base64-js "^1.2.3"
xmlbuilder "^14.0.0"
"@expo/[email protected]":
version "5.1.23"
resolved "https://registry.yarnpkg.com/@expo/plugin-help/-/plugin-help-5.1.23.tgz#36d82111ec6c0e9870a3f0856ae7536186624912"
@@ -1533,15 +1613,15 @@
semver "^7.3.7"
tslib "^2.4.0"
"@expo/prebuild-config@6.2.5":
version "6.2.5"
resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-6.2.5.tgz#2e7fdce8ddef3ac97fa05b4542f2b62a43bcea4b"
integrity sha512-XHgQ4OWZ03rzczD+D2ulQRjyHCVnA36cfX4q+r2x1Say4hI7lIg75ZQEsWdEMU9rZV8TbDUtZlPL4pxNWpYu7Q==
"@expo/prebuild-config@6.7.3":
version "6.7.3"
resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-6.7.3.tgz#8444c1630bd92931c2d1a510791535b7282d8fa6"
integrity sha512-jZIHzlnvdg4Gnln06XR9tvirL3hSp/Jh48COhLKs51vb3THCWumUytZBS4DSMdvGwf8btnaB01Zg00xQhSDBsA==
dependencies:
"@expo/config" "~8.1.0"
"@expo/config-plugins" "~7.2.0"
"@expo/config-types" "^49.0.0-alpha.1"
"@expo/image-utils" "0.3.22"
"@expo/config" "~8.5.0"
"@expo/config-plugins" "~7.8.0"
"@expo/config-types" "^50.0.0-alpha.1"
"@expo/image-utils" "^0.4.0"
"@expo/json-file" "^8.2.37"
debug "^4.3.1"
fs-extra "^9.0.0"
@@ -2151,6 +2231,11 @@
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.0.tgz#6c9eafc78c1529248f8f4d92b0799a712b6052c6"
integrity sha512-i9YbZPN3QgfighY/1X1Pu118VUz2Fmmhd6b2n0/O8YVgGGfw0FbUYoA97k7FkpGJ+pLCFEDLUmAPPV4D1kpeFw==
"@hapi/hoek@^9.3.0":
version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==
"@hapi/topo@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7"
@@ -2158,6 +2243,13 @@
dependencies:
"@hapi/hoek" "^9.0.0"
"@hapi/topo@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012"
integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==
dependencies:
"@hapi/hoek" "^9.0.0"
"@humanwhocodes/config-array@^0.11.13":
version "0.11.14"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b"
@@ -3399,6 +3491,13 @@
dependencies:
"@hapi/hoek" "^9.0.0"
"@sideway/address@^4.1.4":
version "4.1.4"
resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0"
integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw==
dependencies:
"@hapi/hoek" "^9.0.0"
"@sideway/formula@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f"
@@ -9192,6 +9291,17 @@ [email protected]:
"@sideway/formula" "^3.0.1"
"@sideway/pinpoint" "^2.0.0"
joi@^17.11.0:
version "17.12.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.12.0.tgz#a3fb5715f198beb0471cd551dd26792089c308d5"
integrity sha512-HSLsmSmXz+PV9PYoi3p7cgIbj06WnEBNT28n+bbBNcPZXZFqCzzvGqpTBPujx/Z0nh1+KNQPDrNgdmQ8dq0qYw==
dependencies:
"@hapi/hoek" "^9.3.0"
"@hapi/topo" "^5.1.0"
"@sideway/address" "^4.1.4"
"@sideway/formula" "^3.0.1"
"@sideway/pinpoint" "^2.0.0"
joi@^17.9.2:
version "17.9.2"
resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690"
@@ -10032,11 +10142,6 @@ [email protected]:
resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
mime@^2.4.4:
version "2.5.2"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe"
integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
@@ -12398,6 +12503,11 @@ slugify@^1.3.4:
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.4.5.tgz#a7517acf5f4c02a4df41e735354b660a4ed1efcf"
integrity sha512-WpECLAgYaxHoEAJ8Q1Lo8HOs1ngn7LN7QjXgOLbmmfkcWvosyk4ZTXkTzKyhngK640USTZUlgoQJfED1kz5fnQ==
slugify@^1.6.6:
version "1.6.6"
resolved "https://registry.yarnpkg.com/slugify/-/slugify-1.6.6.tgz#2d4ac0eacb47add6af9e04d3be79319cbcc7924b"
integrity sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==
smart-buffer@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba"
@@ -12823,6 +12933,19 @@ [email protected]:
symbol-observable "^1.0.4"
ws "^5.2.0"
[email protected]:
version "3.34.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f"
integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==
dependencies:
"@jridgewell/gen-mapping" "^0.3.2"
commander "^4.0.0"
glob "7.1.6"
lines-and-columns "^1.1.6"
mz "^2.7.0"
pirates "^4.0.1"
ts-interface-checker "^0.1.9"
sucrase@^3.20.0:
version "3.20.1"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.20.1.tgz#1c055e97d0fab2f9857f02461364075b3a4ab226"