mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-14 10:08:06 -10:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f20d970616 | ||
|
|
f3712d5dfb | ||
|
|
cba211d82c |
No files matched your search
@@ -12,9 +12,6 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Upgrade [`eas-build`](https://github.com/expo/eas-build) dependencies. ([#2387](https://github.com/expo/eas-cli/pull/2387) by [@expo-bot](https://github.com/expo-bot))
|
||||
- Improve displaying of device registration QR code. ([#2391](https://github.com/expo/eas-cli/pull/2391) by [@szdziedzic](https://github.com/szdziedzic))
|
||||
|
||||
## [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
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"version": "9.0.8",
|
||||
"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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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.8/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
+10
-30
@@ -18828,12 +18828,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "REPACK",
|
||||
"description": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "RESIGN",
|
||||
"description": null,
|
||||
@@ -22844,6 +22838,16 @@
|
||||
"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": "DeploymentsMutation",
|
||||
@@ -25030,18 +25034,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "repack",
|
||||
"description": "Repack the golden dev client build instead of running full build process. Used for onboarding. Do not use outside of onboarding flow, as for now it's only created with this specific use case in mind.",
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "submitProfile",
|
||||
"description": null,
|
||||
@@ -29860,18 +29852,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "gitCommitMessage",
|
||||
"description": null,
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "gitRef",
|
||||
"description": null,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "eas-cli",
|
||||
"description": "EAS command line tool",
|
||||
"version": "9.0.8",
|
||||
"version": "9.0.7",
|
||||
"author": "Expo <[email protected]>",
|
||||
"bin": {
|
||||
"eas": "./bin/run"
|
||||
@@ -13,8 +13,8 @@
|
||||
"@expo/config": "8.5.4",
|
||||
"@expo/config-plugins": "7.8.4",
|
||||
"@expo/config-types": "50.0.0",
|
||||
"@expo/eas-build-job": "1.0.114",
|
||||
"@expo/eas-json": "9.0.8",
|
||||
"@expo/eas-build-job": "1.0.108",
|
||||
"@expo/eas-json": "9.0.4",
|
||||
"@expo/json-file": "8.2.37",
|
||||
"@expo/logger": "1.0.57",
|
||||
"@expo/multipart-body-parser": "1.1.0",
|
||||
@@ -28,7 +28,7 @@
|
||||
"@expo/results": "1.0.0",
|
||||
"@expo/rudder-sdk-node": "1.1.1",
|
||||
"@expo/spawn-async": "1.7.0",
|
||||
"@expo/steps": "1.0.114",
|
||||
"@expo/steps": "1.0.108",
|
||||
"@expo/timeago.js": "1.0.0",
|
||||
"@oclif/core": "^1.26.2",
|
||||
"@oclif/plugin-autocomplete": "^2.3.10",
|
||||
|
||||
@@ -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';
|
||||
@@ -155,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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ const buildModeToGraphQLBuildMode: Record<BuildMode, GraphQLBuildMode> = {
|
||||
[BuildMode.BUILD]: GraphQLBuildMode.Build,
|
||||
[BuildMode.CUSTOM]: GraphQLBuildMode.Custom,
|
||||
[BuildMode.RESIGN]: GraphQLBuildMode.Resign,
|
||||
[BuildMode.REPACK]: GraphQLBuildMode.Repack,
|
||||
};
|
||||
|
||||
export function transformBuildMode(buildMode: BuildMode): GraphQLBuildMode {
|
||||
|
||||
@@ -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}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -352,6 +352,7 @@ export class SetUpAdhocProvisioningProfile {
|
||||
|
||||
while (true) {
|
||||
if (method === RegistrationMethod.WEBSITE) {
|
||||
Log.newLine();
|
||||
Log.log(chalk.bold("Press any key if you've already finished device registration."));
|
||||
await pressAnyKeyToContinueAsync();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,7 @@ export async function runRegistrationUrlMethodAsync(
|
||||
Log.log(
|
||||
'Open the following link on your iOS devices (or scan the QR code) and follow the instructions to install the development profile:'
|
||||
);
|
||||
Log.newLine();
|
||||
Log.log(chalk.green(`${registrationURL}`));
|
||||
}
|
||||
|
||||
|
||||
+6026
-825
File diff suppressed because it is too large.
Load diff
@@ -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,
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@expo/eas-json",
|
||||
"description": "A library for interacting with eas.json",
|
||||
"version": "9.0.8",
|
||||
"version": "9.0.4",
|
||||
"author": "Expo <[email protected]>",
|
||||
"bugs": "https://github.com/expo/eas-cli/issues",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "7.23.5",
|
||||
"@expo/eas-build-job": "1.0.114",
|
||||
"@expo/eas-build-job": "1.0.108",
|
||||
"chalk": "4.1.2",
|
||||
"env-string": "1.0.1",
|
||||
"fs-extra": "11.2.0",
|
||||
|
||||
@@ -1462,10 +1462,10 @@
|
||||
slugify "^1.3.4"
|
||||
sucrase "^3.20.0"
|
||||
|
||||
"@expo/[email protected]14":
|
||||
version "1.0.114"
|
||||
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.114.tgz#81b69f05ff8a85a2698cba3a603b936739ab8a08"
|
||||
integrity sha512-71zFqQmHVUGfSWcd3NZ+y1LEWLUJ+qNN2ZMwRzfOty75CFFwKJ2gPUm5b19Q3SlEmUUwI67RO/D/B2M7OlDjHw==
|
||||
"@expo/[email protected]08":
|
||||
version "1.0.108"
|
||||
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.108.tgz#198e189beff4ca2405ab68ee04395878cff45084"
|
||||
integrity sha512-4FjqsK+k2KLjfWBT08ECFmlWH5yE9vw7vQmKzM4N8uQHKA/SbA6mMMto/f8XSbs7f5y6kdGnB7pxcMH91RuxbA==
|
||||
dependencies:
|
||||
"@expo/logger" "1.0.57"
|
||||
joi "^17.11.0"
|
||||
@@ -1667,12 +1667,12 @@
|
||||
dependencies:
|
||||
cross-spawn "^7.0.3"
|
||||
|
||||
"@expo/[email protected]14":
|
||||
version "1.0.114"
|
||||
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.114.tgz#8f000fe389228183e86c650c0cd73e1b9db45caf"
|
||||
integrity sha512-TbSCv2cXQQKRXPjZ5BQwo5H4gNNXF05+oWQBaR0k98A4MFXfiaoyAPK/7No2xNj7xBC3rXU+dKzTjMMnTlyt/w==
|
||||
"@expo/[email protected]08":
|
||||
version "1.0.108"
|
||||
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.108.tgz#3d06486108ce27c898799ed8e6a33ff4bdf6b8f8"
|
||||
integrity sha512-MUZE4MkY20Y5y1oKDGvnRFFtue5qtkC/l9gsPW2rAxBe9lXSVIGhfSpIDk0MUgd0sjdJbO/qDmYbrqf09qj/lA==
|
||||
dependencies:
|
||||
"@expo/eas-build-job" "1.0.114"
|
||||
"@expo/eas-build-job" "1.0.108"
|
||||
"@expo/logger" "1.0.57"
|
||||
"@expo/spawn-async" "^1.7.2"
|
||||
arg "^5.0.2"
|
||||
|
||||
Reference in new issue
Block a user