mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-13 20:28:08 -10:00
Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f20d970616 | ||
|
|
f3712d5dfb | ||
|
|
cba211d82c | ||
|
|
61109ea2c1 | ||
|
|
f889929f5f | ||
|
|
4bb314192e | ||
|
|
1a170283db | ||
|
|
ca803eed3f | ||
|
|
4b26472975 | ||
|
|
70b854abb1 | ||
|
|
2576a97704 | ||
|
|
15e50b1536 | ||
|
|
d6f3784cc0 | ||
|
|
a6f7d37d71 |
No files matched your search
@@ -12,6 +12,16 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
## [9.0.7](https://github.com/expo/eas-cli/releases/tag/v9.0.7) - 2024-05-17
|
||||
|
||||
## [9.0.6](https://github.com/expo/eas-cli/releases/tag/v9.0.6) - 2024-05-15
|
||||
|
||||
## [9.0.5](https://github.com/expo/eas-cli/releases/tag/v9.0.5) - 2024-05-13
|
||||
|
||||
## [9.0.4](https://github.com/expo/eas-cli/releases/tag/v9.0.4) - 2024-05-13
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Add loader and progress information to the `diagnostics` command. ([#2378](https://github.com/expo/eas-cli/pull/2378) by [@simek](https://github.com/simek))
|
||||
|
||||
## [9.0.3](https://github.com/expo/eas-cli/releases/tag/v9.0.3) - 2024-05-10
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"version": "9.0.4",
|
||||
"version": "9.0.7",
|
||||
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
|
||||
}
|
||||
+59
-59
@@ -140,7 +140,7 @@ ALIASES
|
||||
$ eas login
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/account/login.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/account/login.ts)_
|
||||
|
||||
## `eas account:logout`
|
||||
|
||||
@@ -157,7 +157,7 @@ ALIASES
|
||||
$ eas logout
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/account/logout.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/account/logout.ts)_
|
||||
|
||||
## `eas account:view`
|
||||
|
||||
@@ -174,7 +174,7 @@ ALIASES
|
||||
$ eas whoami
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/account/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/account/view.ts)_
|
||||
|
||||
## `eas analytics [STATUS]`
|
||||
|
||||
@@ -188,7 +188,7 @@ DESCRIPTION
|
||||
display or change analytics settings
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/analytics.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/analytics.ts)_
|
||||
|
||||
## `eas autocomplete [SHELL]`
|
||||
|
||||
@@ -240,7 +240,7 @@ DESCRIPTION
|
||||
create a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/branch/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/branch/create.ts)_
|
||||
|
||||
## `eas branch:delete [NAME]`
|
||||
|
||||
@@ -261,7 +261,7 @@ DESCRIPTION
|
||||
delete a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/branch/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/branch/delete.ts)_
|
||||
|
||||
## `eas branch:list`
|
||||
|
||||
@@ -281,7 +281,7 @@ DESCRIPTION
|
||||
list all branches
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/branch/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/branch/list.ts)_
|
||||
|
||||
## `eas branch:rename`
|
||||
|
||||
@@ -301,7 +301,7 @@ DESCRIPTION
|
||||
rename a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/branch/rename.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/branch/rename.ts)_
|
||||
|
||||
## `eas branch:view [NAME]`
|
||||
|
||||
@@ -324,7 +324,7 @@ DESCRIPTION
|
||||
view a branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/branch/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/branch/view.ts)_
|
||||
|
||||
## `eas build`
|
||||
|
||||
@@ -361,7 +361,7 @@ DESCRIPTION
|
||||
start a build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/index.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/index.ts)_
|
||||
|
||||
## `eas build:cancel [BUILD_ID]`
|
||||
|
||||
@@ -380,7 +380,7 @@ DESCRIPTION
|
||||
cancel a build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/cancel.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/cancel.ts)_
|
||||
|
||||
## `eas build:configure`
|
||||
|
||||
@@ -397,7 +397,7 @@ DESCRIPTION
|
||||
configure the project to support EAS Build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/configure.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/configure.ts)_
|
||||
|
||||
## `eas build:delete [BUILD_ID]`
|
||||
|
||||
@@ -416,7 +416,7 @@ DESCRIPTION
|
||||
delete a build
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/delete.ts)_
|
||||
|
||||
## `eas build:inspect`
|
||||
|
||||
@@ -451,7 +451,7 @@ DESCRIPTION
|
||||
inspect the state of the project at specific build stages, useful for troubleshooting
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/inspect.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/inspect.ts)_
|
||||
|
||||
## `eas build:list`
|
||||
|
||||
@@ -492,7 +492,7 @@ DESCRIPTION
|
||||
list all builds for your project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/list.ts)_
|
||||
|
||||
## `eas build:resign`
|
||||
|
||||
@@ -518,7 +518,7 @@ DESCRIPTION
|
||||
re-sign a build archive
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/resign.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/resign.ts)_
|
||||
|
||||
## `eas build:run`
|
||||
|
||||
@@ -544,7 +544,7 @@ DESCRIPTION
|
||||
run simulator/emulator builds from eas-cli
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/run.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/run.ts)_
|
||||
|
||||
## `eas build:submit`
|
||||
|
||||
@@ -594,7 +594,7 @@ DESCRIPTION
|
||||
get the latest version from EAS servers
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/version/get.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/version/get.ts)_
|
||||
|
||||
## `eas build:version:set`
|
||||
|
||||
@@ -613,7 +613,7 @@ DESCRIPTION
|
||||
update version of an app
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/version/set.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/version/set.ts)_
|
||||
|
||||
## `eas build:version:sync`
|
||||
|
||||
@@ -632,7 +632,7 @@ DESCRIPTION
|
||||
update a version in native code with a value stored on EAS servers
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/version/sync.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/version/sync.ts)_
|
||||
|
||||
## `eas build:view [BUILD_ID]`
|
||||
|
||||
@@ -649,7 +649,7 @@ DESCRIPTION
|
||||
view a build for your project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/build/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/build/view.ts)_
|
||||
|
||||
## `eas channel:create [NAME]`
|
||||
|
||||
@@ -670,7 +670,7 @@ DESCRIPTION
|
||||
create a channel
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/channel/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/channel/create.ts)_
|
||||
|
||||
## `eas channel:edit [NAME]`
|
||||
|
||||
@@ -692,7 +692,7 @@ DESCRIPTION
|
||||
point a channel at a new branch
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/channel/edit.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/channel/edit.ts)_
|
||||
|
||||
## `eas channel:list`
|
||||
|
||||
@@ -712,7 +712,7 @@ DESCRIPTION
|
||||
list all channels
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/channel/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/channel/list.ts)_
|
||||
|
||||
## `eas channel:rollout [CHANNEL]`
|
||||
|
||||
@@ -744,7 +744,7 @@ DESCRIPTION
|
||||
Roll a new branch out on a channel incrementally.
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/channel/rollout.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/channel/rollout.ts)_
|
||||
|
||||
## `eas channel:view [NAME]`
|
||||
|
||||
@@ -767,7 +767,7 @@ DESCRIPTION
|
||||
view a channel
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/channel/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/channel/view.ts)_
|
||||
|
||||
## `eas config`
|
||||
|
||||
@@ -788,7 +788,7 @@ DESCRIPTION
|
||||
display project configuration (app.json + eas.json)
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/config.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/config.ts)_
|
||||
|
||||
## `eas credentials`
|
||||
|
||||
@@ -805,7 +805,7 @@ DESCRIPTION
|
||||
manage credentials
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/credentials/index.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/credentials/index.ts)_
|
||||
|
||||
## `eas credentials:configure-build`
|
||||
|
||||
@@ -823,7 +823,7 @@ DESCRIPTION
|
||||
Set up credentials for building your project.
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/credentials/configure-build.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/credentials/configure-build.ts)_
|
||||
|
||||
## `eas device:create`
|
||||
|
||||
@@ -837,7 +837,7 @@ DESCRIPTION
|
||||
register new Apple Devices to use for internal distribution
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/device/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/device/create.ts)_
|
||||
|
||||
## `eas device:delete`
|
||||
|
||||
@@ -857,7 +857,7 @@ DESCRIPTION
|
||||
remove a registered device from your account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/device/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/device/delete.ts)_
|
||||
|
||||
## `eas device:list`
|
||||
|
||||
@@ -878,7 +878,7 @@ DESCRIPTION
|
||||
list all registered devices for your account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/device/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/device/list.ts)_
|
||||
|
||||
## `eas device:rename`
|
||||
|
||||
@@ -899,7 +899,7 @@ DESCRIPTION
|
||||
rename a registered device
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/device/rename.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/device/rename.ts)_
|
||||
|
||||
## `eas device:view [UDID]`
|
||||
|
||||
@@ -913,7 +913,7 @@ DESCRIPTION
|
||||
view a device for your project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/device/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/device/view.ts)_
|
||||
|
||||
## `eas diagnostics`
|
||||
|
||||
@@ -927,7 +927,7 @@ DESCRIPTION
|
||||
display environment info
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/diagnostics.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/diagnostics.ts)_
|
||||
|
||||
## `eas help [COMMAND]`
|
||||
|
||||
@@ -1018,7 +1018,7 @@ DESCRIPTION
|
||||
validate the local store configuration
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/metadata/lint.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/metadata/lint.ts)_
|
||||
|
||||
## `eas metadata:pull`
|
||||
|
||||
@@ -1035,7 +1035,7 @@ DESCRIPTION
|
||||
generate the local store configuration from the app stores
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/metadata/pull.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/metadata/pull.ts)_
|
||||
|
||||
## `eas metadata:push`
|
||||
|
||||
@@ -1052,7 +1052,7 @@ DESCRIPTION
|
||||
sync the local store configuration to the app stores
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/metadata/push.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/metadata/push.ts)_
|
||||
|
||||
## `eas open`
|
||||
|
||||
@@ -1066,7 +1066,7 @@ DESCRIPTION
|
||||
open the project page in a web browser
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/open.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/open.ts)_
|
||||
|
||||
## `eas project:info`
|
||||
|
||||
@@ -1080,7 +1080,7 @@ DESCRIPTION
|
||||
information about the current project
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/project/info.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/project/info.ts)_
|
||||
|
||||
## `eas project:init`
|
||||
|
||||
@@ -1102,7 +1102,7 @@ ALIASES
|
||||
$ eas init
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/project/init.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/project/init.ts)_
|
||||
|
||||
## `eas secret:create`
|
||||
|
||||
@@ -1125,7 +1125,7 @@ DESCRIPTION
|
||||
create an environment secret on the current project or owner account
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/secret/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/secret/create.ts)_
|
||||
|
||||
## `eas secret:delete`
|
||||
|
||||
@@ -1143,7 +1143,7 @@ DESCRIPTION
|
||||
delete an environment secret by ID
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/secret/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/secret/delete.ts)_
|
||||
|
||||
## `eas secret:list`
|
||||
|
||||
@@ -1157,7 +1157,7 @@ DESCRIPTION
|
||||
list environment secrets available for your current app
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/secret/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/secret/list.ts)_
|
||||
|
||||
## `eas secret:push`
|
||||
|
||||
@@ -1177,7 +1177,7 @@ DESCRIPTION
|
||||
read environment secrets from env file and store on the server
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/secret/push.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/secret/push.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/secret/push.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/secret/push.ts)_
|
||||
|
||||
## `eas submit`
|
||||
|
||||
@@ -1208,7 +1208,7 @@ ALIASES
|
||||
$ eas build:submit
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/submit.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/submit.ts)_
|
||||
|
||||
## `eas update`
|
||||
|
||||
@@ -1241,7 +1241,7 @@ DESCRIPTION
|
||||
publish an update group
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/index.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/index.ts)_
|
||||
|
||||
## `eas update:configure`
|
||||
|
||||
@@ -1259,7 +1259,7 @@ DESCRIPTION
|
||||
configure the project to support EAS Update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/configure.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/configure.ts)_
|
||||
|
||||
## `eas update:delete GROUPID`
|
||||
|
||||
@@ -1280,7 +1280,7 @@ DESCRIPTION
|
||||
delete all the updates in an update group
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/delete.ts)_
|
||||
|
||||
## `eas update:list`
|
||||
|
||||
@@ -1302,7 +1302,7 @@ DESCRIPTION
|
||||
view the recent updates
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/list.ts)_
|
||||
|
||||
## `eas update:republish`
|
||||
|
||||
@@ -1329,7 +1329,7 @@ DESCRIPTION
|
||||
roll back to an existing update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/republish.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/republish.ts)_
|
||||
|
||||
## `eas update:roll-back-to-embedded`
|
||||
|
||||
@@ -1356,7 +1356,7 @@ DESCRIPTION
|
||||
roll back to the embedded update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
|
||||
|
||||
## `eas update:rollback`
|
||||
|
||||
@@ -1375,7 +1375,7 @@ DESCRIPTION
|
||||
roll back to an embedded update or an existing update
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/rollback.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/rollback.ts)_
|
||||
|
||||
## `eas update:view GROUPID`
|
||||
|
||||
@@ -1395,7 +1395,7 @@ DESCRIPTION
|
||||
update group details
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/update/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/update/view.ts)_
|
||||
|
||||
## `eas webhook:create`
|
||||
|
||||
@@ -1416,7 +1416,7 @@ DESCRIPTION
|
||||
create a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/webhook/create.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/webhook/create.ts)_
|
||||
|
||||
## `eas webhook:delete [ID]`
|
||||
|
||||
@@ -1436,7 +1436,7 @@ DESCRIPTION
|
||||
delete a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/webhook/delete.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/webhook/delete.ts)_
|
||||
|
||||
## `eas webhook:list`
|
||||
|
||||
@@ -1454,7 +1454,7 @@ DESCRIPTION
|
||||
list webhooks
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/webhook/list.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/webhook/list.ts)_
|
||||
|
||||
## `eas webhook:update`
|
||||
|
||||
@@ -1476,7 +1476,7 @@ DESCRIPTION
|
||||
update a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/webhook/update.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/webhook/update.ts)_
|
||||
|
||||
## `eas webhook:view ID`
|
||||
|
||||
@@ -1493,7 +1493,7 @@ DESCRIPTION
|
||||
view a webhook
|
||||
```
|
||||
|
||||
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v9.0.4/packages/eas-cli/src/commands/webhook/view.ts)_
|
||||
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v9.0.7/packages/eas-cli/src/commands/webhook/view.ts)_
|
||||
|
||||
## `eas whoami`
|
||||
|
||||
|
||||
Generated
+197
@@ -11923,6 +11923,22 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "keyP8",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"description": null,
|
||||
@@ -22728,6 +22744,49 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DeploymentSignedUrlResult",
|
||||
"description": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "deploymentId",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "url",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DeploymentsConnection",
|
||||
@@ -22789,6 +22848,72 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DeploymentsMutation",
|
||||
"description": null,
|
||||
"fields": [
|
||||
{
|
||||
"name": "createSignedDeploymentUrl",
|
||||
"description": "Create a signed deployment URL",
|
||||
"args": [
|
||||
{
|
||||
"name": "appId",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "deploymentId",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "DeploymentSignedUrlResult",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "SCALAR",
|
||||
"name": "DevDomainName",
|
||||
"description": "A DevDomainName for a deployed serverless app",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "DiscordUser",
|
||||
@@ -29850,6 +29975,38 @@
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "updateGroups",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "Update",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
@@ -32898,6 +33055,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "turtleJobRunId",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "updateInfoGroup",
|
||||
"description": null,
|
||||
@@ -33787,6 +33956,22 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "deployments",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "DeploymentsMutation",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "devDomainName",
|
||||
"description": "Mutations that assign or modify DevDomainNames for apps",
|
||||
@@ -38896,6 +39081,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "jobRun",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "JobRun",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "manifestFragment",
|
||||
"description": null,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "eas-cli",
|
||||
"description": "EAS command line tool",
|
||||
"version": "9.0.4",
|
||||
"version": "9.0.7",
|
||||
"author": "Expo <[email protected]>",
|
||||
"bin": {
|
||||
"eas": "./bin/run"
|
||||
|
||||
@@ -93,13 +93,18 @@ export async function prepareJobAsync(
|
||||
experimental: {
|
||||
prebuildCommand: buildProfile.prebuildCommand,
|
||||
},
|
||||
mode: buildProfile.config ? BuildMode.CUSTOM : BuildMode.BUILD,
|
||||
mode: buildProfile.config || ctx.repack ? BuildMode.CUSTOM : BuildMode.BUILD,
|
||||
triggeredBy: BuildTrigger.EAS_CLI,
|
||||
...(maybeCustomBuildConfigPath && {
|
||||
customBuildConfig: {
|
||||
path: maybeCustomBuildConfigPath,
|
||||
},
|
||||
}),
|
||||
...(ctx.repack && {
|
||||
customBuildConfig: {
|
||||
path: '__eas/repack.yml',
|
||||
},
|
||||
}),
|
||||
loggerLevel: ctx.loggerLevel,
|
||||
};
|
||||
|
||||
|
||||
@@ -62,4 +62,5 @@ export interface BuildContext<T extends Platform> {
|
||||
requiredPackageManager: NodePackageManager['name'] | null;
|
||||
vcsClient: Client;
|
||||
loggerLevel?: LoggerLevel;
|
||||
repack: boolean;
|
||||
}
|
||||
@@ -16,6 +16,9 @@ import { Analytics, AnalyticsEventProperties, BuildEvent } from '../analytics/An
|
||||
import { DynamicConfigContextFn } from '../commandUtils/context/DynamicProjectConfigContextField';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { CredentialsContext } from '../credentials/context';
|
||||
import { AppStoreApiKeyPurpose } from '../credentials/ios/actions/AscApiKeyUtils';
|
||||
import { getAppFromContextAsync } from '../credentials/ios/actions/BuildCredentialsUtils';
|
||||
import { GetAscApiKey } from '../credentials/ios/actions/GetAscApiKey';
|
||||
import { CustomBuildConfigMetadata } from '../project/customBuildConfig';
|
||||
import { getOwnerAccountForProjectIdAsync } from '../project/projectUtils';
|
||||
import { resolveWorkflowAsync } from '../project/workflow';
|
||||
@@ -42,6 +45,7 @@ export async function createBuildContextAsync<T extends Platform>({
|
||||
customBuildConfigMetadata,
|
||||
buildLoggerLevel,
|
||||
freezeCredentials,
|
||||
repack,
|
||||
}: {
|
||||
buildProfileName: string;
|
||||
buildProfile: BuildProfile<T>;
|
||||
@@ -62,6 +66,7 @@ export async function createBuildContextAsync<T extends Platform>({
|
||||
customBuildConfigMetadata?: CustomBuildConfigMetadata;
|
||||
buildLoggerLevel?: LoggerLevel;
|
||||
freezeCredentials: boolean;
|
||||
repack: boolean;
|
||||
}): Promise<BuildContext<T>> {
|
||||
const { exp, projectId } = await getDynamicPrivateProjectConfigAsync({ env: buildProfile.env });
|
||||
const projectName = exp.slug;
|
||||
@@ -143,6 +148,7 @@ export async function createBuildContextAsync<T extends Platform>({
|
||||
developmentClient,
|
||||
requiredPackageManager,
|
||||
loggerLevel: buildLoggerLevel,
|
||||
repack,
|
||||
};
|
||||
if (platform === Platform.ANDROID) {
|
||||
const common = commonContext as CommonContext<Platform.ANDROID>;
|
||||
@@ -152,10 +158,24 @@ export async function createBuildContextAsync<T extends Platform>({
|
||||
} as BuildContext<T>;
|
||||
} else {
|
||||
const common = commonContext as CommonContext<Platform.IOS>;
|
||||
return {
|
||||
const iosBuildCtx = {
|
||||
...common,
|
||||
ios: await createIosContextAsync(common),
|
||||
} as BuildContext<T>;
|
||||
const appLookupParams = {
|
||||
...(await getAppFromContextAsync(credentialsCtx)),
|
||||
bundleIdentifier: (iosBuildCtx as BuildContext<Platform.IOS>).ios.bundleIdentifier,
|
||||
};
|
||||
const getAscApiKeyAction = new GetAscApiKey(
|
||||
appLookupParams,
|
||||
AppStoreApiKeyPurpose.BUILD_SERVICE
|
||||
);
|
||||
const ascApiKeyManagedByExpo = await getAscApiKeyAction.runAsync(credentialsCtx);
|
||||
if (ascApiKeyManagedByExpo) {
|
||||
// TODO: set credentialCtx with the correct options
|
||||
}
|
||||
|
||||
return iosBuildCtx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -88,13 +88,18 @@ export async function prepareJobAsync(
|
||||
experimental: {
|
||||
prebuildCommand: buildProfile.prebuildCommand,
|
||||
},
|
||||
mode: buildProfile.config ? BuildMode.CUSTOM : BuildMode.BUILD,
|
||||
mode: buildProfile.config || ctx.repack ? BuildMode.CUSTOM : BuildMode.BUILD,
|
||||
triggeredBy: BuildTrigger.EAS_CLI,
|
||||
...(maybeCustomBuildConfigPath && {
|
||||
customBuildConfig: {
|
||||
path: maybeCustomBuildConfigPath,
|
||||
},
|
||||
}),
|
||||
...(ctx.repack && {
|
||||
customBuildConfig: {
|
||||
path: '__eas/repack.yml',
|
||||
},
|
||||
}),
|
||||
loggerLevel: ctx.loggerLevel,
|
||||
};
|
||||
return sanitizeBuildJob(job) as Ios.Job;
|
||||
|
||||
@@ -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 = '1.0.107';
|
||||
const PLUGIN_PACKAGE_VERSION = '1.0.112';
|
||||
|
||||
export enum LocalBuildMode {
|
||||
/**
|
||||
|
||||
@@ -95,6 +95,7 @@ export interface BuildFlags {
|
||||
message?: string;
|
||||
buildLoggerLevel?: LoggerLevel;
|
||||
freezeCredentials: boolean;
|
||||
repack: boolean;
|
||||
}
|
||||
|
||||
export async function runBuildAndSubmitAsync(
|
||||
@@ -375,6 +376,7 @@ async function prepareAndStartBuildAsync({
|
||||
customBuildConfigMetadata,
|
||||
buildLoggerLevel: flags.buildLoggerLevel,
|
||||
freezeCredentials: flags.freezeCredentials,
|
||||
repack: flags.repack,
|
||||
});
|
||||
|
||||
if (moreBuilds) {
|
||||
|
||||
@@ -36,6 +36,7 @@ interface RawBuildFlags {
|
||||
message?: string;
|
||||
'build-logger-level'?: LoggerLevel;
|
||||
'freeze-credentials': boolean;
|
||||
repack: boolean;
|
||||
}
|
||||
|
||||
export default class Build extends EasCommand {
|
||||
@@ -109,6 +110,11 @@ export default class Build extends EasCommand {
|
||||
default: false,
|
||||
description: 'Prevent the build from updating credentials in non-interactive mode',
|
||||
}),
|
||||
repack: Flags.boolean({
|
||||
default: false,
|
||||
hidden: true,
|
||||
description: 'Use the golden dev client build repack flow as it works for onboarding',
|
||||
}),
|
||||
...EasNonInteractiveAndJsonFlags,
|
||||
};
|
||||
|
||||
@@ -223,6 +229,7 @@ export default class Build extends EasCommand {
|
||||
message,
|
||||
buildLoggerLevel: flags['build-logger-level'],
|
||||
freezeCredentials: flags['freeze-credentials'],
|
||||
repack: flags.repack,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ export default class BuildInspect extends EasCommand {
|
||||
workingdir: tmpWorkingdir,
|
||||
artifactsDir: path.join(tmpWorkingdir, 'artifacts'),
|
||||
},
|
||||
repack: false,
|
||||
},
|
||||
actor,
|
||||
getDynamicPrivateProjectConfigAsync
|
||||
|
||||
@@ -86,6 +86,7 @@ export default class BuildInternal extends EasCommand {
|
||||
localBuildMode: LocalBuildMode.INTERNAL,
|
||||
},
|
||||
submitProfile: flags['auto-submit-with-profile'] ?? flags.profile,
|
||||
repack: false,
|
||||
},
|
||||
actor,
|
||||
getDynamicPrivateProjectConfigAsync
|
||||
|
||||
@@ -164,6 +164,10 @@ export default class Onboarding extends EasCommand {
|
||||
targetDir: finalTargetProjectDirectory,
|
||||
});
|
||||
}
|
||||
|
||||
await installDependenciesAsync({
|
||||
projectDir: finalTargetProjectDirectory,
|
||||
});
|
||||
const exp = await getPrivateExpoConfigWithProjectIdAsync({
|
||||
projectDir: finalTargetProjectDirectory,
|
||||
graphqlClient,
|
||||
@@ -175,9 +179,6 @@ export default class Onboarding extends EasCommand {
|
||||
actor,
|
||||
});
|
||||
|
||||
await installDependenciesAsync({
|
||||
projectDir: finalTargetProjectDirectory,
|
||||
});
|
||||
if (!app.githubRepository) {
|
||||
await runCommandAsync({
|
||||
cwd: finalTargetProjectDirectory,
|
||||
@@ -290,6 +291,7 @@ export default class Onboarding extends EasCommand {
|
||||
autoSubmit: false,
|
||||
localBuildOptions: {},
|
||||
freezeCredentials: false,
|
||||
repack: true,
|
||||
},
|
||||
actor,
|
||||
getDynamicProjectConfigFn
|
||||
|
||||
@@ -7,8 +7,10 @@ import * as AndroidGraphqlClient from './android/api/GraphqlClient';
|
||||
import * as IosGraphqlClient from './ios/api/GraphqlClient';
|
||||
import AppStoreApi from './ios/appstore/AppStoreApi';
|
||||
import { AuthenticationMode } from './ios/appstore/authenticateTypes';
|
||||
import { MinimalAscApiKey } from './ios/credentials';
|
||||
import { Analytics } from '../analytics/AnalyticsManager';
|
||||
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
|
||||
import { AppStoreConnectApiKeyFragment } from '../graphql/generated';
|
||||
import Log from '../log';
|
||||
import { getPrivateExpoConfig } from '../project/expoConfig';
|
||||
import { confirmAsync } from '../prompts';
|
||||
@@ -85,6 +87,28 @@ export class CredentialsContext {
|
||||
getPrivateExpoConfig(this.options.projectDir);
|
||||
}
|
||||
|
||||
public configureAppStoreAuth(ascApiKey: AppStoreConnectApiKeyFragment): void {
|
||||
/* keyP8: string;
|
||||
keyId: string;
|
||||
issuerId: string;
|
||||
teamId?: string;
|
||||
teamName?: string;
|
||||
roles?: UserRole[];
|
||||
name?: string; */
|
||||
this.appStore.authCtx = {
|
||||
ascApiKey: {
|
||||
keyP8: ascApiKey.keyP8,
|
||||
keyId: ascApiKey.keyIdentifier,
|
||||
issuerId: ascApiKey.issuerIdentifier,
|
||||
},
|
||||
appleTeam: {
|
||||
teamIdentifier: ascApiKey.appleTeam?.appleTeamIdentifier ?? '',
|
||||
teamName: ascApiKey.appleTeam?.appleTeamName,
|
||||
teamType: ascApiKey.appleTeam,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async bestEffortAppStoreAuthenticateAsync(): Promise<void> {
|
||||
if (this.appStore.authCtx || !this.shouldAskAuthenticateAppStore) {
|
||||
// skip prompts if already have apple ctx or already asked about it
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { UserRole } from '@expo/apple-utils';
|
||||
import chalk from 'chalk';
|
||||
import fs from 'fs-extra';
|
||||
import { nanoid } from 'nanoid';
|
||||
@@ -24,10 +25,19 @@ import { isAscApiKeyValidAndTrackedAsync } from '../validators/validateAscApiKey
|
||||
|
||||
export enum AppStoreApiKeyPurpose {
|
||||
SUBMISSION_SERVICE = 'EAS Submit',
|
||||
BUILD_SERVICE = 'EAS Build',
|
||||
}
|
||||
|
||||
export async function promptForAscApiKeyPathAsync(ctx: CredentialsContext): Promise<AscApiKeyPath> {
|
||||
const { keyId, keyP8Path } = await promptForKeyP8AndIdAsync();
|
||||
export const PURPOSE_TO_ROLES: Record<AppStoreApiKeyPurpose, UserRole[]> = {
|
||||
[AppStoreApiKeyPurpose.SUBMISSION_SERVICE]: [UserRole.ADMIN],
|
||||
[AppStoreApiKeyPurpose.BUILD_SERVICE]: [UserRole.ADMIN],
|
||||
};
|
||||
|
||||
export async function promptForAscApiKeyPathAsync(
|
||||
ctx: CredentialsContext,
|
||||
roles: UserRole[]
|
||||
): Promise<AscApiKeyPath> {
|
||||
const { keyId, keyP8Path } = await promptForKeyP8AndIdAsync(roles);
|
||||
|
||||
const bestEffortIssuerId = await getBestEffortIssuerIdAsync(ctx, keyId);
|
||||
if (bestEffortIssuerId) {
|
||||
@@ -60,15 +70,15 @@ export async function getMinimalAscApiKeyAsync(ascApiKey: AscApiKey): Promise<Mi
|
||||
|
||||
export async function provideOrGenerateAscApiKeyAsync(
|
||||
ctx: CredentialsContext,
|
||||
purpose: AppStoreApiKeyPurpose
|
||||
roles: UserRole[]
|
||||
): Promise<MinimalAscApiKey> {
|
||||
if (ctx.nonInteractive) {
|
||||
throw new Error(`A new App Store Connect API Key cannot be created in non-interactive mode.`);
|
||||
}
|
||||
|
||||
const userProvided = await promptForAscApiKeyAsync(ctx);
|
||||
const userProvided = await promptForAscApiKeyAsync(ctx, roles);
|
||||
if (!userProvided) {
|
||||
return await generateAscApiKeyAsync(ctx, purpose);
|
||||
return await generateAscApiKeyAsync(ctx, roles);
|
||||
}
|
||||
|
||||
if (!ctx.appStore.authCtx) {
|
||||
@@ -86,39 +96,49 @@ export async function provideOrGenerateAscApiKeyAsync(
|
||||
if (useUserProvided) {
|
||||
return userProvided;
|
||||
}
|
||||
return await provideOrGenerateAscApiKeyAsync(ctx, purpose);
|
||||
return await provideOrGenerateAscApiKeyAsync(ctx, roles);
|
||||
}
|
||||
|
||||
async function generateAscApiKeyAsync(
|
||||
ctx: CredentialsContext,
|
||||
purpose: AppStoreApiKeyPurpose
|
||||
roles: UserRole[]
|
||||
): Promise<MinimalAscApiKey> {
|
||||
await ctx.appStore.ensureAuthenticatedAsync();
|
||||
const ascApiKey = await ctx.appStore.createAscApiKeyAsync(ctx.analytics, {
|
||||
nickname: getAscApiKeyName(purpose),
|
||||
nickname: getAscApiKeyName(),
|
||||
roles,
|
||||
});
|
||||
return await getMinimalAscApiKeyAsync(ascApiKey);
|
||||
}
|
||||
|
||||
export function getAscApiKeyName(purpose: AppStoreApiKeyPurpose): string {
|
||||
const nameParts = ['[Expo]', purpose, nanoid(10)];
|
||||
export function getAscApiKeyName(): string {
|
||||
const nameParts = ['[Expo]', nanoid(10)];
|
||||
return nameParts.join(' ');
|
||||
}
|
||||
|
||||
async function promptForAscApiKeyAsync(ctx: CredentialsContext): Promise<MinimalAscApiKey | null> {
|
||||
async function promptForAscApiKeyAsync(
|
||||
ctx: CredentialsContext,
|
||||
roles: UserRole[]
|
||||
): Promise<MinimalAscApiKey | null> {
|
||||
const shouldAutoGenerateCredentials = await shouldAutoGenerateCredentialsAsync(ascApiKeyIdSchema);
|
||||
if (shouldAutoGenerateCredentials) {
|
||||
return null;
|
||||
}
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx);
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx, roles);
|
||||
const { keyP8Path, keyId, issuerId } = ascApiKeyPath;
|
||||
return { keyP8: await fs.readFile(keyP8Path, 'utf-8'), keyId, issuerId };
|
||||
}
|
||||
|
||||
async function promptForKeyP8AndIdAsync(): Promise<Pick<AscApiKeyPath, 'keyP8Path' | 'keyId'>> {
|
||||
async function promptForKeyP8AndIdAsync(
|
||||
roles: UserRole[]
|
||||
): Promise<Pick<AscApiKeyPath, 'keyP8Path' | 'keyId'>> {
|
||||
const rolesStringified = roles.map(r => r.toString()).join(', ');
|
||||
const isPlural = roles.length > 1;
|
||||
Log.log(
|
||||
chalk.bold(
|
||||
'An App Store Connect Api key is required to upload your app to the Apple App Store Connect'
|
||||
`An App Store Connect Api key with the ${rolesStringified} role${
|
||||
isPlural ? 's' : ''
|
||||
} is required to upload your app to the Apple App Store Connect`
|
||||
)
|
||||
);
|
||||
Log.log(
|
||||
@@ -241,13 +261,16 @@ export function sortAscApiKeysByUpdatedAtDesc(
|
||||
}
|
||||
|
||||
export function formatAscApiKey(ascApiKey: AppStoreConnectApiKeyFragment): string {
|
||||
const { keyIdentifier, appleTeam, name, updatedAt } = ascApiKey;
|
||||
const { keyIdentifier, appleTeam, roles, name, updatedAt } = ascApiKey;
|
||||
let line: string = '';
|
||||
line += `Key ID: ${keyIdentifier}`;
|
||||
|
||||
if (name) {
|
||||
line += chalk.gray(`\n Name: ${name}`);
|
||||
}
|
||||
if (roles && roles.length > 0) {
|
||||
line += chalk.gray(`\n Roles: ${roles.join(', ')}`);
|
||||
}
|
||||
if (appleTeam) {
|
||||
line += chalk.gray(`\n ${formatAppleTeam(appleTeam)}`);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { AppStoreApiKeyPurpose } from './AscApiKeyUtils';
|
||||
import { ChooseAssociatedAppleTeamId } from './ChooseAssociatedAppleTeamId';
|
||||
import { UpdateAppleTeamInfo } from './UpdateAppleTeamInfo';
|
||||
import {
|
||||
AppStoreConnectApiKeyFragment,
|
||||
AppleTeamFragment,
|
||||
CommonIosAppCredentialsFragment,
|
||||
} from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
@@ -16,12 +18,15 @@ export class AssignAscApiKey {
|
||||
ascApiKey: AppStoreConnectApiKeyFragment,
|
||||
purpose: AppStoreApiKeyPurpose
|
||||
): Promise<CommonIosAppCredentialsFragment> {
|
||||
const appleTeam =
|
||||
(await resolveAppleTeamIfAuthenticatedAsync(ctx, this.app)) ?? ascApiKey.appleTeam ?? null;
|
||||
const [ascApiKeyWithAppleTeam, appleTeam] = await this.ensureKeyHasAppleTeamInfoAsync(
|
||||
ctx,
|
||||
ascApiKey
|
||||
);
|
||||
|
||||
const appCredentials = await ctx.ios.createOrGetIosAppCredentialsWithCommonFieldsAsync(
|
||||
ctx.graphqlClient,
|
||||
this.app,
|
||||
{ appleTeam: appleTeam ?? undefined }
|
||||
{ appleTeam }
|
||||
);
|
||||
let updatedAppCredentials;
|
||||
if (purpose === AppStoreApiKeyPurpose.SUBMISSION_SERVICE) {
|
||||
@@ -29,7 +34,15 @@ export class AssignAscApiKey {
|
||||
ctx.graphqlClient,
|
||||
appCredentials,
|
||||
{
|
||||
ascApiKeyIdForSubmissions: ascApiKey.id,
|
||||
ascApiKeyIdForSubmissions: ascApiKeyWithAppleTeam.id,
|
||||
}
|
||||
);
|
||||
} else if (purpose === AppStoreApiKeyPurpose.BUILD_SERVICE) {
|
||||
updatedAppCredentials = await ctx.ios.updateIosAppCredentialsAsync(
|
||||
ctx.graphqlClient,
|
||||
appCredentials,
|
||||
{
|
||||
ascApiKeyIdForBuilds: ascApiKeyWithAppleTeam.id,
|
||||
}
|
||||
);
|
||||
} else {
|
||||
@@ -40,4 +53,28 @@ export class AssignAscApiKey {
|
||||
);
|
||||
return updatedAppCredentials;
|
||||
}
|
||||
|
||||
private async ensureKeyHasAppleTeamInfoAsync(
|
||||
ctx: CredentialsContext,
|
||||
ascApiKey: AppStoreConnectApiKeyFragment
|
||||
): Promise<[AppStoreConnectApiKeyFragment, AppleTeamFragment]> {
|
||||
let appleTeamIdentifier = ascApiKey.appleTeam?.appleTeamIdentifier;
|
||||
if (!appleTeamIdentifier) {
|
||||
const chooseAssociatedAppleTeamIdAction = new ChooseAssociatedAppleTeamId(
|
||||
'App Store Connect API Key'
|
||||
);
|
||||
appleTeamIdentifier = await chooseAssociatedAppleTeamIdAction.runAsync(ctx);
|
||||
}
|
||||
const updateAppleTeamAction = new UpdateAppleTeamInfo(this.app.account, appleTeamIdentifier);
|
||||
const appleTeam = await updateAppleTeamAction.runAsync(ctx);
|
||||
if (!ascApiKey.appleTeam) {
|
||||
const updatedAscApiKey = await ctx.ios.updateAscApiKeyAsync(
|
||||
ctx.graphqlClient,
|
||||
ascApiKey,
|
||||
appleTeam
|
||||
);
|
||||
return [updatedAscApiKey, appleTeam];
|
||||
}
|
||||
return [ascApiKey, appleTeam];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Teams } from '@expo/apple-utils';
|
||||
|
||||
import { promptAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
|
||||
export class ChooseAssociatedAppleTeamId {
|
||||
constructor(private associatedCredential: string) {}
|
||||
|
||||
public async runAsync(ctx: CredentialsContext): Promise<string> {
|
||||
if (!ctx.appStore.authCtx) {
|
||||
return await this.promptForAppleTeamIdAsync();
|
||||
}
|
||||
|
||||
const teams = await Teams.getTeamsAsync();
|
||||
const chosenTeamId = await this.promptForAppleTeamIdFromDeveloperPortalAsync(
|
||||
teams.map(team => ({ prettyName: `${team.name} (${team.type})`, teamId: team.teamId }))
|
||||
);
|
||||
return chosenTeamId ?? (await this.promptForAppleTeamIdAsync());
|
||||
}
|
||||
|
||||
private async promptForAppleTeamIdFromDeveloperPortalAsync(
|
||||
teamChoices: { prettyName: string; teamId: string }[]
|
||||
): Promise<string | null> {
|
||||
if (teamChoices.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const { appleTeamId } = await promptAsync({
|
||||
type: 'select',
|
||||
message: `Select the Apple Team associated with your ${this.associatedCredential}:`,
|
||||
name: 'appleTeamId',
|
||||
choices: [
|
||||
...teamChoices.map(({ prettyName, teamId }) => ({ title: prettyName, value: teamId })),
|
||||
{ title: 'None of the above', value: null },
|
||||
],
|
||||
});
|
||||
return appleTeamId;
|
||||
}
|
||||
|
||||
private async promptForAppleTeamIdAsync(): Promise<string> {
|
||||
const { appleTeamId } = await promptAsync({
|
||||
type: 'text',
|
||||
name: 'appleTeamId',
|
||||
message: `Input the Apple Team ID associated with your ${this.associatedCredential}:`,
|
||||
validate: (val: string) => val !== '',
|
||||
});
|
||||
return appleTeamId;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,17 @@
|
||||
import { AppStoreApiKeyPurpose, provideOrGenerateAscApiKeyAsync } from './AscApiKeyUtils';
|
||||
import { AccountFragment, AppStoreConnectApiKeyFragment } from '../../../graphql/generated';
|
||||
import {
|
||||
AppStoreApiKeyPurpose,
|
||||
PURPOSE_TO_ROLES,
|
||||
provideOrGenerateAscApiKeyAsync,
|
||||
} from './AscApiKeyUtils';
|
||||
import { ChooseAssociatedAppleTeamId } from './ChooseAssociatedAppleTeamId';
|
||||
import { UpdateAppleTeamInfo } from './UpdateAppleTeamInfo';
|
||||
import {
|
||||
AccountFragment,
|
||||
AppStoreConnectApiKeyFragment,
|
||||
AppleTeamFragment,
|
||||
} from '../../../graphql/generated';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { MinimalAscApiKey } from '../credentials';
|
||||
|
||||
export class CreateAscApiKey {
|
||||
constructor(private account: AccountFragment) {}
|
||||
@@ -12,8 +23,32 @@ export class CreateAscApiKey {
|
||||
if (ctx.nonInteractive) {
|
||||
throw new Error(`A new App Store Connect API Key cannot be created in non-interactive mode.`);
|
||||
}
|
||||
const roles = PURPOSE_TO_ROLES[purpose];
|
||||
if (!roles) {
|
||||
throw new Error(`Unsupported purpose: ${purpose}`);
|
||||
}
|
||||
|
||||
const ascApiKey = await provideOrGenerateAscApiKeyAsync(ctx, purpose);
|
||||
return await ctx.ios.createAscApiKeyAsync(ctx.graphqlClient, this.account, ascApiKey);
|
||||
const ascApiKey = await provideOrGenerateAscApiKeyAsync(ctx, roles);
|
||||
const appleTeam = await this.ensureKeyHasAppleTeamInfoAsync(ctx, ascApiKey);
|
||||
|
||||
return await ctx.ios.createAscApiKeyAsync(ctx.graphqlClient, this.account, {
|
||||
...ascApiKey,
|
||||
teamId: appleTeam.appleTeamIdentifier,
|
||||
});
|
||||
}
|
||||
|
||||
private async ensureKeyHasAppleTeamInfoAsync(
|
||||
ctx: CredentialsContext,
|
||||
ascApiKey: MinimalAscApiKey
|
||||
): Promise<AppleTeamFragment> {
|
||||
let appleTeamIdentifier = ascApiKey.teamId;
|
||||
if (!appleTeamIdentifier) {
|
||||
const chooseAssociatedAppleTeamIdAction = new ChooseAssociatedAppleTeamId(
|
||||
'App Store Connect API Key'
|
||||
);
|
||||
appleTeamIdentifier = await chooseAssociatedAppleTeamIdAction.runAsync(ctx);
|
||||
}
|
||||
const updateAppleTeamAction = new UpdateAppleTeamInfo(this.account, appleTeamIdentifier);
|
||||
return await updateAppleTeamAction.runAsync(ctx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { AppStoreApiKeyPurpose } from './AscApiKeyUtils';
|
||||
import { AppStoreConnectApiKeyFragment } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
|
||||
export class GetAscApiKey {
|
||||
constructor(
|
||||
private app: AppLookupParams,
|
||||
private purpose: AppStoreApiKeyPurpose
|
||||
) {}
|
||||
|
||||
public async runAsync(ctx: CredentialsContext): Promise<AppStoreConnectApiKeyFragment | null> {
|
||||
const appCredentials = await ctx.ios.getIosAppCredentialsWithCommonFieldsAsync(
|
||||
ctx.graphqlClient,
|
||||
this.app
|
||||
);
|
||||
if (this.purpose === AppStoreApiKeyPurpose.SUBMISSION_SERVICE) {
|
||||
return appCredentials?.appStoreConnectApiKeyForSubmissions ?? null;
|
||||
} else if (this.purpose === AppStoreApiKeyPurpose.BUILD_SERVICE) {
|
||||
const ascApiKey = appCredentials?.appStoreConnectApiKeyForBuilds;
|
||||
if (!ascApiKey) {
|
||||
return null;
|
||||
}
|
||||
const appleTeam = ascApiKey.appleTeam;
|
||||
const hasAppleTeamInfo =
|
||||
!!appleTeam && !!appleTeam.appleTeamIdentifier && !!appleTeam.appleTeamType;
|
||||
if (!hasAppleTeamInfo) {
|
||||
Log.warn(
|
||||
`App Store Connect API Key for ${this.purpose} is missing Apple Team information. Run "eas credentials" and select "Use an existing API Key" to update the missing information.`
|
||||
);
|
||||
return null;
|
||||
}
|
||||
return ascApiKey;
|
||||
} else {
|
||||
throw new Error(`App Store Connect API Keys are not yet supported for ${this.purpose}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,10 +110,13 @@ export class SetUpAscApiKey {
|
||||
ctx.graphqlClient,
|
||||
this.app
|
||||
);
|
||||
if (purpose !== AppStoreApiKeyPurpose.SUBMISSION_SERVICE) {
|
||||
if (purpose === AppStoreApiKeyPurpose.SUBMISSION_SERVICE) {
|
||||
return !!appCredentials?.appStoreConnectApiKeyForSubmissions;
|
||||
} else if (purpose === AppStoreApiKeyPurpose.BUILD_SERVICE) {
|
||||
return !!appCredentials?.appStoreConnectApiKeyForBuilds;
|
||||
} else {
|
||||
throw new Error(`App Store Connect API Key setup is not yet supported for ${purpose}.`);
|
||||
}
|
||||
return !!appCredentials?.appStoreConnectApiKeyForSubmissions;
|
||||
}
|
||||
|
||||
private async processChoicesAsync(
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { Teams } from '@expo/apple-utils';
|
||||
|
||||
import { AccountFragment, AppleTeamFragment, AppleTeamType } from '../../../graphql/generated';
|
||||
import { promptAsync } from '../../../prompts';
|
||||
import { CredentialsContext } from '../../context';
|
||||
import { AppleTeamQuery } from '../api/graphql/queries/AppleTeamQuery';
|
||||
|
||||
/* *
|
||||
* Update the Apple Team for the app.
|
||||
* If the user is logged in, we sync the Team info from the Developer Portal
|
||||
* Else we ask the user to choose their Team Type (Company/Organization, Individual, In-House)
|
||||
*/
|
||||
export class UpdateAppleTeamInfo {
|
||||
constructor(
|
||||
private account: AccountFragment,
|
||||
private appleTeamIdentifier: string
|
||||
) {}
|
||||
|
||||
public async runAsync(ctx: CredentialsContext): Promise<AppleTeamFragment> {
|
||||
const appleTeam = await AppleTeamQuery.getByAppleTeamIdentifierAsync(
|
||||
ctx.graphqlClient,
|
||||
this.account.id,
|
||||
this.appleTeamIdentifier
|
||||
);
|
||||
const hasAppleTeamInfo = !!appleTeam && !!appleTeam.appleTeamType;
|
||||
if (hasAppleTeamInfo) {
|
||||
return appleTeam;
|
||||
}
|
||||
|
||||
if (!ctx.appStore.authCtx) {
|
||||
return await this.promptAndUpdateAppleTeamTypeAsync(ctx);
|
||||
}
|
||||
const teams = await Teams.getTeamsAsync();
|
||||
const team = teams.find(t => t.teamId === this.appleTeamIdentifier);
|
||||
if (!team) {
|
||||
return await this.promptAndUpdateAppleTeamTypeAsync(ctx);
|
||||
}
|
||||
const { teamId, type, name } = team;
|
||||
const teamType = appStoreTeamTypeToEnum(type);
|
||||
return await ctx.ios.createOrUpdateExistingAppleTeamAsync(ctx.graphqlClient, this.account, {
|
||||
appleTeamIdentifier: teamId,
|
||||
appleTeamName: name,
|
||||
appleTeamType: teamType,
|
||||
});
|
||||
}
|
||||
|
||||
private async promptAndUpdateAppleTeamTypeAsync(
|
||||
ctx: CredentialsContext
|
||||
): Promise<AppleTeamFragment> {
|
||||
if (ctx.nonInteractive) {
|
||||
throw new Error(
|
||||
'Unable to get Apple Team information in non-interactive mode. Please re-run with interactive mode.'
|
||||
);
|
||||
}
|
||||
const teamType = await promptForAppleTeamTypeAsync();
|
||||
return await ctx.ios.createOrUpdateExistingAppleTeamAsync(ctx.graphqlClient, this.account, {
|
||||
appleTeamIdentifier: this.appleTeamIdentifier,
|
||||
appleTeamType: teamType,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function appStoreTeamTypeToEnum(
|
||||
teamType: 'In-House' | 'Company/Organization' | 'Individual' | string
|
||||
): AppleTeamType | null {
|
||||
if (teamType === 'In-House') {
|
||||
return AppleTeamType.InHouse;
|
||||
} else if (teamType === 'Company/Organization') {
|
||||
return AppleTeamType.CompanyOrOrganization;
|
||||
} else if (teamType === 'Individual') {
|
||||
return AppleTeamType.Individual;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
async function promptForAppleTeamTypeAsync(): Promise<AppleTeamType> {
|
||||
const { appleTeamType } = await promptAsync({
|
||||
type: 'select',
|
||||
message: 'Select your Apple Team Type:',
|
||||
name: 'appleTeamType',
|
||||
choices: [
|
||||
{ title: 'Enterprise', value: AppleTeamType.InHouse },
|
||||
{ title: 'Company/Organization', value: AppleTeamType.CompanyOrOrganization },
|
||||
{ title: 'Individual', value: AppleTeamType.Individual },
|
||||
],
|
||||
});
|
||||
return appleTeamType;
|
||||
}
|
||||
@@ -1,21 +1,15 @@
|
||||
import { UserRole } from '@expo/apple-utils';
|
||||
|
||||
import { promptAsync } from '../../../../prompts';
|
||||
import { getAppstoreMock, testAuthCtx } from '../../../__tests__/fixtures-appstore';
|
||||
import { createCtxMock } from '../../../__tests__/fixtures-context';
|
||||
import { testAscApiKey } from '../../../__tests__/fixtures-ios';
|
||||
import { getCredentialsFromUserAsync } from '../../../utils/promptForCredentials';
|
||||
import {
|
||||
AppStoreApiKeyPurpose,
|
||||
getAscApiKeyName,
|
||||
promptForAscApiKeyPathAsync,
|
||||
} from '../AscApiKeyUtils';
|
||||
import { getAscApiKeyName, promptForAscApiKeyPathAsync } from '../AscApiKeyUtils';
|
||||
|
||||
jest.mock('../../../../prompts');
|
||||
jest.mock('../../../utils/promptForCredentials');
|
||||
|
||||
function enumKeys<O extends object, K extends keyof O = keyof O>(obj: O): K[] {
|
||||
return Object.keys(obj) as K[];
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
jest.mocked(promptAsync).mockClear();
|
||||
jest.mocked(getCredentialsFromUserAsync).mockClear();
|
||||
@@ -24,11 +18,8 @@ afterEach(() => {
|
||||
describe(getAscApiKeyName, () => {
|
||||
// Apple enforces a 30 char limit on this name
|
||||
it('produces a name under 30 chars', async () => {
|
||||
for (const value of enumKeys(AppStoreApiKeyPurpose)) {
|
||||
const purpose = AppStoreApiKeyPurpose[value];
|
||||
const name = getAscApiKeyName(purpose);
|
||||
expect(name.length < 30).toBe(true);
|
||||
}
|
||||
const name = getAscApiKeyName();
|
||||
expect(name.length < 30).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,7 +42,7 @@ describe(promptForAscApiKeyPathAsync, () => {
|
||||
authCtx: null,
|
||||
},
|
||||
});
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx);
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx, [UserRole.ADMIN]);
|
||||
expect(ascApiKeyPath).toEqual({
|
||||
keyId: 'test-key-id',
|
||||
issuerId: 'test-issuer-id',
|
||||
@@ -76,7 +67,7 @@ describe(promptForAscApiKeyPathAsync, () => {
|
||||
getAscApiKeyAsync: jest.fn(() => testAscApiKey),
|
||||
},
|
||||
});
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx);
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx, [UserRole.ADMIN]);
|
||||
expect(ascApiKeyPath).toEqual({
|
||||
keyId: 'test-key-id',
|
||||
issuerId: 'test-issuer-id-from-apple',
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
AppleDistributionCertificateFragment,
|
||||
ApplePushKeyFragment,
|
||||
AppleTeamFragment,
|
||||
AppleTeamInput,
|
||||
CommonIosAppCredentialsFragment,
|
||||
IosAppBuildCredentialsFragment,
|
||||
IosDistributionType,
|
||||
@@ -189,28 +190,26 @@ export async function updateIosAppCredentialsAsync(
|
||||
{
|
||||
applePushKeyId,
|
||||
ascApiKeyIdForSubmissions,
|
||||
ascApiKeyIdForBuilds,
|
||||
}: {
|
||||
applePushKeyId?: string;
|
||||
ascApiKeyIdForSubmissions?: string;
|
||||
ascApiKeyIdForBuilds?: string;
|
||||
}
|
||||
): Promise<CommonIosAppCredentialsFragment> {
|
||||
let updatedAppCredentials = appCredentials;
|
||||
if (applePushKeyId) {
|
||||
updatedAppCredentials = await IosAppCredentialsMutation.setPushKeyAsync(
|
||||
graphqlClient,
|
||||
updatedAppCredentials.id,
|
||||
applePushKeyId
|
||||
);
|
||||
const updatedAppCredentials = appCredentials;
|
||||
if (!applePushKeyId && !ascApiKeyIdForSubmissions && !ascApiKeyIdForBuilds) {
|
||||
return updatedAppCredentials;
|
||||
}
|
||||
if (ascApiKeyIdForSubmissions) {
|
||||
updatedAppCredentials =
|
||||
await IosAppCredentialsMutation.setAppStoreConnectApiKeyForSubmissionsAsync(
|
||||
graphqlClient,
|
||||
updatedAppCredentials.id,
|
||||
ascApiKeyIdForSubmissions
|
||||
);
|
||||
}
|
||||
return updatedAppCredentials;
|
||||
return await IosAppCredentialsMutation.updateIosAppCredentialsAsync(
|
||||
graphqlClient,
|
||||
appCredentials.id,
|
||||
{
|
||||
pushKeyId: applePushKeyId,
|
||||
appStoreConnectApiKeyForSubmissionsId: ascApiKeyIdForSubmissions,
|
||||
appStoreConnectApiKeyForBuildsId: ascApiKeyIdForBuilds,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function createOrGetExistingIosAppCredentialsWithBuildCredentialsAsync(
|
||||
@@ -263,7 +262,42 @@ async function createOrGetExistingIosAppCredentialsWithBuildCredentialsAsync(
|
||||
export async function createOrGetExistingAppleTeamAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
account: AccountFragment,
|
||||
{ appleTeamIdentifier, appleTeamName }: { appleTeamIdentifier: string; appleTeamName?: string }
|
||||
{ appleTeamIdentifier, appleTeamName, appleTeamType }: AppleTeamInput
|
||||
): Promise<AppleTeamFragment> {
|
||||
return await createOrManageExistingAppleTeamAsync(
|
||||
graphqlClient,
|
||||
account,
|
||||
{
|
||||
appleTeamIdentifier,
|
||||
appleTeamName,
|
||||
appleTeamType,
|
||||
},
|
||||
{ updateMissingFields: false }
|
||||
);
|
||||
}
|
||||
|
||||
export async function createOrUpdateExistingAppleTeamAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
account: AccountFragment,
|
||||
{ appleTeamIdentifier, appleTeamName, appleTeamType }: AppleTeamInput
|
||||
): Promise<AppleTeamFragment> {
|
||||
return await createOrManageExistingAppleTeamAsync(
|
||||
graphqlClient,
|
||||
account,
|
||||
{
|
||||
appleTeamIdentifier,
|
||||
appleTeamName,
|
||||
appleTeamType,
|
||||
},
|
||||
{ updateMissingFields: true }
|
||||
);
|
||||
}
|
||||
|
||||
async function createOrManageExistingAppleTeamAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
account: AccountFragment,
|
||||
{ appleTeamIdentifier, appleTeamName, appleTeamType }: AppleTeamInput,
|
||||
{ updateMissingFields }: { updateMissingFields: boolean }
|
||||
): Promise<AppleTeamFragment> {
|
||||
const appleTeam = await AppleTeamQuery.getByAppleTeamIdentifierAsync(
|
||||
graphqlClient,
|
||||
@@ -271,11 +305,24 @@ export async function createOrGetExistingAppleTeamAsync(
|
||||
appleTeamIdentifier
|
||||
);
|
||||
if (appleTeam) {
|
||||
const didTeamNameChange = appleTeamName && appleTeam.appleTeamName !== appleTeamName;
|
||||
const didTeamTypeChange = appleTeamType && appleTeam.appleTeamType !== appleTeamType;
|
||||
const didFieldsChange = didTeamNameChange || didTeamTypeChange;
|
||||
if (updateMissingFields && didFieldsChange) {
|
||||
return await AppleTeamMutation.updateAppleTeamAsync(
|
||||
graphqlClient,
|
||||
{
|
||||
appleTeamName: didTeamNameChange ? appleTeamName : undefined,
|
||||
appleTeamType: didTeamTypeChange ? appleTeamType : undefined,
|
||||
},
|
||||
appleTeam.id
|
||||
);
|
||||
}
|
||||
return appleTeam;
|
||||
} else {
|
||||
return await AppleTeamMutation.createAppleTeamAsync(
|
||||
graphqlClient,
|
||||
{ appleTeamIdentifier, appleTeamName },
|
||||
{ appleTeamIdentifier, appleTeamName, appleTeamType },
|
||||
account.id
|
||||
);
|
||||
}
|
||||
@@ -521,6 +568,20 @@ export async function createAscApiKeyAsync(
|
||||
);
|
||||
}
|
||||
|
||||
export async function updateAscApiKeyAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
ascApiKey: AppStoreConnectApiKeyFragment,
|
||||
appleTeam: AppleTeamFragment
|
||||
): Promise<AppStoreConnectApiKeyFragment> {
|
||||
return await AppStoreConnectApiKeyMutation.updateAppStoreConnectApiKeyAsync(
|
||||
graphqlClient,
|
||||
{
|
||||
appleTeamId: appleTeam.id,
|
||||
},
|
||||
ascApiKey.id
|
||||
);
|
||||
}
|
||||
|
||||
export async function getAscApiKeysForAccountAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
account: AccountFragment
|
||||
|
||||
+40
@@ -7,8 +7,10 @@ import { withErrorHandlingAsync } from '../../../../../graphql/client';
|
||||
import {
|
||||
AppStoreConnectApiKeyFragment,
|
||||
AppStoreConnectApiKeyInput,
|
||||
AppStoreConnectApiKeyUpdateInput,
|
||||
CreateAppStoreConnectApiKeyMutation,
|
||||
DeleteAppStoreConnectApiKeyMutation,
|
||||
UpdateAppStoreConnectApiKeyMutation,
|
||||
} from '../../../../../graphql/generated';
|
||||
import { AppStoreConnectApiKeyFragmentNode } from '../../../../../graphql/types/credentials/AppStoreConnectApiKey';
|
||||
|
||||
@@ -51,6 +53,44 @@ export const AppStoreConnectApiKeyMutation = {
|
||||
);
|
||||
return data.appStoreConnectApiKey.createAppStoreConnectApiKey;
|
||||
},
|
||||
async updateAppStoreConnectApiKeyAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
appStoreConnectApiKeyUpdateInput: AppStoreConnectApiKeyUpdateInput,
|
||||
appStoreConnectApiKeyId: string
|
||||
): Promise<AppStoreConnectApiKeyFragment> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<UpdateAppStoreConnectApiKeyMutation>(
|
||||
gql`
|
||||
mutation UpdateAppStoreConnectApiKeyMutation(
|
||||
$appStoreConnectApiKeyUpdateInput: AppStoreConnectApiKeyUpdateInput!
|
||||
$id: ID!
|
||||
) {
|
||||
appStoreConnectApiKey {
|
||||
updateAppStoreConnectApiKey(
|
||||
appStoreConnectApiKeyUpdateInput: $appStoreConnectApiKeyUpdateInput
|
||||
id: $id
|
||||
) {
|
||||
id
|
||||
...AppStoreConnectApiKeyFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
${print(AppStoreConnectApiKeyFragmentNode)}
|
||||
`,
|
||||
{
|
||||
appStoreConnectApiKeyUpdateInput,
|
||||
appStoreConnectApiKeyId,
|
||||
}
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
assert(
|
||||
data.appStoreConnectApiKey.updateAppStoreConnectApiKey,
|
||||
'GraphQL: `updateAppStoreConnectApiKey` not defined in server response'
|
||||
);
|
||||
return data.appStoreConnectApiKey.updateAppStoreConnectApiKey;
|
||||
},
|
||||
async deleteAppStoreConnectApiKeyAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
appStoreConnectApiKeyId: string
|
||||
|
||||
@@ -7,7 +7,9 @@ import {
|
||||
AccountFragment,
|
||||
AppleTeamFragment,
|
||||
AppleTeamInput,
|
||||
AppleTeamUpdateInput,
|
||||
CreateAppleTeamMutation,
|
||||
UpdateAppleTeamMutation,
|
||||
} from '../../../../../graphql/generated';
|
||||
import { AccountFragmentNode } from '../../../../../graphql/types/Account';
|
||||
import { AppleTeamFragmentNode } from '../../../../../graphql/types/credentials/AppleTeam';
|
||||
@@ -50,4 +52,40 @@ export const AppleTeamMutation = {
|
||||
);
|
||||
return data.appleTeam.createAppleTeam;
|
||||
},
|
||||
async updateAppleTeamAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
appleTeamUpdateInput: AppleTeamUpdateInput,
|
||||
appleTeamId: string
|
||||
): Promise<AppleTeamMutationResult> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<UpdateAppleTeamMutation>(
|
||||
gql`
|
||||
mutation UpdateAppleTeamMutation(
|
||||
$appleTeamUpdateInput: AppleTeamUpdateInput!
|
||||
$appleTeamId: ID!
|
||||
) {
|
||||
appleTeam {
|
||||
updateAppleTeam(appleTeamUpdateInput: $appleTeamUpdateInput, id: $appleTeamId) {
|
||||
id
|
||||
...AppleTeamFragment
|
||||
account {
|
||||
id
|
||||
...AccountFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${print(AppleTeamFragmentNode)}
|
||||
${print(AccountFragmentNode)}
|
||||
`,
|
||||
{
|
||||
appleTeamUpdateInput,
|
||||
appleTeamId,
|
||||
}
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
return data.appleTeam.updateAppleTeam;
|
||||
},
|
||||
};
|
||||
+39
@@ -10,6 +10,7 @@ import {
|
||||
IosAppCredentialsInput,
|
||||
SetAppStoreConnectApiKeyForSubmissionsMutation,
|
||||
SetPushKeyMutation,
|
||||
UpdateIosAppCredentialsMutation,
|
||||
} from '../../../../../graphql/generated';
|
||||
import { CommonIosAppCredentialsFragmentNode } from '../../../../../graphql/types/credentials/IosAppCredentials';
|
||||
|
||||
@@ -56,6 +57,44 @@ export const IosAppCredentialsMutation = {
|
||||
);
|
||||
return data.iosAppCredentials.createIosAppCredentials;
|
||||
},
|
||||
async updateIosAppCredentialsAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
iosAppCredentialsId: string,
|
||||
iosAppCredentialsInput: IosAppCredentialsInput
|
||||
): Promise<CommonIosAppCredentialsFragment> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<UpdateIosAppCredentialsMutation>(
|
||||
gql`
|
||||
mutation UpdateIosAppCredentialsMutation(
|
||||
$iosAppCredentialsInput: IosAppCredentialsInput!
|
||||
$iosAppCredentialsId: ID!
|
||||
) {
|
||||
iosAppCredentials {
|
||||
updateIosAppCredentials(
|
||||
id: $iosAppCredentialsId
|
||||
iosAppCredentialsInput: $iosAppCredentialsInput
|
||||
) {
|
||||
id
|
||||
...CommonIosAppCredentialsFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
${print(CommonIosAppCredentialsFragmentNode)}
|
||||
`,
|
||||
{
|
||||
iosAppCredentialsInput,
|
||||
iosAppCredentialsId,
|
||||
}
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
assert(
|
||||
data.iosAppCredentials.updateIosAppCredentials,
|
||||
'GraphQL: `updateIosAppCredentials` not defined in server response'
|
||||
);
|
||||
return data.iosAppCredentials.updateIosAppCredentials;
|
||||
},
|
||||
async setPushKeyAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
iosAppCredentialsId: string,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ProfileType } from '@expo/app-store';
|
||||
import { ProfileType, UserRole } from '@expo/app-store';
|
||||
|
||||
import {
|
||||
AscApiKey,
|
||||
@@ -45,16 +45,23 @@ import { createOrReuseAdhocProvisioningProfileAsync } from './provisioningProfil
|
||||
import { createPushKeyAsync, listPushKeysAsync, revokePushKeyAsync } from './pushKey';
|
||||
import { hasAscEnvVars } from './resolveCredentials';
|
||||
import { Analytics } from '../../../analytics/AnalyticsManager';
|
||||
import { AppleTeamType } from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { MinimalAscApiKey } from '../credentials';
|
||||
|
||||
type AscApiKeyAuth = {
|
||||
ascApiKey: MinimalAscApiKey;
|
||||
appleTeam: { teamIdentifier: string; teamName?: string; teamType: AppleTeamType };
|
||||
};
|
||||
export default class AppStoreApi {
|
||||
public authCtx?: AuthCtx;
|
||||
public defaultAuthenticationMode: AuthenticationMode;
|
||||
public readonly ascApiKeyAuth?: AscApiKeyAuth;
|
||||
|
||||
constructor() {
|
||||
this.defaultAuthenticationMode = hasAscEnvVars()
|
||||
? AuthenticationMode.API_KEY
|
||||
: AuthenticationMode.USER;
|
||||
constructor(options: { ascApiKeyAuth?: AscApiKeyAuth } = {}) {
|
||||
this.ascApiKeyAuth = options.ascApiKeyAuth;
|
||||
this.defaultAuthenticationMode =
|
||||
hasAscEnvVars() || this.ascApiKeyAuth ? AuthenticationMode.API_KEY : AuthenticationMode.USER;
|
||||
}
|
||||
|
||||
public async ensureUserAuthenticatedAsync(options?: AuthenticateOptions): Promise<UserAuthCtx> {
|
||||
@@ -195,10 +202,10 @@ export default class AppStoreApi {
|
||||
|
||||
public async createAscApiKeyAsync(
|
||||
analytics: Analytics,
|
||||
{ nickname }: { nickname: string }
|
||||
{ nickname, roles }: { nickname: string; roles: UserRole[] }
|
||||
): Promise<AscApiKey> {
|
||||
const userCtx = await this.ensureUserAuthenticatedAsync();
|
||||
return await createAscApiKeyAsync(analytics, userCtx, { nickname });
|
||||
return await createAscApiKeyAsync(analytics, userCtx, { nickname, roles });
|
||||
}
|
||||
|
||||
public async revokeAscApiKeyAsync(keyId: string): Promise<AscApiKeyInfo> {
|
||||
|
||||
@@ -9,6 +9,7 @@ export enum AuthenticationMode {
|
||||
USER,
|
||||
}
|
||||
|
||||
// TODO: move this to graphql types
|
||||
export enum AppleTeamType {
|
||||
IN_HOUSE = 'IN_HOUSE',
|
||||
COMPANY_OR_ORGANIZATION = 'COMPANY_OR_ORGANIZATION',
|
||||
|
||||
+50
-50
@@ -1,54 +1,54 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`print credentials prints the IosAppCredentials map 1`] = `
|
||||
"iOS Credentials
|
||||
Project @quinlanj/test52
|
||||
Bundle Identifier com.quinlanj.test52
|
||||
Apple Team test-apple-identifier
|
||||
|
||||
Push Key
|
||||
Developer Portal ID 9839M6AY8W
|
||||
Apple Team 77KQ969CHE
|
||||
Updated 6 months ago
|
||||
|
||||
App Store Connect API Key
|
||||
Developer Portal ID NYN468XNN3
|
||||
Name Expo Submissions pl94k8_lnS
|
||||
Issuer ID 69a6de93-e4e4-47e3-e053-5b8c7c11a4d1
|
||||
Roles ADMIN
|
||||
Apple Team 77KQ969CHE
|
||||
Updated 6 months ago
|
||||
|
||||
|
||||
App Store Configuration
|
||||
|
||||
Distribution Certificate
|
||||
Serial Number test-serial
|
||||
Expiration Date Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 6 months ago
|
||||
|
||||
Provisioning Profile
|
||||
Developer Portal ID test-profile-id
|
||||
Status active
|
||||
Expiration Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 5 months ago
|
||||
|
||||
|
||||
Ad Hoc Configuration
|
||||
|
||||
Distribution Certificate
|
||||
Serial Number test-serial
|
||||
Expiration Date Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 6 months ago
|
||||
|
||||
Provisioning Profile
|
||||
Developer Portal ID test-profile-id
|
||||
Status active
|
||||
Expiration Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 5 months ago
|
||||
"
|
||||
"iOS Credentials
|
||||
Project @quinlanj/test52
|
||||
Bundle Identifier com.quinlanj.test52
|
||||
Apple Team test-apple-identifier
|
||||
|
||||
Push Key
|
||||
Developer Portal ID 9839M6AY8W
|
||||
Apple Team 77KQ969CHE
|
||||
Updated 6 months ago
|
||||
|
||||
EAS Submit App Store Connect API Key
|
||||
Developer Portal ID NYN468XNN3
|
||||
Name Expo Submissions pl94k8_lnS
|
||||
Issuer ID 69a6de93-e4e4-47e3-e053-5b8c7c11a4d1
|
||||
Roles ADMIN
|
||||
Apple Team 77KQ969CHE
|
||||
Updated 6 months ago
|
||||
|
||||
|
||||
App Store Configuration
|
||||
|
||||
Distribution Certificate
|
||||
Serial Number test-serial
|
||||
Expiration Date Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 6 months ago
|
||||
|
||||
Provisioning Profile
|
||||
Developer Portal ID test-profile-id
|
||||
Status active
|
||||
Expiration Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 5 months ago
|
||||
|
||||
|
||||
Ad Hoc Configuration
|
||||
|
||||
Distribution Certificate
|
||||
Serial Number test-serial
|
||||
Expiration Date Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 6 months ago
|
||||
|
||||
Provisioning Profile
|
||||
Developer Portal ID test-profile-id
|
||||
Status active
|
||||
Expiration Wed, 13 Oct 2021 18:28:44 UTC
|
||||
Apple Team test-apple-identifier
|
||||
Updated 5 months ago
|
||||
"
|
||||
`;
|
||||
@@ -12,6 +12,7 @@ import { APPLE_DEVICE_CLASS_LABELS } from '../../../graphql/types/credentials/Ap
|
||||
import Log from '../../../log';
|
||||
import { fromNow } from '../../../utils/date';
|
||||
import formatFields from '../../../utils/formatFields';
|
||||
import { AppStoreApiKeyPurpose } from '../actions/AscApiKeyUtils';
|
||||
import { AppLookupParams } from '../api/graphql/types/AppLookupParams';
|
||||
import { App, IosAppBuildCredentialsMap, IosAppCredentialsMap, Target } from '../types';
|
||||
|
||||
@@ -92,7 +93,12 @@ export function displayIosCredentials(
|
||||
continue;
|
||||
}
|
||||
|
||||
const { appleTeam, pushKey, appStoreConnectApiKeyForSubmissions } = targetAppCredentials;
|
||||
const {
|
||||
appleTeam,
|
||||
pushKey,
|
||||
appStoreConnectApiKeyForSubmissions,
|
||||
appStoreConnectApiKeyForBuilds,
|
||||
} = targetAppCredentials;
|
||||
if (appleTeam) {
|
||||
const { appleTeamIdentifier, appleTeamName } = appleTeam;
|
||||
fields.push({
|
||||
@@ -107,7 +113,15 @@ export function displayIosCredentials(
|
||||
}
|
||||
|
||||
if (appStoreConnectApiKeyForSubmissions) {
|
||||
displayAscApiKey(appStoreConnectApiKeyForSubmissions, fields);
|
||||
displayAscApiKey(
|
||||
AppStoreApiKeyPurpose.SUBMISSION_SERVICE,
|
||||
appStoreConnectApiKeyForSubmissions,
|
||||
fields
|
||||
);
|
||||
}
|
||||
|
||||
if (appStoreConnectApiKeyForBuilds) {
|
||||
displayAscApiKey(AppStoreApiKeyPurpose.BUILD_SERVICE, appStoreConnectApiKeyForBuilds, fields);
|
||||
}
|
||||
|
||||
const sortedIosAppBuildCredentialsList = sortBuildCredentialsByDistributionType(
|
||||
@@ -236,10 +250,11 @@ function displayApplePushKey(
|
||||
}
|
||||
|
||||
function displayAscApiKey(
|
||||
purpose: AppStoreApiKeyPurpose,
|
||||
maybeAscApiKey: AppStoreConnectApiKeyFragment | null,
|
||||
fields: { label: string; value: string }[]
|
||||
): void {
|
||||
fields.push({ label: 'App Store Connect API Key', value: '' });
|
||||
fields.push({ label: `${purpose.toString()} App Store Connect API Key`, value: '' });
|
||||
if (maybeAscApiKey) {
|
||||
const { keyIdentifier, issuerIdentifier, appleTeam, name, roles, updatedAt } = maybeAscApiKey;
|
||||
fields.push({ label: 'Developer Portal ID', value: keyIdentifier });
|
||||
|
||||
@@ -29,7 +29,6 @@ export enum AndroidActionType {
|
||||
UseExistingGsaKeyForSubmissions,
|
||||
RemoveGsaKey,
|
||||
SetUpGsaKeyForSubmissions,
|
||||
CreateGsaKeyForFcmV1,
|
||||
UseExistingGsaKeyForFcmV1,
|
||||
RemoveGsaKeyForFcmV1,
|
||||
SetUpGsaKeyForFcmV1,
|
||||
@@ -56,8 +55,8 @@ export enum IosActionType {
|
||||
CreatePushKey,
|
||||
UseExistingPushKey,
|
||||
RemovePushKey,
|
||||
SetUpAscApiKeyForSubmissions,
|
||||
UseExistingAscApiKeyForSubmissions,
|
||||
CreateAscApiKeyForSubmissions,
|
||||
SetUpAscApiKeyForService,
|
||||
CreateAscApiKeyForService,
|
||||
UseExistingAscApiKeyForService,
|
||||
RemoveAscApiKey,
|
||||
}
|
||||
@@ -77,22 +77,22 @@ export function getPushKeyActions(ctx: CredentialsContext): ActionInfo[] {
|
||||
];
|
||||
}
|
||||
|
||||
export function getAscApiKeyActions(ctx: CredentialsContext): ActionInfo[] {
|
||||
export function getAscApiKeyActions(): ActionInfo[] {
|
||||
return [
|
||||
{
|
||||
value: IosActionType.SetUpAscApiKeyForSubmissions,
|
||||
title: 'Set up your project to use an API Key for EAS Submit',
|
||||
value: IosActionType.SetUpAscApiKeyForService,
|
||||
title: `Set up your project to use an API Key`,
|
||||
scope: Scope.Project,
|
||||
},
|
||||
{
|
||||
value: IosActionType.UseExistingAscApiKeyForSubmissions,
|
||||
title: 'Use an existing API Key for EAS Submit',
|
||||
value: IosActionType.UseExistingAscApiKeyForService,
|
||||
title: `Use an existing API Key in your project`,
|
||||
scope: Scope.Project,
|
||||
},
|
||||
{
|
||||
value: IosActionType.CreateAscApiKeyForSubmissions,
|
||||
title: 'Add a new API Key For EAS Submit',
|
||||
scope: ctx.hasProjectContext ? Scope.Project : Scope.Account,
|
||||
value: IosActionType.CreateAscApiKeyForService,
|
||||
title: `Add a new API Key to use in your project`,
|
||||
scope: Scope.Project,
|
||||
},
|
||||
{
|
||||
value: IosActionType.RemoveAscApiKey,
|
||||
|
||||
@@ -85,7 +85,7 @@ export class ManageIos {
|
||||
});
|
||||
const buildCredentialsActions = getBuildCredentialsActions(ctx);
|
||||
const pushKeyActions = getPushKeyActions(ctx);
|
||||
const ascApiKeyActions = getAscApiKeyActions(ctx);
|
||||
const ascApiKeyActions = getAscApiKeyActions();
|
||||
|
||||
await ctx.bestEffortAppStoreAuthenticateAsync();
|
||||
|
||||
@@ -226,8 +226,6 @@ export class ManageIos {
|
||||
await new CreateDistributionCertificate(account).runAsync(ctx);
|
||||
} else if (action === IosActionType.CreatePushKey) {
|
||||
await new CreatePushKey(account).runAsync(ctx);
|
||||
} else if (action === IosActionType.CreateAscApiKeyForSubmissions) {
|
||||
await new CreateAscApiKey(account).runAsync(ctx, AppStoreApiKeyPurpose.SUBMISSION_SERVICE);
|
||||
} else if (action === IosActionType.RemovePushKey) {
|
||||
await new SelectAndRemovePushKey(account).runAsync(ctx);
|
||||
} else if (action === IosActionType.RemoveAscApiKey) {
|
||||
@@ -354,40 +352,29 @@ export class ManageIos {
|
||||
}
|
||||
return;
|
||||
}
|
||||
case IosActionType.SetUpAscApiKeyForSubmissions: {
|
||||
await new SetUpAscApiKey(
|
||||
appLookupParams,
|
||||
AppStoreApiKeyPurpose.SUBMISSION_SERVICE
|
||||
).runAsync(ctx);
|
||||
case IosActionType.SetUpAscApiKeyForService: {
|
||||
const purpose = await this.selectAscApiKeyPurposeAsync();
|
||||
await new SetUpAscApiKey(appLookupParams, purpose).runAsync(ctx);
|
||||
return;
|
||||
}
|
||||
case IosActionType.UseExistingAscApiKeyForSubmissions: {
|
||||
case IosActionType.UseExistingAscApiKeyForService: {
|
||||
const purpose = await this.selectAscApiKeyPurposeAsync();
|
||||
const ascApiKey = await selectAscApiKeysFromAccountAsync(ctx, appLookupParams.account, {
|
||||
filterDifferentAppleTeam: true,
|
||||
});
|
||||
if (ascApiKey) {
|
||||
await new AssignAscApiKey(appLookupParams).runAsync(
|
||||
ctx,
|
||||
ascApiKey,
|
||||
AppStoreApiKeyPurpose.SUBMISSION_SERVICE
|
||||
);
|
||||
await new AssignAscApiKey(appLookupParams).runAsync(ctx, ascApiKey, purpose);
|
||||
}
|
||||
return;
|
||||
}
|
||||
case IosActionType.CreateAscApiKeyForSubmissions: {
|
||||
const ascApiKey = await new CreateAscApiKey(appLookupParams.account).runAsync(
|
||||
ctx,
|
||||
AppStoreApiKeyPurpose.SUBMISSION_SERVICE
|
||||
);
|
||||
case IosActionType.CreateAscApiKeyForService: {
|
||||
const purpose = await this.selectAscApiKeyPurposeAsync();
|
||||
const ascApiKey = await new CreateAscApiKey(appLookupParams.account).runAsync(ctx, purpose);
|
||||
const confirm = await confirmAsync({
|
||||
message: `Do you want ${appLookupParams.projectName} to use the new API Key?`,
|
||||
});
|
||||
if (confirm) {
|
||||
await new AssignAscApiKey(appLookupParams).runAsync(
|
||||
ctx,
|
||||
ascApiKey,
|
||||
AppStoreApiKeyPurpose.SUBMISSION_SERVICE
|
||||
);
|
||||
await new AssignAscApiKey(appLookupParams).runAsync(ctx, ascApiKey, purpose);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -431,4 +418,17 @@ export class ManageIos {
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
protected async selectAscApiKeyPurposeAsync(): Promise<AppStoreApiKeyPurpose> {
|
||||
const { keyPurpose } = await promptAsync({
|
||||
type: 'select',
|
||||
message: `Select the service you'd like to use your ASC Api Key for:`,
|
||||
name: 'keyPurpose',
|
||||
choices: [
|
||||
{ title: 'EAS Submit', value: AppStoreApiKeyPurpose.SUBMISSION_SERVICE },
|
||||
{ title: 'EAS Build', value: AppStoreApiKeyPurpose.BUILD_SERVICE },
|
||||
],
|
||||
});
|
||||
return keyPurpose;
|
||||
}
|
||||
}
|
||||
+6048
-820
File diff suppressed because it is too large.
Load diff
@@ -14,6 +14,8 @@ import {
|
||||
} from '../generated';
|
||||
import { UpdateFragmentNode } from '../types/Update';
|
||||
|
||||
const turtleJobRunId = process.env.EAS_BUILD_ID;
|
||||
|
||||
export const PublishMutation = {
|
||||
async getUploadURLsAsync(
|
||||
graphqlClient: ExpoGraphqlClient,
|
||||
@@ -57,7 +59,12 @@ export const PublishMutation = {
|
||||
}
|
||||
${print(UpdateFragmentNode)}
|
||||
`,
|
||||
{ publishUpdateGroupsInput }
|
||||
{
|
||||
publishUpdateGroupsInput: publishUpdateGroupsInput.map(input => ({
|
||||
...input,
|
||||
turtleJobRunId,
|
||||
})),
|
||||
}
|
||||
)
|
||||
.toPromise()
|
||||
);
|
||||
|
||||
@@ -5,5 +5,6 @@ export const AppleTeamFragmentNode = gql`
|
||||
id
|
||||
appleTeamIdentifier
|
||||
appleTeamName
|
||||
appleTeamType
|
||||
}
|
||||
`;
|
||||
@@ -30,6 +30,10 @@ export const CommonIosAppCredentialsWithoutBuildCredentialsFragmentNode = gql`
|
||||
id
|
||||
...AppStoreConnectApiKeyFragment
|
||||
}
|
||||
appStoreConnectApiKeyForBuilds {
|
||||
id
|
||||
...AppStoreConnectApiKeyFragment
|
||||
}
|
||||
}
|
||||
${AppFragmentNode}
|
||||
${AppleTeamFragmentNode}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { UserRole } from '@expo/apple-utils';
|
||||
import { Platform } from '@expo/eas-build-job';
|
||||
import fs from 'fs-extra';
|
||||
import nullthrows from 'nullthrows';
|
||||
@@ -189,7 +190,7 @@ async function handlePromptSourceAsync(
|
||||
ctx: SubmissionContext<Platform.IOS>,
|
||||
_source: AscApiKeyPromptSource
|
||||
): Promise<AscApiKeyPath> {
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx.credentialsCtx);
|
||||
const ascApiKeyPath = await promptForAscApiKeyPathAsync(ctx.credentialsCtx, [UserRole.ADMIN]);
|
||||
return await getAscApiKeyPathAsync(ctx, {
|
||||
sourceType: AscApiKeySourceType.path,
|
||||
path: ascApiKeyPath,
|
||||
|
||||
Reference in new issue
Block a user