Compare commits

...
Author SHA1 Message Date
evanbacon 2d1bf434ec feat(eas-cli): Add support for VisionOS in provisioning profiles and tests 2025-01-29 13:30:41 -08:00
Evan Bacon ab507d0bdd feat(eas-cli): Use a fallback generated name during EAS Submit (#2842) 2025-01-28 16:49:35 -08:00
Radosław Krzemień 7505b8d40a [eas-cli] [ENG-14633] Start autoIncremented builds at 1 (#2828)
* [eas-cli] Don't bump default version for Android

When the versionCode is initialized with 1, don't bump it even if autoIncrement=true

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1

* [eas-cli] Add tests for Android version

Testing the version resolving behavior for Android

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1

* [eas-cli] Don't bump default version for Ios

When the buildNumber is 1, don't bump it even if autoIncrement=true

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1

* [eas-cli] Add tests for Ios version

Testing the version resolving behavior for Ios

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1

* [eas-cli] Lint

Lint

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1

* [eas-cli] Add tests

Added tests for remote version autoIncrement=true

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1

* [eas-cli] Add changelog

Updated CHANGELOG.md

See: https://linear.app/expo/issue/ENG-14633/start-autoincrement-counter-at-0-so-first-build-has-buildnumber-==-1
2025-01-28 15:56:40 +01:00
Expo Bot b31ddee6e7 Upgrade eas-build dependencies (#2840) 2025-01-27 13:58:25 +01:00
Expo CI 01ce802b73 update CHANGELOG.md 2025-01-22 13:31:34 +00:00
Radoslaw Krzemien f75ef22154 v14.5.0 2025-01-22 14:24:59 +01:00
Radosław Krzemień 7d3f4e8fd4 [eas-json] [ENG-14636] Allow longer submit profile extension chains (#2831)
* [eas-json] Extend submit profile expansion chain

Extended the limit for expansion chain for submit profiles to equal that of build profiles - 5

See: https://linear.app/expo/issue/ENG-14636/allow-longer-profile-extend-chains-in-easjson

* [eas-json] Add tests for submit profiles

Added tests for submit profiles extension chain

See: https://linear.app/expo/issue/ENG-14636/allow-longer-profile-extend-chains-in-easjson

* [eas-json] Add tests for build profiles

Added tests for build profiles extension chain

See: https://linear.app/expo/issue/ENG-14636/allow-longer-profile-extend-chains-in-easjson

* [eas-json] Lint

Lint

See: https://linear.app/expo/issue/ENG-14636/allow-longer-profile-extend-chains-in-easjson

* [eas-json] Add changelog

Updated CHANGELOG.md

See: https://linear.app/expo/issue/ENG-14636/allow-longer-profile-extend-chains-in-easjson
2025-01-22 14:23:07 +01:00
Radosław Krzemień 004caf4bb7 [eas-cli] [ENG-14629] Improve AppleID validation (#2830)
* [eas-cli] Remove invalid unprintable characters from AppleID

Clears the AppleID received from the prompt

See: https://linear.app/expo/issue/ENG-14629/improve-apple-id-input-validation

* [eas-cli] Add tests

Adds tests for `resolveUserCredentialsAsync` function, including reading malformed AppleID from the prompt

See: https://linear.app/expo/issue/ENG-14629/improve-apple-id-input-validation

* [eas-cli] Remove line

Removed redundant expect()

See: https://linear.app/expo/issue/ENG-14629/improve-apple-id-input-validation

* [eas-cli] Add context

Added a comment with context for the change

See: https://linear.app/expo/issue/ENG-14629/improve-apple-id-input-validation

* [eas-cli] Add changelog

Updated CHANGELOG.md

See: https://linear.app/expo/issue/ENG-14629/improve-apple-id-input-validation
2025-01-22 14:17:14 +01:00
Kadi Kraman 5a16f3d6d8 [eas-cli] Detect valid JSON files during hosting upload (#2829)
* Use application/json as content type for valid JSON without an extension

* Add changelog

* Pull getContentTypeAsync to a separate function
2025-01-21 10:51:32 +00:00
Expo Bot d2e4cb5fc6 Upgrade eas-build dependencies (#2826) 2025-01-18 16:29:59 +01:00
21 changed files with 1199 additions and 170 deletions

No files matched your search

+19 -3
View File
@@ -8,15 +8,31 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Allow filtering by `--fingerprint_hash` in `eas build:list` command. ([#2818](https://github.com/expo/eas-cli/pull/2818) by [@szdziedzic](https://github.com/szdziedzic))
- Sanitize and generate names for EAS Submit to prevent failures due to invalid characters or taken names. ([#2842](https://github.com/expo/eas-cli/pull/2842) by [@evanbacon](https://github.com/evanbacon))
### 🐛 Bug fixes
### 🧹 Chores
- Fix tests for VisionOS type.
- Make new autoIncremented builds start at nr 1 by default ([#2828](https://github.com/expo/eas-cli/pull/2828) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
## [14.5.0](https://github.com/expo/eas-cli/releases/tag/v14.5.0) - 2025-01-22
### 🎉 New features
- Allow filtering by `--fingerprint_hash` in `eas build:list` command. ([#2818](https://github.com/expo/eas-cli/pull/2818) by [@szdziedzic](https://github.com/szdziedzic))
### 🐛 Bug fixes
- Ensure that the AASA file is served with content type application/json ([#2829](https://github.com/expo/eas-cli/pull/2829) by [@kadikraman](https://github.com/kadikraman))
- Ensure that the AppleID provided in prompt or saved to cache does not contain invalid unprintable characters ([#2830](https://github.com/expo/eas-cli/pull/2830) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
### 🧹 Chores
- Fix logs typos in the `eas deploy` command. ([#2822](https://github.com/expo/eas-cli/pull/2822) by [@kadikraman](https://github.com/kadikraman))
- Make `deploy` the top level command for hosting. ([#2824](https://github.com/expo/eas-cli/pull/2824) by [@kadikraman](https://github.com/kadikraman))
- Allow longer submit profile extension chain (up to 5, same as build profile) ([#2831](https://github.com/expo/eas-cli/pull/2831) by [@radoslawkrzemien](https://github.com/radoslawkrzemien))
- Make variable naming more explicit, remove deprecated runtimeFingerprintSource uses. ([#2816](https://github.com/expo/eas-cli/pull/2816) by [@wschurman](https://github.com/wschurman))
## [14.4.1](https://github.com/expo/eas-cli/releases/tag/v14.4.1) - 2025-01-15
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "14.4.1",
"version": "14.5.0",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+93 -91
View File
@@ -158,7 +158,7 @@ ALIASES
$ eas login
```
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/account/login.ts)_
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -175,7 +175,7 @@ ALIASES
$ eas logout
```
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -192,7 +192,7 @@ ALIASES
$ eas whoami
```
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/account/view.ts)_
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -206,7 +206,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/analytics.ts)_
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -258,7 +258,7 @@ DESCRIPTION
create a branch
```
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -279,7 +279,7 @@ DESCRIPTION
delete a branch
```
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -299,7 +299,7 @@ DESCRIPTION
list all branches
```
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -319,7 +319,7 @@ DESCRIPTION
rename a branch
```
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -342,7 +342,7 @@ DESCRIPTION
view a branch
```
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -379,7 +379,7 @@ DESCRIPTION
start a build
```
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/index.ts)_
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -398,7 +398,7 @@ DESCRIPTION
cancel a build
```
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -415,7 +415,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
@@ -434,7 +434,7 @@ DESCRIPTION
delete a build
```
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/delete.ts)_
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/delete.ts)_
## `eas build:inspect`
@@ -469,7 +469,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -480,8 +480,8 @@ USAGE
$ eas build:list [-p android|ios|all] [--status
new|in-queue|in-progress|pending-cancel|errored|finished|canceled] [--distribution store|internal|simulator]
[--channel <value>] [--app-version <value>] [--app-build-version <value>] [--sdk-version <value>] [--runtime-version
<value>] [--app-identifier <value>] [-e <value>] [--git-commit-hash <value>] [--offset <value>] [--limit <value>]
[--json --non-interactive] [--simulator]
<value>] [--app-identifier <value>] [-e <value>] [--git-commit-hash <value>] [--fingerprint-hash <value>] [--offset
<value>] [--limit <value>] [--json --non-interactive] [--simulator]
FLAGS
-e, --build-profile=<value> Filter only builds created with the
@@ -496,6 +496,8 @@ FLAGS
--channel=<value>
--distribution=(store|internal|simulator) Filter only builds with the specified
distribution type
--fingerprint-hash=<value> Filter only builds with the specified
fingerprint hash
--git-commit-hash=<value> Filter only builds created with the
specified git commit hash
--json Enable JSON output, non-JSON messages
@@ -519,7 +521,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/list.ts)_
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:resign`
@@ -548,7 +550,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/resign.ts)_
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/resign.ts)_
## `eas build:run`
@@ -574,7 +576,7 @@ DESCRIPTION
run simulator/emulator builds from eas-cli
```
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/run.ts)_
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/run.ts)_
## `eas build:submit`
@@ -624,7 +626,7 @@ DESCRIPTION
get the latest version from EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/version/get.ts)_
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -643,7 +645,7 @@ DESCRIPTION
update version of an app
```
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/version/set.ts)_
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -662,7 +664,7 @@ DESCRIPTION
update a version in native code with a value stored on EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/version/sync.ts)_
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -679,7 +681,7 @@ DESCRIPTION
view a build for your project
```
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/build/view.ts)_
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -700,7 +702,7 @@ DESCRIPTION
create a channel
```
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -722,7 +724,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -742,7 +744,7 @@ DESCRIPTION
list all channels
```
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:pause [NAME]`
@@ -764,7 +766,7 @@ DESCRIPTION
pause a channel to stop it from sending updates
```
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/pause.ts)_
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/pause.ts)_
## `eas channel:resume [NAME]`
@@ -786,7 +788,7 @@ DESCRIPTION
resume a channel to start sending updates
```
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/resume.ts)_
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/resume.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -819,7 +821,7 @@ DESCRIPTION
Roll a new branch out on a channel incrementally.
```
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/rollout.ts)_
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -842,7 +844,7 @@ DESCRIPTION
view a channel
```
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -863,7 +865,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/config.ts)_
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -880,7 +882,7 @@ DESCRIPTION
manage credentials
```
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/credentials/index.ts)_
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/credentials/index.ts)_
## `eas credentials:configure-build`
@@ -898,11 +900,11 @@ DESCRIPTION
Set up credentials for building your project.
```
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/credentials/configure-build.ts)_
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas deploy [options]`
Deploy your Expo web build
Deploy your Expo Router web build and API Routes.
```
USAGE
@@ -920,15 +922,17 @@ FLAGS
--prod Create a new production deployment.
DESCRIPTION
Deploy your Expo web build
Deploy your Expo Router web build and API Routes.
ALIASES
$ eas deploy
$ eas worker:deploy
```
_See code: [packages/eas-cli/src/commands/deploy/index.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/deploy/index.ts)_
## `eas deploy:alias`
Assign deployment aliases
Assign deployment aliases.
```
USAGE
@@ -942,16 +946,18 @@ FLAGS
--prod Promote an existing deployment to production.
DESCRIPTION
Assign deployment aliases
Assign deployment aliases.
ALIASES
$ eas deploy:alias
$ eas worker:alias
$ eas deploy:promote
```
_See code: [packages/eas-cli/src/commands/deploy/alias.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/deploy/alias.ts)_
## `eas deploy:promote`
Assign deployment aliases
Assign deployment aliases.
```
USAGE
@@ -965,10 +971,10 @@ FLAGS
--prod Promote an existing deployment to production.
DESCRIPTION
Assign deployment aliases
Assign deployment aliases.
ALIASES
$ eas deploy:alias
$ eas worker:alias
$ eas deploy:promote
```
@@ -984,7 +990,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/device/create.ts)_
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -1004,7 +1010,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -1025,7 +1031,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/device/list.ts)_
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:rename`
@@ -1046,7 +1052,7 @@ DESCRIPTION
rename a registered device
```
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/device/rename.ts)_
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -1060,7 +1066,7 @@ DESCRIPTION
view a device for your project
```
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/device/view.ts)_
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -1074,7 +1080,7 @@ DESCRIPTION
display environment info
```
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas env:create [ENVIRONMENT]`
@@ -1103,7 +1109,7 @@ DESCRIPTION
create an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/create.ts)_
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/create.ts)_
## `eas env:delete [ENVIRONMENT]`
@@ -1127,7 +1133,7 @@ DESCRIPTION
delete an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/delete.ts)_
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/delete.ts)_
## `eas env:exec ENVIRONMENT BASH_COMMAND`
@@ -1148,7 +1154,7 @@ DESCRIPTION
execute a command with environment variables from the selected environment
```
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/exec.ts)_
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/exec.ts)_
## `eas env:get [ENVIRONMENT]`
@@ -1173,7 +1179,7 @@ DESCRIPTION
view an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/get.ts)_
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/get.ts)_
## `eas env:list [ENVIRONMENT]`
@@ -1198,7 +1204,7 @@ DESCRIPTION
list environment variables for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/list.ts)_
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/list.ts)_
## `eas env:pull [ENVIRONMENT]`
@@ -1221,7 +1227,7 @@ DESCRIPTION
pull environment variables for the selected environment to .env file
```
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/pull.ts)_
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/pull.ts)_
## `eas env:push [ENVIRONMENT]`
@@ -1242,7 +1248,7 @@ DESCRIPTION
push environment variables from .env file to the selected environment
```
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/push.ts)_
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/push.ts)_
## `eas env:update [ENVIRONMENT]`
@@ -1273,7 +1279,7 @@ DESCRIPTION
update an environment variable on the current project or account
```
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/env/update.ts)_
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/env/update.ts)_
## `eas help [COMMAND]`
@@ -1381,7 +1387,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/metadata/lint.ts)_
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -1398,7 +1404,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -1415,7 +1421,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1445,7 +1451,7 @@ DESCRIPTION
open the project page in a web browser
```
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/open.ts)_
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/open.ts)_
## `eas project:info`
@@ -1459,7 +1465,7 @@ DESCRIPTION
information about the current project
```
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/project/info.ts)_
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -1482,7 +1488,7 @@ ALIASES
$ eas init
```
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/project/init.ts)_
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1500,7 +1506,7 @@ ALIASES
$ eas onboarding
```
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/project/onboarding.ts)_
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/project/onboarding.ts)_
## `eas submit`
@@ -1531,7 +1537,7 @@ ALIASES
$ eas build:submit
```
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/submit.ts)_
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -1573,7 +1579,7 @@ DESCRIPTION
publish an update group
```
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/index.ts)_
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1593,7 +1599,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1614,7 +1620,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:edit [GROUPID]`
@@ -1638,7 +1644,7 @@ DESCRIPTION
edit all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/edit.ts)_
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/edit.ts)_
## `eas update:list`
@@ -1660,7 +1666,7 @@ DESCRIPTION
view the recent updates
```
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/list.ts)_
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1692,7 +1698,7 @@ DESCRIPTION
roll back to an existing update
```
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/republish.ts)_
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/republish.ts)_
## `eas update:roll-back-to-embedded`
@@ -1720,7 +1726,7 @@ DESCRIPTION
roll back to the embedded update
```
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
@@ -1740,7 +1746,7 @@ DESCRIPTION
roll back to an embedded update or an existing update
```
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/rollback.ts)_
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -1760,7 +1766,7 @@ DESCRIPTION
update group details
```
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/update/view.ts)_
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1781,7 +1787,7 @@ DESCRIPTION
create a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1801,7 +1807,7 @@ DESCRIPTION
delete a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1819,7 +1825,7 @@ DESCRIPTION
list webhooks
```
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1841,7 +1847,7 @@ DESCRIPTION
update a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1858,7 +1864,7 @@ DESCRIPTION
view a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
@@ -1877,7 +1883,7 @@ ALIASES
## `eas worker:alias`
Assign deployment aliases
Assign deployment aliases.
```
USAGE
@@ -1891,18 +1897,16 @@ FLAGS
--prod Promote an existing deployment to production.
DESCRIPTION
Assign deployment aliases
Assign deployment aliases.
ALIASES
$ eas deploy:alias
$ eas worker:alias
$ eas deploy:promote
```
_See code: [packages/eas-cli/src/commands/worker/alias.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/worker/alias.ts)_
## `eas deploy [options]`
Deploy your Expo web build
Deploy your Expo Router web build and API Routes.
```
USAGE
@@ -1920,14 +1924,12 @@ FLAGS
--prod Create a new production deployment.
DESCRIPTION
Deploy your Expo web build
Deploy your Expo Router web build and API Routes.
ALIASES
$ eas deploy
$ eas worker:deploy
```
_See code: [packages/eas-cli/src/commands/worker/deploy.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/worker/deploy.ts)_
## `eas workflow:create [NAME]`
create a new workflow configuration YAML file
@@ -1946,7 +1948,7 @@ DESCRIPTION
create a new workflow configuration YAML file
```
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/workflow/create.ts)_
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/workflow/create.ts)_
## `eas workflow:run [FILE]`
@@ -1966,7 +1968,7 @@ DESCRIPTION
Run an EAS workflow
```
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/workflow/run.ts)_
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/workflow/run.ts)_
## `eas workflow:validate PATH`
@@ -1986,5 +1988,5 @@ DESCRIPTION
validate a workflow configuration yaml file
```
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v14.4.1/packages/eas-cli/src/commands/workflow/validate.ts)_
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/workflow/validate.ts)_
<!-- commandsstop -->
+4 -4
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "14.4.1",
"version": "14.5.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -12,8 +12,8 @@
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "10.0.6",
"@expo/config-plugins": "9.0.12",
"@expo/eas-build-job": "1.0.156",
"@expo/eas-json": "14.3.1",
"@expo/eas-build-job": "1.0.165",
"@expo/eas-json": "14.5.0",
"@expo/env": "^1.0.0",
"@expo/json-file": "8.3.3",
"@expo/logger": "1.0.117",
@@ -28,7 +28,7 @@
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.7.2",
"@expo/steps": "1.0.161",
"@expo/steps": "1.0.166",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "^1.26.2",
"@oclif/plugin-autocomplete": "^2.3.10",
@@ -1,23 +1,43 @@
import { ExpoConfig } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { BuildProfile } from '@expo/eas-json';
import { AndroidBuildProfile } from '@expo/eas-json/build/build/types';
import assert from 'assert';
import fs from 'fs-extra';
import { vol } from 'memfs';
import os from 'os';
import path from 'path';
import { instance, mock } from 'ts-mockito';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { AppVersionMutation } from '../../../graphql/mutations/AppVersionMutation';
import { AppVersionQuery } from '../../../graphql/queries/AppVersionQuery';
import { getAppBuildGradleAsync, resolveConfigValue } from '../../../project/android/gradleUtils';
import { resolveVcsClient } from '../../../vcs';
import { Client } from '../../../vcs/vcs';
import {
BumpStrategy,
bumpVersionAsync,
bumpVersionInAppJsonAsync,
maybeResolveVersionsAsync,
resolveRemoteVersionCodeAsync,
} from '../version';
const fsReal = jest.requireActual('fs').promises as typeof fs;
jest.mock('fs');
jest.mock('../../../commandUtils/context/contextUtils/createGraphqlClient');
jest.mock('../../../vcs/vcs');
jest.mock('../../../graphql/queries/AppVersionQuery');
jest.mock('../../../graphql/mutations/AppVersionMutation');
jest.mock('../../../ora', () => ({
ora: jest.fn().mockImplementation(() => ({
start: jest.fn().mockImplementation(() => ({
succeed: jest.fn(),
stop: jest.fn(),
fail: jest.fn(),
})),
})),
}));
const vcsClient = resolveVcsClient();
@@ -216,12 +236,160 @@ describe(maybeResolveVersionsAsync, () => {
});
});
describe(resolveRemoteVersionCodeAsync, () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('uses current remote versionCode when remote version set, autoIncrement=false', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue({
buildVersion: '11',
storeVersion: '1.2.3',
});
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject();
const result = await resolveRemoteVersionCodeAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationId: 'fakeApplicationId',
buildProfile: {} as AndroidBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('11');
expect(createAppVersionAsyncSpy).not.toHaveBeenCalled();
});
it('initializes versionCode from local files when remote version not set, autoIncrement=false', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ versionCode: 22, versionName: '2.3.4' });
const result = await resolveRemoteVersionCodeAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationId: 'fakeApplicationId',
buildProfile: {} as AndroidBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('22');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('2.3.4');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('22');
});
it('initializes versionCode starting with 1 when remote version not set and not set in local files, autoIncrement=false', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ versionCode: null, versionName: null });
const result = await resolveRemoteVersionCodeAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationId: 'fakeApplicationId',
buildProfile: {} as AndroidBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('1');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('1.0.0');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('1');
});
it('increments current remote versionCode when remote version set, autoIncrement=true', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue({
buildVersion: '11',
storeVersion: '1.2.3',
});
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject();
const result = await resolveRemoteVersionCodeAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationId: 'fakeApplicationId',
buildProfile: { autoIncrement: true } as AndroidBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('12');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('3.0.0');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('12');
});
it('increments versionCode from local files when remote version not set, autoIncrement=true', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ versionCode: 22, versionName: '2.3.4' });
const result = await resolveRemoteVersionCodeAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationId: 'fakeApplicationId',
buildProfile: { autoIncrement: true } as AndroidBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('23');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('2.3.4');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('23');
});
it('initializes versionCode starting with 1 when remote version not set and not set in local files, autoIncrement=true', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ versionCode: null, versionName: null });
const result = await resolveRemoteVersionCodeAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationId: 'fakeApplicationId',
buildProfile: { autoIncrement: true } as AndroidBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('1');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('1.0.0');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('1');
});
});
function initBareWorkflowProject({
versionCode = 123,
versionName = '3.0.0',
}: {
versionCode?: number;
versionName?: string;
versionCode?: number | null;
versionName?: string | null;
} = {}): ExpoConfig {
const fakeExp: ExpoConfig = {
name: 'myproject',
@@ -239,8 +407,8 @@ function initBareWorkflowProject({
'./android/app/build.gradle': `android {
defaultConfig {
applicationId "com.expo.testapp"
versionCode ${versionCode}
versionName "${versionName}"
${versionCode ? `versionCode "${versionCode}"` : ''}
${versionName ? `versionName "${versionName}"` : ''}
}
}`,
'./android/app/src/main/AndroidManifest.xml': 'fake',
+12 -2
View File
@@ -99,7 +99,7 @@ export async function maybeResolveVersionsAsync(
exp: ExpoConfig,
buildProfile: BuildProfile<Platform.ANDROID>,
vcsClient: Client
): Promise<{ appVersion?: string; appBuildVersion?: string }> {
): Promise<{ appVersion?: string; appBuildVersion?: string; isVersionInitialized?: boolean }> {
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID, vcsClient);
if (workflow === Workflow.GENERIC) {
const buildGradle = await getAppBuildGradleAsync(projectDir);
@@ -113,6 +113,11 @@ export async function maybeResolveVersionsAsync(
resolveConfigValue(buildGradle, 'versionName', parsedGradleCommand?.flavor) ?? '1.0.0',
appBuildVersion:
resolveConfigValue(buildGradle, 'versionCode', parsedGradleCommand?.flavor) ?? '1',
isVersionInitialized: !resolveConfigValue(
buildGradle,
'versionCode',
parsedGradleCommand?.flavor
),
};
} catch {
return {};
@@ -204,6 +209,7 @@ export async function resolveRemoteVersionCodeAsync(
const localVersions = await maybeResolveVersionsAsync(projectDir, exp, buildProfile, vcsClient);
let currentBuildVersion: string;
let shouldInitializeVersionCode = false;
if (remoteVersions?.buildVersion) {
currentBuildVersion = remoteVersions.buildVersion;
} else {
@@ -214,6 +220,7 @@ export async function resolveRemoteVersionCodeAsync(
)
);
currentBuildVersion = localVersions.appBuildVersion;
shouldInitializeVersionCode = localVersions.isVersionInitialized ?? false;
} else {
Log.error(
`Remote versions are not configured and EAS CLI was not able to read the current version from your project. Use "eas build:version:set" to initialize remote versions.`
@@ -223,7 +230,10 @@ export async function resolveRemoteVersionCodeAsync(
}
if (!buildProfile.autoIncrement && remoteVersions?.buildVersion) {
return currentBuildVersion;
} else if (!buildProfile.autoIncrement && !remoteVersions?.buildVersion) {
} else if (
(!buildProfile.autoIncrement && !remoteVersions?.buildVersion) ||
shouldInitializeVersionCode
) {
const spinner = ora(
`Initializing versionCode with ${chalk.bold(currentBuildVersion)}.`
).start();
@@ -1,12 +1,19 @@
import { ExpoConfig } from '@expo/config';
import { IOSConfig } from '@expo/config-plugins';
import { IosBuildProfile } from '@expo/eas-json/build/build/types';
import fs from 'fs-extra';
import { vol } from 'memfs';
import os from 'os';
import { instance, mock } from 'ts-mockito';
import type { XCBuildConfiguration } from 'xcode';
import { ExpoGraphqlClient } from '../../../commandUtils/context/contextUtils/createGraphqlClient';
import { Target } from '../../../credentials/ios/types';
import { AppVersionMutation } from '../../../graphql/mutations/AppVersionMutation';
import { AppVersionQuery } from '../../../graphql/queries/AppVersionQuery';
import { readPlistAsync } from '../../../utils/plist';
import { resolveVcsClient } from '../../../vcs';
import { Client } from '../../../vcs/vcs';
import {
BumpStrategy,
bumpVersionAsync,
@@ -15,9 +22,23 @@ import {
getInfoPlistPath,
readBuildNumberAsync,
readShortVersionAsync,
resolveRemoteBuildNumberAsync,
} from '../version';
jest.mock('fs');
jest.mock('../../../commandUtils/context/contextUtils/createGraphqlClient');
jest.mock('../../../vcs/vcs');
jest.mock('../../../graphql/queries/AppVersionQuery');
jest.mock('../../../graphql/mutations/AppVersionMutation');
jest.mock('../../../ora', () => ({
ora: jest.fn().mockImplementation(() => ({
start: jest.fn().mockImplementation(() => ({
succeed: jest.fn(),
stop: jest.fn(),
fail: jest.fn(),
})),
})),
}));
const vcsClient = resolveVcsClient();
@@ -359,6 +380,154 @@ describe(getInfoPlistPath, () => {
});
});
describe(resolveRemoteBuildNumberAsync, () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('uses current remote buildNumber when remote version set, autoIncrement=false', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue({
buildVersion: '11',
storeVersion: '1.2.3',
});
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject();
const result = await resolveRemoteBuildNumberAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationTarget: {} as Target,
buildProfile: {} as IosBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('11');
expect(createAppVersionAsyncSpy).not.toHaveBeenCalled();
});
it('initializes buildNumber from local files when remote version not set, autoIncrement=false', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ buildNumber: '22', appVersion: '2.3.4' });
const result = await resolveRemoteBuildNumberAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationTarget: {} as Target,
buildProfile: {} as IosBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('22');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('2.3.4');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('22');
});
it('initializes buildNumber starting with 1 when remote version not set and local version is 1, autoIncrement=false', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ buildNumber: '1', appVersion: '1.0.0' });
const result = await resolveRemoteBuildNumberAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationTarget: {} as Target,
buildProfile: {} as IosBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('1');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('1.0.0');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('1');
});
it('increments current remote buildNumber when remote version set, autoIncrement=true', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue({
buildVersion: '11',
storeVersion: '1.2.3',
});
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject();
const result = await resolveRemoteBuildNumberAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationTarget: {} as Target,
buildProfile: { autoIncrement: true } as IosBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('12');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('1.0.0');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('12');
});
it('increments buildNumber from local files when remote version not set, autoIncrement=true', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ buildNumber: '22', appVersion: '2.3.4' });
const result = await resolveRemoteBuildNumberAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationTarget: {} as Target,
buildProfile: { autoIncrement: true } as IosBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('23');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('2.3.4');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('23');
});
it('initializes buildNumber starting with 1 when remote version not set and local version is 1, autoIncrement=true', async () => {
const graphQLClientMock = instance(mock<ExpoGraphqlClient>());
const vcsClientMock = instance(mock<Client>());
vcsClientMock.getRootPathAsync = async () => '/app';
jest.mocked(AppVersionQuery.latestVersionAsync).mockResolvedValue(null);
const createAppVersionAsyncSpy = jest.spyOn(AppVersionMutation, 'createAppVersionAsync');
const exp = initBareWorkflowProject({ buildNumber: '1', appVersion: '1.0.0' });
const result = await resolveRemoteBuildNumberAsync(graphQLClientMock, {
projectDir: '/app',
projectId: 'fakeProjectId',
exp,
applicationTarget: {} as Target,
buildProfile: { autoIncrement: true } as IosBuildProfile,
vcsClient: vcsClientMock,
});
expect(result).toBe('1');
expect(createAppVersionAsyncSpy).toHaveBeenCalled();
expect(createAppVersionAsyncSpy.mock.calls[0][1].storeVersion).toBe('1.0.0');
expect(createAppVersionAsyncSpy.mock.calls[0][1].buildVersion).toBe('1');
});
});
function initBareWorkflowProject({
appVersion = '1.0.0',
buildNumber = '1',
+6 -1
View File
@@ -330,6 +330,7 @@ export async function resolveRemoteBuildNumberAsync(
vcsClient
);
let currentBuildVersion: string;
let shouldInitializeBuildNumber = false;
if (remoteVersions?.buildVersion) {
currentBuildVersion = remoteVersions.buildVersion;
} else {
@@ -340,6 +341,7 @@ export async function resolveRemoteBuildNumberAsync(
)
);
currentBuildVersion = localBuildNumber;
shouldInitializeBuildNumber = localBuildNumber === '1';
} else {
Log.error(
`Remote versions are not configured and EAS CLI was not able to read the current version from your project. Use "eas build:version:set" to initialize remote versions.`
@@ -349,7 +351,10 @@ export async function resolveRemoteBuildNumberAsync(
}
if (!buildProfile.autoIncrement && remoteVersions?.buildVersion) {
return currentBuildVersion;
} else if (!buildProfile.autoIncrement && !remoteVersions?.buildVersion) {
} else if (
(!buildProfile.autoIncrement && !remoteVersions?.buildVersion) ||
shouldInitializeBuildNumber
) {
const spinner = ora(
`Initializing buildNumber with ${chalk.bold(currentBuildVersion)}.`
).start();
@@ -0,0 +1,168 @@
import { Session } from '@expo/apple-utils';
import nock from 'nock';
import { createAppAsync } from '../ensureAppExists';
const FIXTURE_SUCCESS = {
data: {
type: 'apps',
id: '6741087677',
attributes: {
name: 'expo (xxx)',
bundleId: 'com.bacon.jan27.x',
},
},
};
const FIXTURE_INVALID_NAME = {
errors: [
{
id: 'b3e7ca18-e4ce-4e55-83ce-8fff35dbaeca',
status: '409',
code: 'ENTITY_ERROR.ATTRIBUTE.INVALID.INVALID_CHARACTERS',
title: 'An attribute value has invalid characters.',
detail:
'App Name contains certain Unicode symbols, emoticons, diacritics, special characters, or private use characters that are not permitted.',
source: {
pointer: '/included/1/name',
},
},
],
};
const FIXTURE_ALREADY_USED_ON_ACCOUNT = {
errors: [
{
id: 'b91aefc5-0e94-48d9-8613-5b1a464a20f0',
status: '409',
code: 'ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE.SAME_ACCOUNT',
title:
'The provided entity includes an attribute with a value that has already been used on this account.',
detail:
'The app name you entered is already being used for another app in your account. If you would like to use the name for this app you will need to submit an update to your other app to change the name, or remove it from App Store Connect.',
source: {
pointer: '/included/1/name',
},
},
],
};
const FIXTURE_ALREADY_USED_ON_ANOTHER_ACCOUNT = {
errors: [
{
id: '72b960f2-9e51-4f19-8d83-7cc08d42fec4',
status: '409',
code: 'ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE.DIFFERENT_ACCOUNT',
title:
'The provided entity includes an attribute with a value that has already been used on a different account.',
detail:
'The App Name you entered is already being used. If you have trademark rights to this name and would like it released for your use, submit a claim.',
source: {
pointer: '/included/1/name',
},
},
],
};
const MOCK_CONTEXT = {
providerId: 1337,
teamId: 'test-team-id',
token: 'test-token',
};
beforeAll(async () => {
// Mock setup cookies API calls.
nock('https://appstoreconnect.apple.com')
.get(`/olympus/v1/session`)
.reply(200, {
provider: {
providerId: 1337,
publicProviderId: 'xxx-xxx-xxx-xxx-xxx',
name: 'Evan Bacon',
contentTypes: ['SOFTWARE'],
subType: 'INDIVIDUAL',
},
});
await Session.fetchCurrentSessionInfoAsync();
});
function getNameFromBody(body: any): any {
return body.included.find((item: any) => item.id === '${new-appInfoLocalization-id}')?.attributes
?.name;
}
it('asserts invalid name cases', async () => {
const scope = nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`, body => {
expect(getNameFromBody(body)).toBe('Expo 🚀');
return true;
})
.reply(409, FIXTURE_INVALID_NAME);
// Already used on same account
nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`, body => {
expect(getNameFromBody(body)).toBe('Expo -');
return true;
})
.reply(409, FIXTURE_ALREADY_USED_ON_ACCOUNT);
// Already used on different account
nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`, body => {
expect(getNameFromBody(body)).toMatch(/Expo - \([\w\d]+\)/);
return true;
})
.reply(409, FIXTURE_ALREADY_USED_ON_ANOTHER_ACCOUNT);
// Success
nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`, body => {
expect(getNameFromBody(body)).toMatch(/Expo - \([\w\d]+\)/);
return true;
})
.reply(200, FIXTURE_SUCCESS);
await createAppAsync(MOCK_CONTEXT, {
bundleId: 'com.bacon.jan27.x',
name: 'Expo 🚀',
companyName: 'expo',
});
expect(scope.isDone()).toBeTruthy();
});
it('works on first try', async () => {
nock('https://appstoreconnect.apple.com').post(`/iris/v1/apps`).reply(200, FIXTURE_SUCCESS);
await createAppAsync(MOCK_CONTEXT, {
bundleId: 'com.bacon.jan27.x',
name: 'Expo',
companyName: 'expo',
});
});
it('doubles up entropy', async () => {
nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`)
.reply(409, FIXTURE_ALREADY_USED_ON_ANOTHER_ACCOUNT);
nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`)
.reply(409, FIXTURE_ALREADY_USED_ON_ANOTHER_ACCOUNT);
nock('https://appstoreconnect.apple.com')
.post(`/iris/v1/apps`, body => {
expect(getNameFromBody(body)).toMatch(/Expo \([\w\d]+\) \([\w\d]+\)/);
return true;
})
.reply(200, FIXTURE_SUCCESS);
await createAppAsync(MOCK_CONTEXT, {
bundleId: 'com.bacon.jan27.x',
name: 'Expo',
companyName: 'expo',
});
});
@@ -1,11 +1,26 @@
import { JsonFileCache } from '@expo/apple-utils';
import * as fs from 'fs-extra';
import { vol } from 'memfs';
import { promptAsync } from '../../../../prompts';
import { AppleTeamType } from '../authenticateTypes';
import { resolveAppleTeamAsync, resolveAscApiKeyAsync } from '../resolveCredentials';
import * as Keychain from '../keychain';
import {
resolveAppleTeamAsync,
resolveAscApiKeyAsync,
resolveUserCredentialsAsync,
} from '../resolveCredentials';
jest.mock('../../../../prompts');
jest.mock('fs');
jest.mock('@expo/apple-utils', () => {
return {
getCacheAsync: jest.fn(),
usernameCachePath: jest.fn(),
...jest.requireActual('@expo/apple-utils'),
};
});
jest.mock('../keychain');
const testAscApiKey = {
keyP8: 'test-key-p8',
@@ -89,3 +104,139 @@ describe(resolveAppleTeamAsync, () => {
});
});
});
describe(resolveUserCredentialsAsync, () => {
let KeychainMock: any;
beforeAll(() => {
JsonFileCache.getCacheAsync = jest.fn().mockImplementation(async (filePath: string) => {
const content = await fs.readFile(filePath, 'utf-8');
return content ? JSON.parse(content) : null;
});
KeychainMock = jest.mocked(Keychain);
});
beforeEach(() => {
jest.clearAllMocks();
KeychainMock.EXPO_NO_KEYCHAIN = '';
});
it('uses credentials resolved from options', async () => {
const result = await resolveUserCredentialsAsync({
username: 'fakeUsername',
password: 'fakePassword',
});
expect(result).toMatchObject({
username: 'fakeUsername',
password: 'fakePassword',
});
});
it('uses credentials resolved from environment', async () => {
process.env.EXPO_APPLE_ID = 'fakeUsername';
process.env.EXPO_APPLE_PASSWORD = 'fakePassword';
const result = await resolveUserCredentialsAsync({});
expect(result).toMatchObject({
username: 'fakeUsername',
password: 'fakePassword',
});
});
it('uses credentials from prompt, does not update cache if they match', async () => {
vol.fromJSON({
'./.app-store/auth/username.json': `
{
"username": "fakeUsername"
}
`,
});
jest.mocked(promptAsync).mockResolvedValueOnce({ username: 'fakeUsername' });
JsonFileCache.usernameCachePath = jest.fn().mockReturnValue('./.app-store/auth/username.json');
const cacheAsyncSpy = jest.spyOn(JsonFileCache, 'cacheAsync');
const result = await resolveUserCredentialsAsync({});
expect(result).toMatchObject({
username: 'fakeUsername',
});
expect(cacheAsyncSpy).not.toHaveBeenCalled();
});
it("uses credentials from prompt, updates cache if they don't match", async () => {
vol.fromJSON({
'./.app-store/auth/username.json': `
{
"username": "fakeUsername"
}
`,
});
jest.mocked(promptAsync).mockResolvedValueOnce({ username: 'newFakeUsername' });
JsonFileCache.usernameCachePath = jest.fn().mockReturnValue('./.app-store/auth/username.json');
const cacheAsyncSpy = jest.spyOn(JsonFileCache, 'cacheAsync');
expect(JSON.parse(await fs.readFile('./.app-store/auth/username.json', 'utf-8'))).toMatchObject(
{ username: 'fakeUsername' }
);
const result = await resolveUserCredentialsAsync({});
expect(result).toMatchObject({
username: 'newFakeUsername',
});
expect(cacheAsyncSpy).toHaveBeenCalledWith('./.app-store/auth/username.json', {
username: 'newFakeUsername',
});
expect(JSON.parse(await fs.readFile('./.app-store/auth/username.json', 'utf-8'))).toMatchObject(
{ username: 'newFakeUsername' }
);
});
it("uses credentials from prompt, doesn't read or update cache if EXPO_NO_KEYCHAIN is set", async () => {
vol.fromJSON({
'./.app-store/auth/username.json': `
{
"username": "fakeUsername"
}
`,
});
jest.mocked(promptAsync).mockResolvedValueOnce({ username: 'newFakeUsername' });
JsonFileCache.usernameCachePath = jest.fn().mockReturnValue('./.app-store/auth/username.json');
KeychainMock.EXPO_NO_KEYCHAIN = 'true';
const getCacheAsyncSpy = jest.spyOn(JsonFileCache, 'getCacheAsync');
const cacheAsyncSpy = jest.spyOn(JsonFileCache, 'cacheAsync');
expect(JSON.parse(await fs.readFile('./.app-store/auth/username.json', 'utf-8'))).toMatchObject(
{ username: 'fakeUsername' }
);
const result = await resolveUserCredentialsAsync({});
expect(result).toMatchObject({
username: 'newFakeUsername',
});
expect(getCacheAsyncSpy).not.toHaveBeenCalled();
expect(cacheAsyncSpy).not.toHaveBeenCalled();
await expect(fs.access('./.app-store/auth/username.json')).rejects.toThrow();
});
it('clears credentials from prompt if malformed before using and updating cache', async () => {
vol.fromJSON({
'./.app-store/auth/username.json': `
{
"username": "fakeUsername"
}
`,
});
jest.mocked(promptAsync).mockResolvedValueOnce({ username: '\x17newFake\x01Username\x1F' });
JsonFileCache.usernameCachePath = jest.fn().mockReturnValue('./.app-store/auth/username.json');
const cacheAsyncSpy = jest.spyOn(JsonFileCache, 'cacheAsync');
expect(JSON.parse(await fs.readFile('./.app-store/auth/username.json', 'utf-8'))).toMatchObject(
{ username: 'fakeUsername' }
);
const result = await resolveUserCredentialsAsync({});
expect(result).toMatchObject({
username: 'newFakeUsername',
});
expect(cacheAsyncSpy).toHaveBeenCalledWith('./.app-store/auth/username.json', {
username: 'newFakeUsername',
});
expect(JSON.parse(await fs.readFile('./.app-store/auth/username.json', 'utf-8'))).toMatchObject(
{ username: 'newFakeUsername' }
);
});
});
@@ -1,6 +1,7 @@
import { App, BundleId } from '@expo/apple-utils';
import { App, BundleId, RequestContext } from '@expo/apple-utils';
import { JSONObject } from '@expo/json-file';
import chalk from 'chalk';
import { randomBytes } from 'node:crypto';
import { getRequestContext, isUserAuthCtx } from './authenticate';
import { AuthCtx, UserAuthCtx } from './authenticateTypes';
@@ -188,7 +189,7 @@ export async function ensureAppExistsAsync(
/**
* **Does not support App Store Connect API (CI).**
*/
app = await App.createAsync(context, {
app = await createAppAsync(context, {
bundleId: bundleIdentifier,
name,
primaryLocale: language,
@@ -215,3 +216,120 @@ export async function ensureAppExistsAsync(
);
return app;
}
function sanitizeName(name: string): string {
return (
name
// Replace emojis with a `-`
.replace(/[\p{Emoji}]/gu, '-')
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.trim()
);
}
export async function createAppAsync(
context: RequestContext,
props: {
bundleId: string;
name: string;
primaryLocale?: string;
companyName?: string;
sku?: string;
},
retryCount = 0
): Promise<App> {
try {
/**
* **Does not support App Store Connect API (CI).**
*/
return await App.createAsync(context, props);
} catch (error) {
if (retryCount >= 5) {
throw error;
}
if (error instanceof Error) {
const handleDuplicateNameErrorAsync = async (): Promise<App> => {
const generatedName = props.name + ` (${randomBytes(3).toString('hex')})`;
Log.warn(
`App name "${props.name}" is already taken. Using generated name "${generatedName}" which can be changed later from https://appstoreconnect.apple.com.`
);
// Sanitize the name and try again.
return await createAppAsync(
context,
{
...props,
name: generatedName,
},
retryCount + 1
);
};
if (isAppleError(error)) {
// New error class that is thrown when the name is already taken but belongs to you.
if (
error.data.errors.some(
e =>
e.code === 'ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE.SAME_ACCOUNT' ||
e.code === 'ENTITY_ERROR.ATTRIBUTE.INVALID.DUPLICATE.DIFFERENT_ACCOUNT'
)
) {
return await handleDuplicateNameErrorAsync();
}
}
if ('code' in error && typeof error.code === 'string') {
if (
// Name is invalid
error.code === 'APP_CREATE_NAME_INVALID'
// UnexpectedAppleResponse: An attribute value has invalid characters. - App Name contains certain Unicode symbols, emoticons, diacritics, special characters, or private use characters that are not permitted.
// Name is taken
) {
const sanitizedName = sanitizeName(props.name);
if (sanitizedName === props.name) {
throw error;
}
Log.warn(
`App name "${props.name}" contains invalid characters. Using sanitized name "${sanitizedName}" which can be changed later from https://appstoreconnect.apple.com.`
);
// Sanitize the name and try again.
return await createAppAsync(
context,
{
...props,
name: sanitizedName,
},
retryCount + 1
);
}
if (
// UnexpectedAppleResponse: The provided entity includes an attribute with a value that has already been used on a different account. - The App Name you entered is already being used. If you have trademark rights to
// this name and would like it released for your use, submit a claim.
error.code === 'APP_CREATE_NAME_UNAVAILABLE'
) {
return await handleDuplicateNameErrorAsync();
}
}
}
throw error;
}
}
function isAppleError(error: any): error is {
data: {
errors: {
id: string;
status: string;
/** 'ENTITY_ERROR.ATTRIBUTE.INVALID.INVALID_CHARACTERS' */
code: string;
/** 'An attribute value has invalid characters.' */
title: string;
/** 'App Name contains certain Unicode symbols, emoticons, diacritics, special characters, or private use characters that are not permitted.' */
detail: string;
}[];
};
} {
return 'data' in error && 'errors' in error.data && Array.isArray(error.data.errors);
}
@@ -30,6 +30,7 @@ function resolveProfileType(
case ApplePlatform.TV_OS:
return resolveProfileTypeAppleTv(profileClass, isEnterprise);
case ApplePlatform.MAC_OS:
case ApplePlatform.VISION_OS:
throw new Error(`${applePlatform} profiles are not supported`);
}
}
@@ -208,13 +208,18 @@ async function promptUsernameAsync(): Promise<string> {
// the default value for quicker authentication.
const lastAppleId = await getCachedUsernameAsync();
const { username } = await promptAsync({
let { username } = await promptAsync({
type: 'text',
name: 'username',
message: `Apple ID:`,
validate: (val: string) => val !== '',
initial: lastAppleId ?? undefined,
});
// https://github.com/expo/eas-cli/issues/2254
// user got an invalid unprintable character in their username, which was saved to cache and used to prefill the prompt
// which made them accept the prefilled value not knowing it contains the character and fail to log in
// this replace makes sure no such characters are used or cached
username = username.replace(/[\x00-\x1F]/gi, '');
if (username && username !== lastAppleId) {
await cacheUsernameAsync(username);
@@ -29,7 +29,7 @@ describe(getApplePlatformFromSdkRoot, () => {
// Update `getApplePlatformFromSdkRoot` to be compatible with new Apple Platforms
test('all enumerations work with the function', () => {
expect(Object.values(ApplePlatform).sort()).toEqual(
[ApplePlatform.IOS, ApplePlatform.TV_OS, ApplePlatform.MAC_OS].sort()
[ApplePlatform.IOS, ApplePlatform.TV_OS, ApplePlatform.MAC_OS, ApplePlatform.VISION_OS].sort()
);
});
test('existing SDKs work with the function', () => {
+8 -34
View File
@@ -1,6 +1,5 @@
import { App, RequestContext, Session, User } from '@expo/apple-utils';
import { RequestContext, Session, User } from '@expo/apple-utils';
import { Platform } from '@expo/eas-build-job';
import chalk from 'chalk';
import { sanitizeLanguage } from './utils/language';
import { getRequestContext } from '../../credentials/ios/appstore/authenticate';
@@ -85,38 +84,13 @@ async function createAppStoreConnectAppAsync(
);
}
let app: App | null = null;
try {
app = await ensureAppExistsAsync(userAuthCtx, {
name: appName,
language,
companyName,
bundleIdentifier: bundleId,
sku,
});
} catch (error: any) {
if (
// Name is invalid
error.message.match(
/App Name contains certain Unicode(.*)characters that are not permitted/
) ||
// UnexpectedAppleResponse: An attribute value has invalid characters. - App Name contains certain Unicode symbols, emoticons, diacritics, special characters, or private use characters that are not permitted.
// Name is taken
error.message.match(/The App Name you entered is already being used/)
// UnexpectedAppleResponse: The provided entity includes an attribute with a value that has already been used on a different account. - The App Name you entered is already being used. If you have trademark rights to
// this name and would like it released for your use, submit a claim.
) {
Log.addNewLineIfNone();
Log.warn(
`Change the name in your app config, or use a custom name with the ${chalk.bold(
'--app-name'
)} flag`
);
Log.newLine();
}
throw error;
}
const app = await ensureAppExistsAsync(userAuthCtx, {
name: appName,
language,
companyName,
bundleIdentifier: bundleId,
sku,
});
return {
ascAppIdentifier: app.id,
+23 -3
View File
@@ -4,6 +4,7 @@ import mime from 'mime';
import { Gzip } from 'minizlib';
import fetch, { Headers, HeadersInit, RequestInit, Response } from 'node-fetch';
import fs, { createReadStream } from 'node:fs';
import { readFile } from 'node:fs/promises';
import path from 'node:path';
import promiseRetry from 'promise-retry';
@@ -28,6 +29,24 @@ const isCompressible = (contentType: string | null, size: number): boolean => {
}
};
const getContentTypeAsync = async (filePath: string): Promise<string | null> => {
let contentType = mime.getType(path.basename(filePath));
if (!contentType) {
const fileContent = await readFile(filePath, 'utf-8');
try {
// check if file is valid JSON without an extension, e.g. for the apple app site association file
const parsedData = JSON.parse(fileContent);
if (parsedData) {
contentType = 'application/json';
}
} catch {}
}
return contentType;
};
export interface UploadParams extends Omit<RequestInit, 'signal' | 'body'> {
filePath: string;
compress?: boolean;
@@ -70,14 +89,15 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
headers: headersInit,
...requestInit
} = params;
const stat = await fs.promises.stat(params.filePath);
const stat = await fs.promises.stat(filePath);
if (stat.size > MAX_UPLOAD_SIZE) {
throw new Error(
`Upload of "${params.filePath}" aborted: File size is greater than the upload limit (>500MB)`
`Upload of "${filePath}" aborted: File size is greater than the upload limit (>500MB)`
);
}
const contentType = mime.getType(path.basename(params.filePath));
const contentType = await getContentTypeAsync(filePath);
return await promiseRetry(
async retry => {
const headers = new Headers(headersInit);
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "14.3.1",
"version": "14.5.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@babel/code-frame": "7.23.5",
"@expo/eas-build-job": "1.0.156",
"@expo/eas-build-job": "1.0.165",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "11.2.0",
@@ -301,37 +301,124 @@ test('valid profile for internal distribution on Android', async () => {
});
});
test('valid profile extending other profile', async () => {
test('valid profile with extension chain not exceeding 5', async () => {
await fs.writeJson('/project/eas.json', {
build: {
base: {
node: '12.0.0',
},
extension: {
extension1: {
extends: 'base',
distribution: 'internal',
node: '13.0.0',
},
extension2: {
extends: 'extension1',
distribution: 'internal',
node: '14.0.0',
},
extension3: {
extends: 'extension2',
distribution: 'internal',
node: '15.0.0',
},
extension4: {
extends: 'extension3',
distribution: 'internal',
node: '16.0.0',
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const baseProfile = await EasJsonUtils.getBuildProfileAsync(accessor, Platform.ANDROID, 'base');
const extendedProfile = await EasJsonUtils.getBuildProfileAsync(
const extendedProfile1 = await EasJsonUtils.getBuildProfileAsync(
accessor,
Platform.ANDROID,
'extension'
'extension1'
);
const extendedProfile2 = await EasJsonUtils.getBuildProfileAsync(
accessor,
Platform.ANDROID,
'extension2'
);
const extendedProfile3 = await EasJsonUtils.getBuildProfileAsync(
accessor,
Platform.ANDROID,
'extension3'
);
const extendedProfile4 = await EasJsonUtils.getBuildProfileAsync(
accessor,
Platform.ANDROID,
'extension4'
);
expect(baseProfile).toEqual({
distribution: 'store',
credentialsSource: 'remote',
node: '12.0.0',
});
expect(extendedProfile).toEqual({
expect(extendedProfile1).toEqual({
distribution: 'internal',
credentialsSource: 'remote',
node: '13.0.0',
});
expect(extendedProfile2).toEqual({
distribution: 'internal',
credentialsSource: 'remote',
node: '14.0.0',
});
expect(extendedProfile3).toEqual({
distribution: 'internal',
credentialsSource: 'remote',
node: '15.0.0',
});
expect(extendedProfile4).toEqual({
distribution: 'internal',
credentialsSource: 'remote',
node: '16.0.0',
});
});
test('valid profile with extension chain exceeding 5 - too long', async () => {
await fs.writeJson('/project/eas.json', {
build: {
base: {
node: '12.0.0',
},
extension1: {
extends: 'base',
distribution: 'internal',
node: '13.0.0',
},
extension2: {
extends: 'extension1',
distribution: 'internal',
node: '14.0.0',
},
extension3: {
extends: 'extension2',
distribution: 'internal',
node: '15.0.0',
},
extension4: {
extends: 'extension3',
distribution: 'internal',
node: '16.0.0',
},
extension5: {
extends: 'extension4',
distribution: 'internal',
node: '17.0.0',
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
await expect(
EasJsonUtils.getBuildProfileAsync(accessor, Platform.ANDROID, 'extension5')
).rejects.toThrow(
'Too long chain of profile extensions, make sure "extends" keys do not make a cycle'
);
});
test('valid profile extending other profile with platform specific envs', async () => {
@@ -169,7 +169,7 @@ test('ios config with ascApiKey fields set to env var', async () => {
}
});
test('valid profile extending other profile', async () => {
test('valid profile with extension chain not exceeding 5', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
base: {
@@ -179,7 +179,7 @@ test('valid profile extending other profile', async () => {
appleTeamId: 'AB32CZE81F',
},
},
extension: {
extension1: {
extends: 'base',
ios: {
appleTeamId: 'AB32CZE81F',
@@ -188,15 +188,57 @@ test('valid profile extending other profile', async () => {
ascApiKeyId: 'AB32CZE81F',
},
},
extension2: {
extends: 'extension1',
ios: {
appleTeamId: 'AB32CZE81E',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81E',
},
},
extension3: {
extends: 'extension2',
ios: {
appleTeamId: 'AB32CZE81D',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81D',
},
},
extension4: {
extends: 'extension3',
ios: {
appleTeamId: 'AB32CZE81C',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81C',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const baseProfile = await EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'base');
const extendedProfile = await EasJsonUtils.getSubmitProfileAsync(
const extendedProfile1 = await EasJsonUtils.getSubmitProfileAsync(
accessor,
Platform.IOS,
'extension'
'extension1'
);
const extendedProfile2 = await EasJsonUtils.getSubmitProfileAsync(
accessor,
Platform.IOS,
'extension2'
);
const extendedProfile3 = await EasJsonUtils.getSubmitProfileAsync(
accessor,
Platform.IOS,
'extension3'
);
const extendedProfile4 = await EasJsonUtils.getSubmitProfileAsync(
accessor,
Platform.IOS,
'extension4'
);
expect(baseProfile).toEqual({
language: 'en-US',
@@ -204,7 +246,7 @@ test('valid profile extending other profile', async () => {
ascAppId: '1223423523',
appleTeamId: 'AB32CZE81F',
});
expect(extendedProfile).toEqual({
expect(extendedProfile1).toEqual({
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
@@ -213,6 +255,99 @@ test('valid profile extending other profile', async () => {
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81F',
});
expect(extendedProfile2).toEqual({
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'AB32CZE81E',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81E',
});
expect(extendedProfile3).toEqual({
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'AB32CZE81D',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81D',
});
expect(extendedProfile4).toEqual({
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'AB32CZE81C',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81C',
});
});
test('valid profile with extension chain exceeding 5 - too long', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
base: {
ios: {
appleId: '[email protected]',
ascAppId: '1223423523',
appleTeamId: 'AB32CZE81F',
},
},
extension1: {
extends: 'base',
ios: {
appleTeamId: 'AB32CZE81F',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81F',
},
},
extension2: {
extends: 'extension1',
ios: {
appleTeamId: 'AB32CZE81E',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81E',
},
},
extension3: {
extends: 'extension2',
ios: {
appleTeamId: 'AB32CZE81D',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81D',
},
},
extension4: {
extends: 'extension3',
ios: {
appleTeamId: 'AB32CZE81C',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81C',
},
},
extension5: {
extends: 'extension4',
ios: {
appleTeamId: 'AB32CZE81B',
ascApiKeyPath: './path-ABCD.p8',
ascApiKeyIssuerId: '2af70a7a-2ac5-44d4-924e-ae97a7ca9333',
ascApiKeyId: 'AB32CZE81B',
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
await expect(
EasJsonUtils.getSubmitProfileAsync(accessor, Platform.IOS, 'extension5')
).rejects.toThrow(
'Too long chain of profile extensions, make sure "extends" keys do not make a cycle'
);
});
test('ios config with with invalid appleId', async () => {
+1 -1
View File
@@ -47,7 +47,7 @@ function resolveProfile<T extends Platform>({
profileName: string;
depth?: number;
}): SubmitProfile<T> | undefined {
if (depth >= 2) {
if (depth >= 5) {
throw new Error(
'Too long chain of profile extensions, make sure "extends" keys do not make a cycle'
);
Generated
+9 -9
View File
@@ -1465,10 +1465,10 @@
slugify "^1.3.4"
sucrase "3.35.0"
"@expo/[email protected]56":
version "1.0.156"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.156.tgz#c8e1f34a480eba217e6aa37e5d178f440065a7e7"
integrity sha512-pD3vWO7fIaQ4wmJy/x6L2dVK2rwf1qNzTE/4I5JI4r6vYSKrSCv8EIoE87xDBaRUBMk72ZdzyznJe516pMyTaw==
"@expo/[email protected]5":
version "1.0.165"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.165.tgz#71ec010330d23bb6f6c257ce1ca7c0258e8feaaa"
integrity sha512-l4bPVRmc6SlrgiC7AOid6s+o3kyP47x17cGIPQ0d4FOaOxu6pP3bPZ3BuPjts1mfvrKg/c/Phe1fJ1nnNlo3Xw==
dependencies:
"@expo/logger" "1.0.117"
joi "^17.13.1"
@@ -1645,12 +1645,12 @@
dependencies:
cross-spawn "^7.0.3"
"@expo/[email protected]1":
version "1.0.161"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.161.tgz#6201d45b1aa31e5c71cc18216d4272419f9fc6c3"
integrity sha512-CKYYBB+fb0uV1DmaNgIoXcPaT5MBRTWDE8ptRWUbYwrNSf9Dp9k+bVlw+eoI1GTwcoCoLiLSLg+S7hvfQRBeZw==
"@expo/[email protected]6":
version "1.0.166"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.166.tgz#b606ed72def361860ef5bfd3bd2df601112612af"
integrity sha512-dzEFjbQr4ji65XeSrUgesE+lnnhJYMNdXMZV5PRb19mMGTYYbyeT20+RvSo1a+TOPdO6sPdSBZqfiQ7P4mGBmQ==
dependencies:
"@expo/eas-build-job" "1.0.156"
"@expo/eas-build-job" "1.0.165"
"@expo/logger" "1.0.117"
"@expo/spawn-async" "^1.7.2"
arg "^5.0.2"