mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-15 03:38:08 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
70ed1a482a | ||
|
|
920e5ee8a2 | ||
|
|
f334f2c019 | ||
|
|
b145a7d98c | ||
|
|
3c750b60c0 | ||
|
|
b3a9f1af70 | ||
|
|
39d8ab65d1 | ||
|
|
1ff2274d8d | ||
|
|
5ed4b65133 | ||
|
|
10aca5208f | ||
|
|
b2da80d5ea | ||
|
|
b9457d71f9 | ||
|
|
5fd3149a95 | ||
|
|
5f83724833 | ||
|
|
7df558d713 | ||
|
|
543e8ce26d | ||
|
|
355fada383 | ||
|
|
b6625a4cba | ||
|
|
c1ef20afab | ||
|
|
d8321e1f06 | ||
|
|
d8906e085e | ||
|
|
3b823865d3 | ||
|
|
a29ed19653 | ||
|
|
e70ecaa9b5 | ||
|
|
9886fcb3ef | ||
|
|
4f5739b2dc | ||
|
|
c7a40b06a5 | ||
|
|
3f88dc8690 | ||
|
|
874db1c125 |
No files matched your search
@@ -10,6 +10,53 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🐛 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
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "0.44.1"
|
||||
"version": "0.47.0"
|
||||
}
|
||||
+9
-9
@@ -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.1.5",
|
||||
"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",
|
||||
|
||||
+842
-2
@@ -33,8 +33,115 @@ eas --help COMMAND
|
||||
# Commands
|
||||
|
||||
<!-- commands -->
|
||||
* [`eas account:login`](#eas-accountlogin)
|
||||
* [`eas account:logout`](#eas-accountlogout)
|
||||
* [`eas account:view`](#eas-accountview)
|
||||
* [`eas analytics [STATUS]`](#eas-analytics-status)
|
||||
* [`eas autocomplete [SHELL]`](#eas-autocomplete-shell)
|
||||
* [`eas branch:create [NAME]`](#eas-branchcreate-name)
|
||||
* [`eas branch:delete [NAME]`](#eas-branchdelete-name)
|
||||
* [`eas branch:list`](#eas-branchlist)
|
||||
* [`eas branch:rename`](#eas-branchrename)
|
||||
* [`eas branch:view [NAME]`](#eas-branchview-name)
|
||||
* [`eas build`](#eas-build)
|
||||
* [`eas build:cancel [BUILD_ID]`](#eas-buildcancel-build_id)
|
||||
* [`eas build:configure`](#eas-buildconfigure)
|
||||
* [`eas build:inspect`](#eas-buildinspect)
|
||||
* [`eas build:list`](#eas-buildlist)
|
||||
* [`eas build:view [BUILD_ID]`](#eas-buildview-build_id)
|
||||
* [`eas channel:create [NAME]`](#eas-channelcreate-name)
|
||||
* [`eas channel:edit [NAME]`](#eas-channeledit-name)
|
||||
* [`eas channel:list`](#eas-channellist)
|
||||
* [`eas channel:view [NAME]`](#eas-channelview-name)
|
||||
* [`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)
|
||||
* [`eas help [COMMAND]`](#eas-help-command)
|
||||
* [`eas project:info`](#eas-projectinfo)
|
||||
* [`eas project:init`](#eas-projectinit)
|
||||
* [`eas secret:create`](#eas-secretcreate)
|
||||
* [`eas secret:delete`](#eas-secretdelete)
|
||||
* [`eas secret:list`](#eas-secretlist)
|
||||
* [`eas submit`](#eas-submit)
|
||||
* [`eas update`](#eas-update)
|
||||
* [`eas update:configure`](#eas-updateconfigure)
|
||||
* [`eas update:delete GROUPID`](#eas-updatedelete-groupid)
|
||||
* [`eas update:list`](#eas-updatelist)
|
||||
* [`eas update:view GROUPID`](#eas-updateview-groupid)
|
||||
* [`eas webhook:create`](#eas-webhookcreate)
|
||||
* [`eas webhook:delete [ID]`](#eas-webhookdelete-id)
|
||||
* [`eas webhook:list`](#eas-webhooklist)
|
||||
* [`eas webhook:update`](#eas-webhookupdate)
|
||||
* [`eas webhook:view ID`](#eas-webhookview-id)
|
||||
|
||||
## `eas account:login`
|
||||
|
||||
log in with your Expo account
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas account:login
|
||||
|
||||
DESCRIPTION
|
||||
log in with your Expo account
|
||||
|
||||
ALIASES
|
||||
$ eas login
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
log out
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas account:logout
|
||||
|
||||
DESCRIPTION
|
||||
log out
|
||||
|
||||
ALIASES
|
||||
$ eas logout
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
show the username you are logged in as
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas account:view
|
||||
|
||||
DESCRIPTION
|
||||
show the username you are logged in as
|
||||
|
||||
ALIASES
|
||||
$ eas whoami
|
||||
```
|
||||
|
||||
_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]`
|
||||
|
||||
display or change analytics settings
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas analytics [STATUS]
|
||||
|
||||
DESCRIPTION
|
||||
display or change analytics settings
|
||||
```
|
||||
|
||||
_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]`
|
||||
|
||||
@@ -63,7 +170,437 @@ EXAMPLES
|
||||
$ eas autocomplete --refresh-cache
|
||||
```
|
||||
|
||||
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.1.1/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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas branch:create [NAME] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
NAME Name of the branch to create
|
||||
|
||||
FLAGS
|
||||
--json return a json with the new branch ID and name.
|
||||
|
||||
DESCRIPTION
|
||||
create a branch
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas branch:delete [NAME] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
NAME Name of the branch to delete
|
||||
|
||||
FLAGS
|
||||
--json return JSON with the edited branch's ID and name.
|
||||
|
||||
DESCRIPTION
|
||||
delete a branch
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas branch:list [--json]
|
||||
|
||||
FLAGS
|
||||
--json return output as JSON
|
||||
|
||||
DESCRIPTION
|
||||
list all branches
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas branch:rename [--from <value>] [--to <value>] [--json]
|
||||
|
||||
FLAGS
|
||||
--from=<value> current name of the branch.
|
||||
--json return a json with the edited branch's ID and name.
|
||||
--to=<value> new name of the branch.
|
||||
|
||||
DESCRIPTION
|
||||
rename a branch
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas branch:view [NAME] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
NAME Name of the branch to view
|
||||
|
||||
FLAGS
|
||||
--json return a json with the branch's ID name and recent update groups.
|
||||
|
||||
DESCRIPTION
|
||||
view a branch
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas build [-p android|ios|all] [--json] [--skip-project-configuration] [--profile <value>]
|
||||
[--non-interactive] [--local] [--output <value>] [--wait] [--clear-cache] [--auto-submit |
|
||||
--auto-submit-with-profile <value>]
|
||||
|
||||
FLAGS
|
||||
-p, --platform=(android|ios|all)
|
||||
--auto-submit Submit on build complete using the submit profile with the same name as the
|
||||
build profile
|
||||
--auto-submit-with-profile=PROFILE_NAME Submit on build complete using the submit profile with provided name
|
||||
--clear-cache Clear cache before the build
|
||||
--json Enable JSON output, non-JSON messages will be printed to stderr
|
||||
--local Run build locally [experimental]
|
||||
--non-interactive Run command in non-interactive mode
|
||||
--output=<value> Output path for local build
|
||||
--profile=PROFILE_NAME Name of the build profile from eas.json. Defaults to "production" if defined
|
||||
in eas.json.
|
||||
--skip-project-configuration Skip project configuration
|
||||
--[no-]wait Wait for build(s) to complete
|
||||
|
||||
DESCRIPTION
|
||||
start a build
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas build:cancel [BUILD_ID]
|
||||
|
||||
DESCRIPTION
|
||||
cancel a build
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas build:configure [-p android|ios|all]
|
||||
|
||||
FLAGS
|
||||
-p, --platform=(android|ios|all) Platform to configure
|
||||
|
||||
DESCRIPTION
|
||||
configure the project to support EAS Build
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas build:inspect -p android|ios -s archive|pre-build|post-build -o <value> [--profile <value>] [--force] [-v]
|
||||
|
||||
FLAGS
|
||||
-o, --output=OUTPUT_DIRECTORY
|
||||
(required) Output directory.
|
||||
|
||||
-p, --platform=(android|ios)
|
||||
(required)
|
||||
|
||||
-s, --stage=(archive|pre-build|post-build)
|
||||
(required) Stage of the build you want to inspect.
|
||||
archive - builds the project archive that would be uploaded to EAS when building
|
||||
pre-build - prepares the project to be built with Gradle/Xcode. Does not run the native build.
|
||||
post-build - builds the native project and leaves the output directory for inspection
|
||||
|
||||
-v, --verbose
|
||||
|
||||
--force
|
||||
Delete OUTPUT_DIRECTORY if it already exists.
|
||||
|
||||
--profile=PROFILE_NAME
|
||||
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
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
list all builds for your project
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas build:list [--platform all|android|ios] [--json] [--status
|
||||
new|in-queue|in-progress|errored|finished|canceled] [--distribution store|internal|simulator] [--channel <value>]
|
||||
[--appVersion <value>] [--appBuildVersion <value>] [--sdkVersion <value>] [--runtimeVersion <value>]
|
||||
[--appIdentifier <value>] [--buildProfile <value>] [--gitCommitHash <value>] [--limit <value>]
|
||||
|
||||
FLAGS
|
||||
--appBuildVersion=<value>
|
||||
--appIdentifier=<value>
|
||||
--appVersion=<value>
|
||||
--buildProfile=<value>
|
||||
--channel=<value>
|
||||
--distribution=(store|internal|simulator)
|
||||
--gitCommitHash=<value>
|
||||
--json Enable JSON output, non-JSON messages will be printed
|
||||
to stderr
|
||||
--limit=<value>
|
||||
--platform=(all|android|ios)
|
||||
--runtimeVersion=<value>
|
||||
--sdkVersion=<value>
|
||||
--status=(new|in-queue|in-progress|errored|finished|canceled)
|
||||
|
||||
DESCRIPTION
|
||||
list all builds for your project
|
||||
```
|
||||
|
||||
_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]`
|
||||
|
||||
view a build for your project
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas build:view [BUILD_ID] [--json]
|
||||
|
||||
FLAGS
|
||||
--json Enable JSON output, non-JSON messages will be printed to stderr
|
||||
|
||||
DESCRIPTION
|
||||
view a build for your project
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas channel:create [NAME] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
NAME Name of the channel to create
|
||||
|
||||
FLAGS
|
||||
--json print output as a JSON object with the new channel ID, name and branch mapping.
|
||||
|
||||
DESCRIPTION
|
||||
create a channel
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas channel:edit [NAME] [--branch <value>] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
NAME Name of the channel to edit
|
||||
|
||||
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
|
||||
|
||||
DESCRIPTION
|
||||
point a channel at a new branch
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas channel:list [--json]
|
||||
|
||||
FLAGS
|
||||
--json print output as a JSON object with the channel ID, name and branch mapping.
|
||||
|
||||
DESCRIPTION
|
||||
list all channels
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas channel:view [NAME] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
NAME Name of the channel to view
|
||||
|
||||
FLAGS
|
||||
--json print output as a JSON object with the channel ID, name and branch mapping.
|
||||
|
||||
DESCRIPTION
|
||||
view a channel
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
display project configuration (app.json + eas.json)
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas config [-p android|ios] [--profile <value>]
|
||||
|
||||
FLAGS
|
||||
-p, --platform=(android|ios)
|
||||
--profile=<value>
|
||||
|
||||
DESCRIPTION
|
||||
display project configuration (app.json + eas.json)
|
||||
```
|
||||
|
||||
_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 credentials
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas credentials
|
||||
|
||||
DESCRIPTION
|
||||
manage credentials
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
register new Apple Devices to use for internal distribution
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas device:create
|
||||
|
||||
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.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`
|
||||
|
||||
list all registered devices for your account
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas device:list [--apple-team-id <value>]
|
||||
|
||||
FLAGS
|
||||
--apple-team-id=<value>
|
||||
|
||||
DESCRIPTION
|
||||
list all registered devices for your account
|
||||
```
|
||||
|
||||
_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]`
|
||||
|
||||
view a device for your project
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas device:view [UDID]
|
||||
|
||||
DESCRIPTION
|
||||
view a device for your project
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
display environment info
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas diagnostics
|
||||
|
||||
DESCRIPTION
|
||||
display environment info
|
||||
```
|
||||
|
||||
_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]`
|
||||
|
||||
@@ -83,5 +620,308 @@ 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`
|
||||
|
||||
information about the current project
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas project:info
|
||||
|
||||
DESCRIPTION
|
||||
information about the current project
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
create or link an EAS project
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas project:init
|
||||
|
||||
DESCRIPTION
|
||||
create or link an EAS project
|
||||
|
||||
ALIASES
|
||||
$ eas init
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas secret:create [--scope account|project] [--name <value>] [--value <value>] [--force]
|
||||
|
||||
FLAGS
|
||||
--force Delete and recreate existing secrets
|
||||
--name=<value> Name of the secret
|
||||
--scope=(account|project) [default: project] Scope for the secret
|
||||
--value=<value> Value of the secret
|
||||
|
||||
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/v0.47.0/packages/eas-cli/src/commands/secret/create.ts)_
|
||||
|
||||
## `eas secret:delete`
|
||||
|
||||
delete an environment secret by ID
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas secret:delete [--id <value>]
|
||||
|
||||
FLAGS
|
||||
--id=<value> ID of the secret to delete
|
||||
|
||||
DESCRIPTION
|
||||
delete an environment secret by ID
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
list environment secrets available for your current app
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas secret:list
|
||||
|
||||
DESCRIPTION
|
||||
list environment secrets available for your current app
|
||||
```
|
||||
|
||||
_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 app binary to app store
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas submit [-p android|ios|all] [--profile <value>] [--latest | --id <value> | --path <value> | --url
|
||||
<value>] [--verbose] [--wait] [--non-interactive]
|
||||
|
||||
FLAGS
|
||||
-p, --platform=(android|ios|all)
|
||||
--id=<value> ID of the build to submit
|
||||
--latest Submit the latest build for specified platform
|
||||
--non-interactive Run command in non-interactive mode
|
||||
--path=<value> Path to the .apk/.aab/.ipa file
|
||||
--profile=<value> Name of the submit profile from eas.json. Defaults to "production" if defined in
|
||||
eas.json.
|
||||
--url=<value> App archive url
|
||||
--verbose Always print logs from Submission Service
|
||||
--[no-]wait Wait for submission to complete
|
||||
|
||||
DESCRIPTION
|
||||
submit app binary to app store
|
||||
|
||||
ALIASES
|
||||
$ eas build:submit
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas update [--branch <value>] [--message <value>] [--republish | --input-dir <value> | --skip-bundler]
|
||||
[--group <value> | | ] [-p android|ios|all] [--json] [--auto]
|
||||
|
||||
FLAGS
|
||||
-p, --platform=(android|ios|all) [default: all]
|
||||
--auto Use the current git branch and commit message for the EAS branch and update message
|
||||
--branch=<value> Branch to publish the update group on
|
||||
--group=<value> Update group to republish
|
||||
--input-dir=<value> [default: dist] Location of the bundle
|
||||
--json Enable JSON output, non-JSON messages will be printed to stderr
|
||||
--message=<value> A short message describing the update
|
||||
--republish Republish an update group
|
||||
--skip-bundler Skip running Expo CLI to bundle the app before publishing
|
||||
|
||||
DESCRIPTION
|
||||
publish an update group
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas update:configure
|
||||
|
||||
DESCRIPTION
|
||||
configure the project to support EAS Update
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas update:delete [GROUPID] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
GROUPID The ID of an update group to delete.
|
||||
|
||||
FLAGS
|
||||
--json Return a json with the group ID of the deleted updates.
|
||||
|
||||
DESCRIPTION
|
||||
delete all the updates in an update group
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas update:list [--branch <value> | --all] [--json]
|
||||
|
||||
FLAGS
|
||||
--all List all updates associated with this project
|
||||
--branch=<value> List all updates on this branch
|
||||
--json Return a json with all of the recent update groups.
|
||||
|
||||
DESCRIPTION
|
||||
view the recent updates for a branch
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas update:view [GROUPID] [--json]
|
||||
|
||||
ARGUMENTS
|
||||
GROUPID The ID of an update group.
|
||||
|
||||
FLAGS
|
||||
--json Return a json with the updates belonging to the group.
|
||||
|
||||
DESCRIPTION
|
||||
update group details
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas webhook:create [--event BUILD|SUBMIT] [--url <value>] [--secret <value>]
|
||||
|
||||
FLAGS
|
||||
--event=(BUILD|SUBMIT) Event type that triggers the webhook
|
||||
--secret=<value> Secret used to create a hash signature of the request payload, provided in the
|
||||
'Expo-Signature' header.
|
||||
--url=<value> Webhook URL
|
||||
|
||||
DESCRIPTION
|
||||
create a webhook
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas webhook:delete [ID]
|
||||
|
||||
ARGUMENTS
|
||||
ID ID of the webhook to delete
|
||||
|
||||
DESCRIPTION
|
||||
delete a webhook
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas webhook:list [--event BUILD|SUBMIT]
|
||||
|
||||
FLAGS
|
||||
--event=(BUILD|SUBMIT) Event type that triggers the webhook
|
||||
|
||||
DESCRIPTION
|
||||
list webhooks
|
||||
```
|
||||
|
||||
_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`
|
||||
|
||||
update a webhook
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas webhook:update --id <value> [--event BUILD|SUBMIT] [--url <value>] [--secret <value>]
|
||||
|
||||
FLAGS
|
||||
--event=(BUILD|SUBMIT) Event type that triggers the webhook
|
||||
--id=<value> (required) Webhook ID
|
||||
--secret=<value> Secret used to create a hash signature of the request payload, provided in the
|
||||
'Expo-Signature' header.
|
||||
--url=<value> Webhook URL
|
||||
|
||||
DESCRIPTION
|
||||
update a webhook
|
||||
```
|
||||
|
||||
_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
|
||||
|
||||
```
|
||||
USAGE
|
||||
$ eas webhook:view [ID]
|
||||
|
||||
ARGUMENTS
|
||||
ID ID of the webhook to view
|
||||
|
||||
DESCRIPTION
|
||||
view a webhook
|
||||
```
|
||||
|
||||
_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 -->
|
||||
Generated
+20507
-20291
File diff suppressed because it is too large.
Load diff
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "eas-cli",
|
||||
"description": "EAS command line tool",
|
||||
"version": "0.44.1",
|
||||
"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-warn-if-update-available": "2.0.4",
|
||||
"@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.1.2",
|
||||
"@oclif/plugin-autocomplete": "1.1.1",
|
||||
"@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": "1.0.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": "1.0.0",
|
||||
"@types/prompts": "^2.0.9",
|
||||
"@types/semver": "7.3.8",
|
||||
"@types/tar": "4.0.5",
|
||||
"@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"
|
||||
@@ -122,7 +121,10 @@
|
||||
],
|
||||
"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';
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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) {
|
||||
|
||||
@@ -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 = [
|
||||
{
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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' }];
|
||||
|
||||
|
||||
@@ -7,17 +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({
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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,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}`);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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?`,
|
||||
});
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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
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;
|
||||
},
|
||||
};
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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:',
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -20,6 +20,7 @@ export interface CommonBuildProfile {
|
||||
releaseChannel?: string;
|
||||
channel?: string;
|
||||
developmentClient?: boolean;
|
||||
prebuildCommand?: string;
|
||||
|
||||
node?: string;
|
||||
yarn?: string;
|
||||
|
||||
Reference in new issue
Block a user