mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-14 10:08:06 -10:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d1bf434ec | ||
|
|
ab507d0bdd | ||
|
|
7505b8d40a | ||
|
|
b31ddee6e7 | ||
|
|
01ce802b73 | ||
|
|
f75ef22154 | ||
|
|
7d3f4e8fd4 | ||
|
|
004caf4bb7 | ||
|
|
5a16f3d6d8 | ||
|
|
d2e4cb5fc6 |
No files matched your search
+17
-3
@@ -6,7 +6,18 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🛠 Breaking changes
|
||||
|
||||
- Bump minimum required Node version to 18.14.0 to support `FormData` file streaming withi `undici`. ([#2420](https://github.com/expo/eas-cli/pull/2420) by [@byCedric](https://github.com/byCedric))
|
||||
### 🎉 New features
|
||||
|
||||
- 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
|
||||
|
||||
@@ -14,11 +25,14 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🐛 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
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"version": "14.4.1",
|
||||
"version": "14.5.0",
|
||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
|
||||
}
|
||||
+93
-91
@@ -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 [2m[options][22m`
|
||||
|
||||
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 [2m[options][22m`
|
||||
|
||||
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 -->
|
||||
@@ -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",
|
||||
@@ -129,7 +129,7 @@
|
||||
"typescript": "5.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.14.0"
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"files": [
|
||||
"/bin",
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
});
|
||||
});
|
||||
+152
-1
@@ -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', () => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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",
|
||||
@@ -26,7 +26,7 @@
|
||||
"typescript": "5.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.14.0"
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/expo/eas-cli",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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'
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"author": "Expo <[email protected]>",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.14.0"
|
||||
"node": ">=18.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "5.2.0",
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user