Compare commits

...
34 Commits
Author SHA1 Message Date
Dominik Sokal 70ed1a482a v0.47.0 2022-02-08 12:05:54 +01:00
Dominik Sokal 920e5ee8a2 upgrade deps (#946)
* upgrade deps

* update CHANGELOG.md
2022-02-08 11:42:25 +01:00
Dominik Sokal f334f2c019 update CHANGELOG.md 2022-02-08 11:31:33 +01:00
jkh b145a7d98c [eas-cli] assert expo-updates is installed before a publish (#953) 2022-02-07 10:06:01 -05:00
jkh 3c750b60c0 [eas-cli] update error message to new publish command (#952) 2022-02-03 10:44:09 -05:00
jkh b3a9f1af70 [eas-cli] return an informative error if rollout channel dne (#930) 2022-01-28 11:18:34 -05:00
jkh 39d8ab65d1 [eas-cli] fix get branchByNameAsync typing (#929) 2022-01-26 11:23:26 -05:00
Expo CI 1ff2274d8d update CHANGELOG.md 2022-01-26 09:43:42 +00:00
Dominik Sokal 5ed4b65133 v0.46.0 2022-01-26 10:33:41 +01:00
Dominik Sokal 10aca5208f fix url placeholder for iOS submits (#941)
* fix url placeholder for iOS submits

* update CHANGELOG.md
2022-01-25 15:26:20 +01:00
dependabot[bot] b2da80d5ea Bump node-fetch from 2.6.1 to 2.6.7 (#940)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 15:21:45 +01:00
Dominik Sokal b9457d71f9 upgrade deps (#939)
* upgrade deps

* update CHANGELOG.md
2022-01-25 14:48:02 +01:00
Dominik Sokalandjkh 5fd3149a95 unify command descriptions (#925)
* unify command descriptions

* fix lint warnings

* Apply suggestions from code review

Co-authored-by: jkh <[email protected]>

* address PR feedback

* update CHANGELOG.md

Co-authored-by: jkh <[email protected]>
2022-01-21 12:13:40 +01:00
dependabot[bot] 5f83724833 Bump trim-off-newlines from 1.0.1 to 1.0.3 (#923)
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 09:56:09 +01:00
Expo CI 7df558d713 update CHANGELOG.md 2022-01-19 15:50:30 +00:00
Wojciech Kozyra 543e8ce26d v0.45.1 2022-01-19 16:31:12 +01:00
Kim Brandwijk 355fada383 add json output for started builds (#921) 2022-01-19 13:48:37 +01:00
Kim Brandwijk b6625a4cba add support for prebuildCommand in eas.json (#919) 2022-01-19 13:27:31 +01:00
Wojciech Kozyra c1ef20afab [eas-cli] add Monterey image (#922)
* [eas-cli] add Monterey image

* update CHANGELOG.md
2022-01-19 12:45:19 +01:00
Expo CI d8321e1f06 update CHANGELOG.md 2022-01-18 12:28:19 +00:00
kbrandwijk d8906e085e v0.45.0 2022-01-18 13:21:25 +01:00
Dominik Sokal 3b823865d3 upgrade dependencies (#872)
* upgrade dependencies

* fix TS error

* regenerate graphql code

* update CHANGELOG.md
2022-01-18 10:33:50 +01:00
dependabot[bot] a29ed19653 Bump follow-redirects from 1.14.3 to 1.14.7 (#912)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.3 to 1.14.7.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.3...v1.14.7)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 10:15:58 +01:00
Dominik Sokal e70ecaa9b5 upgrade axios to 0.24.0 2022-01-17 10:14:13 +01:00
dependabot[bot] 9886fcb3ef Bump shelljs from 0.8.4 to 0.8.5 (#911)
Bumps [shelljs](https://github.com/shelljs/shelljs) from 0.8.4 to 0.8.5.
- [Release notes](https://github.com/shelljs/shelljs/releases)
- [Changelog](https://github.com/shelljs/shelljs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/shelljs/shelljs/compare/v0.8.4...v0.8.5)

---
updated-dependencies:
- dependency-name: shelljs
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-17 10:09:38 +01:00
kbrandwijk 4f5739b2dc docs: update readme 2022-01-13 14:59:48 +01:00
Kim Brandwijk c7a40b06a5 delete device functionality (#890)
* feat: device delete command
2022-01-12 12:31:10 +01:00
Dominik Sokal 3f88dc8690 fix webhook:update description 2022-01-12 11:43:19 +01:00
Expo CI 874db1c125 update CHANGELOG.md 2022-01-11 20:34:32 +00:00
Brent Vatne 91a147b40b v0.44.1 2022-01-11 12:28:58 -08:00
Brent Vatne cc4553b318 [eas-cli] Only configure updates in generic projects (#904) 2022-01-11 11:52:20 -08:00
Dominik Sokal dd2303dbb2 don't use forked @oclif/plugin-autocomplete (#903)
* upgrade oclif deps

* update CHANGELOG.md
2022-01-11 14:28:49 +01:00
dependabot[bot]andDominik Sokal 967b5d9985 Bump node-forge from 0.10.0 to 1.0.0 (#902)
* Bump node-forge from 0.10.0 to 1.0.0

Bumps [node-forge](https://github.com/digitalbazaar/forge) from 0.10.0 to 1.0.0.
- [Release notes](https://github.com/digitalbazaar/forge/releases)
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/0.10.0...v1.0.0)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

* upgrade @types/node-forge

* update CHANGELOG.md

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Dominik Sokal <[email protected]>
2022-01-11 14:27:00 +01:00
Expo CI 8439cd2141 update CHANGELOG.md 2022-01-11 11:45:09 +00:00
62 changed files with 27697 additions and 28094 deletions

No files matched your search

+62 -2
View File
@@ -6,6 +6,68 @@ This is the log of notable changes to EAS CLI and related packages.
### 🛠 Breaking changes
### 🎉 New features
### 🐛 Bug fixes
- Return informative error when running `eas channel:rollout` with a channel that does not exist. ([#930](https://github.com/expo/eas-cli/pull/930) by [@jkhales](https://github.com/jkhales))
- Check if `expo-updates` is installed before publish. ([#953](https://github.com/expo/eas-cli/pull/953) by [@jkhales](https://github.com/jkhales))
### 🧹 Chores
- Upgrade dependencies. ([#946](https://github.com/expo/eas-cli/pull/946) by [@dsokal](https://github.com/dsokal))
## [0.46.0](https://github.com/expo/eas-cli/releases/tag/v0.46.0) - 2022-01-26
### 🛠 Breaking changes
- Drop support for building iOS builds on macOS Catalina. ([#939](https://github.com/expo/eas-cli/pull/939) by [@dsokal](https://github.com/dsokal))
### 🐛 Bug fixes
- Fix URL placeholder for iOS submits. ([#941](https://github.com/expo/eas-cli/pull/941) by [@dsokal](https://github.com/dsokal))
### 🧹 Chores
- Unify EAS command descriptions style. ([#925](https://github.com/expo/eas-cli/pull/925) by [@dsokal](https://github.com/dsokal))
- Upgrade dependencies. ([#939](https://github.com/expo/eas-cli/pull/939) by [@dsokal](https://github.com/dsokal))
## [0.45.1](https://github.com/expo/eas-cli/releases/tag/v0.45.1) - 2022-01-19
### 🎉 New features
- Add json output for started builds when using `--no-wait`. ([#921](https://github.com/expo/eas-cli/pull/921) by [@kbrandwijk](https://github.com/kbrandwijk))
- Add support to `eas build` for specifying a custom `prebuildCommand` in `eas.json`. ([#919](https://github.com/expo/eas-cli/pull/919) by [@kbrandwijk](https://github.com/kbrandwijk))
### 🧹 Chores
- Add macOS Monterey image. ([#922](https://github.com/expo/eas-cli/pull/922) by [@wkozyra95](https://github.com/wkozyra95))
## [0.45.0](https://github.com/expo/eas-cli/releases/tag/v0.45.0) - 2022-01-18
### 🎉 New features
- Add `eas device:delete`. ([#890](https://github.com/expo/eas-cli/pull/890) by [@kbrandwijk](https://github.com/kbrandwijk))
### 🧹 Chores
- Upgrade dependencies. ([#872](https://github.com/expo/eas-cli/pull/872) by [@dsokal](https://github.com/dsokal))
## [0.44.1](https://github.com/expo/eas-cli/releases/tag/v0.44.1) - 2022-01-11
### 🐛 Bug fixes
- Fix build:configure expo-updates configuration to only run on generic projects. ([#904](https://github.com/expo/eas-cli/pull/904) by [@brentvatne](https://github.com/brentvatne))
### 🧹 Chores
- Upgrade `node-forge` to 1.0.0. ([#902](https://github.com/expo/eas-cli/pull/902) by [@dependabot](https://github.com/apps/dependabot) + [@dsokal](https://github.com/dsokal))
- Replace `@expo/plugin-autocomplete` with `@oclif/plugin-autocomplete`. Upgrade oclif deps. ([#903](https://github.com/expo/eas-cli/pull/903) by [@dsokal](https://github.com/dsokal))
## [0.44.0](https://github.com/expo/eas-cli/releases/tag/v0.44.0) - 2022-01-11
### 🛠 Breaking changes
- No longer enable APNS (iOS Push Notifications) capability by default anymore. ([#797](https://github.com/expo/eas-cli/pull/797) by [@EvanBacon](https://github.com/EvanBacon))
- Don't configure Android projects locally. Clean up old Gradle signing config. Streamline `expo-updates` configuration. ([#888](https://github.com/expo/eas-cli/pull/888) by [@dsokal](https://github.com/dsokal))
@@ -20,8 +82,6 @@ This is the log of notable changes to EAS CLI and related packages.
- Fix creating project archive with symlink cycle. ([#891](https://github.com/expo/eas-cli/pull/891) by [@wkozyra95](https://github.com/wkozyra95))
- Sign Android debug builds with the correct keystore. Previously, all debug builds would be signed with a default debug keystore. ([#888](https://github.com/expo/eas-cli/pull/888) by [@dsokal](https://github.com/dsokal))
### 🧹 Chores
## [0.43.0](https://github.com/expo/eas-cli/releases/tag/v0.43.0) - 2022-01-03
### 🎉 New features
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.44.0"
"version": "0.47.0"
}
+9 -9
View File
@@ -17,19 +17,19 @@
"clean": "lerna run clean && rm -rf node_modules coverage"
},
"devDependencies": {
"@types/jest": "27.0.1",
"@types/jest": "27.4.0",
"@types/node": "16.7.8",
"eslint": "7.32.0",
"eslint-config-universe": "8.0.0",
"eslint": "8.8.0",
"eslint-config-universe": "10.0.0",
"eslint-plugin-async-protect": "1.1.0",
"eslint-plugin-node": "11.1.0",
"jest": "27.1.0",
"jest-watch-typeahead": "0.6.4",
"jest": "27.5.0",
"jest-watch-typeahead": "1.0.0",
"lerna": "4.0.0",
"oclif": "2.0.1",
"prettier": "2.4.1",
"ts-jest": "27.0.5",
"typescript": "4.5.2"
"oclif": "2.4.3",
"prettier": "2.5.1",
"ts-jest": "27.1.3",
"typescript": "4.5.5"
},
"volta": {
"node": "16.10.0",
+125 -110
View File
@@ -56,6 +56,7 @@ eas --help COMMAND
* [`eas config`](#eas-config)
* [`eas credentials`](#eas-credentials)
* [`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)
@@ -92,7 +93,7 @@ ALIASES
$ eas login
```
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/account/login.ts)_
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -109,7 +110,7 @@ ALIASES
$ eas logout
```
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -126,21 +127,21 @@ ALIASES
$ eas whoami
```
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/account/view.ts)_
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
view or change analytics settings
display or change analytics settings
```
USAGE
$ eas analytics [STATUS]
DESCRIPTION
view or change analytics settings
display or change analytics settings
```
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/analytics.ts)_
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -169,11 +170,11 @@ EXAMPLES
$ eas autocomplete --refresh-cache
```
_See code: [@expo/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.0.2/src/commands/autocomplete/index.ts)_
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.2.0/src/commands/autocomplete/index.ts)_
## `eas branch:create [NAME]`
Create a branch on the current project.
create a branch
```
USAGE
@@ -186,14 +187,14 @@ FLAGS
--json return a json with the new branch ID and name.
DESCRIPTION
Create a branch on the current project.
create a branch
```
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
Delete a branch on the current project
delete a branch
```
USAGE
@@ -206,14 +207,14 @@ FLAGS
--json return JSON with the edited branch's ID and name.
DESCRIPTION
Delete a branch on the current project
delete a branch
```
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
List all branches on this project.
list all branches
```
USAGE
@@ -223,14 +224,14 @@ FLAGS
--json return output as JSON
DESCRIPTION
List all branches on this project.
list all branches
```
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
Rename a branch.
rename a branch
```
USAGE
@@ -242,14 +243,14 @@ FLAGS
--to=<value> new name of the branch.
DESCRIPTION
Rename a branch.
rename a branch
```
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
View a branch.
view a branch
```
USAGE
@@ -262,14 +263,14 @@ FLAGS
--json return a json with the branch's ID name and recent update groups.
DESCRIPTION
View a branch.
view a branch
```
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
Start a build
start a build
```
USAGE
@@ -293,28 +294,28 @@ FLAGS
--[no-]wait Wait for build(s) to complete
DESCRIPTION
Start a build
start a build
```
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/build/index.ts)_
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
Cancel a build.
cancel a build
```
USAGE
$ eas build:cancel [BUILD_ID]
DESCRIPTION
Cancel a build.
cancel a build
```
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
Configure the project to support EAS Build.
configure the project to support EAS Build
```
USAGE
@@ -324,14 +325,14 @@ FLAGS
-p, --platform=(android|ios|all) Platform to configure
DESCRIPTION
Configure the project to support EAS Build.
configure the project to support EAS Build
```
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:inspect`
Inspect the state of the project at specific build stages. Useful for troubleshooting.
inspect the state of the project at specific build stages, useful for troubleshooting
```
USAGE
@@ -359,10 +360,10 @@ FLAGS
Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.
DESCRIPTION
Inspect the state of the project at specific build stages. Useful for troubleshooting.
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/v0.44.0/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -395,7 +396,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/build/list.ts)_
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:view [BUILD_ID]`
@@ -412,11 +413,11 @@ DESCRIPTION
view a build for your project
```
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/build/view.ts)_
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
Create a channel on the current project.
create a channel
```
USAGE
@@ -429,14 +430,14 @@ FLAGS
--json print output as a JSON object with the new channel ID, name and branch mapping.
DESCRIPTION
Create a channel on the current project.
create a channel
```
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
Point a channel at a new branch.
point a channel at a new branch
```
USAGE
@@ -447,17 +448,17 @@ ARGUMENTS
FLAGS
--branch=<value> Name of the branch to point to
--json print output as a JSON object with the channel ID, name and branch mapping.
--json Print output as a JSON object with the channel ID, name and branch mapping
DESCRIPTION
Point a channel at a new branch.
point a channel at a new branch
```
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
List all channels on the current project.
list all channels
```
USAGE
@@ -467,14 +468,14 @@ FLAGS
--json print output as a JSON object with the channel ID, name and branch mapping.
DESCRIPTION
List all channels on the current project.
list all channels
```
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:view [NAME]`
View a channel on the current project.
view a channel
```
USAGE
@@ -487,14 +488,14 @@ FLAGS
--json print output as a JSON object with the channel ID, name and branch mapping.
DESCRIPTION
View a channel on the current project.
view a channel
```
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
show the eas.json config
display project configuration (app.json + eas.json)
```
USAGE
@@ -505,24 +506,24 @@ FLAGS
--profile=<value>
DESCRIPTION
show the eas.json config
display project configuration (app.json + eas.json)
```
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
manage your credentials
manage credentials
```
USAGE
$ eas credentials
DESCRIPTION
manage your credentials
manage credentials
```
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/credentials.ts)_
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/credentials.ts)_
## `eas device:create`
@@ -536,7 +537,25 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/device/create.ts)_
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
remove a registered device from your account
```
USAGE
$ eas device:delete [--apple-team-id <value>] [--udid <value>]
FLAGS
--apple-team-id=<value>
--udid=<value>...
DESCRIPTION
remove a registered device from your account
```
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -553,7 +572,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/device/list.ts)_
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:view [UDID]`
@@ -567,21 +586,21 @@ DESCRIPTION
view a device for your project
```
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/device/view.ts)_
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
log environment info to the console
display environment info
```
USAGE
$ eas diagnostics
DESCRIPTION
log environment info to the console
display environment info
```
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -601,7 +620,7 @@ DESCRIPTION
Display help for eas.
```
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.10/src/commands/help.ts)_
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.11/src/commands/help.ts)_
## `eas project:info`
@@ -615,7 +634,7 @@ DESCRIPTION
information about the current project
```
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/project/info.ts)_
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -632,11 +651,11 @@ ALIASES
$ eas init
```
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/project/init.ts)_
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas secret:create`
Create an environment secret on the current project or owner account.
create an environment secret on the current project or owner account
```
USAGE
@@ -649,14 +668,14 @@ FLAGS
--value=<value> Value of the secret
DESCRIPTION
Create an environment secret on the current project or owner account.
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/v0.44.0/packages/eas-cli/src/commands/secret/create.ts)_
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/secret/create.ts)_
## `eas secret:delete`
Delete an environment secret by ID.
delete an environment secret by ID
```
USAGE
@@ -666,30 +685,28 @@ FLAGS
--id=<value> ID of the secret to delete
DESCRIPTION
Delete an environment secret by ID.
Unsure where to find the secret's ID? Run eas secret:list
delete an environment secret by ID
```
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/secret/delete.ts)_
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/secret/delete.ts)_
## `eas secret:list`
Lists environment secrets available for your current app
list environment secrets available for your current app
```
USAGE
$ eas secret:list
DESCRIPTION
Lists environment secrets available for your current app
list environment secrets available for your current app
```
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/secret/list.ts)_
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/secret/list.ts)_
## `eas submit`
Submit build archive to App Store Connect
submit app binary to app store
```
USAGE
@@ -709,19 +726,17 @@ FLAGS
--[no-]wait Wait for submission to complete
DESCRIPTION
Submit build archive to App Store Connect
See how to configure submits with eas.json: https://docs.expo.dev/submit/eas-json/
submit app binary to app store
ALIASES
$ eas build:submit
```
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/submit.ts)_
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
Publish an update group.
publish an update group
```
USAGE
@@ -740,28 +755,28 @@ FLAGS
--skip-bundler Skip running Expo CLI to bundle the app before publishing
DESCRIPTION
Publish an update group.
publish an update group
```
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/update/index.ts)_
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
Configure the project to support EAS Update.
configure the project to support EAS Update
```
USAGE
$ eas update:configure
DESCRIPTION
Configure the project to support EAS Update.
configure the project to support EAS Update
```
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
Delete all the updates in an update Group.
delete all the updates in an update group
```
USAGE
@@ -774,14 +789,14 @@ FLAGS
--json Return a json with the group ID of the deleted updates.
DESCRIPTION
Delete all the updates in an update Group.
delete all the updates in an update group
```
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:list`
View the recent updates for a branch
view the recent updates for a branch
```
USAGE
@@ -793,14 +808,14 @@ FLAGS
--json Return a json with all of the recent update groups.
DESCRIPTION
View the recent updates for a branch
view the recent updates for a branch
```
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/update/list.ts)_
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:view GROUPID`
Update group details.
update group details
```
USAGE
@@ -813,14 +828,14 @@ FLAGS
--json Return a json with the updates belonging to the group.
DESCRIPTION
Update group details.
update group details
```
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/update/view.ts)_
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
Create a webhook on the current project.
create a webhook
```
USAGE
@@ -833,14 +848,14 @@ FLAGS
--url=<value> Webhook URL
DESCRIPTION
Create a webhook on the current project.
create a webhook
```
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
Delete a webhook on the current project.
delete a webhook
```
USAGE
@@ -850,14 +865,14 @@ ARGUMENTS
ID ID of the webhook to delete
DESCRIPTION
Delete a webhook on the current project.
delete a webhook
```
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
List webhooks on the current project.
list webhooks
```
USAGE
@@ -867,14 +882,14 @@ FLAGS
--event=(BUILD|SUBMIT) Event type that triggers the webhook
DESCRIPTION
List webhooks on the current project.
list webhooks
```
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
Create a webhook on the current project.
update a webhook
```
USAGE
@@ -888,14 +903,14 @@ FLAGS
--url=<value> Webhook URL
DESCRIPTION
Create a webhook on the current project.
update a webhook
```
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
View a webhook on the current project.
view a webhook
```
USAGE
@@ -905,8 +920,8 @@ ARGUMENTS
ID ID of the webhook to view
DESCRIPTION
View a webhook on the current project.
view a webhook
```
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.44.0/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.47.0/packages/eas-cli/src/commands/webhook/view.ts)_
<!-- commandsstop -->
+20507 -20291
View File
File diff suppressed because it is too large. Load diff
+53 -51
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "0.44.0",
"version": "0.47.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -9,53 +9,53 @@
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/apple-utils": "0.0.0-alpha.27",
"@expo/config": "6.0.11",
"@expo/config-plugins": "4.0.11",
"@expo/eas-build-job": "0.2.61",
"@expo/eas-json": "0.44.0",
"@expo/config": "6.0.16",
"@expo/config-plugins": "4.0.16",
"@expo/eas-build-job": "0.2.65",
"@expo/eas-json": "0.47.0",
"@expo/json-file": "8.2.34",
"@expo/pkcs12": "0.0.6",
"@expo/plist": "0.0.16",
"@expo/plugin-autocomplete": "1.0.2",
"@expo/plugin-warn-if-update-available": "2.0.1",
"@expo/prebuild-config": "3.0.11",
"@expo/plist": "0.0.17",
"@expo/plugin-warn-if-update-available": "2.1.0",
"@expo/prebuild-config": "3.0.16",
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.5.0",
"@expo/spawn-async": "1.6.0",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "1.0.10",
"@oclif/plugin-help": "5.1.10",
"@urql/core": "2.3.1",
"@urql/exchange-retry": "0.3.0",
"@oclif/core": "1.3.1",
"@oclif/plugin-autocomplete": "1.2.0",
"@oclif/plugin-help": "5.1.11",
"@urql/core": "2.4.1",
"@urql/exchange-retry": "0.3.2",
"chalk": "4.1.2",
"cli-table3": "0.6.0",
"dateformat": "4.5.1",
"cli-table3": "0.6.1",
"dateformat": "4.6.3",
"env-paths": "2.2.0",
"envinfo": "7.8.1",
"fast-glob": "3.2.7",
"fast-glob": "3.2.11",
"figures": "3.2.0",
"form-data": "3.0.0",
"form-data": "4.0.0",
"fs-extra": "10.0.0",
"getenv": "1.0.0",
"got": "11.8.2",
"gradle-to-js": "2.0.0",
"graphql": "15.5.1",
"graphql-tag": "2.12.5",
"ignore": "5.1.8",
"graphql": "16.3.0",
"graphql-tag": "2.12.6",
"ignore": "5.2.0",
"indent-string": "4.0.0",
"jks-js": "1.0.1",
"joi": "17.4.2",
"jks-js": "1.0.2",
"joi": "17.6.0",
"keychain": "1.3.0",
"log-symbols": "4.1.0",
"mime": "2.5.2",
"minimatch": "3.0.4",
"nanoid": "3.1.25",
"node-fetch": "2.6.1",
"node-forge": "0.10.0",
"mime": "3.0.0",
"minimatch": "3.0.5",
"nanoid": "3.2.0",
"node-fetch": "2.6.7",
"node-forge": "1.2.1",
"nullthrows": "1.1.1",
"ora": "5.1.0",
"pkg-dir": "4.2.0",
"prompts": "2.3.2",
"prompts": "2.4.2",
"qrcode-terminal": "0.12.0",
"resolve-from": "5.0.0",
"semver": "7.3.5",
@@ -70,32 +70,31 @@
"wrap-ansi": "7.0.0"
},
"devDependencies": {
"@graphql-codegen/cli": "^1.19.2",
"@graphql-codegen/introspection": "^1.18.0",
"@graphql-codegen/typescript": "^1.17.11",
"@graphql-codegen/typescript-operations": "^1.17.10",
"@graphql-codegen/cli": "2.5.0",
"@graphql-codegen/introspection": "2.1.1",
"@graphql-codegen/typescript": "2.4.3",
"@graphql-codegen/typescript-operations": "2.2.4",
"@types/dateformat": "3.0.1",
"@types/envinfo": "7.8.1",
"@types/form-data": "^2.5.0",
"@types/fs-extra": "9.0.12",
"@types/fs-extra": "9.0.13",
"@types/getenv": "^1.0.0",
"@types/mime": "2.0.3",
"@types/node-fetch": "^2.5.7",
"@types/node-forge": "^0.9.5",
"@types/prompts": "^2.0.9",
"@types/semver": "7.3.8",
"@types/tar": "4.0.5",
"@types/node-forge": "1.0.0",
"@types/prompts": "2.0.14",
"@types/semver": "7.3.9",
"@types/tar": "6.1.1",
"@types/tough-cookie": "4.0.1",
"@types/uuid": "8.3.1",
"@types/uuid": "8.3.4",
"@types/wrap-ansi": "3.0.0",
"axios": "0.21.4",
"axios": "0.25.0",
"eslint-plugin-graphql": "4.0.0",
"memfs": "3.2.2",
"mockdate": "^3.0.2",
"nock": "^13.0.5",
"memfs": "3.4.1",
"mockdate": "3.0.5",
"nock": "13.2.4",
"tempy": "0.7.0",
"ts-deepmerge": "1.0.8",
"typescript": "4.5.2"
"ts-deepmerge": "2.0.1",
"typescript": "4.5.5"
},
"engines": {
"node": ">=12.0.0"
@@ -116,13 +115,16 @@
"bin": "eas",
"commands": "./build/commands",
"plugins": [
"@oclif/plugin-autocomplete",
"@oclif/plugin-help",
"@expo/plugin-warn-if-update-available",
"@expo/plugin-autocomplete"
"@expo/plugin-warn-if-update-available"
],
"topics": {
"account": {
"description": "manage your account"
"description": "manage account"
},
"branch": {
"description": "manage update branches"
},
"build": {
"description": "build app binaries"
@@ -131,10 +133,10 @@
"description": "manage update channels"
},
"device": {
"description": "manage your Apple devices for internal distribution"
"description": "manage Apple devices for Internal Distribution"
},
"project": {
"description": "manage your project"
"description": "manage project"
},
"release": {
"description": "manage update releases"
@@ -18,6 +18,7 @@ export function transformJob(job: Android.Job): AndroidJobInput {
username: job.username,
buildType: job.buildType && transformBuildType(job.buildType),
developmentClient: job.developmentClient,
experimental: job.experimental,
};
}
@@ -75,6 +75,9 @@ export async function prepareJobAsync(
artifactPath: buildProfile.artifactPath,
buildType,
username,
experimental: {
prebuildCommand: ctx.buildProfile.prebuildCommand,
},
};
return sanitizeJob(job);
@@ -7,8 +7,8 @@ import fs from 'fs-extra';
import path from 'path';
import Log from '../../log';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { isExpoUpdatesInstalled } from '../utils/updates';
import { syncUpdatesConfigurationAsync } from './UpdatesModule';
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
@@ -20,6 +20,7 @@ export function transformJob(job: Ios.Job): IosJobInput {
username: job.username,
developmentClient: job.developmentClient,
simulator: job.simulator,
experimental: job.experimental,
};
}
@@ -66,6 +66,9 @@ export async function prepareJobAsync(
buildConfiguration: ctx.buildProfile.buildConfiguration,
artifactPath: ctx.buildProfile.artifactPath,
username,
experimental: {
prebuildCommand: ctx.buildProfile.prebuildCommand,
},
};
return sanitizeJob(job);
}
@@ -3,8 +3,8 @@ import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile, IosVersionAutoIncrement } from '@expo/eas-json';
import type { XCBuildConfiguration } from 'xcode';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { isExpoUpdatesInstalled } from '../utils/updates';
import { syncUpdatesConfigurationAsync } from './UpdatesModule';
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
+1 -1
View File
@@ -6,7 +6,7 @@ import semver from 'semver';
import { ora } from '../ora';
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
const PLUGIN_PACKAGE_VERSION = '0.0.58';
const PLUGIN_PACKAGE_VERSION = '0.0.62';
export interface LocalBuildOptions {
enable: boolean;
+1 -2
View File
@@ -5,7 +5,7 @@ import fs from 'fs-extra';
import resolveFrom from 'resolve-from';
import Log from '../log';
import { getUsername } from '../project/projectUtils';
import { getUsername, isExpoUpdatesInstalled } from '../project/projectUtils';
import { ensureLoggedInAsync } from '../user/actions';
import { easCliVersion } from '../utils/easCli';
import { getVcsClient } from '../vcs';
@@ -20,7 +20,6 @@ import {
readReleaseChannelSafelyAsync as readIosReleaseChannelSafelyAsync,
} from './ios/UpdatesModule';
import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios/version';
import { isExpoUpdatesInstalled } from './utils/updates';
// TODO(JJ): Replace this with the getRuntimeVersionNullable function in @expo/config-plugins
function getRuntimeVersionNullable(
@@ -20,6 +20,7 @@ import {
waitToCompleteAsync as waitForSubmissionsToCompleteAsync,
} from '../submit/submit';
import { printSubmissionDetailsUrls } from '../submit/utils/urls';
import { printJsonOnlyOutput } from '../utils/json';
import { ProfileData, getProfilesAsync } from '../utils/profiles';
import { getVcsClient } from '../vcs';
import { prepareAndroidBuildAsync } from './android/build';
@@ -130,6 +131,9 @@ export async function runBuildAndSubmitAsync(projectDir: string, flags: BuildFla
}
if (!flags.wait) {
if (flags.json) {
printJsonOnlyOutput(startedBuilds.map(buildInfo => buildInfo.build));
}
return;
}
+1 -6
View File
@@ -1,9 +1,4 @@
import { ExpoConfig, getPackageJson } from '@expo/config';
export function isExpoUpdatesInstalled(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.dependencies && 'expo-updates' in packageJson.dependencies);
}
import { ExpoConfig } from '@expo/config';
export function ensureValidVersions(exp: ExpoConfig): void {
if (!exp.runtimeVersion && !exp.sdkVersion) {
+1 -1
View File
@@ -3,7 +3,7 @@ import Log from '../log';
import UserSettings from '../user/UserSettings';
export default class AnalyticsView extends EasCommand {
static description = 'view or change analytics settings';
static description = 'display or change analytics settings';
static args = [{ name: 'STATUS', options: ['on', 'off'] }];
@@ -52,7 +52,7 @@ export async function createUpdateBranchOnAppAsync({
}
export default class BranchCreate extends EasCommand {
static description = 'Create a branch on the current project.';
static description = 'create a branch';
static args = [
{
@@ -77,7 +77,7 @@ async function deleteBranchOnAppAsync({
}
export default class BranchDelete extends EasCommand {
static description = 'Delete a branch on the current project';
static description = 'delete a branch';
static args = [
{
+1 -1
View File
@@ -55,7 +55,7 @@ export async function listBranchesAsync({
}
export default class BranchList extends EasCommand {
static description = 'List all branches on this project.';
static description = 'list all branches';
static flags = {
json: Flags.boolean({
@@ -52,7 +52,7 @@ async function renameUpdateBranchOnAppAsync({
}
export default class BranchRename extends EasCommand {
static description = 'Rename a branch.';
static description = 'rename a branch';
static flags = {
from: Flags.string({
+1 -1
View File
@@ -14,7 +14,7 @@ import formatFields from '../../utils/formatFields';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class BranchView extends EasCommand {
static description = 'View a branch.';
static description = 'view a branch';
static args = [
{
@@ -110,7 +110,7 @@ async function ensureBuildExistsAsync(buildId: string): Promise<void> {
}
export default class BuildCancel extends EasCommand {
static description = 'Cancel a build.';
static description = 'cancel a build';
static args = [{ name: 'BUILD_ID' }];
@@ -1,4 +1,5 @@
import { getConfig } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
@@ -6,16 +7,16 @@ import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync }
import { cleanUpOldEasBuildGradleScriptAsync } from '../../build/android/syncProjectConfiguration';
import { ensureProjectConfiguredAsync } from '../../build/configure';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from '../../build/ios/UpdatesModule';
import { isExpoUpdatesInstalled } from '../../build/utils/updates';
import EasCommand from '../../commandUtils/EasCommand';
import Log, { learnMore } from '../../log';
import { RequestedPlatform } from '../../platform';
import { findProjectRootAsync } from '../../project/projectUtils';
import { findProjectRootAsync, isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync } from '../../prompts';
import { getVcsClient } from '../../vcs';
export default class BuildConfigure extends EasCommand {
static description = 'Configure the project to support EAS Build.';
static description = 'configure the project to support EAS Build';
static flags = {
platform: Flags.enum({
@@ -57,11 +58,17 @@ export default class BuildConfigure extends EasCommand {
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
if ([RequestedPlatform.Android, RequestedPlatform.All].includes(platform)) {
await syncAndroidUpdatesConfigurationAsync(projectDir, exp);
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID);
if (workflow === Workflow.GENERIC) {
await syncAndroidUpdatesConfigurationAsync(projectDir, exp);
}
}
if ([RequestedPlatform.Ios, RequestedPlatform.All].includes(platform)) {
await syncIosUpdatesConfigurationAsync(projectDir, exp);
const workflow = await resolveWorkflowAsync(projectDir, Platform.IOS);
if (workflow === Workflow.GENERIC) {
await syncIosUpdatesConfigurationAsync(projectDir, exp);
}
}
}
+1 -1
View File
@@ -33,7 +33,7 @@ interface RawBuildFlags {
}
export default class Build extends EasCommand {
static description = 'Start a build';
static description = 'start a build';
static flags = {
platform: Flags.enum({
@@ -26,7 +26,7 @@ const STAGE_DESCRIPTION = `Stage of the build you want to inspect.
export default class BuildInspect extends EasCommand {
static description =
'Inspect the state of the project at specific build stages. Useful for troubleshooting.';
'inspect the state of the project at specific build stages, useful for troubleshooting';
static flags = {
platform: Flags.enum({
@@ -9,10 +9,10 @@ import {
CreateUpdateChannelOnAppMutation,
CreateUpdateChannelOnAppMutationVariables,
} from '../../graphql/generated';
import { BranchQuery } from '../../graphql/queries/BranchQuery';
import Log from '../../log';
import {
findProjectRootAsync,
getBranchByNameAsync,
getProjectFullNameAsync,
getProjectIdAsync,
} from '../../project/projectUtils';
@@ -60,7 +60,7 @@ export async function createUpdateChannelOnAppAsync({
}
export default class ChannelCreate extends EasCommand {
static description = 'Create a channel on the current project.';
static description = 'create a channel';
static args = [
{
@@ -106,14 +106,15 @@ export default class ChannelCreate extends EasCommand {
let branchId: string;
let branchMessage: string;
try {
const existingBranch = await getBranchByNameAsync({
appId: projectId,
name: channelName,
});
const existingBranch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: channelName,
});
if (existingBranch) {
branchId = existingBranch.id;
branchMessage = `We found a branch with the same name`;
} catch (e) {
} else {
const newBranch = await createUpdateBranchOnAppAsync({
appId: projectId,
name: channelName,
@@ -22,7 +22,7 @@ import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class ChannelDelete extends EasCommand {
static hidden = true;
static description = 'Delete a channel on the current project';
static description = 'Delete a channel';
static args = [
{
@@ -33,7 +33,7 @@ export default class ChannelDelete extends EasCommand {
];
static flags = {
json: Flags.boolean({
description: `Delete a channel on the current project`,
description: 'print output as a JSON object',
default: false,
}),
'non-interactive': Flags.boolean({
+42 -38
View File
@@ -13,12 +13,9 @@ import {
UpdateChannelBranchMappingMutation,
UpdateChannelBranchMappingMutationVariables,
} from '../../graphql/generated';
import { BranchQuery } from '../../graphql/queries/BranchQuery';
import Log from '../../log';
import {
findProjectRootAsync,
getBranchByNameAsync,
getProjectIdAsync,
} from '../../project/projectUtils';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import { promptAsync } from '../../prompts';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
@@ -96,7 +93,7 @@ export async function updateChannelBranchMappingAsync({
}
export default class ChannelEdit extends EasCommand {
static description = 'Point a channel at a new branch.';
static description = 'point a channel at a new branch';
static args = [
{
@@ -111,17 +108,14 @@ export default class ChannelEdit extends EasCommand {
description: 'Name of the branch to point to',
}),
json: Flags.boolean({
description: 'print output as a JSON object with the channel ID, name and branch mapping.',
description: 'Print output as a JSON object with the channel ID, name and branch mapping',
default: false,
}),
};
async runAsync(): Promise<void> {
let {
args: { name: channelName },
flags: { branch: branchName, json: jsonFlag },
} = await this.parse(ChannelEdit);
if (jsonFlag) {
const { args, flags } = await this.parse(ChannelEdit);
if (flags.json) {
enableJsonOutput();
}
@@ -129,18 +123,7 @@ export default class ChannelEdit extends EasCommand {
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
const projectId = await getProjectIdAsync(exp);
if (!channelName) {
const validationMessage = 'A channel name is required to edit a specific channel.';
if (jsonFlag) {
throw new Error(validationMessage);
}
({ name: channelName } = await promptAsync({
type: 'text',
name: 'name',
message: 'Please enter the name of the channel to edit:',
validate: value => (value ? true : validationMessage),
}));
}
const channelName = args.name ?? (await promptForChannelAsync());
const existingChannel = await getChannelByNameForAppAsync({ appId: projectId, channelName });
if (existingChannel.updateBranches.length > 1) {
@@ -149,20 +132,19 @@ export default class ChannelEdit extends EasCommand {
);
}
if (!branchName) {
const validationMessage = 'branch name may not be empty.';
if (jsonFlag) {
throw new Error(validationMessage);
}
({ name: branchName } = await promptAsync({
type: 'text',
name: 'name',
message: chalk`What branch should it change to?`,
validate: value => (value ? true : validationMessage),
}));
}
const branchName = flags.branch ?? (await promptForBranchAsync());
const branch = await getBranchByNameAsync({ appId: projectId, name: branchName! });
const branch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: branchName,
});
if (!branch) {
throw new Error(
`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk.bold(
'eas branch:list'
)}.`
);
}
const channel = await updateChannelBranchMappingAsync({
channelId: existingChannel.id,
// todo: move branch mapping logic to utility
@@ -172,7 +154,7 @@ export default class ChannelEdit extends EasCommand {
}),
});
if (jsonFlag) {
if (flags.json) {
printJsonOnlyOutput(channel);
} else {
Log.withTick(
@@ -185,3 +167,25 @@ export default class ChannelEdit extends EasCommand {
}
}
}
async function promptForChannelAsync(): Promise<string> {
Log.addNewLineIfNone();
const { name } = await promptAsync({
type: 'text',
name: 'name',
message: 'Please enter the name of the channel to edit:',
validate: value => (value ? true : 'The channel name may not be empty.'),
});
return name;
}
async function promptForBranchAsync(): Promise<string> {
Log.addNewLineIfNone();
const { name } = await promptAsync({
type: 'text',
name: 'name',
message: `To which branch should the channel link?`,
validate: value => (value ? true : 'The branch name may not be empty.'),
});
return name;
}
@@ -67,7 +67,7 @@ async function getAllUpdateChannelForAppAsync({
}
export default class ChannelList extends EasCommand {
static description = 'List all channels on the current project.';
static description = 'list all channels';
static flags = {
json: Flags.boolean({
@@ -4,17 +4,18 @@ import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
import { GetChannelByNameForAppQuery, UpdateBranch } from '../../graphql/generated';
import { BranchQuery } from '../../graphql/queries/BranchQuery';
import { ChannelQuery } from '../../graphql/queries/ChannelQuery';
import Log from '../../log';
import {
findProjectRootAsync,
getBranchByNameAsync,
getProjectFullNameAsync,
getProjectIdAsync,
} from '../../project/projectUtils';
import { promptAsync, selectAsync } from '../../prompts';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
import { updateChannelBranchMappingAsync } from './edit';
import { BranchMapping, getBranchMapping, getUpdateChannelByNameForAppAsync } from './view';
import { BranchMapping, getBranchMapping } from './view';
async function promptForRolloutPercentAsync({
promptMessage,
@@ -39,28 +40,20 @@ async function promptForRolloutPercentAsync({
return rolloutPercent;
}
function getRolloutInfo(getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery): {
function getRolloutInfo(
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>
): {
newBranch: Pick<UpdateBranch, 'name' | 'id'>;
oldBranch: Pick<UpdateBranch, 'name' | 'id'>;
currentPercent: number;
} {
const { branchMapping } = getBranchMapping(
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.branchMapping
);
const { branchMapping } = getBranchMapping(channel.branchMapping);
const [newBranchId, oldBranchId] = branchMapping.data.map(d => d.branchId);
const newBranch =
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.updateBranches.filter(
branch => branch.id === newBranchId
)[0];
const oldBranch =
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.updateBranches.filter(
branch => branch.id === oldBranchId
)[0];
const newBranch = channel.updateBranches.filter(branch => branch.id === newBranchId)[0];
const oldBranch = channel.updateBranches.filter(branch => branch.id === oldBranchId)[0];
if (!newBranch || !oldBranch) {
throw new Error(
`Branch mapping rollout is missing a branch for channel "${getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.name}".`
);
throw new Error(`Branch mapping rollout is missing a branch for channel "${channel.name}".`);
}
const currentPercent = 100 * branchMapping.data[0].branchMappingLogic.operand;
@@ -75,16 +68,16 @@ async function startRolloutAsync({
projectId,
fullName,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
}: {
channelName?: string;
branchName?: string;
branchName: string;
percent?: number;
jsonFlag: boolean;
projectId: string;
fullName: string;
currentBranchMapping: BranchMapping;
getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery;
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
}): Promise<{
newChannelInfo: {
id: string;
@@ -93,19 +86,18 @@ async function startRolloutAsync({
};
logMessage: string;
}> {
if (!branchName) {
const validationMessage = 'A branch must be specified.';
if (jsonFlag) {
throw new Error(validationMessage);
}
({ name: branchName } = await promptAsync({
type: 'text',
name: 'name',
message: `Select a branch to rollout onto ${channelName}`,
validate: value => (value ? true : validationMessage),
}));
const branch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: branchName,
});
if (!branch) {
throw new Error(
`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk.bold(
'eas branch:list'
)}.`
);
}
const branch = await getBranchByNameAsync({ appId: projectId, name: branchName! });
const oldBranchId = currentBranchMapping.data[0].branchId;
if (branch.id === oldBranchId) {
throw new Error(
@@ -138,14 +130,11 @@ async function startRolloutAsync({
],
};
const newChannelInfo = await updateChannelBranchMappingAsync({
channelId: getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.id!,
channelId: channel.id,
branchMapping: JSON.stringify(newBranchMapping),
});
const oldBranch =
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.updateBranches.filter(
branch => branch.id === oldBranchId
)[0];
const oldBranch = channel.updateBranches.filter(branch => branch.id === oldBranchId)[0];
if (!oldBranch) {
throw new Error(
`Branch mapping is missing its only branch for channel "${channelName}" on app "${fullName}"`
@@ -168,13 +157,13 @@ async function editRolloutAsync({
percent,
jsonFlag,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
}: {
channelName?: string;
percent?: number;
jsonFlag: boolean;
currentBranchMapping: BranchMapping;
getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery;
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
}): Promise<{
newChannelInfo: {
id: string;
@@ -183,9 +172,7 @@ async function editRolloutAsync({
};
logMessage: string;
}> {
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(
getUpdateChannelByNameForAppResult
);
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
if (percent == null) {
if (jsonFlag) {
@@ -205,7 +192,7 @@ async function editRolloutAsync({
newBranchMapping.data[0].branchMappingLogic.operand = percent / 100;
const newChannelInfo = await updateChannelBranchMappingAsync({
channelId: getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.id!,
channelId: channel.id,
branchMapping: JSON.stringify(newBranchMapping),
});
@@ -225,13 +212,13 @@ async function endRolloutAsync({
branchName,
jsonFlag,
projectId,
getUpdateChannelByNameForAppResult,
channel,
}: {
channelName?: string;
branchName?: string;
jsonFlag: boolean;
projectId: string;
getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery;
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
}): Promise<{
newChannelInfo: {
id: string;
@@ -241,13 +228,22 @@ async function endRolloutAsync({
logMessage: string;
}> {
// end rollout
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(
getUpdateChannelByNameForAppResult
);
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
let endOnNewBranch;
if (branchName) {
const branch = await getBranchByNameAsync({ appId: projectId, name: branchName! });
const branch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: branchName,
});
if (!branch) {
throw new Error(
`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk.bold(
'eas branch:list'
)}.`
);
}
switch (branch.id) {
case newBranch.id:
endOnNewBranch = true;
@@ -295,7 +291,7 @@ async function endRolloutAsync({
};
const newChannelInfo = await updateChannelBranchMappingAsync({
channelId: getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.id!,
channelId: channel.id,
branchMapping: JSON.stringify(newBranchMapping),
});
const logMessage = `️Rollout on channel ${chalk.bold(
@@ -352,12 +348,20 @@ export default class ChannelRollout extends EasCommand {
const fullName = await getProjectFullNameAsync(exp);
const projectId = await getProjectIdAsync(exp);
const getUpdateChannelByNameForAppResult = await getUpdateChannelByNameForAppAsync({
const channel = await ChannelQuery.getUpdateChannelByNameForAppAsync({
appId: projectId,
channelName: channelName!,
});
if (!channel) {
throw new Error(
`Could not find a channel named "${channelName}". Please check what channels exist on this project with ${chalk.bold(
'eas channel:list'
)}.`
);
}
const { branchMapping: currentBranchMapping, isRollout } = getBranchMapping(
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.branchMapping
channel.branchMapping
);
if (currentBranchMapping.data.length === 0) {
@@ -391,13 +395,13 @@ export default class ChannelRollout extends EasCommand {
if (!isRollout) {
rolloutMutationResult = await startRolloutAsync({
channelName,
branchName,
branchName: branchName ?? (await promptForBranchNameAsync(channelName)),
percent,
jsonFlag,
projectId,
fullName,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
});
} else if (endFlag) {
rolloutMutationResult = await endRolloutAsync({
@@ -405,7 +409,7 @@ export default class ChannelRollout extends EasCommand {
branchName,
jsonFlag,
projectId,
getUpdateChannelByNameForAppResult,
channel,
});
} else {
rolloutMutationResult = await editRolloutAsync({
@@ -413,7 +417,7 @@ export default class ChannelRollout extends EasCommand {
percent,
jsonFlag,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
});
}
if (!rolloutMutationResult) {
@@ -427,3 +431,13 @@ export default class ChannelRollout extends EasCommand {
}
}
}
async function promptForBranchNameAsync(channelName: string): Promise<string> {
const { name } = await promptAsync({
type: 'text',
name: 'name',
message: `Select a branch to rollout onto ${channelName}`,
validate: value => (value ? true : 'A branch must be specified.'),
});
return name;
}
+3 -59
View File
@@ -3,14 +3,9 @@ import { Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import Table from 'cli-table3';
import gql from 'graphql-tag';
import EasCommand from '../../commandUtils/EasCommand';
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
import {
GetChannelByNameForAppQuery,
GetChannelByNameForAppQueryVariables,
} from '../../graphql/generated';
import { ChannelQuery } from '../../graphql/queries/ChannelQuery';
import Log from '../../log';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import { promptAsync } from '../../prompts';
@@ -91,56 +86,6 @@ export function getBranchMapping(branchMappingString?: string): {
return { branchMapping, isRollout, rolloutPercent };
}
export async function getUpdateChannelByNameForAppAsync({
appId,
channelName,
}: GetChannelByNameForAppQueryVariables): Promise<GetChannelByNameForAppQuery> {
return await withErrorHandlingAsync(
graphqlClient
.query<GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables>(
gql`
query GetChannelByNameForApp($appId: String!, $channelName: String!) {
app {
byId(appId: $appId) {
id
updateChannelByName(name: $channelName) {
id
name
createdAt
branchMapping
updateBranches(offset: 0, limit: 1000) {
id
name
updates(offset: 0, limit: 10) {
id
group
message
runtimeVersion
createdAt
platform
actor {
id
... on User {
username
}
... on Robot {
firstName
}
}
}
}
}
}
}
}
`,
{ appId, channelName },
{ additionalTypenames: ['UpdateChannel', 'UpdateBranch', 'Update'] }
)
.toPromise()
);
}
export function logChannelDetails(channel: {
branchMapping: string;
updateBranches: {
@@ -193,7 +138,7 @@ export function logChannelDetails(channel: {
}
export default class ChannelView extends EasCommand {
static description = 'View a channel on the current project.';
static description = 'view a channel';
static args = [
{
@@ -236,11 +181,10 @@ export default class ChannelView extends EasCommand {
}));
}
const getUpdateChannelByNameForAppresult = await getUpdateChannelByNameForAppAsync({
const channel = await ChannelQuery.getUpdateChannelByNameForAppAsync({
appId: projectId,
channelName,
});
const channel = getUpdateChannelByNameForAppresult.app?.byId.updateChannelByName;
if (!channel) {
throw new Error(`Could not find a channel with name: ${channelName}`);
}
+9 -3
View File
@@ -2,16 +2,19 @@ import { getProjectConfigDescription } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { EasJsonReader } from '@expo/eas-json';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../commandUtils/EasCommand';
import { toAppPlatform } from '../graphql/types/AppPlatform';
import Log from '../log';
import { appPlatformEmojis } from '../platform';
import { getExpoConfig } from '../project/expoConfig';
import { findProjectRootAsync } from '../project/projectUtils';
import { selectAsync } from '../prompts';
import { handleDeprecatedEasJsonAsync } from './build';
export default class Config extends EasCommand {
static description = 'show the eas.json config';
static description = 'display project configuration (app.json + eas.json)';
static flags = {
platform: Flags.enum({ char: 'p', options: ['android', 'ios'] }),
@@ -58,12 +61,15 @@ export default class Config extends EasCommand {
const profile = await reader.getBuildProfileAsync(platform, profileName);
const config = getExpoConfig(projectDir, { env: profile.env, isPublicConfig: true });
Log.log(getProjectConfigDescription(projectDir));
Log.addNewLineIfNone();
Log.log(chalk.bold(getProjectConfigDescription(projectDir)));
Log.newLine();
Log.log(JSON.stringify(config, null, 2));
Log.newLine();
Log.newLine();
Log.log(`Build profile "${profileName}" from eas.json for platform ${platform}`);
const appPlatform = toAppPlatform(platform);
const platformEmoji = appPlatformEmojis[appPlatform];
Log.log(`${platformEmoji} ${chalk.bold(`Build profile "${profileName}"`)}`);
Log.newLine();
Log.log(JSON.stringify(profile, null, 2));
}
+1 -1
View File
@@ -2,7 +2,7 @@ import EasCommand from '../commandUtils/EasCommand';
import { SelectPlatform } from '../credentials/manager/SelectPlatform';
export default class Credentials extends EasCommand {
static description = 'manage your credentials';
static description = 'manage credentials';
async runAsync(): Promise<void> {
await new SelectPlatform().runAsync();
@@ -0,0 +1,246 @@
import { Device, DeviceStatus } from '@expo/apple-utils';
import { getConfig } from '@expo/config';
import { Flags } from '@oclif/core';
import assert from 'assert';
import EasCommand from '../../commandUtils/EasCommand';
import { chooseDevicesToDeleteAsync } from '../../credentials/ios/actions/DeviceUtils';
import { AppleDeviceMutation } from '../../credentials/ios/api/graphql/mutations/AppleDeviceMutation';
import {
AppleDeviceQuery,
AppleDeviceQueryResult,
AppleDevicesByTeamIdentifierQueryResult,
} from '../../credentials/ios/api/graphql/queries/AppleDeviceQuery';
import { AppleTeamQuery } from '../../credentials/ios/api/graphql/queries/AppleTeamQuery';
import { authenticateAsync, getRequestContext } from '../../credentials/ios/appstore/authenticate';
import formatDevice from '../../devices/utils/formatDevice';
import { AppleDevice, Maybe } from '../../graphql/generated';
import Log from '../../log';
import { ora } from '../../ora';
import { findProjectRootAsync, getProjectAccountNameAsync } from '../../project/projectUtils';
import { promptAsync, toggleConfirmAsync } from '../../prompts';
export default class DeviceDelete extends EasCommand {
static description = 'remove a registered device from your account';
static flags = {
'apple-team-id': Flags.string(),
udid: Flags.string({ multiple: true }),
};
async runAsync(): Promise<void> {
let {
flags: { 'apple-team-id': appleTeamIdentifier, udid: udids },
} = await this.parse(DeviceDelete);
const projectDir = await findProjectRootAsync();
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
const accountName = await getProjectAccountNameAsync(exp);
if (!appleTeamIdentifier) {
appleTeamIdentifier = await this.askForAppleTeamAsync(accountName);
}
assert(appleTeamIdentifier, 'No team identifier is specified');
const appleDevicesResult = await this.getDevicesForTeamAsync(accountName, appleTeamIdentifier);
if (!appleDevicesResult) {
return;
}
const { appleTeamName, appleDevices } = appleDevicesResult;
const chosenDevices = await this.chooseDevicesToDeleteAsync(appleDevices, udids);
if (chosenDevices.length === 0) {
Log.newLine();
Log.warn('No devices were chosen to be removed.');
return;
}
this.logChosenDevices(chosenDevices, appleTeamName, appleTeamIdentifier);
const hasRemoved = await this.askAndRemoveFromExpoAsync(chosenDevices);
if (!hasRemoved) {
return;
}
await this.askAndDisableOnAppleAsync(chosenDevices, appleTeamIdentifier);
}
async askAndDisableOnAppleAsync(
chosenDevices: (AppleDevice | AppleDeviceQueryResult)[],
appleTeamIdentifier: string
): Promise<void> {
Log.newLine();
const deleteOnApple = await toggleConfirmAsync({
message: 'Do you want to disable these devices on your Apple account as well?',
});
if (!deleteOnApple) {
return;
}
const ctx = await authenticateAsync({ teamId: appleTeamIdentifier });
const context = getRequestContext(ctx);
Log.addNewLineIfNone();
const removeAppleSpinner = ora('Disabling devices on Apple').start();
try {
let realDevices = await Device.getAllIOSProfileDevicesAsync(context);
realDevices = realDevices.filter(d =>
chosenDevices.map(cd => cd.identifier).includes(d.attributes.udid)
);
for (const device of realDevices) {
await device.updateAsync({ status: DeviceStatus.DISABLED });
}
removeAppleSpinner.succeed('Disabled devices on Apple');
} catch (err) {
removeAppleSpinner.fail();
throw err;
}
}
async askAndRemoveFromExpoAsync(
chosenDevices: (AppleDevice | AppleDeviceQueryResult)[]
): Promise<boolean> {
Log.warn(
`You are about to remove the Apple device${
chosenDevices.length > 1 ? 's' : ''
} listed above from your Expo account.`
);
Log.newLine();
const confirmed = await toggleConfirmAsync({
message: 'Are you sure you wish to proceed?',
});
if (confirmed) {
const removalSpinner = ora(`Removing Apple devices on Expo`).start();
try {
for (const chosenDevice of chosenDevices) {
await AppleDeviceMutation.deleteAppleDeviceAsync(chosenDevice.id);
}
removalSpinner.succeed('Removed Apple devices from Expo');
} catch (err) {
removalSpinner.fail();
throw err;
}
}
return confirmed;
}
logChosenDevices(
chosenDevices: (AppleDevice | AppleDeviceQueryResult)[],
appleTeamName: Maybe<string> | undefined,
appleTeamIdentifier: string
): void {
Log.addNewLineIfNone();
chosenDevices.forEach(device => {
Log.log(
formatDevice(device, {
appleTeamName,
appleTeamIdentifier: appleTeamIdentifier!,
})
);
Log.newLine();
});
}
async chooseDevicesToDeleteAsync(
appleDevices: AppleDeviceQueryResult[],
udids: string[]
): Promise<(AppleDevice | AppleDeviceQueryResult)[]> {
let chosenDevices: (AppleDeviceQueryResult | AppleDevice)[] = [];
Log.newLine();
if (udids) {
udids.forEach(udid => {
const foundDevice = appleDevices.find(device => device.identifier === udid);
if (foundDevice) {
chosenDevices.push(foundDevice);
} else {
Log.warn(`No device found with UDID ${udid}.`);
}
});
}
if (chosenDevices.length === 0) {
Log.addNewLineIfNone();
chosenDevices = await chooseDevicesToDeleteAsync(appleDevices);
Log.newLine();
}
return chosenDevices;
}
async getDevicesForTeamAsync(
accountName: string,
appleTeamIdentifier: string
): Promise<AppleDevicesByTeamIdentifierQueryResult | undefined> {
const devicesSpinner = ora().start('Fetching the list of devices for the team…');
try {
const result = await AppleDeviceQuery.getAllForAppleTeamAsync(
accountName,
appleTeamIdentifier
);
if (result?.appleDevices.length) {
const { appleTeamName, appleDevices } = result;
devicesSpinner.succeed(
`Found ${appleDevices.length} devices for team ${appleTeamName ?? appleTeamIdentifier}`
);
return result;
} else {
devicesSpinner.fail(`Couldn't find any devices for the team ${appleTeamIdentifier}`);
return;
}
} catch (e) {
devicesSpinner.fail(`Something went wrong and we couldn't fetch the device list`);
throw e;
}
}
async askForAppleTeamAsync(accountName: string): Promise<string | undefined> {
const teamSpinner = ora().start('Fetching the list of teams for the project…');
try {
const teams = await AppleTeamQuery.getAllForAccountAsync(accountName);
if (teams.length > 0) {
teamSpinner.succeed('Fetched the list of teams for the project');
if (teams.length === 1) {
return teams[0].appleTeamIdentifier;
}
const result = await promptAsync({
type: 'select',
name: 'appleTeamIdentifier',
message: 'What Apple Team would you like to list devices for?',
choices: teams.map(team => ({
title: team.appleTeamName
? `${team.appleTeamName} (ID: ${team.appleTeamIdentifier})`
: team.appleTeamIdentifier,
value: team.appleTeamIdentifier,
})),
});
return result.appleTeamIdentifier;
} else {
teamSpinner.fail(`Couldn't find any teams for the account ${accountName}`);
return;
}
} catch (e) {
teamSpinner.fail(`Something went wrong and we couldn't fetch the list of teams`);
throw e;
}
}
}
+1 -1
View File
@@ -34,7 +34,7 @@ export default class BuildList extends EasCommand {
try {
const teams = await AppleTeamQuery.getAllForAccountAsync(accountName);
if (teams.length) {
if (teams.length > 0) {
spinner.succeed();
if (teams.length === 1) {
+1 -1
View File
@@ -8,7 +8,7 @@ import { resolveWorkflowAsync } from '../project/workflow';
import { easCliVersion } from '../utils/easCli';
export default class Diagnostics extends EasCommand {
static description = 'log environment info to the console';
static description = 'display environment info';
protected requiresAuthentication = false;
@@ -20,7 +20,7 @@ import { getActorDisplayName } from '../../user/User';
import { ensureLoggedInAsync } from '../../user/actions';
export default class EnvironmentSecretCreate extends EasCommand {
static description = 'Create an environment secret on the current project or owner account.';
static description = 'create an environment secret on the current project or owner account';
static flags = {
scope: Flags.enum({
@@ -1,6 +1,5 @@
import { getConfig } from '@expo/config';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
import { EnvironmentSecretMutation } from '../../graphql/mutations/EnvironmentSecretMutation';
@@ -18,8 +17,7 @@ import {
import { promptAsync, toggleConfirmAsync } from '../../prompts';
export default class EnvironmentSecretDelete extends EasCommand {
static description = `Delete an environment secret by ID.
Unsure where to find the secret's ID? Run ${chalk.bold('eas secret:list')}`;
static description = 'delete an environment secret by ID';
static flags = {
id: Flags.string({
+1 -1
View File
@@ -13,7 +13,7 @@ import {
} from '../../project/projectUtils';
export default class EnvironmentSecretList extends EasCommand {
static description = 'Lists environment secrets available for your current app';
static description = 'list environment secrets available for your current app';
async runAsync(): Promise<void> {
const projectDir = await findProjectRootAsync();
+2 -3
View File
@@ -5,7 +5,7 @@ import chalk from 'chalk';
import EasCommand from '../commandUtils/EasCommand';
import { SubmissionFragment } from '../graphql/generated';
import { toAppPlatform } from '../graphql/types/AppPlatform';
import Log, { link } from '../log';
import Log from '../log';
import {
RequestedPlatform,
appPlatformDisplayNames,
@@ -41,8 +41,7 @@ interface CommandFlags {
}
export default class Submit extends EasCommand {
static description = `Submit build archive to App Store Connect
See how to configure submits with eas.json: ${link('https://docs.expo.dev/submit/eas-json/')}`;
static description = 'submit app binary to app store';
static aliases = ['build:submit'];
static flags = {
@@ -73,7 +73,7 @@ async function configureProjectForEASUpdateAsync(
}
export default class UpdateConfigure extends EasCommand {
static description = 'Configure the project to support EAS Update.';
static description = 'configure the project to support EAS Update';
async runAsync(): Promise<void> {
Log.log(
@@ -36,7 +36,7 @@ async function deleteUpdateGroupAsync({
}
export default class UpdateDelete extends EasCommand {
static description = 'Delete all the updates in an update Group.';
static description = 'delete all the updates in an update group';
static args = [
{
@@ -68,8 +68,8 @@ export default class UpdateDelete extends EasCommand {
`${chalk.yellow(`This will delete all of the updates in group "${group}".`)} ${chalk.red(
'This is a permanent operation.'
)}\n\n` +
`If you want to revert to a previous publish, you should use 'branch:publish --republish' targeted at the last working update group instead.\n\n` +
`An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'branch:publish --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
`If you want to revert to a previous publish, you should use 'update --republish' targeted at the last working update group instead.\n\n` +
`An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'update --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
`Would you like to abort?`,
});
+25 -4
View File
@@ -1,7 +1,7 @@
import { ExpoConfig, getConfig } from '@expo/config';
import { Updates } from '@expo/config-plugins';
import { Platform, Workflow } from '@expo/eas-build-job';
import { Flags } from '@oclif/core';
import { Errors, Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import dateFormat from 'dateformat';
@@ -23,7 +23,12 @@ import { PublishMutation } from '../../graphql/mutations/PublishMutation';
import { UpdateQuery } from '../../graphql/queries/UpdateQuery';
import Log from '../../log';
import { ora } from '../../ora';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import {
findProjectRootAsync,
getProjectIdAsync,
installExpoUpdatesAsync,
isExpoUpdatesInstalledOrAvailable,
} from '../../project/projectUtils';
import {
PublishPlatform,
buildBundlesAsync,
@@ -32,7 +37,7 @@ import {
uploadAssetsAsync,
} from '../../project/publish';
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync, selectAsync } from '../../prompts';
import { confirmAsync, promptAsync, selectAsync } from '../../prompts';
import { formatUpdate } from '../../update/utils';
import uniqBy from '../../utils/expodash/uniqBy';
import formatFields from '../../utils/formatFields';
@@ -132,7 +137,7 @@ async function ensureBranchExistsAsync({
}
export default class UpdatePublish extends EasCommand {
static description = 'Publish an update group.';
static description = 'publish an update group';
static flags = {
branch: Flags.string({
@@ -204,6 +209,22 @@ export default class UpdatePublish extends EasCommand {
isPublicConfig: true,
});
if (!isExpoUpdatesInstalledOrAvailable(projectDir, exp.sdkVersion)) {
const install = await confirmAsync({
message: `You are creating an update which requires ${chalk.bold(
'expo-updates'
)} to be installed in your app.\n Do you want EAS CLI to install it for you?`,
instructions: 'The command will abort unless you agree.',
});
if (install) {
await installExpoUpdatesAsync(projectDir, { nonInteractive: false });
} else {
Errors.error(`Install ${chalk.bold('expo-updates')} manually and come back later.`, {
exit: 1,
});
}
}
const runtimeVersions = await getRuntimeVersionObjectAsync(exp, platformFlag, projectDir);
const projectId = await getProjectIdAsync(exp);
await checkEASUpdateURLIsSetAsync(exp);
+1 -1
View File
@@ -23,7 +23,7 @@ type UpdateGroupDescription = FormatUpdateParameter & {
};
export default class BranchView extends EasCommand {
static description = 'View the recent updates for a branch';
static description = 'view the recent updates for a branch';
static flags = {
branch: Flags.string({
+1 -1
View File
@@ -51,7 +51,7 @@ export async function viewUpdateAsync({
return data;
}
export default class UpdateView extends EasCommand {
static description = 'Update group details.';
static description = 'update group details';
static args = [
{
@@ -9,7 +9,7 @@ import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUt
import { prepareInputParamsAsync } from '../../webhooks/input';
export default class WebhookCreate extends EasCommand {
static description = 'Create a webhook on the current project.';
static description = 'create a webhook';
static flags = {
event: Flags.enum({
@@ -14,7 +14,7 @@ import { promptAsync, toggleConfirmAsync } from '../../prompts';
import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookDelete extends EasCommand {
static description = 'Delete a webhook on the current project.';
static description = 'delete a webhook';
static args = [
{
@@ -15,7 +15,7 @@ import {
import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookList extends EasCommand {
static description = 'List webhooks on the current project.';
static description = 'list webhooks';
static flags = {
event: Flags.enum({
@@ -9,7 +9,7 @@ import pick from '../../utils/expodash/pick';
import { prepareInputParamsAsync } from '../../webhooks/input';
export default class WebhookUpdate extends EasCommand {
static description = 'Create a webhook on the current project.';
static description = 'update a webhook';
static flags = {
id: Flags.string({
@@ -5,7 +5,7 @@ import { ora } from '../../ora';
import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookView extends EasCommand {
static description = 'View a webhook on the current project.';
static description = 'view a webhook';
static args = [
{
@@ -26,6 +26,23 @@ export async function chooseDevicesAsync(
return devices;
}
export async function chooseDevicesToDeleteAsync(
allDevices: AppleDeviceFragment[]
): Promise<AppleDevice[]> {
const { devices } = await promptAsync({
type: 'multiselect',
name: 'devices',
message: 'Which devices do you want to remove?',
choices: allDevices.map(device => ({
value: device,
title: formatDeviceLabel(device),
selected: false,
})),
instructions: false,
});
return devices;
}
export function formatDeviceLabel(device: AppleDeviceFragment): string {
const deviceDetails = formatDeviceDetails(device);
return `${device.name ?? device.identifier}${deviceDetails !== '' ? ` ${deviceDetails}` : ''}`;
@@ -6,6 +6,7 @@ import {
AppleDeviceFragment,
AppleDeviceInput,
CreateAppleDeviceMutation,
DeleteAppleDeviceResult,
} from '../../../../../graphql/generated';
import { AppleDeviceFragmentNode } from '../../../../../graphql/types/credentials/AppleDevice';
@@ -40,4 +41,25 @@ export const AppleDeviceMutation = {
);
return data.appleDevice.createAppleDevice;
},
async deleteAppleDeviceAsync(deviceId: string): Promise<string> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<DeleteAppleDeviceResult>(
gql`
mutation DeleteAppleDeviceMutation($deviceId: ID!) {
appleDevice {
deleteAppleDevice(id: $deviceId) {
id
}
}
}
`,
{
deviceId,
}
)
.toPromise()
);
return data.id;
},
};
+3013 -4369
View File
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,44 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { ViewBranchQuery, ViewBranchQueryVariables } from '../generated';
export const BranchQuery = {
async getBranchByNameAsync({
appId,
name,
}: {
appId: string;
name: string;
}): Promise<ViewBranchQuery['app']['byId']['updateBranchByName']> {
const {
app: {
byId: { updateBranchByName: branch },
},
} = await withErrorHandlingAsync<ViewBranchQuery>(
graphqlClient
.query<ViewBranchQuery, ViewBranchQueryVariables>(
gql`
query ViewBranch($appId: String!, $name: String!) {
app {
byId(appId: $appId) {
id
updateBranchByName(name: $name) {
id
name
}
}
}
}
`,
{
appId,
name,
},
{ additionalTypenames: ['UpdateBranch'] }
)
.toPromise()
);
return branch;
},
};
@@ -0,0 +1,63 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables } from '../generated';
export const ChannelQuery = {
async getUpdateChannelByNameForAppAsync({
appId,
channelName,
}: GetChannelByNameForAppQueryVariables): Promise<
GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']
> {
const {
app: {
byId: { updateChannelByName },
},
} = await withErrorHandlingAsync(
graphqlClient
.query<GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables>(
gql`
query GetChannelByNameForApp($appId: String!, $channelName: String!) {
app {
byId(appId: $appId) {
id
updateChannelByName(name: $channelName) {
id
name
createdAt
branchMapping
updateBranches(offset: 0, limit: 1000) {
id
name
updates(offset: 0, limit: 10) {
id
group
message
runtimeVersion
createdAt
platform
actor {
id
... on User {
username
}
... on Robot {
firstName
}
}
}
}
}
}
}
}
`,
{ appId, channelName },
{ additionalTypenames: ['UpdateChannel', 'UpdateBranch', 'Update'] }
)
.toPromise()
);
return updateChannelByName;
},
};
+38 -50
View File
@@ -1,16 +1,22 @@
import { AppJSONConfig, ExpoConfig, getConfigFilePaths, modifyConfigAsync } from '@expo/config';
import {
AppJSONConfig,
ExpoConfig,
getConfigFilePaths,
getPackageJson,
modifyConfigAsync,
} from '@expo/config';
import { Env } from '@expo/eas-build-job';
import chalk from 'chalk';
import gql from 'graphql-tag';
import path from 'path';
import pkgDir from 'pkg-dir';
import semver from 'semver';
import { graphqlClient, withErrorHandlingAsync } from '../graphql/client';
import { AppPrivacy, UpdateBranch } from '../graphql/generated';
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 {
ensureProjectExistsAsync,
findProjectIdByAccountNameAndSlugNullableAsync,
@@ -193,52 +199,6 @@ export function getProjectConfigDescription(projectDir: string): string {
return 'app.config.js/app.json';
}
export async function getBranchByNameAsync({
appId,
name,
}: {
appId: string;
name: string;
}): Promise<UpdateBranch> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<
{
app: {
byId: {
updateBranchByName: UpdateBranch;
};
};
},
{
appId: string;
name: string;
}
>(
gql`
query ViewBranch($appId: String!, $name: String!) {
app {
byId(appId: $appId) {
id
updateBranchByName(name: $name) {
id
name
}
}
}
}
`,
{
appId,
name,
},
{ additionalTypenames: ['UpdateBranch'] }
)
.toPromise()
);
return data.app.byId.updateBranchByName;
}
// return project id of existing/newly created project, or null if user declines
export async function promptToCreateProjectIfNotExistsAsync(
exp: ExpoConfig
@@ -265,3 +225,31 @@ export async function promptToCreateProjectIfNotExistsAsync(
privacy,
});
}
export function isExpoUpdatesInstalled(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.dependencies && 'expo-updates' in packageJson.dependencies);
}
export function isExpoUpdatesInstalledOrAvailable(
projectDir: string,
sdkVersion?: string
): boolean {
// before sdk 44, expo-updates was included in with the expo module
if (sdkVersion && semver.lt(sdkVersion, '44.0.0')) {
return true;
}
return isExpoUpdatesInstalled(projectDir);
}
export async function installExpoUpdatesAsync(
projectDir: string,
{ nonInteractive }: { nonInteractive: boolean }
): Promise<void> {
Log.newLine();
Log.log(`Running ${chalk.bold('expo install expo-updates')}`);
Log.newLine();
await expoCommandAsync(projectDir, ['install', 'expo-updates']);
Log.newLine();
}
+4 -4
View File
@@ -256,7 +256,6 @@ async function handleBuildListSourceAsync(source: ArchiveBuildListSource): Promi
type: 'select',
message: 'Which build would you like to submit?',
choices: choices.map(choice => ({ ...choice, title: `- ${choice.title}` })),
// @ts-expect-error field documented in npm, but not defined in typescript
warn: 'This artifact has expired',
});
@@ -345,7 +344,7 @@ async function handlePromptSourceAsync(source: ArchivePromptSource): Promise<Arc
const sourceType = sourceTypeRaw as ArchiveSourceType;
switch (sourceType) {
case ArchiveSourceType.url: {
const url = await askForArchiveUrlAsync();
const url = await askForArchiveUrlAsync(source.platform);
return getArchiveAsync({
...source,
sourceType: ArchiveSourceType.url,
@@ -379,8 +378,9 @@ async function handlePromptSourceAsync(source: ArchivePromptSource): Promise<Arc
}
}
async function askForArchiveUrlAsync(): Promise<string> {
const defaultArchiveUrl = 'https://url.to/your/archive.aab';
async function askForArchiveUrlAsync(platform: Platform): Promise<string> {
const isIos = platform === Platform.IOS;
const defaultArchiveUrl = `https://url.to/your/archive.${isIos ? 'ipa' : 'aab'}`;
const { url } = await promptAsync({
name: 'url',
message: 'URL:',
+7 -7
View File
@@ -1,24 +1,24 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "0.44.0",
"version": "0.47.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/eas-build-job": "0.2.61",
"@expo/json-file": "8.2.33",
"@expo/eas-build-job": "0.2.65",
"@expo/json-file": "8.2.34",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "10.0.0",
"joi": "17.4.2",
"joi": "17.6.0",
"log-symbols": "4.1.0",
"semver": "7.3.5",
"tslib": "2.3.1"
},
"devDependencies": {
"@types/fs-extra": "9.0.12",
"memfs": "3.2.2",
"typescript": "4.5.2"
"@types/fs-extra": "9.0.13",
"memfs": "3.4.1",
"typescript": "4.5.5"
},
"engines": {
"node": ">=12.0.0"
+1
View File
@@ -16,6 +16,7 @@ const CommonBuildProfileSchema = Joi.object({
releaseChannel: Joi.string().regex(/^[a-z\d][a-z\d._-]*$/),
channel: Joi.string().regex(/^[a-z\d][a-z\d._-]*$/),
developmentClient: Joi.boolean(),
prebuildCommand: Joi.string(),
node: Joi.string().empty(null).custom(semverCheck),
yarn: Joi.string().empty(null).custom(semverCheck),
+1
View File
@@ -20,6 +20,7 @@ export interface CommonBuildProfile {
releaseChannel?: string;
channel?: string;
developmentClient?: boolean;
prebuildCommand?: string;
node?: string;
yarn?: string;
Generated
+3266 -2982
View File
File diff suppressed because it is too large. Load diff