Compare commits

..
14 Commits
Author SHA1 Message Date
Dominik Sokal d4ffb07402 v1.2.0 2022-08-29 11:39:02 +02:00
Evan Bacon 0b2b6ddc14 feat(eas-cli): add 2022 Apple capabilities (#1307)
* feat(eas-cli): add 2022 Apple capabilities

* updated tests

* updated tests and third-party

* update CHANGELOG.md

* updated names

* Update CHANGELOG.md
2022-08-29 11:37:00 +02:00
Szymon Dziedzic 0cff5ef83f [eas-cli] warn about EAS outages (#1312)
* [eas-cli] warn users about EAS Build outages

* [eas-cli] warn users about EAS Submit outages

* [eas-cli] show warnings about EAS outages as a first thing when running build and submit commands

* [eas-cli] don't return null as a result of StatuspageServiceQuery

* [eas-cli] remove unneccessary if check

* [eas-cli] rename warnAboutEasOutagesAsync function to maybeWarnAboutEasOutagesAsync and remove please word from output

* [eas-cli] warn about outages when running `eas update` command

* [eas-cli] improve outage warning communicate

* [eas-cli] move maybeWarnAboutEasOutagesAsync call after flags and project dir validation

* [eas-cli] minor refactor after code review

* [eas-cli] change warning message on EAS outage

* [eas-cli] put platform selection and validation logic into ensurePlatformSelectedAsync function

* update CHANGELOG.md

* [eas-cli] use ensurePlatformSelectedAsync in submit command
2022-08-29 11:29:51 +02:00
Dominik Sokal 396c45269e add eas.json option to skip push notifications setup (#1315)
* add eas.json option to skip push notifications setup

* address PR feedback

* update CHANGELOG.md
2022-08-29 10:19:43 +02:00
Brent Vatne 98ad9798c5 Copy changes to EAS Submit output (#1318)
* Change e-mail -> email

* Update link to build to point to TestFlight

* update CHANGELOG.md
2022-08-29 09:30:20 +02:00
Dominik Sokal b4741293ba improve instructions on setting eas.projectId in app.json (#1316)
* improve instructions on setting eas.projectId in app.json

* address PR feedback

* update CHANGELOG.md
2022-08-26 09:49:41 +02:00
Dominik SokalandBrent Vatne 43a6aa826b [ENG-6125] print warning when eas-cli is installed as dependency (#1310)
* print warning when eas-cli is installed as dependency

* address PR feedback

* Apply suggestions from code review

Co-authored-by: Brent Vatne <[email protected]>

* PR feedback

* Apply suggestions from code review

Co-authored-by: Brent Vatne <[email protected]>

* update CHANGELOG.md

Co-authored-by: Brent Vatne <[email protected]>
2022-08-26 09:24:47 +02:00
Wojciech Kozyra e0a9384e56 update CHANGELOG 2022-08-25 10:21:57 +02:00
Dominik Sokal b5ca8c63d9 add new common submit error 2022-08-25 10:18:10 +02:00
Will Schurman c98401131a [eas-cli] Fix EnvironmentSecretsQuery param name (#1305) 2022-08-24 08:18:16 -07:00
Will Schurman c1cd0f584f [eas-cli] Use AppQuery instead of ProjectQuery (#1309) 2022-08-24 08:16:04 -07:00
Will Schurman f82aae7fc9 [eas-cli] Replace promptToCreateProjectIfNotExistsAsync with getProjectIdAsync (#1303) 2022-08-24 08:14:06 -07:00
Dominik Sokal c349ad7a40 Update CHANGELOG.md 2022-08-24 09:07:03 +02:00
Expo CI 3500a4d5ec update CHANGELOG.md 2022-08-23 19:43:43 +00:00
37 changed files with 2013 additions and 450 deletions

No files matched your search

+20 -3
View File
@@ -8,13 +8,31 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Add 2022 Apple capabilities. ([#1307](https://github.com/expo/eas-cli/pull/1307) by [@EvanBacon](https://github.com/EvanBacon))
- Print warning when eas-cli is installed as project dependency. ([#1310](https://github.com/expo/eas-cli/pull/1310) by [@dsokal](https://github.com/dsokal))
- Add eas.json to skip push notifications credentials setup. ([#1315](https://github.com/expo/eas-cli/pull/1315) by [@dsokal](https://github.com/dsokal))
- Warn about EAS outages when running `build`, `submit`, and `update` commands. ([#1312](https://github.com/expo/eas-cli/pull/1312) by [@szdziedzic](https://github.com/szdziedzic))
### 🐛 Bug fixes
- Replace promptToCreateProjectIfNotExistsAsync with getProjectIdAsync. ([#1303](https://github.com/expo/eas-cli/pull/1303) by [@wschurman](https://github.com/wschurman))
- Use AppQuery instead of ProjectQuery. ([#1304](https://github.com/expo/eas-cli/pull/1304) by [@wschurman](https://github.com/wschurman))
### 🧹 Chores
- Improve instructions on setting `extra.eas.projectId` in app configuration. ([#1316](https://github.com/expo/eas-cli/pull/1316) by [@dsokal](https://github.com/dsokal))
- Improve copy in EAS Submit - "e-mail" -> email, and make the link to app on App Store go directly to the TestFlight tab. ([#1318](https://github.com/expo/eas-cli/pull/1318) by [@brentvatne](https://github.com/brentvatne))
## [1.1.1](https://github.com/expo/eas-cli/releases/tag/v1.1.1) - 2022-08-23
### 🎉 New features
- Add support for `autoIncrement` option at the root of the build profile. ([#1298](https://github.com/expo/eas-cli/pull/1298) by [@szdziedzic](https://github.com/szdziedzic))
### 🐛 Bug fixes
- Handle trailing backslash in `.gitignore`. ([#1306](https://github.com/expo/eas-cli/pull/1306) by [@wkozyra95](https://github.com/wkozyra95))
### 🧹 Chores
- Retry ASC Api Key downloads if it has not fully propagated on Apple's infrastructure. ([#1302](https://github.com/expo/eas-cli/pull/1302) by [@quinlanj](https://github.com/quinlanj))
## [1.1.0](https://github.com/expo/eas-cli/releases/tag/v1.1.0) - 2022-08-23
@@ -24,7 +42,6 @@ This is the log of notable changes to EAS CLI and related packages.
### 🐛 Bug fixes
- Retry ASC Api Key downloads if it has not fully propagated on Apple's infrastructure. ([#1302](https://github.com/expo/eas-cli/pull/1302) by [@quinlanj](https://github.com/quinlanj))
- Prevent throwing dynamic app config write error when configuring project ID. ([#1301](https://github.com/expo/eas-cli/pull/1301) by [@wschurman](https://github.com/wschurman))
### 🧹 Chores
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "1.1.1"
"version": "1.2.0"
}
+68 -76
View File
@@ -19,6 +19,28 @@ npm install -g eas-cli
yarn global add eas-cli
```
## Enforcing eas-cli version for your project
If you want to enforce the `eas-cli` version for your project, use the `"cli.version"` field in **eas.json**. Installing `eas-cli` to your project dependencies is strongly discouraged because it may cause dependency conflicts that are difficult to debug.
An example of **eas.json** that enforces `eas-cli` in version `1.0.0` or newer:
```json
{
"cli": {
"version": ">=1.0.0"
},
"build": {
// build profiles
}
"submit": {
// submit profiles
}
}
```
Learn more: https://docs.expo.dev/build-reference/eas-json/
# Usage
```sh
@@ -58,13 +80,11 @@ eas --help COMMAND
* [`eas channel:view [NAME]`](#eas-channelview-name)
* [`eas config`](#eas-config)
* [`eas credentials`](#eas-credentials)
* [`eas database:create`](#eas-databasecreate)
* [`eas device:create`](#eas-devicecreate)
* [`eas device:delete`](#eas-devicedelete)
* [`eas device:list`](#eas-devicelist)
* [`eas device:view [UDID]`](#eas-deviceview-udid)
* [`eas diagnostics`](#eas-diagnostics)
* [`eas functions:start`](#eas-functionsstart)
* [`eas help [COMMAND]`](#eas-help-command)
* [`eas init`](#eas-init)
* [`eas login`](#eas-login)
@@ -104,7 +124,7 @@ ALIASES
$ eas login
```
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/account/login.ts)_
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -121,7 +141,7 @@ ALIASES
$ eas logout
```
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -138,7 +158,7 @@ ALIASES
$ eas whoami
```
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/account/view.ts)_
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -152,7 +172,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/analytics.ts)_
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -201,7 +221,7 @@ DESCRIPTION
create a branch
```
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -221,7 +241,7 @@ DESCRIPTION
delete a branch
```
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -242,7 +262,7 @@ DESCRIPTION
list all branches
```
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -261,7 +281,7 @@ DESCRIPTION
rename a branch
```
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -285,7 +305,7 @@ DESCRIPTION
view a branch
```
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -315,7 +335,7 @@ DESCRIPTION
start a build
```
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/index.ts)_
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -329,7 +349,7 @@ DESCRIPTION
cancel a build
```
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -346,7 +366,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:inspect`
@@ -381,7 +401,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -414,7 +434,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/list.ts)_
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:submit`
@@ -461,7 +481,7 @@ DESCRIPTION
Update version of an app.
```
_See code: [src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/version/set.ts)_
_See code: [src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -480,7 +500,7 @@ DESCRIPTION
Update a version in native code with a value stored on EAS servers
```
_See code: [src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/version/sync.ts)_
_See code: [src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -497,7 +517,7 @@ DESCRIPTION
view a build for your project
```
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/build/view.ts)_
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -517,7 +537,7 @@ DESCRIPTION
create a channel
```
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -538,7 +558,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -555,7 +575,7 @@ DESCRIPTION
list all channels
```
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:view [NAME]`
@@ -575,7 +595,7 @@ DESCRIPTION
view a channel
```
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -593,7 +613,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -610,21 +630,7 @@ DESCRIPTION
manage credentials
```
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/credentials.ts)_
## `eas database:create`
create a database
```
USAGE
$ eas database:create
DESCRIPTION
create a database
```
_See code: [src/commands/database/create.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/database/create.ts)_
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/credentials.ts)_
## `eas device:create`
@@ -638,7 +644,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/device/create.ts)_
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -656,7 +662,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -673,7 +679,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/device/list.ts)_
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:view [UDID]`
@@ -687,7 +693,7 @@ DESCRIPTION
view a device for your project
```
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/device/view.ts)_
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -701,21 +707,7 @@ DESCRIPTION
display environment info
```
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas functions:start`
start a function
```
USAGE
$ eas functions:start
DESCRIPTION
start a function
```
_See code: [src/commands/functions/start.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/functions/start.ts)_
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -797,7 +789,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -814,7 +806,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas project:info`
@@ -828,7 +820,7 @@ DESCRIPTION
information about the current project
```
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/project/info.ts)_
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -845,7 +837,7 @@ ALIASES
$ eas init
```
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/project/init.ts)_
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas secret:create`
@@ -865,7 +857,7 @@ DESCRIPTION
create an environment secret on the current project or owner account
```
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/secret/create.ts)_
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/secret/create.ts)_
## `eas secret:delete`
@@ -882,7 +874,7 @@ DESCRIPTION
delete an environment secret by ID
```
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/secret/delete.ts)_
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/secret/delete.ts)_
## `eas secret:list`
@@ -896,7 +888,7 @@ DESCRIPTION
list environment secrets available for your current app
```
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/secret/list.ts)_
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/secret/list.ts)_
## `eas submit`
@@ -926,7 +918,7 @@ ALIASES
$ eas build:submit
```
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/submit.ts)_
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -956,7 +948,7 @@ DESCRIPTION
publish an update group
```
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/update/index.ts)_
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -973,7 +965,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -993,7 +985,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:list`
@@ -1012,7 +1004,7 @@ DESCRIPTION
view the recent updates for a branch
```
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/update/list.ts)_
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:view GROUPID`
@@ -1032,7 +1024,7 @@ DESCRIPTION
update group details
```
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/update/view.ts)_
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1052,7 +1044,7 @@ DESCRIPTION
create a webhook
```
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1069,7 +1061,7 @@ DESCRIPTION
delete a webhook
```
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1086,7 +1078,7 @@ DESCRIPTION
list webhooks
```
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1107,7 +1099,7 @@ DESCRIPTION
update a webhook
```
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1124,7 +1116,7 @@ DESCRIPTION
view a webhook
```
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v1.1.1/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v1.2.0/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
+1031 -48
View File
File diff suppressed because it is too large. Load diff
+3 -3
View File
@@ -1,20 +1,20 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "1.1.1",
"version": "1.2.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
},
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/apple-utils": "0.0.0-alpha.33",
"@expo/apple-utils": "0.0.0-alpha.34",
"@expo/code-signing-certificates": "0.0.2",
"@expo/config": "7.0.1",
"@expo/config-plugins": "5.0.1",
"@expo/config-types": "46.0.2",
"@expo/eas-build-job": "0.2.85",
"@expo/eas-json": "1.1.1",
"@expo/eas-json": "1.2.0",
"@expo/json-file": "8.2.36",
"@expo/multipart-body-parser": "1.1.0",
"@expo/package-manager": "0.0.56",
@@ -60,6 +60,7 @@ export async function createBuildContextAsync<T extends Platform>({
projectDir,
user,
env: buildProfile.env,
easJsonCliConfig,
});
const devClientProperties = getDevClientEventProperties({
+1 -3
View File
@@ -1,4 +1,4 @@
import { Env, Ios } from '@expo/eas-build-job';
import { Ios } from '@expo/eas-build-job';
import nullthrows from 'nullthrows';
import { IosJobInput, IosJobSecretsInput } from '../../graphql/generated';
@@ -27,7 +27,6 @@ export function transformJob(job: Ios.Job): IosJobInput {
function transformIosSecrets(secrets: {
buildCredentials?: Ios.BuildCredentials;
env?: Env;
}): IosJobSecretsInput {
const buildCredentials: IosJobSecretsInput['buildCredentials'] = [];
@@ -43,6 +42,5 @@ function transformIosSecrets(secrets: {
return {
buildCredentials,
environmentSecrets: secrets.env,
};
}
@@ -1,5 +1,9 @@
import { EasJsonReader } from '@expo/eas-json';
import * as PackageManagerUtils from '@expo/package-manager';
import { Command } from '@oclif/core';
import chalk from 'chalk';
import fs from 'fs-extra';
import path from 'path';
import semver from 'semver';
import {
@@ -8,6 +12,7 @@ import {
initAsync as initAnalyticsAsync,
logEvent,
} from '../analytics/rudderstackClient';
import { learnMore } from '../log';
import { findProjectRootAsync } from '../project/projectUtils';
import { getUserAsync } from '../user/User';
import { ensureLoggedInAsync } from '../user/actions';
@@ -28,8 +33,11 @@ export default abstract class EasCommand extends Command {
// eslint-disable-next-line async-protect/async-suffix
async run(): Promise<any> {
await initAnalyticsAsync();
if (this.mustBeRunInsideProject) {
await this.applyCliConfigAsync();
const projectDir = await findProjectRootAsync();
await this.applyCliConfigAsync(projectDir);
await this.ensureEasCliIsNotInDependenciesAsync(projectDir);
}
if (this.requiresAuthentication) {
@@ -53,8 +61,7 @@ export default abstract class EasCommand extends Command {
return super.finally(err);
}
private async applyCliConfigAsync(): Promise<void> {
const projectDir = await findProjectRootAsync();
private async applyCliConfigAsync(projectDir: string): Promise<void> {
const easJsonReader = new EasJsonReader(projectDir);
const config = await easJsonReader.getCliConfigAsync();
if (config?.version && !semver.satisfies(easCliVersion, config.version)) {
@@ -66,4 +73,50 @@ export default abstract class EasCommand extends Command {
setVcsClient(new GitClient());
}
}
private async ensureEasCliIsNotInDependenciesAsync(projectDir: string): Promise<void> {
let printCliVersionWarning = false;
const consoleWarn = (msg?: string): void => {
if (msg) {
// eslint-disable-next-line no-console
console.warn(chalk.yellow(msg));
} else {
// eslint-disable-next-line no-console
console.warn();
}
};
if (await this.isEasCliInDependenciesAsync(projectDir)) {
printCliVersionWarning = true;
consoleWarn(`Found ${chalk.bold('eas-cli')} in your project dependencies.`);
}
const maybeRepoRoot = PackageManagerUtils.findWorkspaceRoot(projectDir) ?? projectDir;
if (maybeRepoRoot !== projectDir && (await this.isEasCliInDependenciesAsync(maybeRepoRoot))) {
printCliVersionWarning = true;
consoleWarn(`Found ${chalk.bold('eas-cli')} in your monorepo dependencies.`);
}
if (printCliVersionWarning) {
consoleWarn(
`It's recommended to use the ${chalk.bold(
'"cli.version"'
)} field in eas.json to enforce the ${chalk.bold('eas-cli')} version for your project.`
);
consoleWarn(
learnMore('https://github.com/expo/eas-cli#enforcing-eas-cli-version-for-your-project')
);
consoleWarn();
}
}
private async isEasCliInDependenciesAsync(dir: string): Promise<boolean> {
const packageJsonPath = path.join(dir, 'package.json');
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
return (
packageJson?.dependencies?.['eas-cli'] !== undefined ||
packageJson?.devDependencies?.['eas-cli'] !== undefined
);
}
}
+49 -18
View File
@@ -4,10 +4,12 @@ import path from 'path';
import { BuildFlags, runBuildAndSubmitAsync } from '../../build/runBuildAndSubmit';
import { UserInputResourceClass } from '../../build/types';
import EasCommand from '../../commandUtils/EasCommand';
import { StatuspageServiceName } from '../../graphql/generated';
import Log from '../../log';
import { RequestedPlatform, selectRequestedPlatformAsync } from '../../platform';
import { findProjectRootAsync } from '../../project/projectUtils';
import { enableJsonOutput } from '../../utils/json';
import { maybeWarnAboutEasOutagesAsync } from '../../utils/statuspageService';
interface RawBuildFlags {
platform?: string;
@@ -95,17 +97,30 @@ export default class Build extends EasCommand {
async runAsync(): Promise<void> {
const { flags: rawFlags } = await this.parse(Build);
if (rawFlags.json) {
enableJsonOutput();
}
const flags = await this.sanitizeFlagsAsync(rawFlags);
const flags = this.sanitizeFlags(rawFlags);
const projectDir = await findProjectRootAsync();
await runBuildAndSubmitAsync(projectDir, flags);
if (!flags.localBuildOptions.enable) {
await maybeWarnAboutEasOutagesAsync(
flags.autoSubmit
? [StatuspageServiceName.EasBuild, StatuspageServiceName.EasSubmit]
: [StatuspageServiceName.EasBuild]
);
}
const flagsWithPlatform = await this.ensurePlatformSelectedAsync(flags);
await runBuildAndSubmitAsync(projectDir, flagsWithPlatform);
}
private async sanitizeFlagsAsync(flags: RawBuildFlags): Promise<BuildFlags> {
private sanitizeFlags(
flags: RawBuildFlags
): Omit<BuildFlags, 'requestedPlatform'> & { requestedPlatform?: RequestedPlatform } {
const nonInteractive = flags['non-interactive'];
if (!flags.local && flags.output) {
Errors.error('--output is allowed only for local builds', { exit: 1 });
@@ -117,21 +132,11 @@ export default class Build extends EasCommand {
Errors.error('--json is allowed only when building in non-interactive mode', { exit: 1 });
}
const requestedPlatform = await selectRequestedPlatformAsync(flags.platform);
if (flags.local) {
if (flags['auto-submit'] || flags['auto-submit-with-profile'] !== undefined) {
// TODO: implement this
Errors.error('Auto-submits are not yet supported when building locally', { exit: 1 });
}
if (requestedPlatform === RequestedPlatform.All) {
Errors.error('Builds for multiple platforms are not supported with flag --local', {
exit: 1,
});
} else if (process.platform !== 'darwin' && requestedPlatform === RequestedPlatform.Ios) {
Errors.error('Unsupported platform, macOS is required to build apps for iOS', { exit: 1 });
}
}
const requestedPlatform =
flags.platform &&
Object.values(RequestedPlatform).includes(flags.platform.toLowerCase() as RequestedPlatform)
? (flags.platform.toLowerCase() as RequestedPlatform)
: undefined;
if (flags['skip-credentials-check']) {
Log.warnDeprecatedFlag(
@@ -176,4 +181,30 @@ export default class Build extends EasCommand {
message,
};
}
private async ensurePlatformSelectedAsync(
flags: Omit<BuildFlags, 'requestedPlatform'> & { requestedPlatform?: RequestedPlatform }
): Promise<BuildFlags> {
const requestedPlatform = await selectRequestedPlatformAsync(flags.requestedPlatform);
if (flags.localBuildOptions.enable) {
if (flags.autoSubmit) {
// TODO: implement this
Errors.error('Auto-submits are not yet supported when building locally', { exit: 1 });
}
if (requestedPlatform === RequestedPlatform.All) {
Errors.error('Builds for multiple platforms are not supported with flag --local', {
exit: 1,
});
} else if (process.platform !== 'darwin' && requestedPlatform === RequestedPlatform.Ios) {
Errors.error('Unsupported platform, macOS is required to build apps for iOS', { exit: 1 });
}
}
return {
...flags,
requestedPlatform,
};
}
}
+42 -18
View File
@@ -3,7 +3,7 @@ import { Errors, Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../commandUtils/EasCommand';
import { SubmissionFragment } from '../graphql/generated';
import { StatuspageServiceName, SubmissionFragment } from '../graphql/generated';
import { toAppPlatform } from '../graphql/types/AppPlatform';
import Log from '../log';
import {
@@ -23,6 +23,7 @@ import {
} from '../submit/submit';
import { printSubmissionDetailsUrls } from '../submit/utils/urls';
import { getProfilesAsync } from '../utils/profiles';
import { maybeWarnAboutEasOutagesAsync } from '../utils/statuspageService';
interface RawCommandFlags {
platform?: string;
@@ -91,18 +92,23 @@ export default class Submit extends EasCommand {
async runAsync(): Promise<void> {
const { flags: rawFlags } = await this.parse(Submit);
const flags = await this.sanitizeFlagsAsync(rawFlags);
const flags = this.sanitizeFlags(rawFlags);
const projectDir = await findProjectRootAsync();
const exp = getExpoConfig(projectDir);
const projectId = await getProjectIdAsync(exp);
const platforms = toPlatforms(flags.requestedPlatform);
await maybeWarnAboutEasOutagesAsync([StatuspageServiceName.EasSubmit]);
const flagsWithPlatform = await this.ensurePlatformSelectedAsync(flags);
const platforms = toPlatforms(flagsWithPlatform.requestedPlatform);
const submissionProfiles = await getProfilesAsync({
type: 'submit',
easJsonReader: new EasJsonReader(projectDir),
platforms,
profileName: flags.profile,
profileName: flagsWithPlatform.profile,
});
const submissions: SubmissionFragment[] = [];
@@ -112,8 +118,8 @@ export default class Submit extends EasCommand {
projectDir,
projectId,
profile: submissionProfile.profile,
archiveFlags: flags.archiveFlags,
nonInteractive: flags.nonInteractive,
archiveFlags: flagsWithPlatform.archiveFlags,
nonInteractive: flagsWithPlatform.nonInteractive,
});
if (submissionProfiles.length > 1) {
@@ -133,15 +139,17 @@ export default class Submit extends EasCommand {
Log.newLine();
printSubmissionDetailsUrls(submissions);
if (flags.wait) {
if (flagsWithPlatform.wait) {
const completedSubmissions = await waitToCompleteAsync(submissions, {
verbose: flags.verbose,
verbose: flagsWithPlatform.verbose,
});
exitWithNonZeroCodeIfSomeSubmissionsDidntFinish(completedSubmissions);
}
}
private async sanitizeFlagsAsync(flags: RawCommandFlags): Promise<CommandFlags> {
private sanitizeFlags(
flags: RawCommandFlags
): Omit<CommandFlags, 'requestedPlatform'> & { requestedPlatform?: RequestedPlatform } {
const {
platform,
verbose,
@@ -155,15 +163,11 @@ export default class Submit extends EasCommand {
Errors.error('--platform is required when building in non-interactive mode', { exit: 1 });
}
const requestedPlatform = await selectRequestedPlatformAsync(flags.platform);
if (requestedPlatform === RequestedPlatform.All) {
if (archiveFlags.id || archiveFlags.path || archiveFlags.url) {
Errors.error(
'--id, --path, and --url params are only supported when performing a single-platform submit',
{ exit: 1 }
);
}
}
const requestedPlatform =
flags.platform &&
Object.values(RequestedPlatform).includes(flags.platform.toLowerCase() as RequestedPlatform)
? (flags.platform.toLowerCase() as RequestedPlatform)
: undefined;
return {
archiveFlags,
@@ -174,4 +178,24 @@ export default class Submit extends EasCommand {
nonInteractive,
};
}
private async ensurePlatformSelectedAsync(
flags: Omit<CommandFlags, 'requestedPlatform'> & { requestedPlatform?: RequestedPlatform }
): Promise<CommandFlags> {
const requestedPlatform = await selectRequestedPlatformAsync(flags.requestedPlatform);
if (requestedPlatform === RequestedPlatform.All) {
if (flags.archiveFlags.id || flags.archiveFlags.path || flags.archiveFlags.url) {
Errors.error(
'--id, --path, and --url params are only supported when performing a single-platform submit',
{ exit: 1 }
);
}
}
return {
...flags,
requestedPlatform,
};
}
}
@@ -19,6 +19,7 @@ import {
PublishUpdateGroupInput,
Robot,
RootQueryUpdatesByGroupArgs,
StatuspageServiceName,
Update,
UpdateInfoGroup,
UpdatePublishMutation,
@@ -59,6 +60,7 @@ import {
import uniqBy from '../../utils/expodash/uniqBy';
import formatFields from '../../utils/formatFields';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
import { maybeWarnAboutEasOutagesAsync } from '../../utils/statuspageService';
import { getVcsClient } from '../../vcs';
import { createUpdateBranchOnAppAsync } from '../branch/create';
import { createUpdateChannelOnAppAsync } from '../channel/create';
@@ -228,6 +230,7 @@ export default class UpdatePublish extends EasCommand {
'non-interactive': nonInteractive,
},
} = await this.parse(UpdatePublish);
if (jsonFlag) {
enableJsonOutput();
}
@@ -245,6 +248,8 @@ export default class UpdatePublish extends EasCommand {
isPublicConfig: false,
});
await maybeWarnAboutEasOutagesAsync([StatuspageServiceName.EasUpdate]);
const codeSigningInfo = await getCodeSigningInfoAsync(expPrivate, privateKeyPath);
const hasExpoUpdates = isExpoUpdatesInstalledOrAvailable(projectDir, exp.sdkVersion);
@@ -7,8 +7,8 @@ import {
CommonAndroidAppCredentialsFragment,
GoogleServiceAccountKeyFragment,
} from '../../../graphql/generated';
import { AppQuery } from '../../../graphql/queries/AppQuery';
import { Account } from '../../../user/Account';
import { AppQuery } from '../../ios/api/graphql/queries/AppQuery';
import { GoogleServiceAccountKey, KeystoreWithType } from '../credentials';
import { AndroidAppBuildCredentialsMutation } from './graphql/mutations/AndroidAppBuildCredentialsMutation';
import { AndroidAppCredentialsMutation } from './graphql/mutations/AndroidAppCredentialsMutation';
@@ -1,5 +1,6 @@
import { ExpoConfig } from '@expo/config';
import { Env } from '@expo/eas-build-job';
import { EasJson } from '@expo/eas-json';
import chalk from 'chalk';
import Log from '../log';
@@ -19,6 +20,7 @@ export class CredentialsContext {
public readonly nonInteractive: boolean;
public readonly projectDir: string;
public readonly user: Actor;
public readonly easJsonCliConfig?: EasJson['cli'];
private shouldAskAuthenticateAppStore: boolean = true;
private resolvedExp?: ExpoConfig;
@@ -26,12 +28,14 @@ export class CredentialsContext {
constructor(
private options: {
exp?: ExpoConfig;
easJsonCliConfig?: EasJson['cli'];
nonInteractive?: boolean;
projectDir: string;
user: Actor;
env?: Env;
}
) {
this.easJsonCliConfig = options.easJsonCliConfig;
this.projectDir = options.projectDir;
this.user = options.user;
this.nonInteractive = options.nonInteractive ?? false;
@@ -1,10 +1,16 @@
import { Platform } from '@expo/eas-build-job';
import { CredentialsSource, DistributionType, IosEnterpriseProvisioning } from '@expo/eas-json';
import {
CredentialsSource,
DistributionType,
EasJsonReader,
IosEnterpriseProvisioning,
} from '@expo/eas-json';
import fs from 'fs-extra';
import { CommonIosAppCredentialsFragment } from '../../graphql/generated';
import Log from '../../log';
import { findApplicationTarget } from '../../project/ios/target';
import { confirmAsync } from '../../prompts';
import { selectAsync } from '../../prompts';
import { CredentialsContext } from '../context';
import * as credentialsJsonReader from '../credentialsJson/read';
import { ensureAllTargetsAreConfigured } from '../credentialsJson/utils';
@@ -21,6 +27,12 @@ interface Options {
enterpriseProvisioning?: IosEnterpriseProvisioning;
}
enum PushNotificationSetupOption {
YES,
NO,
NO_DONT_ASK_AGAIN,
}
export default class IosCredentialsProvider {
public readonly platform = Platform.IOS;
@@ -89,13 +101,39 @@ export default class IosCredentialsProvider {
return null;
}
const confirmSetup = await confirmAsync({
message: `Would you like to set up Push Notifications for your project?`,
});
if (!confirmSetup) {
if (ctx.easJsonCliConfig?.promptToConfigurePushNotfications === false) {
return null;
}
return await setupPushKeyAction.runAsync(ctx);
const setupOption = await selectAsync(
`Would you like to set up Push Notifications for your project?`,
[
{ title: 'Yes', value: PushNotificationSetupOption.YES },
{ title: 'No', value: PushNotificationSetupOption.NO },
{
title: `No, don't ask again (preference will be saved to eas.json)`,
value: PushNotificationSetupOption.NO_DONT_ASK_AGAIN,
},
]
);
if (setupOption === PushNotificationSetupOption.YES) {
return await setupPushKeyAction.runAsync(ctx);
} else {
if (setupOption === PushNotificationSetupOption.NO_DONT_ASK_AGAIN) {
await this.disablePushNotificationsSetupInEasJsonAsync(ctx);
}
return null;
}
}
private async disablePushNotificationsSetupInEasJsonAsync(
ctx: CredentialsContext
): Promise<void> {
const easJsonPath = EasJsonReader.formatEasJsonPath(ctx.projectDir);
const easJson = await fs.readJSON(easJsonPath);
easJson.cli = { ...easJson?.cli, promptToConfigurePushNotfications: false };
await fs.writeFile(easJsonPath, `${JSON.stringify(easJson, null, 2)}\n`);
Log.withTick('Updated eas.json');
}
private assertProvisioningProfileType(provisioningProfile: string, targetName?: string): void {
@@ -14,6 +14,7 @@ import {
IosAppBuildCredentialsFragment,
IosDistributionType,
} from '../../../graphql/generated';
import { AppQuery } from '../../../graphql/queries/AppQuery';
import { isWildcardBundleIdentifier } from '../../../project/ios/bundleIdentifier';
import { Account } from '../../../user/Account';
import { DistributionCertificate, PushKey } from '../appstore/Credentials.types';
@@ -33,7 +34,6 @@ import { ApplePushKeyMutation } from './graphql/mutations/ApplePushKeyMutation';
import { AppleTeamMutation } from './graphql/mutations/AppleTeamMutation';
import { IosAppBuildCredentialsMutation } from './graphql/mutations/IosAppBuildCredentialsMutation';
import { IosAppCredentialsMutation } from './graphql/mutations/IosAppCredentialsMutation';
import { AppQuery } from './graphql/queries/AppQuery';
import { AppStoreConnectApiKeyQuery } from './graphql/queries/AppStoreConnectApiKeyQuery';
import { AppleAppIdentifierQuery } from './graphql/queries/AppleAppIdentifierQuery';
import { AppleDeviceQuery } from './graphql/queries/AppleDeviceQuery';
@@ -94,6 +94,30 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
'com.apple.security.application-groups': [
'group.CY-A5149AC2-49FC-11E7-B3F3-0335A16FFB8D.com.cydia.Extender',
],
'com.apple.developer.fileprovider.testing-mode': true,
'com.apple.developer.healthkit.recalibrate-estimates': true,
'com.apple.developer.maps': true,
'com.apple.developer.user-management': true,
'com.apple.developer.networking.custom-protocol': true,
'com.apple.developer.system-extension.install': true,
'com.apple.developer.push-to-talk': true,
'com.apple.developer.driverkit.transport.usb': true,
'com.apple.developer.kernel.increased-memory-limit': true,
'com.apple.developer.driverkit.communicates-with-drivers': true,
'com.apple.developer.media-device-discovery-extension': true,
'com.apple.developer.driverkit.allow-third-party-userclients': true,
'com.apple.developer.weatherkit': true,
'com.apple.developer.on-demand-install-capable': true,
'com.apple.developer.driverkit.family.scsicontroller': true,
'com.apple.developer.driverkit.family.serial': true,
'com.apple.developer.driverkit.family.networking': true,
'com.apple.developer.driverkit.family.hid.eventservice': true,
'com.apple.developer.driverkit.family.hid.device': true,
'com.apple.developer.driverkit': true,
'com.apple.developer.driverkit.transport.hid': true,
'com.apple.developer.driverkit.family.audio': true,
'com.apple.developer.shared-with-you': true,
});
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
@@ -135,36 +159,153 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
},
{ capabilityType: 'AUTOFILL_CREDENTIAL_PROVIDER', option: 'ON' },
{ capabilityType: 'APP_GROUPS', option: 'ON' },
{
capabilityType: 'FILEPROVIDER_TESTINGMODE',
option: 'ON',
},
{
capabilityType: 'HEALTHKIT_RECALIBRATE_ESTIMATES',
option: 'ON',
},
{
capabilityType: 'MAPS',
option: 'ON',
},
{
capabilityType: 'USER_MANAGEMENT',
option: 'ON',
},
{
capabilityType: 'NETWORK_CUSTOM_PROTOCOL',
option: 'ON',
},
{
capabilityType: 'SYSTEM_EXTENSION_INSTALL',
option: 'ON',
},
{
capabilityType: 'PUSH_TO_TALK',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_USBTRANSPORT_PUB',
option: 'ON',
},
{
capabilityType: 'INCREASED_MEMORY_LIMIT',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_COMMUNICATESWITHDRIVERS',
option: 'ON',
},
{
capabilityType: 'MEDIA_DEVICE_DISCOVERY',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_ALLOWTHIRDPARTY_USERCLIENTS',
option: 'ON',
},
{
capabilityType: 'WEATHERKIT',
option: 'ON',
},
{
capabilityType: 'ONDEMANDINSTALL_EXTENSIONS',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_FAMILY_SCSICONTROLLER_PUB',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_FAMILY_SERIAL_PUB',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_FAMILY_NETWORKING_PUB',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_FAMILY_HIDEVENTSERVICE_PUB',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_FAMILY_HIDDEVICE_PUB',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_PUBLIC',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_TRANSPORT_HID_PUB',
option: 'ON',
},
{
capabilityType: 'DRIVERKIT_FAMILY_AUDIO_PUB',
option: 'ON',
},
{
capabilityType: 'SHARED_WITH_YOU',
option: 'ON',
},
]);
expect(results.enabled).toStrictEqual([
'HealthKit',
'Apple Pay Payment Processing',
'iCloud',
'ClassKit',
'Data Protection',
'Network Extensions',
'Personal VPN',
'Hotspot',
'Extended Virtual Address Space',
'HomeKit',
'Multipath',
'Wireless Accessory Configuration',
'Inter-App Audio',
'Wallet',
'Fonts',
'App Attest',
'NFC Tag Reading',
'Sign In with Apple',
'SiriKit',
'Access WiFi Information',
'Communication Notifications',
'Time Sensitive Notifications',
'Group Activities',
'Family Controls',
'AutoFill Credential Provider',
'App Groups',
]);
expect(results.enabled).toMatchInlineSnapshot(`
Array [
"HealthKit",
"Apple Pay Payment Processing",
"iCloud",
"ClassKit",
"Data Protection",
"Network Extensions",
"Personal VPN",
"Hotspot",
"Extended Virtual Address Space",
"HomeKit",
"Multipath",
"Wireless Accessory Configuration",
"Inter-App Audio",
"Wallet",
"Fonts",
"App Attest",
"NFC Tag Reading",
"Sign In with Apple",
"SiriKit",
"Access WiFi Information",
"Communication Notifications",
"Time Sensitive Notifications",
"Group Activities",
"Family Controls",
"AutoFill Credential Provider",
"App Groups",
"FileProvider TestingMode",
"Recalibrate Estimates",
"Maps",
"TV Services",
"Custom Network Protocol",
"System Extension",
"Push to Talk",
"DriverKit USB Transport (development)",
"Increased Memory Limit",
"Communicates with Drivers",
"Media Device Discovery",
"DriverKit Allow Third Party UserClients",
"WeatherKit",
"On Demand Install Capable for App Clip Extensions",
"DriverKit Family SCSIController (development)",
"DriverKit Family Serial (development)",
"DriverKit Family Networking (development)",
"DriverKit Family HID EventService (development)",
"DriverKit Family HID Device (development)",
"DriverKit for Development",
"DriverKit Transport HID (development)",
"DriverKit Family Audio (development)",
"Shared with You",
]
`);
expect(results.disabled).toStrictEqual([]);
});
@@ -484,6 +484,7 @@ export const CapabilityMapping: CapabilityClassifier[] = [
{
// https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_networking_vpn_api
name: 'Push Notifications',
// com.apple.developer.aps-environment
entitlement: 'aps-environment',
capability: CapabilityType.PUSH_NOTIFICATIONS,
validateOptions: validateDevProdString,
@@ -522,6 +523,181 @@ export const CapabilityMapping: CapabilityClassifier[] = [
validateOptions: validateDevProdString,
getOptions: getDefinedOptions,
},
{
entitlement: 'com.apple.developer.coremedia.hls.low-latency',
name: 'Low Latency HLS',
capability: CapabilityType.HLS_LOW_LATENCY,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.associated-domains.mdm-managed',
name: 'MDM Managed Associated Domains',
capability: CapabilityType.MDM_MANAGED_ASSOCIATED_DOMAINS,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.fileprovider.testing-mode',
name: 'FileProvider TestingMode',
capability: CapabilityType.FILE_PROVIDER_TESTING_MODE,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.healthkit.recalibrate-estimates',
name: 'Recalibrate Estimates',
capability: CapabilityType.HEALTH_KIT_RECALIBRATE_ESTIMATES,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.maps',
name: 'Maps',
capability: CapabilityType.MAPS,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.user-management',
name: 'TV Services',
capability: CapabilityType.USER_MANAGEMENT,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.networking.custom-protocol',
name: 'Custom Network Protocol',
capability: CapabilityType.NETWORK_CUSTOM_PROTOCOL,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.system-extension.install',
name: 'System Extension',
capability: CapabilityType.SYSTEM_EXTENSION_INSTALL,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.push-to-talk',
name: 'Push to Talk',
capability: CapabilityType.PUSH_TO_TALK,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.transport.usb',
name: 'DriverKit USB Transport (development)',
capability: CapabilityType.DRIVER_KIT_USB_TRANSPORT_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.kernel.increased-memory-limit',
name: 'Increased Memory Limit',
capability: CapabilityType.INCREASED_MEMORY_LIMIT,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.communicates-with-drivers',
name: 'Communicates with Drivers',
capability: CapabilityType.DRIVER_KIT_COMMUNICATES_WITH_DRIVERS,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.media-device-discovery-extension',
name: 'Media Device Discovery',
capability: CapabilityType.MEDIA_DEVICE_DISCOVERY,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.allow-third-party-userclients',
name: 'DriverKit Allow Third Party UserClients',
capability: CapabilityType.DRIVER_KIT_ALLOW_THIRD_PARTY_USER_CLIENTS,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.weatherkit',
name: 'WeatherKit',
capability: CapabilityType.WEATHER_KIT,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.on-demand-install-capable',
name: 'On Demand Install Capable for App Clip Extensions',
capability: CapabilityType.ON_DEMAND_INSTALL_EXTENSIONS,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.family.scsicontroller',
name: 'DriverKit Family SCSIController (development)',
capability: CapabilityType.DRIVER_KIT_FAMILY_SCSI_CONTROLLER_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.family.serial',
name: 'DriverKit Family Serial (development)',
capability: CapabilityType.DRIVER_KIT_FAMILY_SERIAL_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.family.networking',
name: 'DriverKit Family Networking (development)',
capability: CapabilityType.DRIVER_KIT_FAMILY_NETWORKING_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.family.hid.eventservice',
name: 'DriverKit Family HID EventService (development)',
capability: CapabilityType.DRIVER_KIT_FAMILY_HID_EVENT_SERVICE_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.family.hid.device',
name: 'DriverKit Family HID Device (development)',
capability: CapabilityType.DRIVER_KIT_FAMILY_HID_DEVICE_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit',
name: 'DriverKit for Development',
capability: CapabilityType.DRIVER_KIT_PUBLIC,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.transport.hid',
name: 'DriverKit Transport HID (development)',
capability: CapabilityType.DRIVER_KIT_TRANSPORT_HID_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.driverkit.family.audio',
name: 'DriverKit Family Audio (development)',
capability: CapabilityType.DRIVER_KIT_FAMILY_AUDIO_PUB,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
{
entitlement: 'com.apple.developer.shared-with-you',
name: 'Shared with You',
capability: CapabilityType.SHARED_WITH_YOU,
validateOptions: validateBooleanOptions,
getOptions: getBooleanOptions,
},
// These don't appear to have entitlements, so it's unclear how we can automatically enable / disable them at this time.
// TODO: Maybe add a warning about manually enabling features?
@@ -534,24 +710,9 @@ export const CapabilityMapping: CapabilityClassifier[] = [
// },
// {
// entitlement: '',
// name: 'FileProvider TestingMode',
// capability: 'FILEPROVIDER_TESTINGMODE',
// },
// {
// entitlement: '',
// name: 'HLS Interstitial Previews',
// capability: 'HLS_INTERSTITIAL_PREVIEW',
// },
// {
// entitlement: '',
// name: 'Low Latency HLS',
// capability: 'COREMEDIA_HLS_LOW_LATENCY',
// },
// {
// entitlement: '',
// name: 'MDM Managed Associated Domains',
// capability: 'MDM_MANAGED_ASSOCIATED_DOMAINS',
// },
// "Game Controllers" doesn't appear in Dev Portal but it does show up in Xcode,
// toggling in Xcode causes no network request to be sent.
@@ -4,10 +4,7 @@ import assert from 'assert';
import Log, { learnMore } from '../../log';
import { GradleBuildContext, resolveGradleBuildContextAsync } from '../../project/android/gradle';
import {
getProjectAccountName,
promptToCreateProjectIfNotExistsAsync,
} from '../../project/projectUtils';
import { getProjectAccountName, getProjectIdAsync } from '../../project/projectUtils';
import { promptAsync } from '../../prompts';
import { findAccountByName } from '../../user/Account';
import { ensureActorHasUsername, ensureLoggedInAsync } from '../../user/actions';
@@ -80,12 +77,6 @@ export class ManageAndroid {
while (true) {
try {
if (ctx.hasProjectContext) {
const maybeProjectId = await promptToCreateProjectIfNotExistsAsync(ctx.exp);
if (!maybeProjectId) {
throw new Error(
'Your project must be registered with EAS in order to use the credentials manager.'
);
}
const appLookupParams = await getAppLookupParamsFromContextAsync(ctx, gradleContext);
const appCredentials = await ctx.android.getAndroidAppCredentialsWithCommonFieldsAsync(
appLookupParams
@@ -156,12 +147,10 @@ export class ManageAndroid {
buildProfile: BuildProfile<Platform.ANDROID>
): Promise<GradleBuildContext | undefined> {
assert(ctx.hasProjectContext, 'createProjectContextAsync: must have project context.');
const maybeProjectId = await promptToCreateProjectIfNotExistsAsync(ctx.exp);
if (!maybeProjectId) {
throw new Error(
'Your project must be registered with EAS in order to use the credentials manager.'
);
}
// ensure the project exists on the EAS server
await getProjectIdAsync(ctx.exp);
return await resolveGradleBuildContextAsync(ctx.projectDir, buildProfile);
}
@@ -11,10 +11,7 @@ import {
import Log, { learnMore } from '../../log';
import { resolveXcodeBuildContextAsync } from '../../project/ios/scheme';
import { resolveTargetsAsync } from '../../project/ios/target';
import {
getProjectAccountName,
promptToCreateProjectIfNotExistsAsync,
} from '../../project/projectUtils';
import { getProjectAccountName, getProjectIdAsync } from '../../project/projectUtils';
import { confirmAsync, promptAsync, selectAsync } from '../../prompts';
import { Account, findAccountByName } from '../../user/Account';
import { ensureActorHasUsername, ensureLoggedInAsync } from '../../user/actions';
@@ -175,12 +172,9 @@ export class ManageIos {
targets: Target[];
}> {
assert(ctx.hasProjectContext, 'createProjectContextAsync: must have project context.');
const maybeProjectId = await promptToCreateProjectIfNotExistsAsync(ctx.exp);
if (!maybeProjectId) {
throw new Error(
'Your project must be registered with EAS in order to use the credentials manager.'
);
}
// ensure the project exists on the EAS server
await getProjectIdAsync(ctx.exp);
const app = { account, projectName: ctx.exp.slug };
const xcodeBuildContext = await resolveXcodeBuildContextAsync(
+171 -22
View File
@@ -280,8 +280,8 @@ export type AccountMutation = {
grantActorPermissions: Account;
/** Rename this account and the primary user's username if this account is a personal account */
rename: Account;
/** Requests a refund for the specified charge. Returns true if auto-refund was possible, otherwise requests a manual refund from support and returns false. */
requestRefund: Scalars['Boolean'];
/** Requests a refund for the specified charge by requesting a manual refund from support */
requestRefund?: Maybe<Scalars['Boolean']>;
/** Revoke specified Permissions for Actor. Actor must already have at least one permission on the account. */
revokeActorPermissions: Account;
/**
@@ -803,9 +803,23 @@ export type AndroidJobKeystoreInput = {
keystorePassword: Scalars['String'];
};
export type AndroidJobOverridesInput = {
artifactPath?: InputMaybe<Scalars['String']>;
buildType?: InputMaybe<AndroidBuildType>;
builderEnvironment?: InputMaybe<AndroidBuilderEnvironmentInput>;
cache?: InputMaybe<BuildCacheInput>;
developmentClient?: InputMaybe<Scalars['Boolean']>;
experimental?: InputMaybe<Scalars['JSONObject']>;
gradleCommand?: InputMaybe<Scalars['String']>;
releaseChannel?: InputMaybe<Scalars['String']>;
secrets?: InputMaybe<AndroidJobSecretsInput>;
updates?: InputMaybe<BuildUpdatesInput>;
username?: InputMaybe<Scalars['String']>;
version?: InputMaybe<AndroidJobVersionInput>;
};
export type AndroidJobSecretsInput = {
buildCredentials?: InputMaybe<AndroidJobBuildCredentialsInput>;
environmentSecrets?: InputMaybe<Scalars['JSONObject']>;
};
export type AndroidJobVersionInput = {
@@ -1932,8 +1946,15 @@ export type BuildMutation = {
createIosBuild: CreateBuildResult;
/** Delete an EAS Build build */
deleteBuild: Build;
/** Retry an EAS Build build */
/** Retry an Android EAS Build */
retryAndroidBuild: Build;
/**
* Retry an EAS Build build
* @deprecated Use retryAndroidBuild and retryIosBuild instead
*/
retryBuild: Build;
/** Retry an iOS EAS Build */
retryIosBuild: Build;
};
@@ -1963,10 +1984,22 @@ export type BuildMutationDeleteBuildArgs = {
};
export type BuildMutationRetryAndroidBuildArgs = {
buildId: Scalars['ID'];
jobOverrides?: InputMaybe<AndroidJobOverridesInput>;
};
export type BuildMutationRetryBuildArgs = {
buildId: Scalars['ID'];
};
export type BuildMutationRetryIosBuildArgs = {
buildId: Scalars['ID'];
jobOverrides?: InputMaybe<IosJobOverridesInput>;
};
export type BuildOrBuildJob = {
id: Scalars['ID'];
};
@@ -2711,9 +2744,28 @@ export type IosJobInput = {
version?: InputMaybe<IosJobVersionInput>;
};
export type IosJobOverridesInput = {
artifactPath?: InputMaybe<Scalars['String']>;
buildConfiguration?: InputMaybe<Scalars['String']>;
/** @deprecated */
buildType?: InputMaybe<IosBuildType>;
builderEnvironment?: InputMaybe<IosBuilderEnvironmentInput>;
cache?: InputMaybe<BuildCacheInput>;
developmentClient?: InputMaybe<Scalars['Boolean']>;
/** @deprecated */
distribution?: InputMaybe<DistributionType>;
experimental?: InputMaybe<Scalars['JSONObject']>;
releaseChannel?: InputMaybe<Scalars['String']>;
scheme?: InputMaybe<Scalars['String']>;
secrets?: InputMaybe<IosJobSecretsInput>;
simulator?: InputMaybe<Scalars['Boolean']>;
updates?: InputMaybe<BuildUpdatesInput>;
username?: InputMaybe<Scalars['String']>;
version?: InputMaybe<IosJobVersionInput>;
};
export type IosJobSecretsInput = {
buildCredentials?: InputMaybe<Array<InputMaybe<IosJobTargetCredentialsInput>>>;
environmentSecrets?: InputMaybe<Scalars['JSONObject']>;
};
export type IosJobTargetCredentialsInput = {
@@ -3215,8 +3267,6 @@ export type RootMutationBuildJobArgs = {
export type RootQuery = {
__typename?: 'RootQuery';
/** Top-level query object for querying GitHub App information and resources it has access to. */
GitHubApp: GitHubAppQuery;
/**
* This is a placeholder field
* @deprecated Not used.
@@ -3251,6 +3301,8 @@ export type RootQuery = {
clientBuilds: ClientBuildQuery;
/** Top-level query object for querying Experimentation configuration. */
experimentation: ExperimentationQuery;
/** Top-level query object for querying GitHub App information and resources it has access to. */
githubApp: GitHubAppQuery;
/** Top-level query object for querying Stripe Invoices. */
invoice: InvoiceQuery;
/**
@@ -3265,6 +3317,8 @@ export type RootQuery = {
meActor?: Maybe<Actor>;
project: ProjectQuery;
snack: SnackQuery;
/** Top-level query object for querying Expo status page services. */
statuspageService: StatuspageServiceQuery;
submissions: SubmissionQuery;
/** fetch all updates in a group */
updatesByGroup: Array<Update>;
@@ -3424,6 +3478,100 @@ export enum StandardOffer {
YearlySub = 'YEARLY_SUB'
}
/** Incident for a given component from Expo status page API. */
export type StatuspageIncident = {
__typename?: 'StatuspageIncident';
createdAt: Scalars['DateTime'];
id: Scalars['ID'];
/** Impact of an incident from Expo status page. */
impact: StatuspageIncidentImpact;
name: Scalars['String'];
resolvedAt?: Maybe<Scalars['DateTime']>;
/** Shortlink to the incident from Expo status page. */
shortlink: Scalars['String'];
/** Current status of an incident from Expo status page. */
status: StatuspageIncidentStatus;
updatedAt: Scalars['DateTime'];
/** List of all updates for an incident from Expo status page. */
updates: Array<StatuspageIncidentUpdate>;
};
/** Possible Incident impact values from Expo status page API. */
export enum StatuspageIncidentImpact {
Critical = 'CRITICAL',
Maintenance = 'MAINTENANCE',
Major = 'MAJOR',
Minor = 'MINOR',
None = 'NONE'
}
/** Possible Incident statuses from Expo status page API. */
export enum StatuspageIncidentStatus {
Completed = 'COMPLETED',
Identified = 'IDENTIFIED',
Investigating = 'INVESTIGATING',
InProgress = 'IN_PROGRESS',
Monitoring = 'MONITORING',
Resolved = 'RESOLVED',
Scheduled = 'SCHEDULED',
Verifying = 'VERIFYING'
}
/** Update for an Incident from Expo status page API. */
export type StatuspageIncidentUpdate = {
__typename?: 'StatuspageIncidentUpdate';
/** Text of an update from Expo status page. */
body: Scalars['String'];
createdAt: Scalars['DateTime'];
id: Scalars['ID'];
/** Status set at the moment of update. */
status: StatuspageIncidentStatus;
};
/** Service monitored by Expo status page. */
export type StatuspageService = {
__typename?: 'StatuspageService';
/** Description of a service from Expo status page. */
description?: Maybe<Scalars['String']>;
id: Scalars['ID'];
/**
* List of last inicdents for a service from Expo status page (we always query for 50 latest incidents for all services)
* sorted by createdAt field in descending order.
*/
incidents: Array<StatuspageIncident>;
/** Name of a service monitored by Expo status page. */
name: StatuspageServiceName;
/** Current status of a service from Expo status page. */
status: StatuspageServiceStatus;
};
/** Name of a service monitored by Expo status page. */
export enum StatuspageServiceName {
EasBuild = 'EAS_BUILD',
EasSubmit = 'EAS_SUBMIT',
EasUpdate = 'EAS_UPDATE'
}
export type StatuspageServiceQuery = {
__typename?: 'StatuspageServiceQuery';
/** Query services from Expo status page by names. */
byServiceNames: Array<StatuspageService>;
};
export type StatuspageServiceQueryByServiceNamesArgs = {
serviceNames: Array<StatuspageServiceName>;
};
/** Possible statuses for a service. */
export enum StatuspageServiceStatus {
DegradedPerformance = 'DEGRADED_PERFORMANCE',
MajorOutage = 'MAJOR_OUTAGE',
Operational = 'OPERATIONAL',
PartialOutage = 'PARTIAL_OUTAGE',
UnderMaintenance = 'UNDER_MAINTENANCE'
}
export type StripeCoupon = {
__typename?: 'StripeCoupon';
amountOff?: Maybe<Scalars['String']>;
@@ -4471,13 +4619,6 @@ export type SetAppStoreConnectApiKeyForSubmissionsMutationVariables = Exact<{
export type SetAppStoreConnectApiKeyForSubmissionsMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', setAppStoreConnectApiKeyForSubmissions: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null } } };
export type AppByFullNameQueryVariables = Exact<{
fullName: Scalars['String'];
}>;
export type AppByFullNameQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, fullName: string, slug: string } } };
export type AppStoreConnectApiKeyByAccountQueryVariables = Exact<{
accountName: Scalars['String'];
}>;
@@ -4722,6 +4863,13 @@ export type DeleteWebhookMutationVariables = Exact<{
export type DeleteWebhookMutation = { __typename?: 'RootMutation', webhook: { __typename?: 'WebhookMutation', deleteWebhook: { __typename?: 'DeleteWebhookResult', id: string } } };
export type AppByFullNameQueryVariables = Exact<{
fullName: Scalars['String'];
}>;
export type AppByFullNameQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, fullName: string, slug: string } } };
export type LatestAppVersionQueryVariables = Exact<{
appId: Scalars['String'];
platform: AppPlatform;
@@ -4794,14 +4942,6 @@ export type EnvironmentSecretsByAppIdQueryVariables = Exact<{
export type EnvironmentSecretsByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentSecrets: Array<{ __typename?: 'EnvironmentSecret', id: string, name: string, createdAt: any }> } } };
export type ProjectByUsernameAndSlugQueryVariables = Exact<{
username: Scalars['String'];
slug: Scalars['String'];
}>;
export type ProjectByUsernameAndSlugQuery = { __typename?: 'RootQuery', project: { __typename?: 'ProjectQuery', byUsernameAndSlug: { __typename?: 'App', id: string } | { __typename?: 'Snack', id: string } } };
export type GetAssetMetadataQueryVariables = Exact<{
storageKeys: Array<Scalars['String']> | Scalars['String'];
}>;
@@ -4816,6 +4956,13 @@ export type GetAssetLimitPerUpdateGroupForAppQueryVariables = Exact<{
export type GetAssetLimitPerUpdateGroupForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, assetLimitPerUpdateGroup: number } } };
export type StatuspageServiceByServiceNamesQueryVariables = Exact<{
serviceNames: Array<StatuspageServiceName> | StatuspageServiceName;
}>;
export type StatuspageServiceByServiceNamesQuery = { __typename?: 'RootQuery', statuspageService: { __typename?: 'StatuspageServiceQuery', byServiceNames: Array<{ __typename?: 'StatuspageService', id: string, name: StatuspageServiceName, status: StatuspageServiceStatus, incidents: Array<{ __typename?: 'StatuspageIncident', id: string, status: StatuspageIncidentStatus, name: string, impact: StatuspageIncidentImpact, shortlink: string }> }> } };
export type SubmissionsByIdQueryVariables = Exact<{
submissionId: Scalars['ID'];
}>;
@@ -4881,6 +5028,8 @@ export type BuildWithSubmissionsFragment = { __typename?: 'Build', id: string, s
export type EnvironmentSecretFragment = { __typename?: 'EnvironmentSecret', id: string, name: string, createdAt: any };
export type StatuspageServiceFragment = { __typename?: 'StatuspageService', id: string, name: StatuspageServiceName, status: StatuspageServiceStatus, incidents: Array<{ __typename?: 'StatuspageIncident', id: string, status: StatuspageIncidentStatus, name: string, impact: StatuspageIncidentImpact, shortlink: string }> };
export type SubmissionFragment = { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, createdAt: any, message?: string | null, runtimeVersion: string, group: string, platform: string, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'User', username: string, id: string } | null }> };
@@ -2,9 +2,9 @@ import assert from 'assert';
import { print } from 'graphql';
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../../../../../graphql/client';
import { AppByFullNameQuery, AppFragment } from '../../../../../graphql/generated';
import { AppFragmentNode } from '../../../../../graphql/types/App';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { AppByFullNameQuery, AppFragment } from '../generated';
import { AppFragmentNode } from '../types/App';
export const AppQuery = {
async byFullNameAsync(fullName: string): Promise<AppFragment> {
@@ -75,11 +75,11 @@ export const EnvironmentSecretsQuery = {
},
async allAsync(
projectAccountName: string,
projectFullName: string
projectId: string
): Promise<EnvironmentSecretWithScope[]> {
const [accountSecrets, appSecrets] = await Promise.all([
this.byAccountNameAsync(projectAccountName),
this.byAppIdAsync(projectFullName),
this.byAppIdAsync(projectId),
]);
return [
@@ -1,32 +0,0 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { Project, ProjectByUsernameAndSlugQuery } from '../generated';
type ProjectQueryResult = Pick<Project, 'id'>;
export const ProjectQuery = {
async byUsernameAndSlugAsync(username: string, slug: string): Promise<ProjectQueryResult> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<ProjectByUsernameAndSlugQuery>(
gql`
query ProjectByUsernameAndSlugQuery($username: String!, $slug: String!) {
project {
byUsernameAndSlug(username: $username, slug: $slug) {
id
}
}
}
`,
{ username, slug },
{
additionalTypenames: ['App', 'Snack'] /* typenames that use the Project type*/,
}
)
.toPromise()
);
return data.project.byUsernameAndSlug;
},
};
@@ -0,0 +1,41 @@
import { print } from 'graphql';
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import {
StatuspageServiceByServiceNamesQuery,
StatuspageServiceByServiceNamesQueryVariables,
StatuspageServiceFragment,
StatuspageServiceName,
} from '../generated';
import { StatuspageServiceFragmentNode } from '../types/StatuspageService';
export const StatuspageServiceQuery = {
async statuspageServicesAsync(
serviceNames: StatuspageServiceName[]
): Promise<StatuspageServiceFragment[]> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<StatuspageServiceByServiceNamesQuery, StatuspageServiceByServiceNamesQueryVariables>(
gql`
query StatuspageServiceByServiceNamesQuery($serviceNames: [StatuspageServiceName!]!) {
statuspageService {
byServiceNames(serviceNames: $serviceNames) {
id
...StatuspageServiceFragment
}
}
}
${print(StatuspageServiceFragmentNode)}
`,
{ serviceNames },
{
additionalTypenames: ['StatuspageService', 'StatuspageIncident'],
}
)
.toPromise()
);
return data.statuspageService.byServiceNames;
},
};
@@ -0,0 +1,16 @@
import gql from 'graphql-tag';
export const StatuspageServiceFragmentNode = gql`
fragment StatuspageServiceFragment on StatuspageService {
id
name
status
incidents {
id
status
name
impact
shortlink
}
}
`;
@@ -1,18 +1,13 @@
import { getConfig, modifyConfigAsync } from '@expo/config';
import { vol } from 'memfs';
import { confirmAsync } from '../../prompts';
import { Actor, getUserAsync } from '../../user/User';
import {
ensureProjectExistsAsync,
findProjectIdByAccountNameAndSlugNullableAsync,
} from '../ensureProjectExists';
import { ensureProjectExistsAsync } from '../ensureProjectExists';
import {
findProjectRootAsync,
getProjectAccountName,
getProjectAccountNameAsync,
getProjectIdAsync,
promptToCreateProjectIfNotExistsAsync,
} from '../projectUtils';
jest.mock('@expo/config');
@@ -186,75 +181,6 @@ describe(getProjectAccountNameAsync, () => {
});
});
describe(promptToCreateProjectIfNotExistsAsync, () => {
beforeEach(() => {
jest.mocked(getUserAsync).mockReset();
jest.mocked(findProjectIdByAccountNameAndSlugNullableAsync).mockReset();
});
it('returns the existing project', async () => {
jest.mocked(getUserAsync).mockImplementation(
async (): Promise<Actor> => ({
__typename: 'User',
id: 'user_id',
username: 'quin',
accounts: [{ id: 'account_id_1', name: 'quin' }],
isExpoAdmin: false,
})
);
jest
.mocked(findProjectIdByAccountNameAndSlugNullableAsync)
.mockImplementation(async () => 'already-existing-project-id');
const exp: any = {};
const projectId = await promptToCreateProjectIfNotExistsAsync(exp);
expect(projectId).toBe('already-existing-project-id');
});
it('makes a new project if none exists', async () => {
jest.mock('../../prompts');
jest.mocked(getUserAsync).mockImplementation(
async (): Promise<Actor> => ({
__typename: 'User',
id: 'user_id',
username: 'quin',
accounts: [{ id: 'account_id_1', name: 'quin' }],
isExpoAdmin: false,
})
);
jest
.mocked(findProjectIdByAccountNameAndSlugNullableAsync)
.mockImplementation(async () => null);
jest.mocked(ensureProjectExistsAsync).mockImplementation(async () => 'new-project-id');
// user agrees to make new project
jest.mocked(confirmAsync).mockImplementation(async () => true);
const exp: any = {};
const projectId = await promptToCreateProjectIfNotExistsAsync(exp);
expect(projectId).toBe('new-project-id');
});
it('aborts making a new project if the user declines', async () => {
jest.mock('../../prompts');
jest.mocked(getUserAsync).mockImplementation(
async (): Promise<Actor> => ({
__typename: 'User',
id: 'user_id',
username: 'quin',
accounts: [{ id: 'account_id_1', name: 'quin' }],
isExpoAdmin: false,
})
);
jest
.mocked(findProjectIdByAccountNameAndSlugNullableAsync)
.mockImplementation(async () => null);
jest.mocked(ensureProjectExistsAsync).mockImplementation(async () => 'new-project-id');
// user doesnt agree to make new project
jest.mocked(confirmAsync).mockImplementation(async () => false);
const exp: any = {};
const projectId = await promptToCreateProjectIfNotExistsAsync(exp);
expect(projectId).toBe(null);
});
});
describe(getProjectIdAsync, () => {
beforeEach(() => {
jest.mocked(getUserAsync).mockImplementation(
@@ -5,7 +5,7 @@ import terminalLink from 'terminal-link';
import { getProjectDashboardUrl } from '../build/utils/url';
import { AppPrivacy } from '../graphql/generated';
import { AppMutation } from '../graphql/mutations/AppMutation';
import { ProjectQuery } from '../graphql/queries/ProjectQuery';
import { AppQuery } from '../graphql/queries/AppQuery';
import { ora } from '../ora';
import { findAccountByName } from '../user/Account';
import { ensureLoggedInAsync } from '../user/actions';
@@ -71,12 +71,13 @@ export async function ensureProjectExistsAsync(projectInfo: ProjectInfo): Promis
* @param slug project slug
* @returns A promise resolving to Project ID, null if it doesn't exist
*/
export async function findProjectIdByAccountNameAndSlugNullableAsync(
async function findProjectIdByAccountNameAndSlugNullableAsync(
accountName: string,
slug: string
): Promise<string | null> {
try {
return await findProjectIdByAccountNameAndSlugAsync(accountName, slug);
const { id } = await AppQuery.byFullNameAsync(`@${accountName}/${slug}`);
return id;
} catch (err: any) {
if (err.graphQLErrors?.some((it: any) => it.extensions?.errorCode !== 'EXPERIENCE_NOT_FOUND')) {
throw err;
@@ -85,20 +86,6 @@ export async function findProjectIdByAccountNameAndSlugNullableAsync(
}
}
/**
* Finds project by `@accountName/slug` and returns its ID
* @param accountName account name
* @param slug project slug
* @returns A promise resolving to Project ID
*/
async function findProjectIdByAccountNameAndSlugAsync(
accountName: string,
slug: string
): Promise<string> {
const { id } = await ProjectQuery.byUsernameAndSlugAsync(accountName, slug);
return id;
}
/**
* Registers new project on EAS servers
* @returns Created project's ID
+16 -40
View File
@@ -9,15 +9,11 @@ import semver from 'semver';
import { AppPrivacy } from '../graphql/generated';
import Log from '../log';
import { confirmAsync } from '../prompts';
import { Actor } from '../user/User';
import { ensureLoggedInAsync } from '../user/actions';
import { expoCommandAsync } from '../utils/expoCli';
import { getVcsClient } from '../vcs';
import {
ensureProjectExistsAsync,
findProjectIdByAccountNameAndSlugNullableAsync,
} from './ensureProjectExists';
import { ensureProjectExistsAsync } from './ensureProjectExists';
import { getExpoConfig } from './expoConfig';
export function getProjectAccountName(exp: ExpoConfig, user: Actor): string {
@@ -100,17 +96,24 @@ export async function saveProjectIdToAppConfigAsync(
case 'success':
break;
case 'warn': {
Log.log();
Log.warn('It looks like you are using a dynamic configuration!');
Log.log(
chalk.dim(
'https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs)\n'
)
Log.warn();
Log.warn(
`Warning: Your project uses dynamic app configuration, and the EAS project ID can't automatically be added to it.`
);
Log.warn(
'In order to finish setting up your project you are going to need manually add the following to your "extra" key:\n\n'
chalk.dim(
'https://docs.expo.dev/workflow/configuration/#dynamic-configuration-with-appconfigjs'
)
);
Log.log(chalk.bold(`"extra": {\n ...\n "eas": {\n "projectId": "${projectId}"\n }\n}`));
Log.warn();
Log.warn(
`To complete the setup process, set the ${chalk.bold(
'extra.eas.projectId'
)} in your ${chalk.bold(getProjectConfigDescription(projectDir))}:`
);
Log.warn();
Log.warn(chalk.bold(JSON.stringify({ expo: { extra: { eas: { projectId } } } }, null, 2)));
Log.warn();
throw new Error(result.message);
}
case 'fail':
@@ -207,33 +210,6 @@ export function getProjectConfigDescription(projectDir: string): string {
return 'app.config.js/app.json';
}
// return project id of existing/newly created project, or null if user declines
export async function promptToCreateProjectIfNotExistsAsync(
exp: ExpoConfig
): Promise<string | null> {
const accountName = getProjectAccountName(exp, await ensureLoggedInAsync());
const maybeProjectId = await findProjectIdByAccountNameAndSlugNullableAsync(
accountName,
exp.slug
);
if (maybeProjectId) {
return maybeProjectId;
}
const fullName = await getProjectFullNameAsync(exp);
const shouldCreateProject = await confirmAsync({
message: `Looks like ${fullName} is new. Register it with EAS?`,
});
if (!shouldCreateProject) {
return null;
}
const privacy = toAppPrivacy(exp.privacy);
return await ensureProjectExistsAsync({
accountName,
projectName: exp.slug,
privacy,
});
}
export function isExpoUpdatesInstalled(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.dependencies && 'expo-updates' in packageJson.dependencies);
@@ -164,7 +164,7 @@ function formatServiceAccountSummary({ summary }: ServiceAccountKeyResult): stri
value: serviceAccountKeyPath,
},
{
label: 'Account E-mail',
label: 'Account Email',
value: serviceAccountEmail,
},
];
+2 -2
View File
@@ -74,12 +74,12 @@ function printInstructionsForIosSubmission(submission: SubmissionFragment): void
if (submission.status === SubmissionStatus.Finished) {
const logMsg = [
chalk.bold('Your binary has been successfully uploaded to App Store Connect!'),
'- It is now being processed by Apple - you will receive an e-mail when the processing finishes.',
'- It is now being processed by Apple - you will receive an email when the processing finishes.',
'- It usually takes about 5-10 minutes depending on how busy Apple servers are.',
// ascAppIdentifier should be always available for ios submissions but check it anyway
submission.iosConfig?.ascAppIdentifier &&
`- When it's done, you can see your build here: ${link(
`https://appstoreconnect.apple.com/apps/${submission.iosConfig?.ascAppIdentifier}/appstore/ios`
`https://appstoreconnect.apple.com/apps/${submission.iosConfig?.ascAppIdentifier}/testflight/ios`
)}`,
].join('\n');
Log.addNewLineIfNone();
@@ -19,6 +19,7 @@ enum SubmissionErrorCode {
IOS_IPAD_INVALID_ORIENTATION = 'SUBMISSION_SERVICE_IOS_IPAD_INVALID_ORIENTATION',
IOS_APPLE_MAINTENANCE = 'SUBMISSION_SERVICE_IOS_APPLE_MAINTENANCE',
IOS_INVALID_PROVISIONING_PROFILE_SIGNATURE = 'SUBMISSION_SERVICE_IOS_INVALID_PROVISIONING_PROFILE_SIGNATURE',
IOS_SIGNED_WITH_ADHOC_PROFILE = 'SUBMISSION_SERVICE_IOS_SIGNED_WITH_ADHOC_PROFILE',
}
const SubmissionErrorMessages: Record<SubmissionErrorCode, string> = {
@@ -73,6 +74,8 @@ const SubmissionErrorMessages: Record<SubmissionErrorCode, string> = {
'Delete your Provisioning Profile from your account. Then rebuild the app interactively to generate a new one, and try submitting it to the App Store again.',
[SubmissionErrorCode.UPLOAD_TAKING_TOO_LONG_ERROR]:
'Submission has reached the timeout limit. Try again.',
[SubmissionErrorCode.IOS_SIGNED_WITH_ADHOC_PROFILE]:
'Invalid Provisioning Profile for Apple App Store distribution. The application was signed with an Ad Hoc/Enterprise Provisioning Profile, which is meant for "Internal Distribution". In order to distribute an app on the store, it must be signed with a Distribution Provisioning Profile. Ensure that you are submitting the correct build, or rebuild the application with a Distribution Provisioning Profile and submit that new build.',
};
export function printSubmissionError(error: SubmissionError): boolean {
@@ -0,0 +1,59 @@
import chalk from 'chalk';
import {
StatuspageServiceFragment,
StatuspageServiceName,
StatuspageServiceStatus,
} from '../graphql/generated';
import { StatuspageServiceQuery } from '../graphql/queries/StatuspageServiceQuery';
import Log, { link } from '../log';
export async function maybeWarnAboutEasOutagesAsync(
serviceNames: StatuspageServiceName[]
): Promise<void> {
const services = await getStatuspageServiceAsync(serviceNames);
for (const service of services) {
warnAboutServiceOutage(service);
}
}
const humanReadableServiceName: Record<StatuspageServiceName, string> = {
[StatuspageServiceName.EasBuild]: 'EAS Build',
[StatuspageServiceName.EasSubmit]: 'EAS Submit',
[StatuspageServiceName.EasUpdate]: 'EAS Update',
};
function warnAboutServiceOutage(service: StatuspageServiceFragment): void {
if (service.status === StatuspageServiceStatus.Operational) {
return;
}
const outageType = service.status === StatuspageServiceStatus.MajorOutage ? 'major' : 'partial';
Log.warn(
chalk.bold(`${humanReadableServiceName[service.name]} is experiencing a ${outageType} outage.`)
);
if (service.incidents.length > 0) {
const [currentIncident] = service.incidents;
Log.warn(`Reason: ${currentIncident.name}`);
}
Log.warn(
`All information on service status and incidents available at ${link(
'https://status.expo.dev/'
)}.`
);
Log.newLine();
}
async function getStatuspageServiceAsync(
serviceNames: StatuspageServiceName[]
): Promise<StatuspageServiceFragment[]> {
try {
return await StatuspageServiceQuery.statuspageServicesAsync(serviceNames);
} catch {
return [];
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "1.1.1",
"version": "1.2.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
+5
View File
@@ -37,6 +37,11 @@
"When using local, the `autoIncrement` is based on your local project values.",
"When using remote, the `autoIncrement` is based on the values stored on EAS servers."
]
},
"promptToConfigurePushNotfications" : {
"type": "boolean",
"description": "Specifies where EAS CLI should prompt to configure Push Notifications credentials. Defaults to true.",
"default": true
}
}
},
+1
View File
@@ -9,6 +9,7 @@ export const EasJsonSchema = Joi.object({
version: Joi.string(),
requireCommit: Joi.boolean(),
appVersionSource: Joi.string().valid(...Object.values(AppVersionSource)),
promptToConfigurePushNotfications: Joi.boolean(),
}),
build: Joi.object().pattern(Joi.string(), BuildProfileSchema),
submit: Joi.object().pattern(Joi.string(), SubmitProfileSchema),
+1
View File
@@ -21,6 +21,7 @@ export interface EasJson {
version?: string;
requireCommit?: boolean;
appVersionSource?: AppVersionSource;
promptToConfigurePushNotfications?: boolean;
};
build?: { [profileName: string]: EasJsonBuildProfile };
submit?: { [profileName: string]: EasJsonSubmitProfile };
Generated
+4 -4
View File
@@ -1277,10 +1277,10 @@
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@expo/[email protected]3":
version "0.0.0-alpha.33"
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-0.0.0-alpha.33.tgz#ca3bd7c5b50c200161d27e173e6ac3389ac9ee98"
integrity sha512-4tG9Vou0ruvZgBFhMzTVtRPk5IH/hUU6fdpXcdRYPsULGI2QvB15CV6C+ee8utd4lmw/FIX8W9jLB8RehBBsJw==
"@expo/[email protected]4":
version "0.0.0-alpha.34"
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-0.0.0-alpha.34.tgz#b36547de894e69a73290b8e43a8ef48ffe0ce240"
integrity sha512-GRHN1xhI3Yjb76aFVLhxE7o/Pdx8D78Gm2HaRHxdFRSSdYK5lPw2/1y1/GhDH7DoXqqGwo2uQSevd6ywlj657g==
"@expo/bunyan@^4.0.0":
version "4.0.0"