Compare commits

..
Author SHA1 Message Date
Kudo Chien e7b7eacd4e fix lint errors 2024-12-19 00:20:26 +08:00
Kudo Chien ec43906005 update changelog 2024-12-19 00:19:03 +08:00
Kudo Chien b71f324c83 [eas-cli] support platform version 2024-12-19 00:11:52 +08:00
51 changed files with 625 additions and 3503 deletions

No files matched your search

+1 -52
View File
@@ -8,70 +8,19 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Allow filtering by `--fingerprint_hash` in `eas build:list` command. ([#2818](https://github.com/expo/eas-cli/pull/2818) by [@szdziedzic](https://github.com/szdziedzic))
### 🐛 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
### 🐛 Bug fixes
- Enable shell execution for env:exec commands. ([#2788](https://github.com/expo/eas-cli/pull/2788) by [@tharakadesilva](https://github.com/tharakadesilva))
### 🧹 Chores
- Make automatic env resolution message shorter. ([#2806](https://github.com/expo/eas-cli/pull/2806) by [@szdziedzic](https://github.com/szdziedzic))
- Make "No remote versions are configured" message green instead of yellow. ([#2805](https://github.com/expo/eas-cli/pull/2805) by [@szdziedzic](https://github.com/szdziedzic))
- Upload local fingerprint on `eas fingerprint:compare`. ([#2808](https://github.com/expo/eas-cli/pull/2808) by [@quinlanj](https://github.com/quinlanj))
- Upgrade `eas-cli-local-build-plugin` to `1.0.163` to support Bun's new text-based lock file in local builds. ([#2817](https://github.com/expo/eas-cli/pull/2817) by [@shiroyasha9](https://github.com/shiroyasha9))
## [14.4.0](https://github.com/expo/eas-cli/releases/tag/v14.4.0) - 2025-01-09
### 🎉 New features
- Load `.env` variables even when `--environment` is specified for `deploy` command. Conflicts will be highlighted by a warning message. ([#2783](https://github.com/expo/eas-cli/pull/2783) by [@kitten](https://github.com/kitten))
- Silence all non-command output in non-interactive mode of eas env:exec. ([#2800](https://github.com/expo/eas-cli/pull/2800) by [@wschurman](https://github.com/wschurman))
- Unhide `deploy` and `deploy:alias` commands ([#2807](https://github.com/expo/eas-cli/pull/2807) by [@kitten](https://github.com/kitten))
## [14.3.1](https://github.com/expo/eas-cli/releases/tag/v14.3.1) - 2025-01-08
### 🧹 Chores
- Bump `@expo/[email protected]` to support Bun text-based lock files. ([#2801](https://github.com/expo/eas-cli/pull/2801) by [@kudo](https://github.com/kudo))
## [14.3.0](https://github.com/expo/eas-cli/releases/tag/v14.3.0) - 2025-01-07
### 🎉 New features
- Upload `package.json` when uploading workflow sources. ([#2786](https://github.com/expo/eas-cli/pull/2786) by [@sjchmiela](https://github.com/sjchmiela))
- Added support to read platform version from `app.json`. ([#2778](https://github.com/expo/eas-cli/pull/2778) by [@kudo](https://github.com/kudo))
### 🐛 Bug fixes
- Show `eas deploy` upload error messages. ([#2771](https://github.com/expo/eas-cli/pull/2771) by [@kadikraman](https://github.com/kadikraman))
- Prevent EAS CLI dependencies check from running repeatedly. ([#2781](https://github.com/expo/eas-cli/pull/2781) by [@kitten](https://github.com/kitten))
- Prevent optimistic request body parsing for `eas deploy`. ([#2784](https://github.com/expo/eas-cli/pull/2784) by [@kadikraman](https://github.com/kadikraman))
### 🧹 Chores
- Update log output for `worker` deploy and alias commands. ([#2780](https://github.com/expo/eas-cli/pull/2780) by [@kitten](https://github.com/kitten))
- Update various messages wording. ([#2790](https://github.com/expo/eas-cli/pull/2790) by [@simek](https://github.com/simek))
- Use node18 as tsconfig base. ([#2739](https://github.com/expo/eas-cli/pull/2739) by [@quinlanj](https://github.com/quinlanj))
## [14.2.0](https://github.com/expo/eas-cli/releases/tag/v14.2.0) - 2024-12-13
### 🎉 New features
- Add `eas deploy --dry-run` flag to output tarball. ([#2761](https://github.com/expo/eas-cli/pull/2761) by [@kitten](https://github.com/kitten))
- Allow specifying credentials for android builds. ([#2775](https://github.com/expo/eas-cli/pull/2775) by [@khamilowicz](https://github.com/khamilowicz))
### 🐛 Bug fixes
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "14.5.0",
"version": "14.2.0",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+72 -204
View File
@@ -88,9 +88,6 @@ eas --help COMMAND
* [`eas config`](#eas-config)
* [`eas credentials`](#eas-credentials)
* [`eas credentials:configure-build`](#eas-credentialsconfigure-build)
* [`eas deploy [options]`](#eas-deploy-2moptions22m)
* [`eas deploy:alias`](#eas-deployalias)
* [`eas deploy:promote`](#eas-deploypromote)
* [`eas device:create`](#eas-devicecreate)
* [`eas device:delete`](#eas-devicedelete)
* [`eas device:list`](#eas-devicelist)
@@ -134,8 +131,6 @@ eas --help COMMAND
* [`eas webhook:update`](#eas-webhookupdate)
* [`eas webhook:view ID`](#eas-webhookview-id)
* [`eas whoami`](#eas-whoami)
* [`eas worker:alias`](#eas-workeralias)
* [`eas deploy [options]`](#eas-deploy-2moptions22m-1)
* [`eas workflow:create [NAME]`](#eas-workflowcreate-name)
* [`eas workflow:run [FILE]`](#eas-workflowrun-file)
* [`eas workflow:validate PATH`](#eas-workflowvalidate-path)
@@ -158,7 +153,7 @@ ALIASES
$ eas login
```
_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)_
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -175,7 +170,7 @@ ALIASES
$ eas logout
```
_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)_
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -192,7 +187,7 @@ ALIASES
$ eas whoami
```
_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)_
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -206,7 +201,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/analytics.ts)_
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -258,7 +253,7 @@ DESCRIPTION
create a branch
```
_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)_
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -279,7 +274,7 @@ DESCRIPTION
delete a branch
```
_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)_
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -299,7 +294,7 @@ DESCRIPTION
list all branches
```
_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)_
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -319,7 +314,7 @@ DESCRIPTION
rename a branch
```
_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)_
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -342,7 +337,7 @@ DESCRIPTION
view a branch
```
_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)_
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -379,7 +374,7 @@ DESCRIPTION
start a build
```
_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)_
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -398,7 +393,7 @@ DESCRIPTION
cancel a build
```
_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)_
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -415,7 +410,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
@@ -434,7 +429,7 @@ DESCRIPTION
delete a build
```
_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)_
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/delete.ts)_
## `eas build:inspect`
@@ -469,7 +464,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -480,8 +475,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>] [--fingerprint-hash <value>] [--offset
<value>] [--limit <value>] [--json --non-interactive] [--simulator]
<value>] [--app-identifier <value>] [-e <value>] [--git-commit-hash <value>] [--offset <value>] [--limit <value>]
[--json --non-interactive] [--simulator]
FLAGS
-e, --build-profile=<value> Filter only builds created with the
@@ -496,8 +491,6 @@ 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
@@ -521,7 +514,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:resign`
@@ -550,7 +543,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/resign.ts)_
## `eas build:run`
@@ -576,7 +569,7 @@ DESCRIPTION
run simulator/emulator builds from eas-cli
```
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/run.ts)_
## `eas build:submit`
@@ -626,7 +619,7 @@ DESCRIPTION
get the latest version from EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -645,7 +638,7 @@ DESCRIPTION
update version of an app
```
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -664,7 +657,7 @@ DESCRIPTION
update a version in native code with a value stored on EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -681,7 +674,7 @@ DESCRIPTION
view a build for your project
```
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -702,7 +695,7 @@ DESCRIPTION
create a channel
```
_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)_
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -724,7 +717,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -744,7 +737,7 @@ DESCRIPTION
list all channels
```
_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)_
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:pause [NAME]`
@@ -766,7 +759,7 @@ DESCRIPTION
pause a channel to stop it from sending updates
```
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/channel/pause.ts)_
## `eas channel:resume [NAME]`
@@ -788,7 +781,7 @@ DESCRIPTION
resume a channel to start sending updates
```
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/channel/resume.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -821,7 +814,7 @@ DESCRIPTION
Roll a new branch out on a channel incrementally.
```
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -844,7 +837,7 @@ DESCRIPTION
view a channel
```
_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)_
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -865,7 +858,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/config.ts)_
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -882,7 +875,7 @@ DESCRIPTION
manage credentials
```
_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)_
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/credentials/index.ts)_
## `eas credentials:configure-build`
@@ -900,83 +893,7 @@ DESCRIPTION
Set up credentials for building your project.
```
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas deploy [options]`
Deploy your Expo Router web build and API Routes.
```
USAGE
$ eas deploy [options]
$ eas deploy --prod
FLAGS
--alias=name Custom alias to assign to the new deployment.
--dry-run Outputs a tarball of the new deployment instead of uploading it.
--environment=(development|preview|production) Environment variable's environment
--export-dir=dir [default: dist] Directory where the Expo project was exported.
--id=xyz123 Custom unique identifier for the new deployment.
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
--prod Create a new production deployment.
DESCRIPTION
Deploy your Expo Router web build and API Routes.
ALIASES
$ 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.
```
USAGE
$ eas deploy:alias [--prod] [--alias <value>] [--id <value>] [--json --non-interactive]
FLAGS
--alias=name Custom alias to assign to the existing deployment.
--id=xyz123 Unique identifier of an existing deployment.
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
--prod Promote an existing deployment to production.
DESCRIPTION
Assign deployment aliases.
ALIASES
$ 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.
```
USAGE
$ eas deploy:promote [--prod] [--alias <value>] [--id <value>] [--json --non-interactive]
FLAGS
--alias=name Custom alias to assign to the existing deployment.
--id=xyz123 Unique identifier of an existing deployment.
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
--prod Promote an existing deployment to production.
DESCRIPTION
Assign deployment aliases.
ALIASES
$ eas worker:alias
$ eas deploy:promote
```
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas device:create`
@@ -990,7 +907,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -1010,7 +927,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -1031,7 +948,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:rename`
@@ -1052,7 +969,7 @@ DESCRIPTION
rename a registered device
```
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -1066,7 +983,7 @@ DESCRIPTION
view a device for your project
```
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -1080,7 +997,7 @@ DESCRIPTION
display environment info
```
_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)_
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas env:create [ENVIRONMENT]`
@@ -1109,7 +1026,7 @@ DESCRIPTION
create an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/create.ts)_
## `eas env:delete [ENVIRONMENT]`
@@ -1133,7 +1050,7 @@ DESCRIPTION
delete an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/delete.ts)_
## `eas env:exec ENVIRONMENT BASH_COMMAND`
@@ -1154,7 +1071,7 @@ DESCRIPTION
execute a command with environment variables from the selected environment
```
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/exec.ts)_
## `eas env:get [ENVIRONMENT]`
@@ -1179,7 +1096,7 @@ DESCRIPTION
view an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/get.ts)_
## `eas env:list [ENVIRONMENT]`
@@ -1204,7 +1121,7 @@ DESCRIPTION
list environment variables for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/list.ts)_
## `eas env:pull [ENVIRONMENT]`
@@ -1227,7 +1144,7 @@ DESCRIPTION
pull environment variables for the selected environment to .env file
```
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/pull.ts)_
## `eas env:push [ENVIRONMENT]`
@@ -1248,7 +1165,7 @@ DESCRIPTION
push environment variables from .env file to the selected environment
```
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/push.ts)_
## `eas env:update [ENVIRONMENT]`
@@ -1279,7 +1196,7 @@ DESCRIPTION
update an environment variable on the current project or account
```
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/env/update.ts)_
## `eas help [COMMAND]`
@@ -1387,7 +1304,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -1404,7 +1321,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -1421,7 +1338,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1451,7 +1368,7 @@ DESCRIPTION
open the project page in a web browser
```
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v14.5.0/packages/eas-cli/src/commands/open.ts)_
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/open.ts)_
## `eas project:info`
@@ -1465,7 +1382,7 @@ DESCRIPTION
information about the current project
```
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -1488,7 +1405,7 @@ ALIASES
$ eas init
```
_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)_
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1506,7 +1423,7 @@ ALIASES
$ eas onboarding
```
_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)_
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/project/onboarding.ts)_
## `eas submit`
@@ -1537,7 +1454,7 @@ ALIASES
$ eas build:submit
```
_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)_
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -1579,7 +1496,7 @@ DESCRIPTION
publish an update group
```
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1599,7 +1516,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1620,7 +1537,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:edit [GROUPID]`
@@ -1644,7 +1561,7 @@ DESCRIPTION
edit all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/edit.ts)_
## `eas update:list`
@@ -1666,7 +1583,7 @@ DESCRIPTION
view the recent updates
```
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1698,7 +1615,7 @@ DESCRIPTION
roll back to an existing update
```
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/republish.ts)_
## `eas update:roll-back-to-embedded`
@@ -1726,7 +1643,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.5.0/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.2.0/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
@@ -1746,7 +1663,7 @@ DESCRIPTION
roll back to an embedded update or an existing update
```
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -1766,7 +1683,7 @@ DESCRIPTION
update group details
```
_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)_
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1787,7 +1704,7 @@ DESCRIPTION
create a webhook
```
_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)_
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1807,7 +1724,7 @@ DESCRIPTION
delete a webhook
```
_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)_
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1825,7 +1742,7 @@ DESCRIPTION
list webhooks
```
_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)_
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1847,7 +1764,7 @@ DESCRIPTION
update a webhook
```
_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)_
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1864,7 +1781,7 @@ DESCRIPTION
view a webhook
```
_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)_
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
@@ -1881,55 +1798,6 @@ ALIASES
$ eas whoami
```
## `eas worker:alias`
Assign deployment aliases.
```
USAGE
$ eas worker:alias [--prod] [--alias <value>] [--id <value>] [--json --non-interactive]
FLAGS
--alias=name Custom alias to assign to the existing deployment.
--id=xyz123 Unique identifier of an existing deployment.
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
--prod Promote an existing deployment to production.
DESCRIPTION
Assign deployment aliases.
ALIASES
$ eas worker:alias
$ eas deploy:promote
```
## `eas deploy [options]`
Deploy your Expo Router web build and API Routes.
```
USAGE
$ eas deploy [options]
$ eas deploy --prod
FLAGS
--alias=name Custom alias to assign to the new deployment.
--dry-run Outputs a tarball of the new deployment instead of uploading it.
--environment=(development|preview|production) Environment variable's environment
--export-dir=dir [default: dist] Directory where the Expo project was exported.
--id=xyz123 Custom unique identifier for the new deployment.
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
--prod Create a new production deployment.
DESCRIPTION
Deploy your Expo Router web build and API Routes.
ALIASES
$ eas worker:deploy
```
## `eas workflow:create [NAME]`
create a new workflow configuration YAML file
@@ -1948,7 +1816,7 @@ DESCRIPTION
create a new workflow configuration YAML file
```
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/workflow/create.ts)_
## `eas workflow:run [FILE]`
@@ -1968,7 +1836,7 @@ DESCRIPTION
Run an EAS workflow
```
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/workflow/run.ts)_
## `eas workflow:validate PATH`
@@ -1988,5 +1856,5 @@ DESCRIPTION
validate a workflow configuration yaml file
```
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v14.5.0/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.2.0/packages/eas-cli/src/commands/workflow/validate.ts)_
<!-- commandsstop -->
+68 -2125
View File
File diff suppressed because it is too large. Load diff
+6 -7
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "14.5.0",
"version": "14.2.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -12,14 +12,14 @@
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "10.0.6",
"@expo/config-plugins": "9.0.12",
"@expo/eas-build-job": "1.0.165",
"@expo/eas-json": "14.5.0",
"@expo/env": "^1.0.0",
"@expo/eas-build-job": "1.0.156",
"@expo/eas-json": "14.2.0",
"@expo/env": "^0.4.0",
"@expo/json-file": "8.3.3",
"@expo/logger": "1.0.117",
"@expo/multipart-body-parser": "2.0.0",
"@expo/osascript": "2.1.4",
"@expo/package-manager": "1.7.0",
"@expo/package-manager": "1.6.1",
"@expo/pkcs12": "0.1.3",
"@expo/plist": "0.2.0",
"@expo/plugin-help": "5.1.23",
@@ -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.165",
"@expo/steps": "1.0.156",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "^1.26.2",
"@oclif/plugin-autocomplete": "^2.3.10",
@@ -95,7 +95,6 @@
"@graphql-codegen/introspection": "4.0.0",
"@graphql-codegen/typescript": "4.0.1",
"@graphql-codegen/typescript-operations": "4.0.1",
"@tsconfig/node18": "18.2.4",
"@types/cli-progress": "3.11.5",
"@types/dateformat": "3.0.1",
"@types/diff": "6.0.0",
@@ -151,7 +151,6 @@ async function ensureAndroidCredentialsAsync(
ctx.android.gradleContext
);
const provider = new AndroidCredentialsProvider(ctx.credentialsCtx, {
name: ctx.buildProfile.keystoreName,
app: {
account: nullthrows(
ctx.user.accounts.find(a => a.name === ctx.accountName),
+17 -10
View File
@@ -20,7 +20,11 @@ import { getNextVersionCode } from '../../project/android/versions';
import { resolveWorkflowAsync } from '../../project/workflow';
import { Client } from '../../vcs/vcs';
import { updateAppJsonConfigAsync } from '../utils/appJson';
import { bumpAppVersionAsync, ensureStaticConfigExists } from '../utils/version';
import {
bumpAppVersionAsync,
ensureStaticConfigExists,
getVersionConfigTarget,
} from '../utils/version';
export enum BumpStrategy {
APP_VERSION,
@@ -53,9 +57,11 @@ export async function bumpVersionAsync({
await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
Log.log('Updated versions in app.json');
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.ANDROID });
const version = versionGetter(exp);
await updateNativeVersionsAsync({
projectDir,
version: exp.version,
version,
versionCode: exp.android?.versionCode,
});
Log.log('Synchronized versions with build gradle');
@@ -79,7 +85,7 @@ export async function bumpVersionInAppJsonAsync({
if (bumpStrategy === BumpStrategy.APP_VERSION) {
const appVersion = AndroidConfig.Version.getVersionName(exp) ?? '1.0.0';
await bumpAppVersionAsync({ appVersion, projectDir, exp });
await bumpAppVersionAsync({ appVersion, projectDir, exp, platform: Platform.ANDROID });
} else {
const versionCode = AndroidConfig.Version.getVersionCode(exp);
const bumpedVersionCode = getNextVersionCode(versionCode);
@@ -118,9 +124,11 @@ export async function maybeResolveVersionsAsync(
return {};
}
} else {
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.ANDROID });
const appVersion = versionGetter(exp);
return {
appBuildVersion: String(AndroidConfig.Version.getVersionCode(exp)),
appVersion: exp.version,
appVersion,
};
}
}
@@ -202,16 +210,15 @@ export async function resolveRemoteVersionCodeAsync(
applicationId
);
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.ANDROID });
const localVersions = await maybeResolveVersionsAsync(projectDir, exp, buildProfile, vcsClient);
let currentBuildVersion: string;
if (remoteVersions?.buildVersion) {
currentBuildVersion = remoteVersions.buildVersion;
} else {
if (localVersions.appBuildVersion) {
Log.log(
chalk.green(
'No remote versions are configured for this project, versionCode will be initialized based on the value from the local project.'
)
Log.warn(
'No remote versions are configured for this project, versionCode will be initialized based on the value from the local project.'
);
currentBuildVersion = localVersions.appBuildVersion;
} else {
@@ -232,7 +239,7 @@ export async function resolveRemoteVersionCodeAsync(
appId: projectId,
platform: AppPlatform.Android,
applicationIdentifier: applicationId,
storeVersion: localVersions.appVersion ?? exp.version ?? '1.0.0',
storeVersion: localVersions.appVersion ?? versionGetter(exp) ?? '1.0.0',
buildVersion: currentBuildVersion,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.ANDROID)) ??
@@ -256,7 +263,7 @@ export async function resolveRemoteVersionCodeAsync(
appId: projectId,
platform: AppPlatform.Android,
applicationIdentifier: applicationId,
storeVersion: localVersions.appVersion ?? exp.version ?? '1.0.0',
storeVersion: localVersions.appVersion ?? versionGetter(exp) ?? '1.0.0',
buildVersion: String(nextBuildVersion),
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.ANDROID)) ??
+3 -6
View File
@@ -709,10 +709,7 @@ async function computeAndMaybeUploadFingerprintFromExpoUpdatesAsync<T extends Pl
* It's ok for fingerprintSources or runtimeVersion to be empty
* fingerprintSources only exist if the project is using runtimeVersion.policy: fingerprint
*/
if (
!resolvedRuntimeVersion.expoUpdatesRuntimeFingerprint ||
!resolvedRuntimeVersion.runtimeVersion
) {
if (!resolvedRuntimeVersion.fingerprint || !resolvedRuntimeVersion.runtimeVersion) {
return {
runtimeVersion: resolvedRuntimeVersion.runtimeVersion ?? undefined,
};
@@ -720,14 +717,14 @@ async function computeAndMaybeUploadFingerprintFromExpoUpdatesAsync<T extends Pl
const uploadedFingerprint = await maybeUploadFingerprintAsync({
hash: resolvedRuntimeVersion.runtimeVersion,
fingerprint: resolvedRuntimeVersion.expoUpdatesRuntimeFingerprint,
fingerprint: resolvedRuntimeVersion.fingerprint,
graphqlClient: ctx.graphqlClient,
localBuildMode: ctx.localBuildOptions.localBuildMode,
});
return {
runtimeVersion: uploadedFingerprint.hash,
fingerprintSource: uploadedFingerprint.fingerprintSource,
fingerprintHash: resolvedRuntimeVersion.expoUpdatesRuntimeFingerprintHash ?? undefined,
fingerprintHash: resolvedRuntimeVersion.fingerprintHash ?? undefined,
};
}
@@ -84,13 +84,13 @@ async function resolveEnvVarsAsync({
if (Object.keys(serverEnvVars).length > 0) {
Log.log(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${Object.keys(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS servers: ${Object.keys(
serverEnvVars
).join(', ')}.`
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS.`
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS servers.`
);
}
@@ -112,7 +112,7 @@ async function resolveEnvVarsAsync({
);
if (overlappingKeys.length > 0) {
Log.warn(
`The following environment variables are defined in both the "${buildProfileName}" build profile "env" configuration and the "${environment.toLowerCase()}" environment on EAS: ${overlappingKeys.join(
`The following environment variables are defined in both the "${buildProfileName}" build profile "env" configuration and the "${environment.toLowerCase()}" environment on EAS servers: ${overlappingKeys.join(
', '
)}. The values from the build profile configuration will be used.`
);
@@ -135,18 +135,23 @@ async function resolveEnvVarsAsync({
function resolveSuggestedEnvironmentForBuildProfileConfiguration(
buildProfile: BuildProfile
): EnvironmentVariableEnvironment {
const environment =
buildProfile.distribution === 'store'
? EnvironmentVariableEnvironment.Production
: buildProfile.developmentClient
? EnvironmentVariableEnvironment.Development
: EnvironmentVariableEnvironment.Preview;
Log.log(
`Resolved "${environment.toLowerCase()}" environment for the build. ${learnMore(
'https://docs.expo.dev/eas/environment-variables/#setting-the-environment-for-your-builds'
)}`
);
return environment;
const setEnvironmentMessage =
'Set the "environment" field in the build profile if you want to specify the environment manually.';
if (buildProfile.distribution === 'store') {
Log.log(
`We detected that you are building for the "store" distribution. Resolving the environment for environment variables used during the build to "production". ${setEnvironmentMessage}`
);
return EnvironmentVariableEnvironment.Production;
} else {
if (buildProfile.developmentClient) {
Log.log(
`We detected that you are building the development client. Resolving the environment for environment variables used during the build to "development". ${setEnvironmentMessage}`
);
return EnvironmentVariableEnvironment.Development;
}
Log.log(
`We detected that you are building for the "internal" distribution. Resolving the environment for environment variables used during the build to "preview". ${setEnvironmentMessage}`
);
return EnvironmentVariableEnvironment.Preview;
}
}
+15 -9
View File
@@ -21,7 +21,11 @@ import uniqBy from '../../utils/expodash/uniqBy';
import { readPlistAsync, writePlistAsync } from '../../utils/plist';
import { Client } from '../../vcs/vcs';
import { updateAppJsonConfigAsync } from '../utils/appJson';
import { bumpAppVersionAsync, ensureStaticConfigExists } from '../utils/version';
import {
bumpAppVersionAsync,
ensureStaticConfigExists,
getVersionConfigTarget,
} from '../utils/version';
const SHORT_VERSION_REGEX = /^\d+(\.\d+){0,2}$/;
@@ -48,9 +52,11 @@ export async function bumpVersionAsync({
ensureStaticConfigExists(projectDir);
await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
Log.log('Updated versions in app.json');
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.IOS });
const version = versionGetter(exp);
await updateNativeVersionsAsync({
projectDir,
version: exp.version,
version,
buildNumber: exp.ios?.buildNumber,
targets,
});
@@ -73,7 +79,7 @@ export async function bumpVersionInAppJsonAsync({
Log.addNewLineIfNone();
if (bumpStrategy === BumpStrategy.APP_VERSION) {
const appVersion = IOSConfig.Version.getVersion(exp);
await bumpAppVersionAsync({ appVersion, projectDir, exp });
await bumpAppVersionAsync({ appVersion, projectDir, exp, platform: Platform.IOS });
} else {
const buildNumber = IOSConfig.Version.getBuildNumber(exp);
if (isValidBuildNumber(buildNumber)) {
@@ -141,8 +147,10 @@ export async function readShortVersionAsync(
validateShortVersion({ shortVersion, workflow });
return shortVersion;
} else {
validateShortVersion({ shortVersion: exp.version, workflow });
return exp.version;
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.IOS });
const shortVersion = versionGetter(exp);
validateShortVersion({ shortVersion, workflow });
return shortVersion;
}
}
@@ -334,10 +342,8 @@ export async function resolveRemoteBuildNumberAsync(
currentBuildVersion = remoteVersions.buildVersion;
} else {
if (localBuildNumber) {
Log.log(
chalk.green(
'No remote versions are configured for this project, buildNumber will be initialized based on the value from the local project.'
)
Log.warn(
'No remote versions are configured for this project, buildNumber will be initialized based on the value from the local project.'
);
currentBuildVersion = localBuildNumber;
} else {
+1 -1
View File
@@ -7,7 +7,7 @@ import Log from '../log';
import { ora } from '../ora';
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
const PLUGIN_PACKAGE_VERSION = '1.0.163';
const PLUGIN_PACKAGE_VERSION = '1.0.152';
export enum LocalBuildMode {
/**
@@ -0,0 +1,148 @@
import { ExpoConfig } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { updateAppJsonConfigAsync } from '../appJson';
import { bumpAppVersionAsync, getVersionConfigTarget } from '../version';
jest.mock('../appJson', () => ({
__esModule: true,
updateAppJsonConfigAsync: jest.fn().mockImplementation(
async (
{
exp,
}: {
projectDir: string;
exp: ExpoConfig;
},
modifyConfig: (config: any) => void
) => {
// a mocked implementation that only mutates the config object without writing to disk
modifyConfig(exp);
}
),
}));
describe(bumpAppVersionAsync, () => {
const name = 'test';
const slug = 'test';
const projectDir = '/app';
const mockUpdateAppJsonConfigAsync = updateAppJsonConfigAsync as jest.MockedFunction<
typeof updateAppJsonConfigAsync
>;
it('should bump expo.version for valid semver', async () => {
const appVersion = '1.0.0';
const exp: ExpoConfig = {
name,
slug,
version: appVersion,
};
await bumpAppVersionAsync({ appVersion, projectDir, exp, platform: Platform.IOS });
expect(mockUpdateAppJsonConfigAsync).toHaveBeenCalled();
expect(exp.version).toBe('1.0.1');
});
it('should bump expo.android.version if the expo.android.version exists', async () => {
const exp: ExpoConfig = {
name,
slug,
version: '0.0.0',
android: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '1.0.0',
},
ios: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '2.0.0',
},
};
await bumpAppVersionAsync({ appVersion: '1.0.0', projectDir, exp, platform: Platform.ANDROID });
expect(mockUpdateAppJsonConfigAsync).toHaveBeenCalled();
expect(exp.version).toBe('0.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.android.version).toBe('1.0.1');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.ios.version).toBe('2.0.0');
});
it('should bump expo.ios.version if the expo.ios.version exists', async () => {
const exp: ExpoConfig = {
name,
slug,
version: '0.0.0',
android: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '1.0.0',
},
ios: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '2.0.0',
},
};
await bumpAppVersionAsync({ appVersion: '2.0.0', projectDir, exp, platform: Platform.IOS });
expect(mockUpdateAppJsonConfigAsync).toHaveBeenCalled();
expect(exp.version).toBe('0.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.android.version).toBe('1.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.ios.version).toBe('2.0.1');
});
});
describe(getVersionConfigTarget, () => {
const exp: ExpoConfig = {
name: 'test',
slug: 'test',
version: '0.0.0',
android: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '1.0.0',
},
ios: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '2.0.0',
},
};
it('should return the correct config target for the android platform', () => {
const { fieldName, versionGetter, versionUpdater } = getVersionConfigTarget({
exp,
platform: Platform.ANDROID,
});
expect(fieldName).toBe('expo.android.version');
expect(versionGetter(exp)).toBe('1.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(versionUpdater(exp, '3.3.3').android.version).toBe('3.3.3');
expect(versionUpdater(exp, '0.0.0').version).toBe('0.0.0');
});
it('should return the correct config target for the ios platform', () => {
const { fieldName, versionGetter, versionUpdater } = getVersionConfigTarget({
exp,
platform: Platform.IOS,
});
expect(fieldName).toBe('expo.ios.version');
expect(versionGetter(exp)).toBe('2.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(versionUpdater(exp, '3.3.3').ios.version).toBe('3.3.3');
expect(versionUpdater(exp, '0.0.0').version).toBe('0.0.0');
});
it('should return the correct config target for common version', () => {
const exp: ExpoConfig = {
name: 'test',
slug: 'test',
version: '0.0.0',
};
const { fieldName, versionGetter, versionUpdater } = getVersionConfigTarget({
exp,
platform: Platform.IOS,
});
expect(fieldName).toBe('expo.version');
expect(versionGetter(exp)).toBe('0.0.0');
expect(versionUpdater(exp, '3.3.3').version).toBe('3.3.3');
});
});
+58 -3
View File
@@ -1,4 +1,5 @@
import { ExpoConfig, getConfigFilePaths } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
import semver from 'semver';
@@ -18,21 +19,25 @@ export async function bumpAppVersionAsync({
appVersion,
projectDir,
exp,
platform,
}: {
appVersion: string;
projectDir: string;
exp: ExpoConfig;
platform: Platform;
}): Promise<void> {
const { fieldName, versionUpdater } = getVersionConfigTarget({ exp, platform });
let bumpedAppVersion: string;
if (semver.valid(appVersion)) {
bumpedAppVersion = nullthrows(semver.inc(appVersion, 'patch'));
Log.log(
`Bumping ${chalk.bold('expo.version')} from ${chalk.bold(appVersion)} to ${chalk.bold(
`Bumping ${chalk.bold(fieldName)} from ${chalk.bold(appVersion)} to ${chalk.bold(
bumpedAppVersion
)}`
);
} else {
Log.log(`${chalk.bold('expo.version')} = ${chalk.bold(appVersion)} is not a valid semver`);
Log.log(`${chalk.bold(fieldName)} = ${chalk.bold(appVersion)} is not a valid semver`);
bumpedAppVersion = (
await promptAsync({
type: 'text',
@@ -42,6 +47,56 @@ export async function bumpAppVersionAsync({
).bumpedAppVersion;
}
await updateAppJsonConfigAsync({ projectDir, exp }, config => {
config.version = bumpedAppVersion;
versionUpdater(config, bumpedAppVersion);
});
}
/**
* Get the target version field from ExpoConfig based on the platform.
*/
export function getVersionConfigTarget({
exp,
platform,
}: {
exp: ExpoConfig;
platform: Platform;
}): {
fieldName: string;
versionGetter: (config: ExpoConfig) => string | undefined;
versionUpdater: (config: ExpoConfig, version: string) => ExpoConfig;
} {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
if (platform === Platform.ANDROID && typeof exp.android?.version === 'string') {
return {
fieldName: 'expo.android.version',
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
versionGetter: config => config.android?.version,
versionUpdater: (config, version) => {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
config.android = { ...config.android, version };
return config;
},
};
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
} else if (platform === Platform.IOS && typeof exp.ios?.version === 'string') {
return {
fieldName: 'expo.ios.version',
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
versionGetter: config => config.ios?.version,
versionUpdater: (config, version) => {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
config.ios = { ...config.ios, version };
return config;
},
};
}
return {
fieldName: 'expo.version',
versionGetter: config => config.version,
versionUpdater: (config, version) => {
config.version = version;
return config;
},
};
}
@@ -103,8 +103,6 @@ export async function findProjectRootAsync({
}
}
let ranEnsureEasCliIsNotInDependencies = false;
/**
* Determine the project root directory and ensure some constraints about the project setup
* like CLI version and dependencies.
@@ -115,9 +113,6 @@ let ranEnsureEasCliIsNotInDependencies = false;
export async function findProjectDirAndVerifyProjectSetupAsync(): Promise<string> {
const projectDir = await findProjectRootAsync();
await applyCliConfigAsync(projectDir);
if (!ranEnsureEasCliIsNotInDependencies) {
ranEnsureEasCliIsNotInDependencies = true;
await ensureEasCliIsNotInDependenciesAsync(projectDir);
}
await ensureEasCliIsNotInDependenciesAsync(projectDir);
return projectDir;
}
@@ -42,13 +42,13 @@ export async function loadServerSideEnvironmentVariablesAsync({
if (Object.keys(serverEnvVars).length > 0) {
Log.log(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${Object.keys(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS servers: ${Object.keys(
serverEnvVars
).join(', ')}.`
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS.`
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS servers.`
);
}
Log.newLine();
@@ -62,9 +62,6 @@ export default class BuildList extends EasCommand {
aliases: ['gitCommitHash'],
description: 'Filter only builds created with the specified git commit hash',
}),
'fingerprint-hash': Flags.string({
description: 'Filter only builds with the specified fingerprint hash',
}),
...EasPaginatedQueryFlags,
limit: getLimitFlagWithCustomValues({ defaultTo: 10, limit: BUILDS_LIMIT }),
...EasNonInteractiveAndJsonFlags,
@@ -133,7 +130,6 @@ export default class BuildList extends EasCommand {
buildProfile: flags['build-profile'],
gitCommitHash: flags['git-commit-hash'],
simulator: flags.simulator,
fingerprintHash: flags['fingerprint-hash'],
},
paginatedQueryOptions,
});
@@ -5,6 +5,7 @@ import { Flags } from '@oclif/core';
import chalk from 'chalk';
import { evaluateConfigWithEnvVarsAsync } from '../../../build/evaluateConfigWithEnvVarsAsync';
import { getVersionConfigTarget } from '../../../build/utils/version';
import EasCommand from '../../../commandUtils/EasCommand';
import { AppVersionMutation } from '../../../graphql/mutations/AppVersionMutation';
import { AppVersionQuery } from '../../../graphql/queries/AppVersionQuery';
@@ -111,6 +112,7 @@ export default class BuildVersionSetView extends EasCommand {
: `What version would you like to initialize it with?`;
Log.log(currentStateMessage);
const { versionGetter } = getVersionConfigTarget({ exp, platform });
const { version } = await promptAsync({
type: platform === Platform.ANDROID ? 'number' : 'text',
name: 'version',
@@ -124,7 +126,7 @@ export default class BuildVersionSetView extends EasCommand {
appId: projectId,
platform: toAppPlatform(platform),
applicationIdentifier,
storeVersion: exp.version ?? '1.0.0',
storeVersion: versionGetter(exp) ?? '1.0.0',
buildVersion: String(version),
runtimeVersion:
(await getRuntimeVersionNullableAsync(projectDir, exp, platform)) ?? undefined,
@@ -120,7 +120,7 @@ export default class BuildVersionSyncView extends EasCommand {
const workflow = await resolveWorkflowAsync(projectDir, profileInfo.platform, vcsClient);
if (!remoteVersions?.buildVersion) {
Log.warn(
`Skipping versions sync for ${platformDisplayName}. There are no versions configured on EAS, use "eas build:version:set" or run a build to initialize it.`
`Skipping versions sync for ${platformDisplayName}. There are no versions configured on Expo servers, use "eas build:version:set" or run a build to initialize it.`
);
continue;
}
@@ -147,10 +147,10 @@ export default class DeviceDelete extends EasCommand {
graphqlClient: ExpoGraphqlClient,
chosenDevice: AppleDevice | AppleDeviceQueryResult
): Promise<void> {
const removalSpinner = ora(`Removing Apple device on EAS`).start();
const removalSpinner = ora(`Removing Apple device on Expo`).start();
try {
await AppleDeviceMutation.deleteAppleDeviceAsync(graphqlClient, chosenDevice.id);
removalSpinner.succeed('Removed Apple device from EAS');
removalSpinner.succeed('Removed Apple device from Expo');
} catch (err) {
removalSpinner.fail();
throw err;
@@ -105,12 +105,12 @@ export default class DeviceRename extends EasCommand {
chosenDevice: AppleDevice | AppleDeviceQueryResult,
newDeviceName: string
): Promise<void> {
const removalSpinner = ora(`Renaming Apple device on EAS`).start();
const removalSpinner = ora(`Renaming Apple device on Expo`).start();
try {
await AppleDeviceMutation.updateAppleDeviceAsync(graphqlClient, chosenDevice.id, {
name: newDeviceName,
});
removalSpinner.succeed('Renamed Apple device on EAS');
removalSpinner.succeed('Renamed Apple device on Expo');
} catch (err) {
removalSpinner.fail();
throw err;
+18 -69
View File
@@ -53,10 +53,9 @@ export default class EnvExec extends EasCommand {
},
];
private isNonInteractive: boolean = false;
async runAsync(): Promise<void> {
const { flags, args } = await this.parse(EnvExec);
const parsedFlags = this.sanitizeFlagsAndArgs(flags, args);
const {
@@ -66,8 +65,6 @@ export default class EnvExec extends EasCommand {
nonInteractive: parsedFlags.nonInteractive,
});
this.isNonInteractive = parsedFlags.nonInteractive;
const environment =
parsedFlags.environment ??
(await promptVariableEnvironmentAsync({ nonInteractive: parsedFlags.nonInteractive }));
@@ -75,20 +72,12 @@ export default class EnvExec extends EasCommand {
graphqlClient,
projectId,
environment,
nonInteractive: parsedFlags.nonInteractive,
});
if (parsedFlags.nonInteractive) {
await this.runCommandNonInteractiveWithEnvVarsAsync({
command: parsedFlags.command,
environmentVariables,
});
} else {
await this.runCommandWithEnvVarsAsync({
command: parsedFlags.command,
environmentVariables,
});
}
await this.runCommandWithEnvVarsAsync({
command: parsedFlags.command,
environmentVariables,
});
}
private sanitizeFlagsAndArgs(
@@ -107,48 +96,13 @@ export default class EnvExec extends EasCommand {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
const firstChar = bash_command[0];
const lastChar = bash_command[bash_command.length - 1];
const cleanCommand =
(firstChar === '"' && lastChar === '"') || (firstChar === "'" && lastChar === "'")
? bash_command.slice(1, -1)
: bash_command;
return {
nonInteractive: rawFlags['non-interactive'],
environment,
command: cleanCommand,
command: bash_command,
};
}
// eslint-disable-next-line async-protect/async-suffix
protected override async catch(err: Error): Promise<any> {
// when in non-interactive, make the behavior of this command a pure passthrough, outputting only the subprocess' stdout and stderr and exiting with the
// sub-command's exit status
if (this.isNonInteractive) {
process.exitCode = process.exitCode ?? (err as any).status ?? 1;
} else {
await super.catch(err);
}
}
private async runCommandNonInteractiveWithEnvVarsAsync({
command,
environmentVariables,
}: {
command: string;
environmentVariables: Record<string, string>;
}): Promise<void> {
await spawnAsync(command, [], {
shell: true,
stdio: 'inherit',
env: {
...process.env,
...environmentVariables,
},
});
}
private async runCommandWithEnvVarsAsync({
command,
environmentVariables,
@@ -157,8 +111,7 @@ export default class EnvExec extends EasCommand {
environmentVariables: Record<string, string>;
}): Promise<void> {
Log.log(`Running command: ${chalk.bold(command)}`);
const spawnPromise = spawnAsync(command, [], {
shell: true,
const spawnPromise = spawnAsync('bash', ['-c', command], {
stdio: ['inherit', 'pipe', 'pipe'],
env: {
...process.env,
@@ -194,12 +147,10 @@ export default class EnvExec extends EasCommand {
graphqlClient,
projectId,
environment,
nonInteractive,
}: {
graphqlClient: ExpoGraphqlClient;
projectId: string;
environment: EnvironmentVariableEnvironment;
nonInteractive: boolean;
}): Promise<Record<string, string>> {
const environmentVariablesQueryResult =
await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(graphqlClient, {
@@ -211,20 +162,18 @@ export default class EnvExec extends EasCommand {
({ value }) => !!value
);
if (!nonInteractive) {
if (nonSecretEnvironmentVariables.length > 0) {
Log.log(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${nonSecretEnvironmentVariables
.map(e => e.name)
.join(', ')}.`
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS.`
);
}
Log.newLine();
if (nonSecretEnvironmentVariables.length > 0) {
Log.log(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${nonSecretEnvironmentVariables
.map(e => e.name)
.join(', ')}.`
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS servers.`
);
}
Log.newLine();
const environmentVariables: Record<string, string> = {};
for (const { name, value } of nonSecretEnvironmentVariables) {
@@ -7,12 +7,10 @@ import { fetchBuildsAsync, formatBuild } from '../../commandUtils/builds';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
import { AppPlatform, BuildStatus } from '../../graphql/generated';
import { FingerprintMutation } from '../../graphql/mutations/FingerprintMutation';
import { BuildQuery } from '../../graphql/queries/BuildQuery';
import Log from '../../log';
import { ora } from '../../ora';
import { RequestedPlatform } from '../../platform';
import { maybeUploadFingerprintAsync } from '../../project/maybeUploadFingerprintAsync';
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
import { resolveWorkflowPerPlatformAsync } from '../../project/workflow';
import { selectAsync } from '../../prompts';
@@ -96,20 +94,6 @@ export default class FingerprintCompare extends EasCommand {
Log.error('Project fingerprints can only be computed for projects with SDK 52 or higher');
return;
}
const uploadedFingerprint = await maybeUploadFingerprintAsync({
hash: fingerprint.hash,
fingerprint: {
fingerprintSources: fingerprint.sources,
isDebugFingerprintSource: Log.isDebug,
},
graphqlClient,
});
await FingerprintMutation.createFingerprintAsync(graphqlClient, projectId, {
hash: uploadedFingerprint.hash,
source: uploadedFingerprint.fingerprintSource,
});
if (fingerprint.hash === projectFingerprint.hash) {
Log.log(`✅ Project fingerprint matches build`);
return;
@@ -410,11 +410,11 @@ export default class UpdatePublish extends EasCommand {
runtimeToPlatformsAndFingerprintInfoMapping.map(async info => {
return {
...info,
expoUpdatesRuntimeFingerprintSource: info.expoUpdatesRuntimeFingerprint
fingerprintSource: info.fingerprint
? (
await maybeUploadFingerprintAsync({
hash: info.runtimeVersion,
fingerprint: info.expoUpdatesRuntimeFingerprint,
fingerprint: info.fingerprint,
graphqlClient,
})
).fingerprintSource ?? null
@@ -449,7 +449,7 @@ export default class UpdatePublish extends EasCommand {
// Sort the updates into different groups based on their platform specific runtime versions
const updateGroups: PublishUpdateGroupInput[] =
runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.map(
({ runtimeVersion, platforms, fingerprintInfoGroup }) => {
({ runtimeVersion, platforms, fingerprintSource, fingerprintInfoGroup }) => {
const localUpdateInfoGroup = Object.fromEntries(
platforms.map(platform => [
platform,
@@ -485,6 +485,9 @@ export default class UpdatePublish extends EasCommand {
branchId: branch.id,
updateInfoGroup: localUpdateInfoGroup,
rolloutInfoGroup: localRolloutInfoGroup,
runtimeFingerprintSource: fingerprintSource
? transformFingerprintSource(fingerprintSource)
: null,
fingerprintInfoGroup: transformedFingerprintInfoGroup,
runtimeVersion,
message: updateMessage,
@@ -208,8 +208,8 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
platform,
runtimeVersionInfo: {
runtimeVersion: selectedRuntime,
expoUpdatesRuntimeFingerprint: null,
expoUpdatesRuntimeFingerprintHash: null,
fingerprint: null,
fingerprintHash: null,
},
}))
);
@@ -33,9 +33,12 @@ interface RawDeployAliasFlags {
}
export default class WorkerAlias extends EasCommand {
static override description = 'Assign deployment aliases.';
static override aliases = ['worker:alias', 'deploy:promote'];
static override state = 'preview';
static override description = 'Assign deployment aliases';
static override aliases = ['deploy:alias', 'deploy:promote'];
// TODO(@kitten): Keep command hidden until worker deployments are live
static override hidden = true;
static override state = 'beta';
static override flags = {
prod: Flags.boolean({
@@ -70,7 +73,7 @@ export default class WorkerAlias extends EasCommand {
enableJsonOutput();
}
Log.warn('EAS Hosting is still in preview and subject to changes.');
Log.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
const {
getDynamicPrivateProjectConfigAsync,
@@ -65,10 +65,13 @@ interface DeployInProgressParams {
}
export default class WorkerDeploy extends EasCommand {
static override description = 'Deploy your Expo Router web build and API Routes.';
static override aliases = ['worker:deploy'];
static override description = 'Deploy your Expo web build';
static override aliases = ['deploy'];
static override usage = [chalk`deploy {dim [options]}`, `deploy --prod`];
static override state = 'preview';
// TODO(@kitten): Keep command hidden until worker deployments are live
static override hidden = true;
static override state = 'beta';
static override flags = {
prod: Flags.boolean({
@@ -111,7 +114,7 @@ export default class WorkerDeploy extends EasCommand {
enableJsonOutput();
}
Log.warn('EAS Hosting is still in preview and subject to changes.');
Log.warn('EAS Worker Deployments are in beta and subject to breaking changes.');
const {
getDynamicPrivateProjectConfigAsync,
@@ -250,7 +253,7 @@ export default class WorkerDeploy extends EasCommand {
let progress = ora('Preparing project').start();
try {
const manifestResult = await WorkerAssets.createManifestAsync(
const manifest = await WorkerAssets.createManifestAsync(
{
environment: flags.environment,
projectDir,
@@ -258,20 +261,13 @@ export default class WorkerDeploy extends EasCommand {
},
graphqlClient
);
if (manifestResult.conflictingVariableNames?.length) {
Log.warn(
'> The following environment variables were present in local .env files as well as EAS environment variables. ' +
'In case of conflict, the EAS environment variable values will be used: ' +
manifestResult.conflictingVariableNames.join(' ')
);
}
assetMap = await WorkerAssets.createAssetMapAsync(
projectDist.type === 'server' ? projectDist.clientPath : projectDist.path
);
tarPath = await WorkerAssets.packFilesIterableAsync(
emitWorkerTarballAsync({
assetMap,
manifest: manifestResult.manifest,
manifest,
})
);
@@ -430,7 +426,7 @@ async function resolveExportedProjectAsync(
if (!exportDirStat?.isDirectory()) {
throw new Error(
`No "${flags.exportDir}/" folder found. Export your app with "npx expo export --platform web"`
`No "${flags.exportDir}/" folder found. Prepare your project for deployment with "npx expo export --platform web"`
);
}
@@ -455,8 +451,7 @@ function logExportedProjectInfo(
// Only show the timestamp for exports older than 1 minute
if (project.modifiedAt && Date.now() - project.modifiedAt.getTime() > 60_000) {
modifiedAgo = ` - exported ${formatTimeAgo(project.modifiedAt)}`;
Log.warn(`> Project export: ${project.type}${modifiedAgo}`);
} else {
Log.log(chalk`{dim > Project export: ${project.type}}`);
}
Log.log(chalk`{dim > Project export: ${project.type}${modifiedAgo}}`);
}
+3 -12
View File
@@ -9,7 +9,7 @@ import { WorkflowRevisionMutation } from '../../graphql/mutations/WorkflowRevisi
import { WorkflowRunMutation } from '../../graphql/mutations/WorkflowRunMutation';
import Log, { link } from '../../log';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import { uploadAccountScopedFileAsync } from '../../project/uploadAccountScopedFileAsync';
import { uploadAccountScopedEasJsonAsync } from '../../project/uploadAccountScopedEasJsonAsync';
import { uploadAccountScopedProjectSourceAsync } from '../../project/uploadAccountScopedProjectSourceAsync';
import { WorkflowFile } from '../../utils/workflowFile';
@@ -81,7 +81,6 @@ export default class WorkflowRun extends EasCommand {
let projectArchiveBucketKey: string;
let easJsonBucketKey: string;
let packageJsonBucketKey: string;
try {
({ projectArchiveBucketKey } = await uploadAccountScopedProjectSourceAsync({
@@ -89,17 +88,10 @@ export default class WorkflowRun extends EasCommand {
vcsClient,
accountId: account.id,
}));
({ fileBucketKey: easJsonBucketKey } = await uploadAccountScopedFileAsync({
({ easJsonBucketKey } = await uploadAccountScopedEasJsonAsync({
graphqlClient,
accountId: account.id,
filePath: path.join(projectDir, 'eas.json'),
maxSizeBytes: 1024 * 1024,
}));
({ fileBucketKey: packageJsonBucketKey } = await uploadAccountScopedFileAsync({
graphqlClient,
accountId: account.id,
filePath: path.join(projectDir, 'package.json'),
maxSizeBytes: 1024 * 1024,
projectDir,
}));
} catch (err) {
Log.error('Failed to upload project sources.');
@@ -121,7 +113,6 @@ export default class WorkflowRun extends EasCommand {
type: WorkflowProjectSourceType.Gcs,
projectArchiveBucketKey,
easJsonBucketKey,
packageJsonBucketKey,
},
},
}
@@ -15,7 +15,6 @@ export interface AndroidCredentials {
interface Options {
app: AppLookupParams;
name?: string;
}
export default class AndroidCredentialsProvider {
@@ -38,7 +37,7 @@ export default class AndroidCredentialsProvider {
}
private async getRemoteAsync(): Promise<AndroidCredentials> {
const setupBuildCredentialsAction = new SetUpBuildCredentials(this.options);
const setupBuildCredentialsAction = new SetUpBuildCredentials({ app: this.options.app });
const buildCredentials = await setupBuildCredentialsAction.runAsync(this.ctx);
return this.toAndroidCredentials(buildCredentials);
}
@@ -1,26 +1,11 @@
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 * as Keychain from '../keychain';
import {
resolveAppleTeamAsync,
resolveAscApiKeyAsync,
resolveUserCredentialsAsync,
} from '../resolveCredentials';
import { resolveAppleTeamAsync, resolveAscApiKeyAsync } 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',
@@ -104,139 +89,3 @@ 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' }
);
});
});
@@ -208,18 +208,13 @@ async function promptUsernameAsync(): Promise<string> {
// the default value for quicker authentication.
const lastAppleId = await getCachedUsernameAsync();
let { username } = await promptAsync({
const { 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);
@@ -48,7 +48,7 @@ async function collectDataAndRegisterDeviceAsync(
}
const { udid, deviceClass, name } = deviceData;
const spinner = ora(`Registering Apple device on EAS`).start();
const spinner = ora(`Registering Apple device on Expo`).start();
try {
await AppleDeviceMutation.createAppleDeviceAsync(
graphqlClient,
@@ -45,7 +45,7 @@ async function collectDataAndRegisterDeviceAsync(
): Promise<void> {
const { udid, deviceClass, name } = await collectDeviceDataAsync(appleTeam);
const spinner = ora(`Registering Apple device on EAS`).start();
const spinner = ora(`Registering Apple device on Expo`).start();
try {
await AppleDeviceMutation.createAppleDeviceAsync(
graphqlClient,
+13 -284
View File
@@ -24,7 +24,6 @@ export type Scalars = {
JSON: { input: any; output: any; }
JSONObject: { input: any; output: any; }
WorkerDeploymentIdentifier: { input: any; output: any; }
WorkerDeploymentRequestID: { input: any; output: any; }
};
export type AcceptUserInvitationResult = {
@@ -134,12 +133,9 @@ export type Account = {
id: Scalars['ID']['output'];
isCurrent: Scalars['Boolean']['output'];
isDisabled: Scalars['Boolean']['output'];
/** Whether an Account plan falls into AppDevDomainName's free or paid tier */
isFreeAppDevDomainTier: Scalars['Boolean']['output'];
/** Whether this account has SSO enabled. Can be queried by all members. */
isSSOEnabled: Scalars['Boolean']['output'];
lastDeletionAttemptTime?: Maybe<Scalars['DateTime']['output']>;
logRocketOrganization?: Maybe<LogRocketOrganization>;
name: Scalars['String']['output'];
/** Offers set on this account */
offers?: Maybe<Array<Offer>>;
@@ -147,7 +143,6 @@ export type Account = {
owner?: Maybe<User>;
/** Owning UserActor of this account if personal account */
ownerUserActor?: Maybe<UserActor>;
profileImageUrl: Scalars['String']['output'];
pushSecurityEnabled: Scalars['Boolean']['output'];
/** @deprecated Legacy access tokens are deprecated */
requiresAccessTokenForPushSecurity: Scalars['Boolean']['output'];
@@ -727,7 +722,12 @@ export type AccountUsageEasBuildMetadata = {
waiverType?: Maybe<EasBuildWaiverType>;
};
export type AccountUsageMetadata = AccountUsageEasBuildMetadata;
export type AccountUsageEasJobsMetadata = {
__typename?: 'AccountUsageEASJobsMetadata';
resourceClassDisplayName: Scalars['String']['output'];
};
export type AccountUsageMetadata = AccountUsageEasBuildMetadata | AccountUsageEasJobsMetadata;
export type AccountUsageMetric = {
__typename?: 'AccountUsageMetric';
@@ -1251,7 +1251,6 @@ export type App = Project & {
environmentVariables: Array<EnvironmentVariable>;
/** Environment variables for an app with decrypted secret values */
environmentVariablesIncludingSensitive: Array<EnvironmentVariableWithSecret>;
fingerprintsPaginated: AppFingerprintsConnection;
fullName: Scalars['String']['output'];
githubBuildTriggers: Array<GitHubBuildTrigger>;
githubJobRunTriggers: Array<GitHubJobRunTrigger>;
@@ -1301,7 +1300,6 @@ export type App = Project & {
likeCount: Scalars['Int']['output'];
/** @deprecated 'likes' have been deprecated. */
likedBy: Array<Maybe<User>>;
logRocketProject?: Maybe<LogRocketProject>;
name: Scalars['String']['output'];
ownerAccount: Account;
/** @deprecated No longer supported */
@@ -1368,8 +1366,6 @@ export type App = Project & {
/** EAS updates owned by an app */
updates: Array<Update>;
updatesPaginated: AppUpdatesConnection;
/** Project query object for querying EAS usage metrics */
usageMetrics: AppUsageMetrics;
/** @deprecated Use ownerAccount.name instead */
username: Scalars['String']['output'];
/** @deprecated No longer supported */
@@ -1483,16 +1479,6 @@ export type AppEnvironmentVariablesIncludingSensitiveArgs = {
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppFingerprintsPaginatedArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<FingerprintFilterInput>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppIosAppCredentialsArgs = {
filter?: InputMaybe<IosAppCredentialsFilter>;
@@ -1746,18 +1732,6 @@ export type AppDevDomainNameMutationChangeDevDomainNameArgs = {
name: Scalars['DevDomainName']['input'];
};
export type AppFingerprintEdge = {
__typename?: 'AppFingerprintEdge';
cursor: Scalars['String']['output'];
node: Fingerprint;
};
export type AppFingerprintsConnection = {
__typename?: 'AppFingerprintsConnection';
edges: Array<AppFingerprintEdge>;
pageInfo: PageInfo;
};
export type AppIcon = {
__typename?: 'AppIcon';
/** @deprecated No longer supported */
@@ -2079,44 +2053,6 @@ export enum AppUploadSessionType {
ProfileImageUpload = 'PROFILE_IMAGE_UPLOAD'
}
export type AppUsageMetric = {
__typename?: 'AppUsageMetric';
id: Scalars['ID']['output'];
metricType: UsageMetricType;
serviceMetric: EasServiceMetric;
timestamp: Scalars['DateTime']['output'];
value: Scalars['Float']['output'];
};
export type AppUsageMetricTotal = {
__typename?: 'AppUsageMetricTotal';
billingPeriod: BillingPeriod;
id: Scalars['ID']['output'];
planMetrics: Array<EstimatedUsage>;
/** Total cost of overages, in cents */
totalCost: Scalars['Float']['output'];
};
export type AppUsageMetrics = {
__typename?: 'AppUsageMetrics';
byBillingPeriod: AppUsageMetricTotal;
metricsForServiceMetric: Array<AppUsageMetric>;
};
export type AppUsageMetricsByBillingPeriodArgs = {
date: Scalars['DateTime']['input'];
service?: InputMaybe<EasService>;
};
export type AppUsageMetricsMetricsForServiceMetricArgs = {
filterParams?: InputMaybe<Scalars['JSONObject']['input']>;
granularity: UsageMetricsGranularity;
serviceMetric: EasServiceMetric;
timespan: UsageMetricsTimespan;
};
/** Represents Play Store/App Store version of an application */
export type AppVersion = {
__typename?: 'AppVersion';
@@ -2934,7 +2870,6 @@ export type BuildFilter = {
buildProfile?: InputMaybe<Scalars['String']['input']>;
channel?: InputMaybe<Scalars['String']['input']>;
distribution?: InputMaybe<DistributionType>;
fingerprintHash?: InputMaybe<Scalars['String']['input']>;
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
hasFingerprint?: InputMaybe<Scalars['Boolean']['input']>;
platform?: InputMaybe<AppPlatform>;
@@ -2948,7 +2883,6 @@ export type BuildFilterInput = {
channel?: InputMaybe<Scalars['String']['input']>;
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
distributions?: InputMaybe<Array<DistributionType>>;
fingerprintHash?: InputMaybe<Scalars['String']['input']>;
hasFingerprint?: InputMaybe<Scalars['Boolean']['input']>;
platforms?: InputMaybe<Array<AppPlatform>>;
releaseChannel?: InputMaybe<Scalars['String']['input']>;
@@ -3360,7 +3294,6 @@ export enum CrashSampleFor {
}
export type CrashesFilters = {
crashKind?: InputMaybe<Array<WorkerDeploymentCrashKind>>;
name?: InputMaybe<Array<Scalars['String']['input']>>;
};
@@ -3413,11 +3346,6 @@ export type CreateEnvironmentVariableInput = {
visibility: EnvironmentVariableVisibility;
};
export type CreateFingerprintInput = {
hash: Scalars['String']['input'];
source?: InputMaybe<FingerprintSourceInput>;
};
export type CreateGitHubAppInstallationInput = {
accountId: Scalars['ID']['input'];
installationIdentifier: Scalars['Int']['input'];
@@ -3668,16 +3596,6 @@ export type DeleteIosAppCredentialsResult = {
id: Scalars['ID']['output'];
};
export type DeleteLogRocketOrganizationResult = {
__typename?: 'DeleteLogRocketOrganizationResult';
accountId: Scalars['ID']['output'];
};
export type DeleteLogRocketProjectResult = {
__typename?: 'DeleteLogRocketProjectResult';
id: Scalars['ID']['output'];
};
export type DeleteRobotResult = {
__typename?: 'DeleteRobotResult';
id: Scalars['ID']['output'];
@@ -4000,9 +3918,6 @@ export enum EntityTypeName {
IosAppCredentialsEntity = 'IosAppCredentialsEntity',
UserInvitationEntity = 'UserInvitationEntity',
UserPermissionEntity = 'UserPermissionEntity',
WorkerCustomDomainEntity = 'WorkerCustomDomainEntity',
WorkerDeploymentAliasEntity = 'WorkerDeploymentAliasEntity',
WorkerEntity = 'WorkerEntity',
WorkflowEntity = 'WorkflowEntity',
WorkflowRevisionEntity = 'WorkflowRevisionEntity'
}
@@ -4265,44 +4180,12 @@ export enum Feature {
export type Fingerprint = {
__typename?: 'Fingerprint';
app: App;
builds: AppBuildsConnection;
createdAt: Scalars['DateTime']['output'];
debugInfoUrl?: Maybe<Scalars['String']['output']>;
hash: Scalars['String']['output'];
id: Scalars['ID']['output'];
source?: Maybe<FingerprintSource>;
updatedAt: Scalars['DateTime']['output'];
updates: AppUpdatesConnection;
};
export type FingerprintBuildsArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<FingerprintBuildsFilterInput>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
export type FingerprintUpdatesArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
export type FingerprintBuildsFilterInput = {
channel?: InputMaybe<Scalars['String']['input']>;
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
distributions?: InputMaybe<Array<DistributionType>>;
platforms?: InputMaybe<Array<AppPlatform>>;
releaseChannel?: InputMaybe<Scalars['String']['input']>;
simulator?: InputMaybe<Scalars['Boolean']['input']>;
};
export type FingerprintFilterInput = {
hashes?: InputMaybe<Array<Scalars['String']['input']>>;
};
export type FingerprintInfo = {
@@ -4316,18 +4199,6 @@ export type FingerprintInfoGroup = {
web?: InputMaybe<FingerprintInfo>;
};
export type FingerprintMutation = {
__typename?: 'FingerprintMutation';
/** Create or get an existing fingerprint for an App */
createOrGetExistingFingerprint: Fingerprint;
};
export type FingerprintMutationCreateOrGetExistingFingerprintArgs = {
appId: Scalars['ID']['input'];
fingerprintData: CreateFingerprintInput;
};
export type FingerprintSource = {
__typename?: 'FingerprintSource';
bucketKey: Scalars['String']['output'];
@@ -4355,22 +4226,6 @@ export type FutureSubscription = {
startDate: Scalars['DateTime']['output'];
};
export type GenerateLogRocketOrganizationLinkResult = {
__typename?: 'GenerateLogRocketOrganizationLinkResult';
url: Scalars['String']['output'];
};
export type GenerateLogRocketOrganizationLinkingUrlInput = {
accountId: Scalars['ID']['input'];
callbackUrl: Scalars['String']['input'];
};
export type GenerateLogRocketReplayTokenResult = {
__typename?: 'GenerateLogRocketReplayTokenResult';
orgSlug: Scalars['String']['output'];
replayToken: Scalars['String']['output'];
};
export type GetSignedAssetUploadSpecificationsResult = {
__typename?: 'GetSignedAssetUploadSpecificationsResult';
specifications: Array<Scalars['String']['output']>;
@@ -5251,15 +5106,6 @@ export type LineDataset = {
label: Scalars['String']['output'];
};
export type LinkLogRocketOrganizationToExpoAccountInput = {
accountId: Scalars['ID']['input'];
client_id: Scalars['String']['input'];
client_secret: Scalars['String']['input'];
orgName: Scalars['String']['input'];
orgSlug: Scalars['String']['input'];
state: Scalars['String']['input'];
};
export type LinkSharedEnvironmentVariableInput = {
appId: Scalars['ID']['input'];
environment?: InputMaybe<EnvironmentVariableEnvironment>;
@@ -5272,76 +5118,6 @@ export type LogNameTypeMapping = {
typeName: EntityTypeName;
};
export type LogRocketOrganization = {
__typename?: 'LogRocketOrganization';
account: Account;
createdAt: Scalars['DateTime']['output'];
id: Scalars['ID']['output'];
orgName: Scalars['String']['output'];
orgSlug: Scalars['String']['output'];
};
export type LogRocketOrganizationMutation = {
__typename?: 'LogRocketOrganizationMutation';
/** Delete a LogRocket organization by ID */
deleteLogRocketOrganization: DeleteLogRocketOrganizationResult;
/** Generate a LogRocket linking URL */
generateLogRocketOrganizationLinkingURL: GenerateLogRocketOrganizationLinkResult;
/** Generate a LogRocket replay token for an organization */
generateLogRocketReplayToken: GenerateLogRocketReplayTokenResult;
/** Link a LogRocket organization to an Expo account */
linkLogRocketOrganizationToExpoAccount: LogRocketOrganization;
};
export type LogRocketOrganizationMutationDeleteLogRocketOrganizationArgs = {
accountId: Scalars['ID']['input'];
};
export type LogRocketOrganizationMutationGenerateLogRocketOrganizationLinkingUrlArgs = {
input: GenerateLogRocketOrganizationLinkingUrlInput;
};
export type LogRocketOrganizationMutationGenerateLogRocketReplayTokenArgs = {
accountId: Scalars['ID']['input'];
};
export type LogRocketOrganizationMutationLinkLogRocketOrganizationToExpoAccountArgs = {
input: LinkLogRocketOrganizationToExpoAccountInput;
};
export type LogRocketProject = {
__typename?: 'LogRocketProject';
app: App;
createdAt: Scalars['DateTime']['output'];
id: Scalars['ID']['output'];
logRocketOrgId: Scalars['ID']['output'];
logRocketProjectSlug: Scalars['String']['output'];
updatedAt: Scalars['DateTime']['output'];
};
export type LogRocketProjectMutation = {
__typename?: 'LogRocketProjectMutation';
/** Create a LogRocket project */
createLogRocketProject: LogRocketProject;
/** Delete a LogRocket project by ID */
deleteLogRocketProject: DeleteLogRocketProjectResult;
};
export type LogRocketProjectMutationCreateLogRocketProjectArgs = {
appId: Scalars['ID']['input'];
logRocketProjectSlug: Scalars['String']['input'];
};
export type LogRocketProjectMutationDeleteLogRocketProjectArgs = {
logRocketProjectId: Scalars['ID']['input'];
};
export type LogsTimespan = {
end: Scalars['DateTime']['input'];
start?: InputMaybe<Scalars['DateTime']['input']>;
@@ -5736,7 +5512,6 @@ export type PublicArtifacts = {
export type PublishUpdateGroupInput = {
awaitingCodeSigningInfo?: InputMaybe<Scalars['Boolean']['input']>;
branchId: Scalars['String']['input'];
environment?: InputMaybe<EnvironmentVariableEnvironment>;
excludedAssets?: InputMaybe<Array<PartialManifestAsset>>;
fingerprintInfoGroup?: InputMaybe<FingerprintInfoGroup>;
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
@@ -5766,12 +5541,10 @@ export type RequestsFilters = {
hasCustomDomainOrigin?: InputMaybe<Scalars['Boolean']['input']>;
isAsset?: InputMaybe<Scalars['Boolean']['input']>;
isCrash?: InputMaybe<Scalars['Boolean']['input']>;
isLimitExceeded?: InputMaybe<Scalars['Boolean']['input']>;
isVerifiedBot?: InputMaybe<Scalars['Boolean']['input']>;
method?: InputMaybe<Array<RequestMethod>>;
os?: InputMaybe<Array<UserAgentOs>>;
pathname?: InputMaybe<Scalars['String']['input']>;
requestId?: InputMaybe<Array<Scalars['WorkerDeploymentRequestID']['input']>>;
responseType?: InputMaybe<Array<ResponseType>>;
status?: InputMaybe<Array<Scalars['Int']['input']>>;
statusType?: InputMaybe<Array<ResponseStatusType>>;
@@ -5844,11 +5617,8 @@ export type Robot = Actor & {
*/
featureGates: Scalars['JSONObject']['output'];
firstName?: Maybe<Scalars['String']['output']>;
/** GitHub App Installations that manage this actor */
githubAppInstallations: Array<GitHubAppInstallation>;
id: Scalars['ID']['output'];
isExpoAdmin: Scalars['Boolean']['output'];
isManagedByGitHubApp: Scalars['Boolean']['output'];
lastDeletionAttemptTime?: Maybe<Scalars['DateTime']['output']>;
};
@@ -5961,8 +5731,6 @@ export type RootMutation = {
environmentSecret: EnvironmentSecretMutation;
/** Mutations that create and delete EnvironmentVariables */
environmentVariable: EnvironmentVariableMutation;
/** Mutations that modify App fingerprints */
fingerprint: FingerprintMutation;
/** Mutations that utilize services facilitated by the GitHub App */
githubApp: GitHubAppMutation;
/** Mutations for GitHub App installations */
@@ -5985,10 +5753,6 @@ export type RootMutation = {
/** Mutations that modify an EAS Build */
jobRun: JobRunMutation;
keystoreGenerationUrl: KeystoreGenerationUrlMutation;
/** Mutations for LogRocket organizations */
logRocketOrganization: LogRocketOrganizationMutation;
/** Mutations for LogRocket projects */
logRocketProject: LogRocketProjectMutation;
/** Mutations that modify the currently authenticated User */
me: MeMutation;
/** Mutations that modify a NotificationSubscription */
@@ -6619,7 +6383,7 @@ export enum SubmissionAndroidTrack {
}
export type SubmissionArchiveSourceInput = {
/** Required if the archive source type is GCS_BUILD_APPLICATION_ARCHIVE, GCS_BUILD_APPLICATION_ARCHIVE_ORCHESTRATOR or GCS_SUBMIT_ARCHIVE */
/** Required if the archive source type is GCS_BUILD_APPLICATION_ARCHIVE or GCS_SUBMIT_ARCHIVE */
bucketKey?: InputMaybe<Scalars['String']['input']>;
type: SubmissionArchiveSourceType;
/** Required if the archive source type is URL */
@@ -6628,7 +6392,6 @@ export type SubmissionArchiveSourceInput = {
export enum SubmissionArchiveSourceType {
GcsBuildApplicationArchive = 'GCS_BUILD_APPLICATION_ARCHIVE',
GcsBuildApplicationArchiveOrchestrator = 'GCS_BUILD_APPLICATION_ARCHIVE_ORCHESTRATOR',
GcsSubmitArchive = 'GCS_SUBMIT_ARCHIVE',
Url = 'URL'
}
@@ -6786,7 +6549,6 @@ export type Update = ActivityTimelineProjectActivity & {
codeSigningInfo?: Maybe<CodeSigningInfo>;
createdAt: Scalars['DateTime']['output'];
deployments: DeploymentResult;
environment?: Maybe<EnvironmentVariableEnvironment>;
expoGoSDKVersion?: Maybe<Scalars['String']['output']>;
fingerprint?: Maybe<Fingerprint>;
gitCommitHash?: Maybe<Scalars['String']['output']>;
@@ -7879,7 +7641,6 @@ export type WorkerDeployment = ActivityTimelineProjectActivity & {
activityTimestamp: Scalars['DateTime']['output'];
actor?: Maybe<Actor>;
aliases?: Maybe<Array<WorkerDeploymentAlias>>;
app: App;
crashes?: Maybe<WorkerDeploymentCrashes>;
createdAt: Scalars['DateTime']['output'];
deploymentDomain: Scalars['String']['output'];
@@ -7890,6 +7651,7 @@ export type WorkerDeployment = ActivityTimelineProjectActivity & {
logs?: Maybe<WorkerDeploymentLogs>;
requests?: Maybe<WorkerDeploymentRequests>;
subdomain: Scalars['String']['output'];
tier?: Maybe<WorkerDeploymentTier>;
url: Scalars['String']['output'];
};
@@ -7943,19 +7705,9 @@ export type WorkerDeploymentCrashEdge = {
request?: Maybe<WorkerDeploymentRequestNode>;
};
export enum WorkerDeploymentCrashKind {
ExceededCpu = 'EXCEEDED_CPU',
ExceededMemory = 'EXCEEDED_MEMORY',
ExceededSubrequests = 'EXCEEDED_SUBREQUESTS',
Generic = 'GENERIC',
Internal = 'INTERNAL',
ResponseStreamDisconnected = 'RESPONSE_STREAM_DISCONNECTED'
}
export type WorkerDeploymentCrashNode = {
__typename?: 'WorkerDeploymentCrashNode';
crashHash: Scalars['ID']['output'];
crashKind: WorkerDeploymentCrashKind;
crashTimestamp: Scalars['DateTime']['output'];
deploymentIdentifier: Scalars['String']['output'];
firstStackLine?: Maybe<Scalars['String']['output']>;
@@ -8067,7 +7819,6 @@ export type WorkerDeploymentRequestNode = {
hasCustomDomainOrigin: Scalars['Boolean']['output'];
isAsset: Scalars['Boolean']['output'];
isCrash: Scalars['Boolean']['output'];
isLimitExceeded: Scalars['Boolean']['output'];
isRejected: Scalars['Boolean']['output'];
isStaleIfError: Scalars['Boolean']['output'];
isStaleWhileRevalidate: Scalars['Boolean']['output'];
@@ -8077,7 +7828,6 @@ export type WorkerDeploymentRequestNode = {
os?: Maybe<UserAgentOs>;
pathname: Scalars['String']['output'];
region?: Maybe<Scalars['String']['output']>;
requestId: Scalars['WorkerDeploymentRequestID']['output'];
requestTimestamp: Scalars['DateTime']['output'];
responseType: ResponseType;
scriptName: Scalars['String']['output'];
@@ -8179,8 +7929,6 @@ export type WorkerDeploymentRequestsAggregationNode = {
durationP50: Scalars['Float']['output'];
durationP90: Scalars['Float']['output'];
durationP99: Scalars['Float']['output'];
limitExceededPerMs?: Maybe<Scalars['Float']['output']>;
limitExceededSum: Scalars['Int']['output'];
requestsPerMs?: Maybe<Scalars['Float']['output']>;
requestsSum: Scalars['Int']['output'];
sampleRate?: Maybe<Scalars['Float']['output']>;
@@ -8256,6 +8004,11 @@ export type WorkerDeploymentRequestsTimeseriesEdge = {
timestamp: Scalars['DateTime']['output'];
};
export enum WorkerDeploymentTier {
Free = 'FREE',
Paid = 'PAID'
}
export type WorkerDeploymentsConnection = {
__typename?: 'WorkerDeploymentsConnection';
edges: Array<WorkerDeploymentEdge>;
@@ -8359,7 +8112,6 @@ export enum WorkflowJobType {
AppleDeviceRegistrationRequest = 'APPLE_DEVICE_REGISTRATION_REQUEST',
Build = 'BUILD',
Custom = 'CUSTOM',
Deploy = 'DEPLOY',
GetBuild = 'GET_BUILD',
MaestroTest = 'MAESTRO_TEST',
RequireApproval = 'REQUIRE_APPROVAL',
@@ -8369,7 +8121,6 @@ export enum WorkflowJobType {
export type WorkflowProjectSourceInput = {
easJsonBucketKey: Scalars['String']['input'];
packageJsonBucketKey?: InputMaybe<Scalars['String']['input']>;
projectArchiveBucketKey: Scalars['String']['input'];
type: WorkflowProjectSourceType;
};
@@ -8453,10 +8204,7 @@ export type WorkflowRun = ActivityTimelineProjectActivity & {
name: Scalars['String']['output'];
pullRequestNumber?: Maybe<Scalars['Int']['output']>;
requestedGitRef?: Maybe<Scalars['String']['output']>;
retriedWorkflowRun?: Maybe<WorkflowRun>;
retries: Array<WorkflowRun>;
status: WorkflowRunStatus;
triggerEventType: WorkflowRunTriggerEventType;
updatedAt: Scalars['DateTime']['output'];
workflow: Workflow;
workflowRevision?: Maybe<WorkflowRevision>;
@@ -8482,7 +8230,6 @@ export type WorkflowRunMutation = {
__typename?: 'WorkflowRunMutation';
cancelWorkflowRun: WorkflowRun;
createWorkflowRun: WorkflowRun;
retryWorkflowRun: WorkflowRun;
};
@@ -8497,11 +8244,6 @@ export type WorkflowRunMutationCreateWorkflowRunArgs = {
workflowRunInput: WorkflowRunInput;
};
export type WorkflowRunMutationRetryWorkflowRunArgs = {
workflowRunId: Scalars['ID']['input'];
};
export type WorkflowRunQuery = {
__typename?: 'WorkflowRunQuery';
byId: WorkflowRun;
@@ -8522,11 +8264,6 @@ export enum WorkflowRunStatus {
Success = 'SUCCESS'
}
export enum WorkflowRunTriggerEventType {
Github = 'GITHUB',
Manual = 'MANUAL'
}
export type WorkflowRunsConnection = {
__typename?: 'WorkflowRunsConnection';
edges: Array<WorkflowRunEdge>;
@@ -9189,14 +8926,6 @@ export type CreateBulkEnvironmentVariablesForAppMutationVariables = Exact<{
export type CreateBulkEnvironmentVariablesForAppMutation = { __typename?: 'RootMutation', environmentVariable: { __typename?: 'EnvironmentVariableMutation', createBulkEnvironmentVariablesForApp: Array<{ __typename?: 'EnvironmentVariable', id: string }> } };
export type CreateFingeprintMutationVariables = Exact<{
fingerprintData: CreateFingerprintInput;
appId: Scalars['ID']['input'];
}>;
export type CreateFingeprintMutation = { __typename?: 'RootMutation', fingerprint: { __typename?: 'FingerprintMutation', createOrGetExistingFingerprint: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null } } };
export type CreateKeystoreGenerationUrlMutationVariables = Exact<{ [key: string]: never; }>;
@@ -1,39 +0,0 @@
import { FingerprintSource } from '@expo/eas-build-job';
import { print } from 'graphql';
import gql from 'graphql-tag';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import { CreateFingeprintMutation, FingerprintFragment } from '../generated';
import { FingerprintFragmentNode } from '../types/Fingerprint';
export const FingerprintMutation = {
async createFingerprintAsync(
graphqlClient: ExpoGraphqlClient,
appId: string,
fingerprintData: { hash: string; source?: FingerprintSource }
): Promise<FingerprintFragment> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<CreateFingeprintMutation>(
gql`
mutation CreateFingeprintMutation(
$fingerprintData: CreateFingerprintInput!
$appId: ID!
) {
fingerprint {
createOrGetExistingFingerprint(fingerprintData: $fingerprintData, appId: $appId) {
id
...FingerprintFragment
}
}
}
${print(FingerprintFragmentNode)}
`,
{ appId, fingerprintData }
)
.toPromise()
);
return data.fingerprint.createOrGetExistingFingerprint;
},
};
@@ -84,13 +84,13 @@ export async function fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsyn
const projectDashboardUrl = getProjectDashboardUrl(accountName, projectName);
const projectLink = link(projectDashboardUrl, { text: projectFullName });
const spinner = ora(`Creating ${chalk.bold(projectFullName)} on EAS`).start();
const spinner = ora(`Creating ${chalk.bold(projectFullName)} on Expo`).start();
try {
const id = await AppMutation.createAppAsync(graphqlClient, {
accountId: account.id,
projectName,
});
spinner.succeed(`Created ${chalk.bold(projectLink)} on EAS`);
spinner.succeed(`Created ${chalk.bold(projectLink)} on Expo`);
return id;
} catch (err) {
spinner.fail();
+18 -22
View File
@@ -733,11 +733,11 @@ export const defaultPublishPlatforms: UpdatePublishPlatform[] = ['android', 'ios
export type RuntimeVersionInfo = {
runtimeVersion: string;
expoUpdatesRuntimeFingerprint: {
fingerprint: {
fingerprintSources: object[];
isDebugFingerprintSource: boolean;
} | null;
expoUpdatesRuntimeFingerprintHash: string | null;
fingerprintHash: string | null;
};
type FingerprintInfoGroup = {
@@ -797,11 +797,11 @@ async function getRuntimeVersionInfoForPlatformAsync({
env: Env | undefined;
}): Promise<{
runtimeVersion: string;
expoUpdatesRuntimeFingerprint: {
fingerprint: {
fingerprintSources: object[];
isDebugFingerprintSource: boolean;
} | null;
expoUpdatesRuntimeFingerprintHash: string | null;
fingerprintHash: string | null;
}> {
if (await isModernExpoUpdatesCLIWithRuntimeVersionCommandSupportedAsync(projectDir)) {
try {
@@ -852,8 +852,8 @@ async function getRuntimeVersionInfoForPlatformAsync({
return {
runtimeVersion: resolvedRuntimeVersion,
expoUpdatesRuntimeFingerprint: null,
expoUpdatesRuntimeFingerprintHash: null,
fingerprint: null,
fingerprintHash: null,
};
}
@@ -875,15 +875,13 @@ export function getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersion
platforms: runtimeVersionInfoObjects.map(
runtimeVersionInfoObject => runtimeVersionInfoObject.platform
),
expoUpdatesRuntimeFingerprint:
fingerprint:
runtimeVersionInfoObjects.map(
runtimeVersionInfoObject =>
runtimeVersionInfoObject.runtimeVersionInfo.expoUpdatesRuntimeFingerprint
runtimeVersionInfoObject => runtimeVersionInfoObject.runtimeVersionInfo.fingerprint
)[0] ?? null,
expoUpdatesRuntimeFingerprintHash:
fingerprintHash:
runtimeVersionInfoObjects.map(
runtimeVersionInfoObject =>
runtimeVersionInfoObject.runtimeVersionInfo.expoUpdatesRuntimeFingerprintHash
runtimeVersionInfoObject => runtimeVersionInfoObject.runtimeVersionInfo.fingerprintHash
)[0] ?? null,
};
}
@@ -901,20 +899,20 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
graphqlClient: ExpoGraphqlClient;
runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping: (RuntimeVersionInfo & {
platforms: UpdatePublishPlatform[];
expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
fingerprintSource: FingerprintSource | null;
})[];
workflowsByPlatform: Record<Platform, Workflow>;
env: Env | undefined;
}): Promise<
(RuntimeVersionInfo & {
platforms: UpdatePublishPlatform[];
expoUpdatesRuntimeFingerprintSource: FingerprintSource | null;
fingerprintSource: FingerprintSource | null;
fingerprintInfoGroup: FingerprintInfoGroup;
})[]
> {
const runtimesToComputeFingerprintsFor =
runtimeToPlatformsAndFingerprintInfoAndFingerprintSourceMapping.filter(
infoGroup => !infoGroup.expoUpdatesRuntimeFingerprintHash
infoGroup => !infoGroup.fingerprintHash
);
const fingerprintOptionsByRuntimeAndPlatform = new Map<string, FingerprintOptions>();
for (const infoGroup of runtimesToComputeFingerprintsFor) {
@@ -977,11 +975,9 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
infoGroup
): infoGroup is RuntimeVersionInfo & {
platforms: UpdatePublishPlatform[];
expoUpdatesRuntimeFingerprintSource: FingerprintSource;
expoUpdatesRuntimeFingerprintHash: string;
} =>
!!infoGroup.expoUpdatesRuntimeFingerprintHash &&
!!infoGroup.expoUpdatesRuntimeFingerprintSource
fingerprintSource: FingerprintSource;
fingerprintHash: string;
} => !!infoGroup.fingerprintHash && !!infoGroup.fingerprintSource
)
.map(infoGroup => {
const platform = infoGroup.platforms[0];
@@ -989,8 +985,8 @@ export async function maybeCalculateFingerprintForRuntimeVersionInfoObjectsWitho
...infoGroup,
fingerprintInfoGroup: {
[platform]: {
fingerprintHash: infoGroup.expoUpdatesRuntimeFingerprintHash,
fingerprintSource: infoGroup.expoUpdatesRuntimeFingerprintSource,
fingerprintHash: infoGroup.fingerprintHash,
fingerprintSource: infoGroup.fingerprintSource,
},
},
};
@@ -23,11 +23,11 @@ export async function resolveRuntimeVersionUsingCLIAsync({
cwd?: string;
}): Promise<{
runtimeVersion: string | null;
expoUpdatesRuntimeFingerprint: {
fingerprint: {
fingerprintSources: object[];
isDebugFingerprintSource: boolean;
} | null;
expoUpdatesRuntimeFingerprintHash: string | null;
fingerprintHash: string | null;
}> {
Log.debug('Using expo-updates runtimeversion:resolve CLI for runtime version resolution');
@@ -47,13 +47,13 @@ export async function resolveRuntimeVersionUsingCLIAsync({
return {
runtimeVersion: runtimeVersionResult.runtimeVersion ?? null,
expoUpdatesRuntimeFingerprint: runtimeVersionResult.fingerprintSources
fingerprint: runtimeVersionResult.fingerprintSources
? {
fingerprintSources: runtimeVersionResult.fingerprintSources,
isDebugFingerprintSource: useDebugFingerprintSource,
}
: null,
expoUpdatesRuntimeFingerprintHash: runtimeVersionResult.fingerprintSources
fingerprintHash: runtimeVersionResult.fingerprintSources
? runtimeVersionResult.runtimeVersion
: null,
};
@@ -75,19 +75,19 @@ export async function resolveRuntimeVersionAsync({
cwd?: string;
}): Promise<{
runtimeVersion: string | null;
expoUpdatesRuntimeFingerprint: {
fingerprint: {
fingerprintSources: object[];
isDebugFingerprintSource: boolean;
} | null;
expoUpdatesRuntimeFingerprintHash: string | null;
fingerprintHash: string | null;
} | null> {
if (!(await isModernExpoUpdatesCLIWithRuntimeVersionCommandSupportedAsync(projectDir))) {
// fall back to the previous behavior (using the @expo/config-plugins eas-cli dependency rather
// than the versioned @expo/config-plugins dependency in the project)
return {
runtimeVersion: await Updates.getRuntimeVersionNullableAsync(projectDir, exp, platform),
expoUpdatesRuntimeFingerprint: null,
expoUpdatesRuntimeFingerprintHash: null,
fingerprint: null,
fingerprintHash: null,
};
}
@@ -0,0 +1,47 @@
import chalk from 'chalk';
import fs from 'node:fs';
import path from 'node:path';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AccountUploadSessionType } from '../graphql/generated';
import { uploadAccountScopedFileAtPathToGCSAsync } from '../uploads';
import { formatBytes } from '../utils/files';
import { createProgressTracker } from '../utils/progress';
/**
* Uploads the `eas.json` file to GCS as account-scoped object.
* Used in workflows. Takes care of logging progress.
*/
export async function uploadAccountScopedEasJsonAsync({
graphqlClient,
accountId,
projectDir,
}: {
graphqlClient: ExpoGraphqlClient;
accountId: string;
projectDir: string;
}): Promise<{ easJsonBucketKey: string }> {
const easJsonFilePath = path.join(projectDir, 'eas.json');
const easJsonFileStat = await fs.promises.stat(easJsonFilePath);
if (easJsonFileStat.size > 1024 * 1024) {
throw new Error('eas.json is too big. Maximum allowed size is 1MB.');
}
const easJsonBucketKey = await uploadAccountScopedFileAtPathToGCSAsync(graphqlClient, {
accountId,
type: AccountUploadSessionType.WorkflowsProjectSources,
path: easJsonFilePath,
handleProgressEvent: createProgressTracker({
total: easJsonFileStat.size,
message: ratio =>
`Uploading eas.json to EAS (${formatBytes(easJsonFileStat.size * ratio)} / ${formatBytes(
easJsonFileStat.size
)})`,
completedMessage: (duration: string) => `Uploaded eas.json to EAS ${chalk.dim(duration)}`,
}),
});
return { easJsonBucketKey };
}
@@ -1,49 +0,0 @@
import chalk from 'chalk';
import fs from 'node:fs';
import path from 'node:path';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AccountUploadSessionType } from '../graphql/generated';
import { uploadAccountScopedFileAtPathToGCSAsync } from '../uploads';
import { formatBytes } from '../utils/files';
import { createProgressTracker } from '../utils/progress';
/**
* Uploads a file to GCS as account-scoped object.
* Used in workflows. Takes care of logging progress.
* (Uses file name when mentioning file in logs.)
*/
export async function uploadAccountScopedFileAsync({
graphqlClient,
accountId,
filePath,
maxSizeBytes,
}: {
graphqlClient: ExpoGraphqlClient;
accountId: string;
filePath: string;
maxSizeBytes: number;
}): Promise<{ fileBucketKey: string }> {
const fileName = path.basename(filePath);
const fileStat = await fs.promises.stat(filePath);
if (fileStat.size > maxSizeBytes) {
throw new Error(`File is too big. Maximum allowed size is ${formatBytes(maxSizeBytes)}.`);
}
const fileBucketKey = await uploadAccountScopedFileAtPathToGCSAsync(graphqlClient, {
accountId,
type: AccountUploadSessionType.WorkflowsProjectSources,
path: filePath,
handleProgressEvent: createProgressTracker({
total: fileStat.size,
message: ratio =>
`Uploading ${fileName} to EAS (${formatBytes(fileStat.size * ratio)} / ${formatBytes(
fileStat.size
)})`,
completedMessage: (duration: string) => `Uploaded ${fileName} to EAS ${chalk.dim(duration)}`,
}),
});
return { fileBucketKey };
}
@@ -42,13 +42,13 @@ function warnAboutServiceOutage(service: StatuspageServiceFragment): void {
if (service.incidents.length > 0) {
const [currentIncident] = service.incidents;
Log.warn(`Reason: ${currentIncident.name}.`);
Log.warn(`Reason: ${currentIncident.name}`);
}
Log.warn(
`All information on service status and incidents available at ${link(
'https://status.expo.dev/'
)}`
)}.`
);
Log.newLine();
}
+15 -29
View File
@@ -1,4 +1,4 @@
import { parseProjectEnv } from '@expo/env';
import { get as getEnv } from '@expo/env';
import { Gzip, GzipOptions } from 'minizlib';
import { HashOptions, createHash, randomBytes } from 'node:crypto';
import fs, { createWriteStream } from 'node:fs';
@@ -98,11 +98,6 @@ export interface Manifest {
env: Record<string, string | undefined>;
}
export interface CreateManifestResult {
conflictingVariableNames: string[] | undefined;
manifest: Manifest;
}
interface CreateManifestParams {
projectId: string;
projectDir: string;
@@ -113,32 +108,23 @@ interface CreateManifestParams {
export async function createManifestAsync(
params: CreateManifestParams,
graphqlClient: ExpoGraphqlClient
): Promise<CreateManifestResult> {
// Resolve .env file variables
const { env } = parseProjectEnv(params.projectDir, { mode: 'production' });
// Maybe load EAS Environment Variables (based on `--environment` arg)
let conflictingVariableNames: string[] | undefined;
): Promise<Manifest> {
let env: Record<string, string | undefined>;
if (params.environment) {
const loadedVariables = await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(
graphqlClient,
{
appId: params.projectId,
environment: params.environment,
}
env = Object.fromEntries(
(
await EnvironmentVariablesQuery.byAppIdWithSensitiveAsync(graphqlClient, {
appId: params.projectId,
environment: params.environment,
})
).map(variable => [variable.name, variable.value ?? undefined])
);
// Load EAS Env vars into `env` object, keeping track of conflicts
conflictingVariableNames = [];
for (const variable of loadedVariables) {
if (variable.value != null) {
if (env[variable.name] != null) {
conflictingVariableNames.push(variable.name);
}
env[variable.name] = variable.value;
}
}
} else {
// NOTE: This is required for the .env resolution
process.env.NODE_ENV = 'production';
env = getEnv(params.projectDir).env;
}
const manifest: Manifest = { env };
return { conflictingVariableNames, manifest };
return { env };
}
interface WorkerFileEntry {
+7 -29
View File
@@ -4,7 +4,6 @@ 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';
@@ -29,24 +28,6 @@ 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;
@@ -89,15 +70,14 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
headers: headersInit,
...requestInit
} = params;
const stat = await fs.promises.stat(filePath);
const stat = await fs.promises.stat(params.filePath);
if (stat.size > MAX_UPLOAD_SIZE) {
throw new Error(
`Upload of "${filePath}" aborted: File size is greater than the upload limit (>500MB)`
`Upload of "${params.filePath}" aborted: File size is greater than the upload limit (>500MB)`
);
}
const contentType = await getContentTypeAsync(filePath);
const contentType = mime.getType(path.basename(params.filePath));
return await promiseRetry(
async retry => {
const headers = new Headers(headersInit);
@@ -129,10 +109,8 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
return retry(error);
}
const getErrorMessageAsync = async (): Promise<string> => {
const body = await response.json().catch(() => null);
return body?.error ?? `Upload of "${filePath}" failed: ${response.statusText}`;
};
const body = await response.json().catch(() => null);
const errorMessage = body?.error ?? `Upload of "${filePath}" failed: ${response.statusText}`;
if (
response.status === 408 ||
@@ -140,12 +118,12 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
response.status === 429 ||
(response.status >= 500 && response.status <= 599)
) {
return retry(new Error(await getErrorMessageAsync()));
return retry(new Error(errorMessage));
} else if (response.status === 413) {
const message = `Upload of "${filePath}" failed: File size exceeded the upload limit`;
throw new Error(message);
} else if (!response.ok) {
throw new Error(await getErrorMessageAsync());
throw new Error(errorMessage);
}
return {
+3 -2
View File
@@ -1,15 +1,16 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"compilerOptions": {
"declaration": true,
"importHelpers": true,
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"target": "ES2022",
"outDir": "build",
"rootDir": "src",
"typeRoots": ["../../ts-declarations", "../../node_modules/@types", "./node_modules/@types"]
+2 -3
View File
@@ -1,12 +1,12 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "14.5.0",
"version": "14.2.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.165",
"@expo/eas-build-job": "1.0.156",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "11.2.0",
@@ -18,7 +18,6 @@
"tslib": "2.4.1"
},
"devDependencies": {
"@tsconfig/node18": "18.2.4",
"@types/babel__code-frame": "7.0.3",
"@types/fs-extra": "11.0.4",
"memfs": "3.4.13",
@@ -129,33 +129,6 @@ test('valid eas.json with specified environment', async () => {
});
});
test('valid eas.json with specified keystoreName', async () => {
const keystoreName = 'this-is-a-keystore-name';
await fs.writeJson('/project/eas.json', {
build: {
development: {
android: {
credentialsSource: 'remote',
keystoreName,
},
},
},
});
const accessor = EasJsonAccessor.fromProjectPath('/project');
const androidProfile = await EasJsonUtils.getBuildProfileAsync(
accessor,
Platform.ANDROID,
'development'
);
expect(androidProfile).toEqual(
expect.objectContaining({
keystoreName,
})
);
});
test('valid eas.json with top level withoutCredentials property', async () => {
await fs.writeJson('/project/eas.json', {
build: {
@@ -301,124 +274,37 @@ test('valid profile for internal distribution on Android', async () => {
});
});
test('valid profile with extension chain not exceeding 5', async () => {
test('valid profile extending other profile', async () => {
await fs.writeJson('/project/eas.json', {
build: {
base: {
node: '12.0.0',
},
extension1: {
extension: {
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 extendedProfile1 = await EasJsonUtils.getBuildProfileAsync(
const extendedProfile = await EasJsonUtils.getBuildProfileAsync(
accessor,
Platform.ANDROID,
'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'
'extension'
);
expect(baseProfile).toEqual({
distribution: 'store',
credentialsSource: 'remote',
node: '12.0.0',
});
expect(extendedProfile1).toEqual({
expect(extendedProfile).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 with extension chain not exceeding 5', async () => {
test('valid profile extending other profile', async () => {
await fs.writeJson('/project/eas.json', {
submit: {
base: {
@@ -179,7 +179,7 @@ test('valid profile with extension chain not exceeding 5', async () => {
appleTeamId: 'AB32CZE81F',
},
},
extension1: {
extension: {
extends: 'base',
ios: {
appleTeamId: 'AB32CZE81F',
@@ -188,57 +188,15 @@ test('valid profile with extension chain not exceeding 5', 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 extendedProfile1 = await EasJsonUtils.getSubmitProfileAsync(
const extendedProfile = await EasJsonUtils.getSubmitProfileAsync(
accessor,
Platform.IOS,
'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'
'extension'
);
expect(baseProfile).toEqual({
language: 'en-US',
@@ -246,7 +204,7 @@ test('valid profile with extension chain not exceeding 5', async () => {
ascAppId: '1223423523',
appleTeamId: 'AB32CZE81F',
});
expect(extendedProfile1).toEqual({
expect(extendedProfile).toEqual({
language: 'en-US',
appleId: '[email protected]',
ascAppId: '1223423523',
@@ -255,99 +213,6 @@ test('valid profile with extension chain not exceeding 5', 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 () => {
-8
View File
@@ -101,14 +101,6 @@ const AndroidBuildProfileSchema = PlatformBuildProfileSchema.concat(
Joi.boolean(),
Joi.string().valid('version', 'versionCode')
),
keystoreName: Joi.when('credentialsSource', {
is: 'remote',
then: Joi.string(),
otherwise: Joi.forbidden().messages({
'any.unknown': 'keystoreName is not allowed when credentialsSource is not remote',
}),
}),
})
);
-2
View File
@@ -93,8 +93,6 @@ export interface AndroidBuildProfile extends PlatformBuildProfile {
// versions
autoIncrement?: AndroidVersionAutoIncrement;
keystoreName?: string;
}
export interface IosBuildProfile extends PlatformBuildProfile {
+1 -1
View File
@@ -47,7 +47,7 @@ function resolveProfile<T extends Platform>({
profileName: string;
depth?: number;
}): SubmitProfile<T> | undefined {
if (depth >= 5) {
if (depth >= 2) {
throw new Error(
'Too long chain of profile extensions, make sure "extends" keys do not make a cycle'
);
+4 -3
View File
@@ -1,18 +1,19 @@
{
"extends": "@tsconfig/node18/tsconfig.json",
"compilerOptions": {
"declaration": true,
"importHelpers": true,
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"target": "ES2022",
"outDir": "build",
"rootDir": "src",
"typeRoots": ["../../node_modules/@types", "../../ts-declarations", "./node_modules/@types"]
},
"include": ["src/**/*"]
}
}
Generated
+17 -22
View File
@@ -1465,20 +1465,20 @@
slugify "^1.3.4"
sucrase "3.35.0"
"@expo/[email protected]65":
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==
"@expo/[email protected]6":
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==
dependencies:
"@expo/logger" "1.0.117"
joi "^17.13.1"
semver "^7.6.2"
zod "^3.23.8"
"@expo/env@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@expo/env/-/env-1.0.0.tgz#8e22894fae04ba6dc41fe0f1351a4973d410273a"
integrity sha512-43R5rxlaLJQOWunyfnQEpgHJCsSLCUWDoU/wJNABEYkHdt1Sjrlf+ieH3MG1f/RZYE+1Wss3sYiO9oPps1aMNg==
"@expo/env@^0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@expo/env/-/env-0.4.0.tgz#1ff3a15084566d12ca92cb67e5b0a9796a9f0aa7"
integrity sha512-g2JYFqck3xKIwJyK+8LxZ2ENZPWtRgjFWpeht9abnKgzXVXBeSNECFBkg+WQjQocSIdxXhEWM6hz4ZAe7Tc4ng==
dependencies:
chalk "^4.0.0"
debug "^4.3.4"
@@ -1543,10 +1543,10 @@
"@expo/spawn-async" "^1.7.2"
exec-async "^2.2.0"
"@expo/package-manager@1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.7.0.tgz#6d98090fdfa9d31ab885acb012d6615741594fd1"
integrity sha512-yWn5TIjd42wLHZjNtdZkvCkcxqUGxlI4YHb+bQmgm3tWZ8aBHnLhPb0rgU8+hVHCofmRvVUXfVZv8Uh+kkLXgw==
"@expo/package-manager@1.6.1":
version "1.6.1"
resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.6.1.tgz#ab845238dec10bb48bca2b90e060dfe8c1525602"
integrity sha512-4rT46wP/94Ll+CWXtFKok1Lbo9XncSUtErFOo/9/3FVughGbIfdG4SKZOAWIpr9wxwEfkyhHfAP9q71ONlWODw==
dependencies:
"@expo/json-file" "^9.0.0"
"@expo/spawn-async" "^1.7.2"
@@ -1645,12 +1645,12 @@
dependencies:
cross-spawn "^7.0.3"
"@expo/[email protected]65":
version "1.0.165"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.165.tgz#16cc510174aebaafbc864377e32d4091efad77c1"
integrity sha512-Eo7BYU0iCCdJnxvvj/fVjsYUxV8nmej0VxZaaUpgqlutbRBJNsiBx0BQNxk9Hx/2Ix4n/amcW7IiddBVYzoCUQ==
"@expo/[email protected]6":
version "1.0.156"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.156.tgz#79a043a7dd4f5c098c954ed7a013c407631f515a"
integrity sha512-fa2rMaWqF0DaqqyDXy2Dy5pBbXTPfnMD1ALQid3ApjokMV5Gq+CTyr7sYFGqr1vywK0sftpmKVAOMJzHV95dDg==
dependencies:
"@expo/eas-build-job" "1.0.165"
"@expo/eas-build-job" "1.0.156"
"@expo/logger" "1.0.117"
"@expo/spawn-async" "^1.7.2"
arg "^5.0.2"
@@ -3577,11 +3577,6 @@
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e"
integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==
"@tsconfig/[email protected]":
version "18.2.4"
resolved "https://registry.yarnpkg.com/@tsconfig/node18/-/node18-18.2.4.tgz#094efbdd70f697d37c09f34067bf41bc4a828ae3"
integrity sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==
"@tufjs/[email protected]":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31"