mirror of
https://github.com/expo/eas-cli.git
synced 2026-11-15 03:38:08 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2364ed74d7 | ||
|
|
87fb74dd5a | ||
|
|
eef0c6ae6e | ||
|
|
5ee905a977 | ||
|
|
ca3e083995 | ||
|
|
b7ae91892c | ||
|
|
508ca745c1 | ||
|
|
95e8a38c85 | ||
|
|
441f3eaf4c | ||
|
|
9edb10ca55 | ||
|
|
7f094bc605 | ||
|
|
2463e958aa | ||
|
|
390e6fef9e | ||
|
|
6b416c3dfb | ||
|
|
60d2daf4c8 | ||
|
|
9528f25ff2 | ||
|
|
5da03dfca7 | ||
|
|
8b3b0376c3 | ||
|
|
5f3c4756d2 | ||
|
|
3b34a64893 | ||
|
|
243cf8d630 | ||
|
|
671ce30ed4 | ||
|
|
9021887072 | ||
|
|
6a80d4c8e9 | ||
|
|
471e26817a |
No files matched your search
+30
-12
@@ -1,14 +1,7 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['universe/node'],
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/__tests__/*'],
|
||||
},
|
||||
],
|
||||
globals: {
|
||||
jasmine: false,
|
||||
},
|
||||
plugins: ['async-protect'],
|
||||
rules: {
|
||||
'no-console': 'warn',
|
||||
'no-constant-condition': ['warn', { checkLoops: false }],
|
||||
@@ -21,10 +14,35 @@ module.exports = {
|
||||
'flowtype/no-types-missing-file-annotation': 'off',
|
||||
curly: 'warn',
|
||||
'import/no-relative-packages': 'error',
|
||||
'no-restricted-imports': [
|
||||
'error',
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: 'lodash',
|
||||
message: "Don't use lodash, it's heavy!",
|
||||
},
|
||||
{
|
||||
name: 'node-fetch',
|
||||
message: 'Use got instead, node-fetch is used only for the GraphQL client.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/explicit-function-return-type': [
|
||||
'warn',
|
||||
{
|
||||
allowExpressions: true,
|
||||
},
|
||||
],
|
||||
'async-protect/async-suffix': 'error',
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
overrides: [
|
||||
{
|
||||
files: ['**/__tests__/**/*.ts', '**/__mocks__/**/*.ts'],
|
||||
rules: {
|
||||
'async-protect/async-suffix': 'off',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
+27
-3
@@ -8,17 +8,41 @@ This is the log of notable changes to EAS CLI and related packages.
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Use envs from build profile to resolve app config when auto-submitting. ([#614](https://github.com/expo/eas-cli/pull/614) by [@dsokal](https://github.com/dsokal))
|
||||
- Support multi flavor Android projects. ([#595](https://github.com/expo/eas-cli/pull/595) by [@wkozyra95](https://github.com/wkozyra95))
|
||||
- Improve experience when using the build details page as a build artifact URL in `eas submit`. ([#620](https://github.com/expo/eas-cli/pull/620) by [@dsokal](https://github.com/dsokal))
|
||||
- Better error message when eas.json is invalid JSON. ([#618](https://github.com/expo/eas-cli/pull/618) by [@dsokal](https://github.com/dsokal))
|
||||
- Add warning about the legacy build service IDs in `eas submit`. ([#624](https://github.com/expo/eas-cli/pull/624) by [@dsokal](https://github.com/dsokal))
|
||||
- Validate that project includes `expo-dev-client` when building with `developmentClient` flag. ([#627](https://github.com/expo/eas-cli/pull/627) by [@dsokal](https://github.com/dsokal))
|
||||
- Better experience when not logged in in non-interactive mode. ([#628](https://github.com/expo/eas-cli/pull/628) by [@dsokal](https://github.com/dsokal))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
- Reduce `eas-cli` size by almost getting rid of `lodash` from dependencies. ([#605](https://github.com/expo/eas-cli/pull/605) by [@dsokal](https://github.com/dsokal))
|
||||
- Enforce explicit return type in all functions. ([#619](https://github.com/expo/eas-cli/pull/619) by [@wkozyra95](https://github.com/wkozyra95))
|
||||
- Enforce `Async` suffix for async functions. ([#623](https://github.com/expo/eas-cli/pull/623) by [@dsokal](https://github.com/dsokal))
|
||||
|
||||
## [0.27.1](https://github.com/expo/eas-cli/releases/tag/v0.27.1) - 2021-09-10
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
- Fixed force-creation, app secret creation, and secret deletion mutations. ([#606](https://github.com/expo/eas-cli/pull/606) by [@fiberjw](https://github.com/fiberjw))
|
||||
|
||||
## [0.27.0](https://github.com/expo/eas-cli/releases/tag/v0.27.0) - 2021-09-10
|
||||
|
||||
### 🎉 New features
|
||||
|
||||
- Implement support for `--platform all` in `eas submit`. ([#598](https://github.com/expo/eas-cli/pull/598) by [@dsokal](https://github.com/dsokal))
|
||||
- Implement support for `--non-interactive` in `eas submit`. ([#600](https://github.com/expo/eas-cli/pull/600) by [@dsokal](https://github.com/dsokal))
|
||||
- Add auto-submit feature. Run `eas build --submit` to submit automatically on build complete. ([#603](https://github.com/expo/eas-cli/pull/603) by [@dsokal](https://github.com/dsokal))
|
||||
- Add auto-submit feature. Run `eas build --auto-submit` to submit automatically on build complete. ([#603](https://github.com/expo/eas-cli/pull/603) by [@dsokal](https://github.com/dsokal))
|
||||
- Allow using env var for `android.serviceAccountKeyPath` in submit profiles. ([#604](https://github.com/expo/eas-cli/pull/604) by [@dsokal](https://github.com/dsokal))
|
||||
|
||||
### 🐛 Bug fixes
|
||||
|
||||
- Fix detecting `googleServicesFile` on Windows. ([#602](https://github.com/expo/eas-cli/pull/602) by [@wkozyra95](https://github.com/wkozyra95))
|
||||
|
||||
### 🧹 Chores
|
||||
|
||||
## [0.26.0](https://github.com/expo/eas-cli/releases/tag/v0.26.0) - 2021-09-08
|
||||
|
||||
### 🛠 Breaking changes
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"version": "0.27.0"
|
||||
"version": "0.28.0"
|
||||
}
|
||||
+2
-1
@@ -19,7 +19,8 @@
|
||||
"@types/jest": "27.0.1",
|
||||
"@types/node": "16.7.8",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-universe": "7.0.1",
|
||||
"eslint-config-universe": "8.0.0",
|
||||
"eslint-plugin-async-protect": "1.1.0",
|
||||
"jest": "27.1.0",
|
||||
"jest-watch-typeahead": "0.6.4",
|
||||
"lerna": "4.0.0",
|
||||
|
||||
+26
-26
@@ -73,7 +73,7 @@ ALIASES
|
||||
$ eas login
|
||||
```
|
||||
|
||||
_See code: [src/commands/account/login.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/account/login.js)_
|
||||
_See code: [src/commands/account/login.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/account/login.js)_
|
||||
|
||||
## `eas account:logout`
|
||||
|
||||
@@ -87,7 +87,7 @@ ALIASES
|
||||
$ eas logout
|
||||
```
|
||||
|
||||
_See code: [src/commands/account/logout.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/account/logout.js)_
|
||||
_See code: [src/commands/account/logout.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/account/logout.js)_
|
||||
|
||||
## `eas account:view`
|
||||
|
||||
@@ -101,7 +101,7 @@ ALIASES
|
||||
$ eas whoami
|
||||
```
|
||||
|
||||
_See code: [src/commands/account/view.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/account/view.js)_
|
||||
_See code: [src/commands/account/view.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/account/view.js)_
|
||||
|
||||
## `eas analytics [STATUS]`
|
||||
|
||||
@@ -112,7 +112,7 @@ USAGE
|
||||
$ eas analytics [STATUS]
|
||||
```
|
||||
|
||||
_See code: [src/commands/analytics.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/analytics.js)_
|
||||
_See code: [src/commands/analytics.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/analytics.js)_
|
||||
|
||||
## `eas build`
|
||||
|
||||
@@ -145,7 +145,7 @@ OPTIONS
|
||||
--[no-]wait Wait for build(s) to complete
|
||||
```
|
||||
|
||||
_See code: [src/commands/build/index.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/build/index.js)_
|
||||
_See code: [src/commands/build/index.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/build/index.js)_
|
||||
|
||||
## `eas build:cancel [BUILD_ID]`
|
||||
|
||||
@@ -156,7 +156,7 @@ USAGE
|
||||
$ eas build:cancel [BUILD_ID]
|
||||
```
|
||||
|
||||
_See code: [src/commands/build/cancel.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/build/cancel.js)_
|
||||
_See code: [src/commands/build/cancel.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/build/cancel.js)_
|
||||
|
||||
## `eas build:configure`
|
||||
|
||||
@@ -170,7 +170,7 @@ OPTIONS
|
||||
-p, --platform=(android|ios|all) Platform to configure
|
||||
```
|
||||
|
||||
_See code: [src/commands/build/configure.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/build/configure.js)_
|
||||
_See code: [src/commands/build/configure.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/build/configure.js)_
|
||||
|
||||
## `eas build:list`
|
||||
|
||||
@@ -203,7 +203,7 @@ OPTIONS
|
||||
--status=(new|in-queue|in-progress|errored|finished|canceled)
|
||||
```
|
||||
|
||||
_See code: [src/commands/build/list.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/build/list.js)_
|
||||
_See code: [src/commands/build/list.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/build/list.js)_
|
||||
|
||||
## `eas build:view [BUILD_ID]`
|
||||
|
||||
@@ -217,7 +217,7 @@ OPTIONS
|
||||
--json Enable JSON output, non-JSON messages will be printed to stderr
|
||||
```
|
||||
|
||||
_See code: [src/commands/build/view.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/build/view.js)_
|
||||
_See code: [src/commands/build/view.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/build/view.js)_
|
||||
|
||||
## `eas config`
|
||||
|
||||
@@ -232,7 +232,7 @@ OPTIONS
|
||||
--profile=profile
|
||||
```
|
||||
|
||||
_See code: [src/commands/config.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/config.js)_
|
||||
_See code: [src/commands/config.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/config.js)_
|
||||
|
||||
## `eas credentials`
|
||||
|
||||
@@ -243,7 +243,7 @@ USAGE
|
||||
$ eas credentials
|
||||
```
|
||||
|
||||
_See code: [src/commands/credentials.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/credentials.js)_
|
||||
_See code: [src/commands/credentials.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/credentials.js)_
|
||||
|
||||
## `eas device:create`
|
||||
|
||||
@@ -254,7 +254,7 @@ USAGE
|
||||
$ eas device:create
|
||||
```
|
||||
|
||||
_See code: [src/commands/device/create.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/device/create.js)_
|
||||
_See code: [src/commands/device/create.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/device/create.js)_
|
||||
|
||||
## `eas device:list`
|
||||
|
||||
@@ -268,7 +268,7 @@ OPTIONS
|
||||
--apple-team-id=apple-team-id
|
||||
```
|
||||
|
||||
_See code: [src/commands/device/list.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/device/list.js)_
|
||||
_See code: [src/commands/device/list.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/device/list.js)_
|
||||
|
||||
## `eas device:view [UDID]`
|
||||
|
||||
@@ -279,7 +279,7 @@ USAGE
|
||||
$ eas device:view [UDID]
|
||||
```
|
||||
|
||||
_See code: [src/commands/device/view.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/device/view.js)_
|
||||
_See code: [src/commands/device/view.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/device/view.js)_
|
||||
|
||||
## `eas diagnostics`
|
||||
|
||||
@@ -290,7 +290,7 @@ USAGE
|
||||
$ eas diagnostics
|
||||
```
|
||||
|
||||
_See code: [src/commands/diagnostics.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/diagnostics.js)_
|
||||
_See code: [src/commands/diagnostics.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/diagnostics.js)_
|
||||
|
||||
## `eas help [COMMAND]`
|
||||
|
||||
@@ -318,7 +318,7 @@ USAGE
|
||||
$ eas project:info
|
||||
```
|
||||
|
||||
_See code: [src/commands/project/info.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/project/info.js)_
|
||||
_See code: [src/commands/project/info.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/project/info.js)_
|
||||
|
||||
## `eas project:init`
|
||||
|
||||
@@ -332,7 +332,7 @@ ALIASES
|
||||
$ eas init
|
||||
```
|
||||
|
||||
_See code: [src/commands/project/init.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/project/init.js)_
|
||||
_See code: [src/commands/project/init.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/project/init.js)_
|
||||
|
||||
## `eas secret:create`
|
||||
|
||||
@@ -349,7 +349,7 @@ OPTIONS
|
||||
--value=value Value of the secret
|
||||
```
|
||||
|
||||
_See code: [src/commands/secret/create.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/secret/create.js)_
|
||||
_See code: [src/commands/secret/create.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/secret/create.js)_
|
||||
|
||||
## `eas secret:delete`
|
||||
|
||||
@@ -366,7 +366,7 @@ DESCRIPTION
|
||||
Unsure where to find the secret's ID? Run eas secrets:list
|
||||
```
|
||||
|
||||
_See code: [src/commands/secret/delete.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/secret/delete.js)_
|
||||
_See code: [src/commands/secret/delete.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/secret/delete.js)_
|
||||
|
||||
## `eas secret:list`
|
||||
|
||||
@@ -377,7 +377,7 @@ USAGE
|
||||
$ eas secret:list
|
||||
```
|
||||
|
||||
_See code: [src/commands/secret/list.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/secret/list.js)_
|
||||
_See code: [src/commands/secret/list.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/secret/list.js)_
|
||||
|
||||
## `eas submit`
|
||||
|
||||
@@ -410,7 +410,7 @@ ALIASES
|
||||
$ eas build:submit
|
||||
```
|
||||
|
||||
_See code: [src/commands/submit.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/submit.js)_
|
||||
_See code: [src/commands/submit.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/submit.js)_
|
||||
|
||||
## `eas webhook:create`
|
||||
|
||||
@@ -429,7 +429,7 @@ OPTIONS
|
||||
--url=url Webhook URL
|
||||
```
|
||||
|
||||
_See code: [src/commands/webhook/create.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/webhook/create.js)_
|
||||
_See code: [src/commands/webhook/create.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/webhook/create.js)_
|
||||
|
||||
## `eas webhook:delete [ID]`
|
||||
|
||||
@@ -443,7 +443,7 @@ ARGUMENTS
|
||||
ID ID of the webhook to delete
|
||||
```
|
||||
|
||||
_See code: [src/commands/webhook/delete.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/webhook/delete.js)_
|
||||
_See code: [src/commands/webhook/delete.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/webhook/delete.js)_
|
||||
|
||||
## `eas webhook:list`
|
||||
|
||||
@@ -457,7 +457,7 @@ OPTIONS
|
||||
--event=(BUILD) Event type that triggers the webhook
|
||||
```
|
||||
|
||||
_See code: [src/commands/webhook/list.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/webhook/list.js)_
|
||||
_See code: [src/commands/webhook/list.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/webhook/list.js)_
|
||||
|
||||
## `eas webhook:update`
|
||||
|
||||
@@ -477,7 +477,7 @@ OPTIONS
|
||||
--url=url Webhook URL
|
||||
```
|
||||
|
||||
_See code: [src/commands/webhook/update.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/webhook/update.js)_
|
||||
_See code: [src/commands/webhook/update.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/webhook/update.js)_
|
||||
|
||||
## `eas webhook:view ID`
|
||||
|
||||
@@ -491,5 +491,5 @@ ARGUMENTS
|
||||
ID ID of the webhook to view
|
||||
```
|
||||
|
||||
_See code: [src/commands/webhook/view.js](https://github.com/expo/eas-cli/blob/v0.27.0/packages/eas-cli/src/commands/webhook/view.js)_
|
||||
_See code: [src/commands/webhook/view.js](https://github.com/expo/eas-cli/blob/v0.28.0/packages/eas-cli/src/commands/webhook/view.js)_
|
||||
<!-- commandsstop -->
|
||||
Generated
+215
-575
@@ -324,22 +324,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "easBuild",
|
||||
"description": "Top-level query object for querying EAS Build configuration.",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildQuery",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "experimentation",
|
||||
"description": "Top-level query object for querying Experimentation configuration.",
|
||||
@@ -6510,8 +6494,8 @@
|
||||
"name": "SubmissionAndroidArchiveType",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
"isDeprecated": true,
|
||||
"deprecationReason": "archiveType is deprecated and will be null"
|
||||
},
|
||||
{
|
||||
"name": "track",
|
||||
@@ -7375,8 +7359,8 @@
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "channel",
|
||||
"description": "",
|
||||
"name": "channelName",
|
||||
"description": "The name of this deployment's associated channel. It is specified separately from the `channel`\nfield to allow specifying a deployment before an EAS Update channel has been created.",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
@@ -7390,6 +7374,18 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "channel",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateChannel",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "recentBuilds",
|
||||
"description": "",
|
||||
@@ -7414,18 +7410,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "branchMapping",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateBranch",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "mostRecentlyUpdatedAt",
|
||||
"description": "",
|
||||
@@ -7448,6 +7432,170 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateChannel",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "appId",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "branchMapping",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "createdAt",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "DateTime",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "updatedAt",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "DateTime",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "updateBranches",
|
||||
"description": "",
|
||||
"args": [
|
||||
{
|
||||
"name": "offset",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateBranch",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateBranch",
|
||||
@@ -10011,170 +10159,6 @@
|
||||
],
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateChannel",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "appId",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "branchMapping",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "String",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "createdAt",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "DateTime",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "updatedAt",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "DateTime",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "updateBranches",
|
||||
"description": "",
|
||||
"args": [
|
||||
{
|
||||
"name": "offset",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "limit",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Int",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "UpdateBranch",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "EnvironmentSecret",
|
||||
@@ -12246,113 +12230,6 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildQuery",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "killSwitches",
|
||||
"description": "Get EAS Build kill switches state",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildKillSwitch",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildKillSwitch",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "ENUM",
|
||||
"name": "EasBuildKillSwitchName",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "ENUM",
|
||||
"name": "EasBuildKillSwitchName",
|
||||
"description": "",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": [
|
||||
{
|
||||
"name": "STOP_ACCEPTING_BUILDS",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "STOP_SCHEDULING_BUILDS",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "STOP_ACCEPTING_NORMAL_PRIORITY_BUILDS",
|
||||
"description": "",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "ExperimentationQuery",
|
||||
@@ -13480,22 +13357,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "easBuildKillSwitch",
|
||||
"description": "",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildKillSwitchMutation",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "emailSubscription",
|
||||
"description": "Mutations that modify an EmailSubscription",
|
||||
@@ -14145,108 +14006,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "extendOffer",
|
||||
"description": "Extend offer to account",
|
||||
"args": [
|
||||
{
|
||||
"name": "accountName",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "offer",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "ENUM",
|
||||
"name": "StandardOffer",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "suppressMessage",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "Account",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "sendEmail",
|
||||
"description": "Send an email to primary account email",
|
||||
"args": [
|
||||
{
|
||||
"name": "accountName",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "ID",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "emailTemplate",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "ENUM",
|
||||
"name": "EmailTemplate",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "OBJECT",
|
||||
"name": "Account",
|
||||
"ofType": null
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "setPushSecurityEnabled",
|
||||
"description": "Require authorization to send push notifications for experiences owned by this account",
|
||||
@@ -14347,64 +14106,6 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "ENUM",
|
||||
"name": "StandardOffer",
|
||||
"description": "",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": [
|
||||
{
|
||||
"name": "DEFAULT",
|
||||
"description": "$29 USD per month, 30 day trial",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "YEARLY_SUB",
|
||||
"description": "$348 USD per year, 30 day trial",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "YC_DEALS",
|
||||
"description": "$29 USD per month, 1 year trial",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "SUPPORT",
|
||||
"description": "$800 USD per month",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "ENUM",
|
||||
"name": "EmailTemplate",
|
||||
"description": "",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": [
|
||||
{
|
||||
"name": "DEV_SERVICES_OFFER_EXTENDED",
|
||||
"description": "Able to purchase Developer Services",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "DEV_SERVICES_ONBOARDING",
|
||||
"description": "Developer Services Signup",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "AndroidAppBuildCredentialsMutation",
|
||||
@@ -20528,18 +20229,6 @@
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "archiveType",
|
||||
"description": "",
|
||||
"type": {
|
||||
"kind": "ENUM",
|
||||
"name": "SubmissionAndroidArchiveType",
|
||||
"ofType": null
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "applicationIdentifier",
|
||||
"description": "",
|
||||
@@ -22893,90 +22582,6 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildKillSwitchMutation",
|
||||
"description": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "set",
|
||||
"description": "Set an EAS Build kill switch to a given value",
|
||||
"args": [
|
||||
{
|
||||
"name": "name",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "ENUM",
|
||||
"name": "EasBuildKillSwitchName",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"description": null,
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "SCALAR",
|
||||
"name": "Boolean",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"defaultValue": null,
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildKillSwitch",
|
||||
"ofType": null
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "resetAll",
|
||||
"description": "Reset all EAS Build kill switches (set them to false)",
|
||||
"args": [],
|
||||
"type": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "LIST",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "NON_NULL",
|
||||
"name": null,
|
||||
"ofType": {
|
||||
"kind": "OBJECT",
|
||||
"name": "EasBuildKillSwitch",
|
||||
"ofType": null
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"inputFields": null,
|
||||
"interfaces": [],
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "OBJECT",
|
||||
"name": "EmailSubscriptionMutation",
|
||||
@@ -23682,6 +23287,41 @@
|
||||
"enumValues": null,
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "ENUM",
|
||||
"name": "StandardOffer",
|
||||
"description": "",
|
||||
"fields": null,
|
||||
"inputFields": null,
|
||||
"interfaces": null,
|
||||
"enumValues": [
|
||||
{
|
||||
"name": "DEFAULT",
|
||||
"description": "$29 USD per month, 30 day trial",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "YEARLY_SUB",
|
||||
"description": "$348 USD per year, 30 day trial",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "YC_DEALS",
|
||||
"description": "$29 USD per month, 1 year trial",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
},
|
||||
{
|
||||
"name": "SUPPORT",
|
||||
"description": "$800 USD per month",
|
||||
"isDeprecated": false,
|
||||
"deprecationReason": null
|
||||
}
|
||||
],
|
||||
"possibleTypes": null
|
||||
},
|
||||
{
|
||||
"kind": "ENUM",
|
||||
"name": "CacheControlScope",
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
{
|
||||
"name": "eas-cli",
|
||||
"description": "EAS command line tool",
|
||||
"version": "0.27.0",
|
||||
"version": "0.28.0",
|
||||
"author": "Expo <[email protected]>",
|
||||
"bin": {
|
||||
"eas": "./bin/run"
|
||||
},
|
||||
"bugs": "https://github.com/expo/eas-cli/issues",
|
||||
"dependencies": {
|
||||
"@amplitude/identify": "1.7.0",
|
||||
"@amplitude/node": "1.7.0",
|
||||
"@expo/apple-utils": "0.0.0-alpha.25",
|
||||
"@expo/config": "3.3.42",
|
||||
"@expo/config": "5.0.9",
|
||||
"@expo/config-plugins": "3.1.0",
|
||||
"@expo/eas-build-job": "0.2.46",
|
||||
"@expo/eas-json": "^0.27.0",
|
||||
"@expo/json-file": "8.2.25",
|
||||
"@expo/eas-json": "^0.28.0",
|
||||
"@expo/json-file": "8.2.33",
|
||||
"@expo/pkcs12": "0.0.4",
|
||||
"@expo/plist": "0.0.14",
|
||||
"@expo/plugin-warn-if-update-available": "1.7.0",
|
||||
"@expo/prebuild-config": "2.1.0",
|
||||
"@expo/results": "1.0.0",
|
||||
"@expo/rudder-sdk-node": "1.0.7",
|
||||
"@expo/sdk-runtime-versions": "1.0.0",
|
||||
"@expo/spawn-async": "1.5.0",
|
||||
"@expo/timeago.js": "1.0.0",
|
||||
"@oclif/command": "1.8.0",
|
||||
"@oclif/config": "1.17.0",
|
||||
"@oclif/errors": "1.3.5",
|
||||
@@ -40,6 +40,7 @@
|
||||
"fs-extra": "10.0.0",
|
||||
"getenv": "1.0.0",
|
||||
"got": "11.8.2",
|
||||
"gradle-to-js": "2.0.0",
|
||||
"graphql": "15.5.1",
|
||||
"graphql-tag": "2.12.5",
|
||||
"ignore": "5.1.8",
|
||||
@@ -47,7 +48,6 @@
|
||||
"jks-js": "1.0.1",
|
||||
"joi": "17.4.2",
|
||||
"keychain": "1.3.0",
|
||||
"lodash": "4.17.21",
|
||||
"mime": "2.5.2",
|
||||
"minimatch": "3.0.4",
|
||||
"nanoid": "3.1.25",
|
||||
@@ -62,9 +62,7 @@
|
||||
"semver": "7.3.5",
|
||||
"strip-ansi": "6.0.0",
|
||||
"tar": "6.1.11",
|
||||
"tempy": "0.7.0",
|
||||
"terminal-link": "2.1.1",
|
||||
"timeago.js": "4.0.2",
|
||||
"tslib": "2.3.1",
|
||||
"turndown": "7.1.1",
|
||||
"untildify": "4.0.0",
|
||||
@@ -81,7 +79,6 @@
|
||||
"@types/form-data": "^2.5.0",
|
||||
"@types/fs-extra": "9.0.12",
|
||||
"@types/getenv": "^1.0.0",
|
||||
"@types/lodash": "4.14.172",
|
||||
"@types/mime": "2.0.3",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/node-forge": "^0.9.5",
|
||||
@@ -95,7 +92,9 @@
|
||||
"eslint-plugin-graphql": "4.0.0",
|
||||
"memfs": "3.2.2",
|
||||
"mockdate": "^3.0.2",
|
||||
"nock": "^13.0.5"
|
||||
"nock": "^13.0.5",
|
||||
"tempy": "0.7.0",
|
||||
"ts-deepmerge": "1.0.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
@@ -120,7 +119,6 @@
|
||||
"@oclif/plugin-help",
|
||||
"@expo/plugin-warn-if-update-available"
|
||||
],
|
||||
"helpClass": "./build/help",
|
||||
"topics": {
|
||||
"account": {
|
||||
"description": "manage your account"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { Identify } from '@amplitude/identify';
|
||||
import * as Amplitude from '@amplitude/node';
|
||||
import RudderAnalytics from '@expo/rudder-sdk-node';
|
||||
import os from 'os';
|
||||
import { URL } from 'url';
|
||||
@@ -20,40 +18,46 @@ const PLATFORM_TO_ANALYTICS_PLATFORM: { [platform: string]: string } = {
|
||||
linux: 'Linux',
|
||||
};
|
||||
|
||||
let amplitudeClient: Amplitude.NodeClient | null = null;
|
||||
let rudderstackClient: RudderAnalytics | null = null;
|
||||
let userIdentified = false;
|
||||
let identifyData: {
|
||||
userId: string;
|
||||
deviceId: string;
|
||||
identify: Identify;
|
||||
traits: Record<string, any>;
|
||||
} | null = null;
|
||||
|
||||
export async function initAsync(): Promise<void> {
|
||||
if (process.env.DISABLE_EAS_ANALYTICS) {
|
||||
await UserSettings.setAsync('amplitudeEnabled', false);
|
||||
// TODO: remove after some time
|
||||
const amplitudeEnabled = await UserSettings.getAsync('amplitudeEnabled', null);
|
||||
if (amplitudeEnabled !== null) {
|
||||
await UserSettings.setAsync('analyticsEnabled', amplitudeEnabled);
|
||||
await UserSettings.deleteKeyAsync('amplitudeEnabled');
|
||||
}
|
||||
const amplitudeEnabled = await UserSettings.getAsync('amplitudeEnabled', true);
|
||||
if (amplitudeEnabled) {
|
||||
const amplitudeDeviceId = await UserSettings.getAsync('amplitudeDeviceId', null);
|
||||
if (amplitudeDeviceId !== null) {
|
||||
await UserSettings.setAsync('analyticsDeviceId', amplitudeDeviceId);
|
||||
await UserSettings.deleteKeyAsync('amplitudeDeviceId');
|
||||
}
|
||||
// TODO: cut here
|
||||
if (process.env.DISABLE_EAS_ANALYTICS) {
|
||||
await UserSettings.setAsync('analyticsEnabled', false);
|
||||
}
|
||||
|
||||
const analyticsEnabled = await UserSettings.getAsync('analyticsEnabled', true);
|
||||
if (analyticsEnabled) {
|
||||
const config =
|
||||
process.env.EXPO_STAGING || process.env.EXPO_LOCAL
|
||||
? {
|
||||
// staging environment
|
||||
amplitudeWriteKey: 'cdebbc678931403439486c4750781544',
|
||||
rudderstackWriteKey: '1wpX20Da4ltFGSXbPFYUL00Chb7',
|
||||
rudderstackDataPlaneURL: 'https://cdp.expo.dev',
|
||||
}
|
||||
: {
|
||||
// prod environment
|
||||
amplitudeWriteKey: '4ac443afd5073c0df6169291db1d3495',
|
||||
rudderstackWriteKey: '1wpXLFxmujq86etH6G6cc90hPcC',
|
||||
rudderstackDataPlaneURL: 'https://cdp.expo.dev',
|
||||
};
|
||||
|
||||
amplitudeClient = Amplitude.init(config.amplitudeWriteKey, {
|
||||
retryClass: new Amplitude.OfflineRetryHandler(config.amplitudeWriteKey),
|
||||
});
|
||||
|
||||
rudderstackClient = new RudderAnalytics(
|
||||
config.rudderstackWriteKey,
|
||||
new URL('/v1/batch', config.rudderstackDataPlaneURL).toString(),
|
||||
@@ -65,24 +69,17 @@ export async function initAsync(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function setUserDataAsync(
|
||||
userId: string,
|
||||
properties: Record<string, any>
|
||||
): Promise<void> {
|
||||
const identify = new Identify();
|
||||
Object.entries(properties).forEach(([property, value]) => {
|
||||
identify.set(property, value);
|
||||
});
|
||||
const savedDeviceId = await UserSettings.getAsync('amplitudeDeviceId', null);
|
||||
export async function setUserDataAsync(userId: string, traits: Record<string, any>): Promise<void> {
|
||||
const savedDeviceId = await UserSettings.getAsync('analyticsDeviceId', null);
|
||||
const deviceId = savedDeviceId ?? uuidv4();
|
||||
if (!savedDeviceId) {
|
||||
await UserSettings.setAsync('amplitudeDeviceId', deviceId);
|
||||
await UserSettings.setAsync('analyticsDeviceId', deviceId);
|
||||
}
|
||||
|
||||
identifyData = {
|
||||
userId,
|
||||
deviceId,
|
||||
identify,
|
||||
traits,
|
||||
};
|
||||
|
||||
ensureUserIdentified();
|
||||
@@ -92,14 +89,10 @@ export async function flushAsync(): Promise<void> {
|
||||
if (rudderstackClient) {
|
||||
rudderstackClient.flush();
|
||||
}
|
||||
|
||||
if (amplitudeClient) {
|
||||
await amplitudeClient.flush();
|
||||
}
|
||||
}
|
||||
|
||||
export function logEvent(name: string, properties: Record<string, any> = {}) {
|
||||
if (!amplitudeClient && !rudderstackClient) {
|
||||
export function logEvent(name: string, properties: Record<string, any> = {}): void {
|
||||
if (!rudderstackClient) {
|
||||
return;
|
||||
}
|
||||
ensureUserIdentified();
|
||||
@@ -107,56 +100,31 @@ export function logEvent(name: string, properties: Record<string, any> = {}) {
|
||||
const { userId, deviceId } = identifyData ?? {};
|
||||
const commonEventProperties = { source_version: packageJSON?.version, source: 'eas cli' };
|
||||
|
||||
if (amplitudeClient) {
|
||||
amplitudeClient.logEvent({
|
||||
event_type: name,
|
||||
event_properties: { ...properties, ...commonEventProperties },
|
||||
...(userId && { user_id: userId }),
|
||||
...(deviceId && { device_id: deviceId }),
|
||||
...getAmplitudeContext(),
|
||||
});
|
||||
}
|
||||
|
||||
if (rudderstackClient) {
|
||||
const identity = { userId: userId ?? undefined, anonymousId: deviceId ?? uuidv4() };
|
||||
rudderstackClient.track({
|
||||
event: name,
|
||||
properties: { ...properties, ...commonEventProperties },
|
||||
...identity,
|
||||
context: getRudderStackContext(),
|
||||
});
|
||||
}
|
||||
const identity = { userId: userId ?? undefined, anonymousId: deviceId ?? uuidv4() };
|
||||
rudderstackClient.track({
|
||||
event: name,
|
||||
properties: { ...properties, ...commonEventProperties },
|
||||
...identity,
|
||||
context: getRudderStackContext(),
|
||||
});
|
||||
}
|
||||
|
||||
function ensureUserIdentified() {
|
||||
if (!(rudderstackClient || amplitudeClient) || userIdentified || !identifyData) {
|
||||
function ensureUserIdentified(): void {
|
||||
if (!rudderstackClient || userIdentified || !identifyData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (amplitudeClient) {
|
||||
amplitudeClient.identify(identifyData.userId, identifyData.deviceId, identifyData.identify);
|
||||
}
|
||||
|
||||
if (rudderstackClient) {
|
||||
rudderstackClient.identify({
|
||||
userId: identifyData.userId,
|
||||
anonymousId: identifyData.deviceId,
|
||||
traits: identifyData.traits,
|
||||
});
|
||||
}
|
||||
userIdentified = true;
|
||||
}
|
||||
|
||||
function getAmplitudeContext() {
|
||||
const platform = PLATFORM_TO_ANALYTICS_PLATFORM[os.platform()] || os.platform();
|
||||
return {
|
||||
os_name: platform,
|
||||
os_version: os.release(),
|
||||
device_brand: platform,
|
||||
device_model: platform,
|
||||
};
|
||||
}
|
||||
|
||||
function getRudderStackContext() {
|
||||
function getRudderStackContext(): Record<string, any> {
|
||||
const platform = PLATFORM_TO_ANALYTICS_PLATFORM[os.platform()] || os.platform();
|
||||
return {
|
||||
os: { name: platform, version: os.release() },
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { ExpoConfig } from '@expo/config';
|
||||
import { Platform } from '@expo/eas-build-job';
|
||||
import { BuildProfile } from '@expo/eas-json';
|
||||
import fs from 'fs-extra';
|
||||
import { vol } from 'memfs';
|
||||
import os from 'os';
|
||||
|
||||
import { readVersionCodeAsync, readVersionNameAsync } from '../version';
|
||||
import { maybeResolveVersionsAsync } from '../version';
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
@@ -20,36 +22,29 @@ beforeEach(() => {
|
||||
fs.mkdirpSync(os.tmpdir());
|
||||
});
|
||||
|
||||
describe(readVersionCodeAsync, () => {
|
||||
describe(maybeResolveVersionsAsync, () => {
|
||||
describe('generic project', () => {
|
||||
it('reads the version code from native code', async () => {
|
||||
const exp = initGenericProject();
|
||||
const versionCode = await readVersionCodeAsync('/repo', exp);
|
||||
expect(versionCode).toBe(123);
|
||||
const { appVersion, appBuildVersion } = await maybeResolveVersionsAsync(
|
||||
'/repo',
|
||||
exp,
|
||||
{} as BuildProfile<Platform.ANDROID>
|
||||
);
|
||||
expect(appVersion).toBe('2.0');
|
||||
expect(appBuildVersion).toBe('123');
|
||||
});
|
||||
});
|
||||
describe('managed project', () => {
|
||||
it('reads the version code from expo config', async () => {
|
||||
const exp = initManagedProject();
|
||||
const versionCode = await readVersionCodeAsync('/repo', exp);
|
||||
expect(versionCode).toBe(123);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe(readVersionNameAsync, () => {
|
||||
describe('generic project', () => {
|
||||
it('reads the version name from native code', async () => {
|
||||
const exp = initGenericProject();
|
||||
const versionName = await readVersionNameAsync('/repo', exp);
|
||||
expect(versionName).toBe('1.0');
|
||||
});
|
||||
});
|
||||
describe('managed project', () => {
|
||||
it('reads the version from expo config', async () => {
|
||||
const exp = initManagedProject();
|
||||
const versionName = await readVersionNameAsync('/repo', exp);
|
||||
expect(versionName).toBe('1.0.0');
|
||||
const { appVersion, appBuildVersion } = await maybeResolveVersionsAsync(
|
||||
'/repo',
|
||||
exp,
|
||||
{} as BuildProfile<Platform.ANDROID>
|
||||
);
|
||||
expect(appVersion).toBe('5.0.0');
|
||||
expect(appBuildVersion).toBe('126');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -69,7 +64,7 @@ function initGenericProject(): ExpoConfig {
|
||||
defaultConfig {
|
||||
applicationId "com.expo.testapp"
|
||||
versionCode 123
|
||||
versionName "1.0"
|
||||
versionName "2.0"
|
||||
}
|
||||
}`,
|
||||
'./android/app/src/main/AndroidManifest.xml': 'fake',
|
||||
@@ -80,9 +75,9 @@ function initGenericProject(): ExpoConfig {
|
||||
const fakeExp: ExpoConfig = {
|
||||
name: 'myproject',
|
||||
slug: 'myproject',
|
||||
version: '1.0.0',
|
||||
version: '3.0.0',
|
||||
android: {
|
||||
versionCode: 123,
|
||||
versionCode: 124,
|
||||
},
|
||||
};
|
||||
return fakeExp;
|
||||
@@ -93,9 +88,9 @@ function initManagedProject(): ExpoConfig {
|
||||
{
|
||||
'./app.json': JSON.stringify({
|
||||
expo: {
|
||||
version: '1.0.0',
|
||||
version: '4.0.0',
|
||||
android: {
|
||||
versionCode: 123,
|
||||
versionCode: 125,
|
||||
},
|
||||
},
|
||||
}),
|
||||
@@ -106,9 +101,9 @@ function initManagedProject(): ExpoConfig {
|
||||
const fakeExp: ExpoConfig = {
|
||||
name: 'myproject',
|
||||
slug: 'myproject',
|
||||
version: '1.0.0',
|
||||
version: '5.0.0',
|
||||
android: {
|
||||
versionCode: 123,
|
||||
versionCode: 126,
|
||||
},
|
||||
};
|
||||
return fakeExp;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Android, Metadata, Platform, Workflow } from '@expo/eas-build-job';
|
||||
import { Android, Job, Metadata, Platform, Workflow } from '@expo/eas-build-job';
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
@@ -12,11 +12,13 @@ import {
|
||||
ensureApplicationIdIsDefinedForManagedProjectAsync,
|
||||
getApplicationIdAsync,
|
||||
} from '../../project/android/applicationId';
|
||||
import { GradleBuildContext, resolveGradleBuildContextAsync } from '../../project/android/gradle';
|
||||
import { toggleConfirmAsync } from '../../prompts';
|
||||
import { findAccountByName } from '../../user/Account';
|
||||
import {
|
||||
BuildRequestSender,
|
||||
CredentialsResult,
|
||||
JobData,
|
||||
prepareBuildRequestForPlatformAsync,
|
||||
} from '../build';
|
||||
import { BuildContext } from '../context';
|
||||
@@ -51,20 +53,31 @@ This means that it will most likely produce an AAB and you will not be able to i
|
||||
checkNodeEnvVariable(ctx);
|
||||
await checkGoogleServicesFileAsync(ctx);
|
||||
|
||||
const gradleContext = await resolveGradleBuildContextAsync(ctx.projectDir, buildProfile);
|
||||
|
||||
if (ctx.workflow === Workflow.MANAGED) {
|
||||
await ensureApplicationIdIsDefinedForManagedProjectAsync(ctx.projectDir, ctx.exp);
|
||||
}
|
||||
|
||||
return await prepareBuildRequestForPlatformAsync({
|
||||
ctx,
|
||||
ensureCredentialsAsync: ensureAndroidCredentialsAsync,
|
||||
ensureCredentialsAsync: async (ctx: BuildContext<Platform.ANDROID>) => {
|
||||
return await ensureAndroidCredentialsAsync(ctx, gradleContext);
|
||||
},
|
||||
ensureProjectConfiguredAsync: async () => {
|
||||
if (ctx.workflow === Workflow.GENERIC) {
|
||||
await validateAndSyncProjectConfigurationAsync(ctx.projectDir, ctx.exp);
|
||||
}
|
||||
},
|
||||
getMetadataContext: () => ({}),
|
||||
prepareJobAsync,
|
||||
getMetadataContext: () => ({
|
||||
gradleContext,
|
||||
}),
|
||||
prepareJobAsync: async (
|
||||
ctx: BuildContext<Platform.ANDROID>,
|
||||
jobData: JobData<AndroidCredentials>
|
||||
): Promise<Job> => {
|
||||
return await prepareJobAsync(ctx, jobData);
|
||||
},
|
||||
sendBuildRequestAsync: async (
|
||||
appId: string,
|
||||
job: Android.Job,
|
||||
@@ -86,12 +99,17 @@ function shouldProvideCredentials(ctx: BuildContext<Platform.ANDROID>): boolean
|
||||
}
|
||||
|
||||
async function ensureAndroidCredentialsAsync(
|
||||
ctx: BuildContext<Platform.ANDROID>
|
||||
ctx: BuildContext<Platform.ANDROID>,
|
||||
gradleContext?: GradleBuildContext
|
||||
): Promise<CredentialsResult<AndroidCredentials> | undefined> {
|
||||
if (!shouldProvideCredentials(ctx)) {
|
||||
return;
|
||||
}
|
||||
const androidApplicationIdentifier = await getApplicationIdAsync(ctx.projectDir, ctx.exp);
|
||||
const androidApplicationIdentifier = await getApplicationIdAsync(
|
||||
ctx.projectDir,
|
||||
ctx.exp,
|
||||
gradleContext
|
||||
);
|
||||
const provider = new AndroidCredentialsProvider(
|
||||
await createCredentialsContextAsync(ctx.projectDir, {
|
||||
exp: ctx.exp,
|
||||
|
||||
@@ -1,50 +1,41 @@
|
||||
import { ExpoConfig } from '@expo/config';
|
||||
import { AndroidConfig } from '@expo/config-plugins';
|
||||
import { Platform, Workflow } from '@expo/eas-build-job';
|
||||
import fs from 'fs-extra';
|
||||
import { BuildProfile } from '@expo/eas-json';
|
||||
|
||||
import {
|
||||
getAppBuildGradleAsync,
|
||||
parseGradleCommand,
|
||||
resolveConfigValue,
|
||||
} from '../../project/android/gradleUtils';
|
||||
import { resolveWorkflowAsync } from '../../project/workflow';
|
||||
|
||||
export async function readVersionCodeAsync(
|
||||
export async function maybeResolveVersionsAsync(
|
||||
projectDir: string,
|
||||
exp: ExpoConfig
|
||||
): Promise<number | undefined> {
|
||||
exp: ExpoConfig,
|
||||
buildProfile: BuildProfile<Platform.ANDROID>
|
||||
): Promise<{ appVersion?: string; appBuildVersion?: string }> {
|
||||
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID);
|
||||
if (workflow === Workflow.GENERIC) {
|
||||
const buildGradle = readBuildGradle(projectDir);
|
||||
const matchResult = buildGradle?.match(/versionCode (.*)/);
|
||||
if (matchResult) {
|
||||
return Number(matchResult[1]);
|
||||
} else {
|
||||
return undefined;
|
||||
const buildGradle = await getAppBuildGradleAsync(projectDir);
|
||||
try {
|
||||
const parsedGradleCommand = buildProfile.gradleCommand
|
||||
? parseGradleCommand(buildProfile.gradleCommand, buildGradle)
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
appVersion:
|
||||
resolveConfigValue(buildGradle, 'versionName', parsedGradleCommand?.flavor) ?? '1.0.0',
|
||||
appBuildVersion:
|
||||
resolveConfigValue(buildGradle, 'versionCode', parsedGradleCommand?.flavor) ?? '1',
|
||||
};
|
||||
} catch (err: any) {
|
||||
return {};
|
||||
}
|
||||
} else {
|
||||
return AndroidConfig.Version.getVersionCode(exp) ?? 1;
|
||||
return {
|
||||
appBuildVersion: String(AndroidConfig.Version.getVersionCode(exp)),
|
||||
appVersion: exp.version,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function readVersionNameAsync(
|
||||
projectDir: string,
|
||||
exp: ExpoConfig
|
||||
): Promise<string | undefined> {
|
||||
const workflow = await resolveWorkflowAsync(projectDir, Platform.ANDROID);
|
||||
if (workflow === Workflow.GENERIC) {
|
||||
const buildGradle = readBuildGradle(projectDir);
|
||||
const matchResult = buildGradle?.match(/versionName ["'](.*)["']/);
|
||||
if (matchResult) {
|
||||
return matchResult[1];
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
return exp.version;
|
||||
}
|
||||
}
|
||||
|
||||
function readBuildGradle(projectDir: string): string | undefined {
|
||||
const buildGradlePath = AndroidConfig.Paths.getAppBuildGradleFilePath(projectDir);
|
||||
if (!fs.pathExistsSync(buildGradlePath)) {
|
||||
return undefined;
|
||||
}
|
||||
return fs.readFileSync(buildGradlePath, 'utf8');
|
||||
}
|
||||
@@ -10,19 +10,18 @@ import { BuildResult } from '../graphql/mutations/BuildMutation';
|
||||
import { BuildQuery } from '../graphql/queries/BuildQuery';
|
||||
import Log, { learnMore } from '../log';
|
||||
import { requestedPlatformDisplayNames } from '../platform';
|
||||
import { promptAsync } from '../prompts';
|
||||
import { uploadAsync } from '../uploads';
|
||||
import { formatBytes } from '../utils/files';
|
||||
import { createProgressTracker } from '../utils/progress';
|
||||
import { sleep } from '../utils/promise';
|
||||
import { sleepAsync } from '../utils/promise';
|
||||
import vcs from '../vcs';
|
||||
import { BuildContext } from './context';
|
||||
import { runLocalBuildAsync } from './local';
|
||||
import { MetadataContext, collectMetadata } from './metadata';
|
||||
import { MetadataContext, collectMetadataAsync } from './metadata';
|
||||
import { TrackingContext } from './types';
|
||||
import Analytics, { Event } from './utils/analytics';
|
||||
import { printDeprecationWarnings } from './utils/printBuildInfo';
|
||||
import { commitPromptAsync, makeProjectTarballAsync } from './utils/repository';
|
||||
import { makeProjectTarballAsync, reviewAndCommitChangesAsync } from './utils/repository';
|
||||
|
||||
export interface CredentialsResult<Credentials> {
|
||||
source: CredentialsSource.LOCAL | CredentialsSource.REMOTE;
|
||||
@@ -89,7 +88,7 @@ export async function prepareBuildRequestForPlatformAsync<
|
||||
} as const);
|
||||
|
||||
const metadataContext = builder.getMetadataContext();
|
||||
const metadata = await collectMetadata(ctx, metadataContext);
|
||||
const metadata = await collectMetadataAsync(ctx, metadataContext);
|
||||
const job = await builder.prepareJobAsync(ctx, {
|
||||
projectArchive,
|
||||
credentials: credentialsResult?.credentials,
|
||||
@@ -230,58 +229,6 @@ async function withAnalyticsAsync<Result>(
|
||||
}
|
||||
}
|
||||
|
||||
enum ShouldCommitChanges {
|
||||
Yes,
|
||||
ShowDiffFirst,
|
||||
Abort,
|
||||
}
|
||||
|
||||
async function reviewAndCommitChangesAsync(
|
||||
initialCommitMessage: string,
|
||||
{ nonInteractive, askedFirstTime = true }: { nonInteractive: boolean; askedFirstTime?: boolean }
|
||||
): Promise<void> {
|
||||
if (process.env.EAS_BUILD_AUTOCOMMIT) {
|
||||
await vcs.commitAsync({ commitMessage: initialCommitMessage, commitAllFiles: false });
|
||||
Log.withTick('Committed changes.');
|
||||
return;
|
||||
}
|
||||
if (nonInteractive) {
|
||||
throw new Error(
|
||||
'Cannot commit changes when --non-interactive is specified. Run the command in interactive mode or set EAS_BUILD_AUTOCOMMIT=1 in your environment.'
|
||||
);
|
||||
}
|
||||
const { selected } = await promptAsync({
|
||||
type: 'select',
|
||||
name: 'selected',
|
||||
message: 'Can we commit these changes to git for you?',
|
||||
choices: [
|
||||
{ title: 'Yes', value: ShouldCommitChanges.Yes },
|
||||
...(askedFirstTime
|
||||
? [{ title: 'Show the diff and ask me again', value: ShouldCommitChanges.ShowDiffFirst }]
|
||||
: []),
|
||||
{
|
||||
title: 'Abort build process',
|
||||
value: ShouldCommitChanges.Abort,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (selected === ShouldCommitChanges.Abort) {
|
||||
throw new Error(
|
||||
"Aborting, run the command again once you're ready. Make sure to commit any changes you've made."
|
||||
);
|
||||
} else if (selected === ShouldCommitChanges.Yes) {
|
||||
await commitPromptAsync({ initialCommitMessage });
|
||||
Log.withTick('Committed changes.');
|
||||
} else if (selected === ShouldCommitChanges.ShowDiffFirst) {
|
||||
await vcs.showDiffAsync();
|
||||
await reviewAndCommitChangesAsync(initialCommitMessage, {
|
||||
nonInteractive,
|
||||
askedFirstTime: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function waitForBuildEndAsync(
|
||||
buildIds: string[],
|
||||
{ timeoutSec = 3600, intervalSec = 30 } = {}
|
||||
@@ -369,7 +316,7 @@ export async function waitForBuildEndAsync(
|
||||
}
|
||||
}
|
||||
time = new Date().getTime();
|
||||
await sleep(intervalSec * 1000);
|
||||
await sleepAsync(intervalSec * 1000);
|
||||
}
|
||||
spinner.warn('Timed out');
|
||||
throw new Error(
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
BumpStrategy,
|
||||
bumpVersionAsync,
|
||||
bumpVersionInAppJsonAsync,
|
||||
evaluateTemplateString,
|
||||
readBuildNumberAsync,
|
||||
readShortVersionAsync,
|
||||
} from '../version';
|
||||
@@ -28,6 +29,12 @@ beforeEach(() => {
|
||||
fs.mkdirpSync(os.tmpdir());
|
||||
});
|
||||
|
||||
describe(evaluateTemplateString, () => {
|
||||
it('evaluates the template string', () => {
|
||||
expect(evaluateTemplateString('$(BLAH_BLAH)', { BLAH_BLAH: 123 })).toBe('123');
|
||||
});
|
||||
});
|
||||
|
||||
// generic workflow
|
||||
describe(bumpVersionAsync, () => {
|
||||
it('bumps expo.ios.buildNumber and CFBundleVersion when strategy = BumpStrategy.BUILD_NUMBER', async () => {
|
||||
|
||||
@@ -67,7 +67,11 @@ export async function prepareIosBuildAsync(
|
||||
buildConfiguration: applicationTarget.buildConfiguration,
|
||||
});
|
||||
const buildSettings = xcBuildConfiguration?.buildSettings ?? {};
|
||||
return { buildSettings };
|
||||
return {
|
||||
buildSettings,
|
||||
targetName: applicationTarget.targetName,
|
||||
buildConfiguration: applicationTarget.buildConfiguration,
|
||||
};
|
||||
},
|
||||
prepareJobAsync: async (
|
||||
ctx: BuildContext<Platform.IOS>,
|
||||
|
||||
@@ -10,7 +10,6 @@ import Log from '../../log';
|
||||
import { resolveWorkflowAsync } from '../../project/workflow';
|
||||
import { promptAsync } from '../../prompts';
|
||||
import { updateAppJsonConfigAsync } from '../utils/appJson';
|
||||
import { evaluateString } from '../utils/template';
|
||||
import { readPlistAsync, writePlistAsync } from './plist';
|
||||
|
||||
export enum BumpStrategy {
|
||||
@@ -114,7 +113,7 @@ export async function readShortVersionAsync(
|
||||
const infoPlist = await readInfoPlistAsync(projectDir);
|
||||
return (
|
||||
infoPlist.CFBundleShortVersionString &&
|
||||
evaluateString(infoPlist.CFBundleShortVersionString, buildSettings)
|
||||
evaluateTemplateString(infoPlist.CFBundleShortVersionString, buildSettings)
|
||||
);
|
||||
} else {
|
||||
return exp.version;
|
||||
@@ -129,12 +128,29 @@ export async function readBuildNumberAsync(
|
||||
const workflow = await resolveWorkflowAsync(projectDir, Platform.IOS);
|
||||
if (workflow === Workflow.GENERIC) {
|
||||
const infoPlist = await readInfoPlistAsync(projectDir);
|
||||
return infoPlist.CFBundleVersion && evaluateString(infoPlist.CFBundleVersion, buildSettings);
|
||||
return (
|
||||
infoPlist.CFBundleVersion && evaluateTemplateString(infoPlist.CFBundleVersion, buildSettings)
|
||||
);
|
||||
} else {
|
||||
return IOSConfig.Version.getBuildNumber(exp);
|
||||
}
|
||||
}
|
||||
|
||||
export async function maybeResolveVersionsAsync(
|
||||
projectDir: string,
|
||||
exp: ExpoConfig,
|
||||
buildSettings: XCBuildConfiguration['buildSettings']
|
||||
): Promise<{ appVersion?: string; appBuildVersion?: string }> {
|
||||
try {
|
||||
return {
|
||||
appBuildVersion: await readBuildNumberAsync(projectDir, exp, buildSettings),
|
||||
appVersion: await readShortVersionAsync(projectDir, exp, buildSettings),
|
||||
};
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
async function writeVersionsToInfoPlistAsync({
|
||||
projectDir,
|
||||
exp,
|
||||
@@ -172,3 +188,7 @@ function ensureStaticConfigExists(projectDir: string): void {
|
||||
throw new Error('autoIncrement option is not supported when using app.config.js');
|
||||
}
|
||||
}
|
||||
|
||||
export function evaluateTemplateString(s: string, vars: Record<string, any>): string {
|
||||
return s.replace(/\$\((\w+)\)/g, (match, key) => (vars.hasOwnProperty(key) ? vars[key] : match));
|
||||
}
|
||||
@@ -11,7 +11,7 @@ const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
|
||||
export async function runLocalBuildAsync(job: Job): Promise<void> {
|
||||
const execNameOrPath =
|
||||
process.env.EAS_LOCAL_BUILD_PLUGIN_PATH ??
|
||||
(await findWithNodeResolution()) ??
|
||||
(await findWithNodeResolutionAsync()) ??
|
||||
PLUGIN_PACKAGE_NAME;
|
||||
try {
|
||||
const arg = Buffer.from(JSON.stringify({ job })).toString('base64');
|
||||
@@ -31,7 +31,7 @@ export async function runLocalBuildAsync(job: Job): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async function findWithNodeResolution(): Promise<string | undefined> {
|
||||
async function findWithNodeResolutionAsync(): Promise<string | undefined> {
|
||||
try {
|
||||
const resolvedPath = path.resolve(
|
||||
path.dirname(require.resolve(PLUGIN_PACKAGE_NAME)),
|
||||
|
||||
@@ -3,6 +3,7 @@ import { IosEnterpriseProvisioning } from '@expo/eas-json';
|
||||
import type { XCBuildConfiguration } from 'xcode';
|
||||
|
||||
import { getApplicationIdAsync } from '../project/android/applicationId';
|
||||
import { GradleBuildContext } from '../project/android/gradle';
|
||||
import { getBundleIdentifierAsync } from '../project/ios/bundleIdentifier';
|
||||
import { getUsername } from '../project/projectUtils';
|
||||
import { ensureLoggedInAsync } from '../user/actions';
|
||||
@@ -11,13 +12,13 @@ import {
|
||||
readChannelSafelyAsync as readAndroidChannelSafelyAsync,
|
||||
readReleaseChannelSafelyAsync as readAndroidReleaseChannelSafelyAsync,
|
||||
} from './android/UpdatesModule';
|
||||
import { readVersionCodeAsync, readVersionNameAsync } from './android/version';
|
||||
import { maybeResolveVersionsAsync as maybeResolveAndroidVersionsAsync } from './android/version';
|
||||
import { BuildContext } from './context';
|
||||
import {
|
||||
readChannelSafelyAsync as readIosChannelSafelyAsync,
|
||||
readReleaseChannelSafelyAsync as readIosReleaseChannelSafelyAsync,
|
||||
} from './ios/UpdatesModule';
|
||||
import { readBuildNumberAsync, readShortVersionAsync } from './ios/version';
|
||||
import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios/version';
|
||||
import { isExpoUpdatesInstalled } from './utils/updates';
|
||||
|
||||
/**
|
||||
@@ -28,16 +29,21 @@ import { isExpoUpdatesInstalled } from './utils/updates';
|
||||
const packageJSON = require('../../package.json');
|
||||
|
||||
export type MetadataContext<T extends Platform> = T extends Platform.ANDROID
|
||||
? object
|
||||
? AndroidMetadataContext
|
||||
: IosMetadataContext;
|
||||
|
||||
export interface AndroidMetadataContext {
|
||||
gradleContext?: GradleBuildContext;
|
||||
}
|
||||
export interface IosMetadataContext {
|
||||
buildSettings: XCBuildConfiguration['buildSettings'];
|
||||
targetName?: string;
|
||||
buildConfiguration?: string;
|
||||
}
|
||||
|
||||
export async function collectMetadata<T extends Platform>(
|
||||
export async function collectMetadataAsync<T extends Platform>(
|
||||
ctx: BuildContext<T>,
|
||||
platformContext?: MetadataContext<T>
|
||||
platformContext: MetadataContext<T>
|
||||
): Promise<Metadata> {
|
||||
const channelOrReleaseChannel = await resolveChannelOrReleaseChannelAsync(ctx);
|
||||
const distribution =
|
||||
@@ -46,8 +52,7 @@ export async function collectMetadata<T extends Platform>(
|
||||
: ctx.buildProfile.distribution) ?? 'store';
|
||||
const metadata = {
|
||||
trackingContext: ctx.trackingCtx,
|
||||
appVersion: await resolveAppVersionAsync(ctx, platformContext),
|
||||
appBuildVersion: await resolveAppBuildVersionAsync(ctx, platformContext),
|
||||
...(await maybeResolveVersionsAsync(ctx, platformContext)),
|
||||
cliVersion: packageJSON.version,
|
||||
workflow: ctx.workflow,
|
||||
credentialsSource: ctx.buildProfile.credentialsSource,
|
||||
@@ -56,7 +61,7 @@ export async function collectMetadata<T extends Platform>(
|
||||
...channelOrReleaseChannel,
|
||||
distribution,
|
||||
appName: ctx.exp.name,
|
||||
appIdentifier: await resolveAppIdentifierAsync(ctx),
|
||||
appIdentifier: await resolveAppIdentifierAsync(ctx, platformContext),
|
||||
buildProfile: ctx.buildProfileName,
|
||||
gitCommitHash: await vcs.getCommitHashAsync(),
|
||||
username: getUsername(ctx.exp, await ensureLoggedInAsync()),
|
||||
@@ -69,38 +74,38 @@ export async function collectMetadata<T extends Platform>(
|
||||
return sanitizeMetadata(metadata);
|
||||
}
|
||||
|
||||
async function resolveAppVersionAsync<T extends Platform>(
|
||||
async function maybeResolveVersionsAsync<T extends Platform>(
|
||||
ctx: BuildContext<T>,
|
||||
platformContext?: MetadataContext<T>
|
||||
): Promise<string | undefined> {
|
||||
platformContext: MetadataContext<T>
|
||||
): Promise<{ appBuildVersion?: string; appVersion?: string }> {
|
||||
if (ctx.platform === Platform.IOS) {
|
||||
const iosContext = platformContext as IosMetadataContext | undefined;
|
||||
return await readShortVersionAsync(ctx.projectDir, ctx.exp, iosContext?.buildSettings ?? {});
|
||||
const iosContext = platformContext as IosMetadataContext;
|
||||
return await maybeResolveIosVersionsAsync(
|
||||
ctx.projectDir,
|
||||
ctx.exp,
|
||||
iosContext?.buildSettings ?? {}
|
||||
);
|
||||
} else if (ctx.platform === Platform.ANDROID) {
|
||||
const androidCtx = ctx as BuildContext<Platform.ANDROID>;
|
||||
return await maybeResolveAndroidVersionsAsync(ctx.projectDir, ctx.exp, androidCtx.buildProfile);
|
||||
} else {
|
||||
return await readVersionNameAsync(ctx.projectDir, ctx.exp);
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveAppBuildVersionAsync<T extends Platform>(
|
||||
ctx: BuildContext<T>,
|
||||
platformContext?: MetadataContext<T>
|
||||
): Promise<string | undefined> {
|
||||
if (ctx.platform === Platform.IOS) {
|
||||
const iosContext = platformContext as IosMetadataContext | undefined;
|
||||
return await readBuildNumberAsync(ctx.projectDir, ctx.exp, iosContext?.buildSettings ?? {});
|
||||
} else {
|
||||
const versionCode = await readVersionCodeAsync(ctx.projectDir, ctx.exp);
|
||||
return versionCode !== undefined ? String(versionCode) : undefined;
|
||||
throw new Error(`Unsupported platform ${ctx.platform}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveAppIdentifierAsync<T extends Platform>(
|
||||
ctx: BuildContext<T>
|
||||
ctx: BuildContext<T>,
|
||||
platformContext: MetadataContext<T>
|
||||
): Promise<string> {
|
||||
if (ctx.platform === Platform.IOS) {
|
||||
return await getBundleIdentifierAsync(ctx.projectDir, ctx.exp);
|
||||
const iosContext = platformContext as IosMetadataContext;
|
||||
return await getBundleIdentifierAsync(ctx.projectDir, ctx.exp, {
|
||||
targetName: iosContext.targetName,
|
||||
buildConfiguration: iosContext.buildConfiguration,
|
||||
});
|
||||
} else {
|
||||
return await getApplicationIdAsync(ctx.projectDir, ctx.exp);
|
||||
const androidContext = platformContext as AndroidMetadataContext;
|
||||
return await getApplicationIdAsync(ctx.projectDir, ctx.exp, androidContext.gradleContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,10 @@ import chalk from 'chalk';
|
||||
import Log from '../../log';
|
||||
import { requestedPlatformDisplayNames } from '../../platform';
|
||||
|
||||
export function logCredentialsSource(credentialsSource: CredentialsSource, platform: Platform) {
|
||||
export function logCredentialsSource(
|
||||
credentialsSource: CredentialsSource,
|
||||
platform: Platform
|
||||
): void {
|
||||
let message = `Using ${credentialsSource} ${requestedPlatformDisplayNames[platform]} credentials`;
|
||||
if (credentialsSource === CredentialsSource.LOCAL) {
|
||||
message += ` ${chalk.dim('(credentials.json)')}`;
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
import { Platform, Workflow } from '@expo/eas-build-job';
|
||||
import { EasJsonReader } from '@expo/eas-json';
|
||||
import { error } from '@oclif/errors';
|
||||
import chalk from 'chalk';
|
||||
import resolveFrom from 'resolve-from';
|
||||
|
||||
import { toAppPlatform } from '../../graphql/types/AppPlatform';
|
||||
import Log, { learnMore } from '../../log';
|
||||
import { appPlatformDisplayNames } from '../../platform';
|
||||
import { resolveWorkflowAsync } from '../../project/workflow';
|
||||
import { confirmAsync } from '../../prompts';
|
||||
import { expoCommandAsync } from '../../utils/expoCommand';
|
||||
import zipObject from '../../utils/expodash/zipObject';
|
||||
import { reviewAndCommitChangesAsync } from './repository';
|
||||
|
||||
export async function ensureExpoDevClientInstalledForDevClientBuildsAsync({
|
||||
projectDir,
|
||||
platforms,
|
||||
profile,
|
||||
nonInteractive = false,
|
||||
}: {
|
||||
projectDir: string;
|
||||
platforms: Platform[];
|
||||
profile: string;
|
||||
nonInteractive?: boolean;
|
||||
}): Promise<void> {
|
||||
if (await isExpoDevClientInstalledAsync(projectDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const easJsonReader = new EasJsonReader(projectDir);
|
||||
const devClientPerPlatformList = await Promise.all(
|
||||
platforms.map(async platform => {
|
||||
const buildProfile = await easJsonReader.readBuildProfileAsync(platform, profile);
|
||||
return buildProfile.developmentClient ?? false;
|
||||
})
|
||||
);
|
||||
|
||||
const isDevClientRequired = devClientPerPlatformList.some(i => i);
|
||||
if (!isDevClientRequired) {
|
||||
return;
|
||||
}
|
||||
|
||||
const devClientPerPlatform = zipObject(platforms, devClientPerPlatformList);
|
||||
const platformsToCheck = platforms.filter(platform => devClientPerPlatform[platform]);
|
||||
const workflowPerPlatformList = await Promise.all(
|
||||
platformsToCheck.map(platform => resolveWorkflowAsync(projectDir, platform))
|
||||
);
|
||||
|
||||
Log.newLine();
|
||||
Log.error(
|
||||
`You want to build a development client build for platforms: ${platformsToCheck
|
||||
.map(i => chalk.bold(appPlatformDisplayNames[toAppPlatform(i)]))
|
||||
.join(', ')}`
|
||||
);
|
||||
Log.error(
|
||||
`However, we detected that you don't have ${chalk.bold(
|
||||
'expo-dev-client'
|
||||
)} installed for your project.`
|
||||
);
|
||||
const areAllManaged = workflowPerPlatformList.every(i => i === Workflow.MANAGED);
|
||||
if (areAllManaged) {
|
||||
const install = await confirmAsync({
|
||||
message: 'Do you want EAS CLI to install expo-dev-client for you?',
|
||||
instructions: 'The command will abort unless you agree.',
|
||||
});
|
||||
if (install) {
|
||||
await installExpoDevClientAsync(projectDir, { nonInteractive });
|
||||
} else {
|
||||
error(`Install ${chalk.bold('expo-dev-client')} on your own and come back later.`, {
|
||||
exit: 1,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
Log.warn(`Unfortunately, you need to install ${chalk.bold('expo-dev-client')} on your own.`);
|
||||
Log.warn(
|
||||
learnMore('https://docs.expo.dev/clients/installation/', {
|
||||
learnMoreMessage: 'See installation instructions on how to do it',
|
||||
dim: false,
|
||||
})
|
||||
);
|
||||
Log.warn('If you proceed anyway, you might not get the build you want.');
|
||||
Log.newLine();
|
||||
const shouldContinue = await confirmAsync({
|
||||
message: 'Do you want to proceed anyway?',
|
||||
initial: false,
|
||||
});
|
||||
if (!shouldContinue) {
|
||||
error('Come back later', { exit: 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function isExpoDevClientInstalledAsync(projectDir: string): Promise<boolean> {
|
||||
try {
|
||||
resolveFrom(projectDir, 'expo-dev-client/package.json');
|
||||
return true;
|
||||
} catch (err: any) {
|
||||
Log.debug(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function installExpoDevClientAsync(
|
||||
projectDir: string,
|
||||
{ nonInteractive }: { nonInteractive: boolean }
|
||||
): Promise<void> {
|
||||
Log.newLine();
|
||||
Log.log(`Running ${chalk.bold('expo install expo-dev-client')}`);
|
||||
Log.newLine();
|
||||
await expoCommandAsync(projectDir, ['install', 'expo-dev-client']);
|
||||
Log.newLine();
|
||||
await reviewAndCommitChangesAsync('Install expo-dev-client', {
|
||||
nonInteractive,
|
||||
});
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { appPlatformDisplayNames } from '../../platform';
|
||||
import formatFields from '../../utils/formatFields';
|
||||
import { getBuildLogsUrl } from './url';
|
||||
|
||||
export function formatGraphQLBuild(build: BuildFragment) {
|
||||
export function formatGraphQLBuild(build: BuildFragment): string {
|
||||
const actor = getActorName(build);
|
||||
const fields: { label: string; value?: string | null }[] = [
|
||||
{ label: 'ID', value: build.id },
|
||||
|
||||
@@ -121,3 +121,55 @@ export async function makeProjectTarballAsync(): Promise<{ path: string; size: n
|
||||
|
||||
return { size, path: tarPath };
|
||||
}
|
||||
|
||||
enum ShouldCommitChanges {
|
||||
Yes,
|
||||
ShowDiffFirst,
|
||||
Abort,
|
||||
}
|
||||
|
||||
export async function reviewAndCommitChangesAsync(
|
||||
initialCommitMessage: string,
|
||||
{ nonInteractive, askedFirstTime = true }: { nonInteractive: boolean; askedFirstTime?: boolean }
|
||||
): Promise<void> {
|
||||
if (process.env.EAS_BUILD_AUTOCOMMIT) {
|
||||
await vcs.commitAsync({ commitMessage: initialCommitMessage, commitAllFiles: false });
|
||||
Log.withTick('Committed changes.');
|
||||
return;
|
||||
}
|
||||
if (nonInteractive) {
|
||||
throw new Error(
|
||||
'Cannot commit changes when --non-interactive is specified. Run the command in interactive mode or set EAS_BUILD_AUTOCOMMIT=1 in your environment.'
|
||||
);
|
||||
}
|
||||
const { selected } = await promptAsync({
|
||||
type: 'select',
|
||||
name: 'selected',
|
||||
message: 'Can we commit these changes to git for you?',
|
||||
choices: [
|
||||
{ title: 'Yes', value: ShouldCommitChanges.Yes },
|
||||
...(askedFirstTime
|
||||
? [{ title: 'Show the diff and ask me again', value: ShouldCommitChanges.ShowDiffFirst }]
|
||||
: []),
|
||||
{
|
||||
title: 'Abort build process',
|
||||
value: ShouldCommitChanges.Abort,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
if (selected === ShouldCommitChanges.Abort) {
|
||||
throw new Error(
|
||||
"Aborting, run the command again once you're ready. Make sure to commit any changes you've made."
|
||||
);
|
||||
} else if (selected === ShouldCommitChanges.Yes) {
|
||||
await commitPromptAsync({ initialCommitMessage });
|
||||
Log.withTick('Committed changes.');
|
||||
} else if (selected === ShouldCommitChanges.ShowDiffFirst) {
|
||||
await vcs.showDiffAsync();
|
||||
await reviewAndCommitChangesAsync(initialCommitMessage, {
|
||||
nonInteractive,
|
||||
askedFirstTime: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import template from 'lodash/template';
|
||||
|
||||
export function evaluateString(s: string, vars: Record<string, any>): string {
|
||||
return template(s, { interpolate: /\$\(([\s\S]+?)\)/g })(vars);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ExpoConfig, getPackageJson } from '@expo/config';
|
||||
|
||||
export function isExpoUpdatesInstalled(projectDir: string) {
|
||||
export function isExpoUpdatesInstalled(projectDir: string): boolean {
|
||||
const packageJson = getPackageJson(projectDir);
|
||||
return packageJson.dependencies && 'expo-updates' in packageJson.dependencies;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,16 @@ export default abstract class EasCommand extends Command {
|
||||
*/
|
||||
protected requiresAuthentication = true;
|
||||
|
||||
async init() {
|
||||
protected abstract runAsync(): Promise<any>;
|
||||
|
||||
// eslint-disable-next-line async-protect/async-suffix
|
||||
async run(): Promise<any> {
|
||||
await initAnalyticsAsync();
|
||||
|
||||
if (this.requiresAuthentication) {
|
||||
await ensureLoggedInAsync();
|
||||
const { flags } = this.parse();
|
||||
const nonInteractive = (flags as any)['non-interactive'] ?? false;
|
||||
await ensureLoggedInAsync({ nonInteractive });
|
||||
} else {
|
||||
await getUserAsync();
|
||||
}
|
||||
@@ -29,9 +34,11 @@ export default abstract class EasCommand extends Command {
|
||||
// commands/submit === submit, commands/build/list === build:list
|
||||
action: `eas ${this.id}`,
|
||||
});
|
||||
return this.runAsync();
|
||||
}
|
||||
|
||||
async finally(err: Error) {
|
||||
// eslint-disable-next-line async-protect/async-suffix
|
||||
async finally(err: Error): Promise<any> {
|
||||
await flushAnalyticsAsync();
|
||||
return super.finally(err);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,17 @@ jest.mock('../../analytics', () => {
|
||||
};
|
||||
});
|
||||
|
||||
let originalProcessArgv: string[];
|
||||
|
||||
beforeAll(() => {
|
||||
originalProcessArgv = process.argv;
|
||||
process.argv = [];
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
process.argv = originalProcessArgv;
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
(getUserAsync as jest.Mock).mockReset().mockImplementation(() => mockJester);
|
||||
(ensureLoggedInAsync as jest.Mock).mockReset().mockImplementation(() => mockJester);
|
||||
|
||||
@@ -3,11 +3,11 @@ import EasCommand from '../EasCommand';
|
||||
export default class TestEasCommand extends EasCommand {
|
||||
requiresAuthentication = this.authValue();
|
||||
|
||||
authValue() {
|
||||
authValue(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
async run() {}
|
||||
async runAsync(): Promise<void> {}
|
||||
}
|
||||
|
||||
TestEasCommand.id = 'TestEasCommand'; // normally oclif will assign ids, but b/c this is located outside the commands folder it will not
|
||||
@@ -1,15 +1,14 @@
|
||||
import { Command } from '@oclif/command';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import Log from '../../log';
|
||||
import { showLoginPromptAsync } from '../../user/actions';
|
||||
|
||||
export default class AccountLogin extends Command {
|
||||
export default class AccountLogin extends EasCommand {
|
||||
static description = 'log in with your Expo account';
|
||||
|
||||
static aliases = ['login'];
|
||||
|
||||
async run() {
|
||||
Log.log('Log in to EAS');
|
||||
protected requiresAuthentication = false;
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
await showLoginPromptAsync();
|
||||
Log.log('Logged in');
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Command } from '@oclif/command';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import Log from '../../log';
|
||||
import { logoutAsync } from '../../user/User';
|
||||
|
||||
export default class AccountLogout extends Command {
|
||||
export default class AccountLogout extends EasCommand {
|
||||
static description = 'log out';
|
||||
|
||||
static aliases = ['logout'];
|
||||
|
||||
async run() {
|
||||
protected requiresAuthentication = false;
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
await logoutAsync();
|
||||
Log.log('Logged out');
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { Command } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import Log from '../../log';
|
||||
import { getActorDisplayName, getUserAsync } from '../../user/User';
|
||||
|
||||
export default class AccountView extends Command {
|
||||
export default class AccountView extends EasCommand {
|
||||
static description = 'show the username you are logged in as';
|
||||
|
||||
static aliases = ['whoami'];
|
||||
|
||||
async run() {
|
||||
protected requiresAuthentication = false;
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const user = await getUserAsync();
|
||||
if (user) {
|
||||
Log.log(chalk.green(getActorDisplayName(user)));
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
import { Command } from '@oclif/command';
|
||||
|
||||
import EasCommand from '../commandUtils/EasCommand';
|
||||
import Log from '../log';
|
||||
import UserSettings from '../user/UserSettings';
|
||||
|
||||
export default class AnalyticsView extends Command {
|
||||
export default class AnalyticsView extends EasCommand {
|
||||
static description = 'view or change analytics settings';
|
||||
|
||||
static args = [{ name: 'STATUS', options: ['on', 'off'] }];
|
||||
|
||||
async run() {
|
||||
protected requiresAuthentication = false;
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const { STATUS: status } = this.parse(AnalyticsView).args;
|
||||
if (status) {
|
||||
await UserSettings.setAsync('amplitudeEnabled', status === 'on');
|
||||
await UserSettings.setAsync('analyticsEnabled', status === 'on');
|
||||
Log.withTick(`${status === 'on' ? 'Enabling' : 'Disabling'} analytics.`);
|
||||
} else {
|
||||
const amplitudeEnabled = await UserSettings.getAsync('amplitudeEnabled', null);
|
||||
const analyticsEnabled = await UserSettings.getAsync('analyticsEnabled', null);
|
||||
Log.log(
|
||||
`Analytics are ${
|
||||
amplitudeEnabled === false ? 'disabled' : 'enabled'
|
||||
analyticsEnabled === false ? 'disabled' : 'enabled'
|
||||
} on this eas-cli installation.`
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
CreateUpdateBranchForAppMutation,
|
||||
@@ -49,7 +50,7 @@ export async function createUpdateBranchOnAppAsync({
|
||||
return newBranch;
|
||||
}
|
||||
|
||||
export default class BranchCreate extends Command {
|
||||
export default class BranchCreate extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Create a branch on the current project.';
|
||||
|
||||
@@ -68,7 +69,7 @@ export default class BranchCreate extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name },
|
||||
flags,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
DeleteUpdateBranchMutation,
|
||||
@@ -73,7 +74,7 @@ async function deleteBranchOnAppAsync({
|
||||
return data.updateBranch.deleteUpdateBranch;
|
||||
}
|
||||
|
||||
export default class BranchDelete extends Command {
|
||||
export default class BranchDelete extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Republish an update group';
|
||||
|
||||
@@ -91,7 +92,7 @@ export default class BranchDelete extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name },
|
||||
flags: { json: jsonFlag },
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import CliTable from 'cli-table3';
|
||||
import { print } from 'graphql';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import { BranchesByAppQuery, BranchesByAppQueryVariables } from '../../graphql/generated';
|
||||
import {
|
||||
BranchesByAppQuery,
|
||||
BranchesByAppQueryVariables,
|
||||
UpdateBranchFragment,
|
||||
} from '../../graphql/generated';
|
||||
import { UpdateBranchFragmentNode } from '../../graphql/types/UpdateBranch';
|
||||
import Log from '../../log';
|
||||
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
|
||||
import { UPDATE_COLUMNS, formatUpdate, getPlatformsForGroup } from '../../update/utils';
|
||||
|
||||
const BRANCHES_LIMIT = 10_000;
|
||||
|
||||
export async function listBranchesAsync({ projectId }: { projectId: string }) {
|
||||
export async function listBranchesAsync({
|
||||
projectId,
|
||||
}: {
|
||||
projectId: string;
|
||||
}): Promise<UpdateBranchFragment[]> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.query<BranchesByAppQuery, BranchesByAppQueryVariables>(
|
||||
@@ -23,29 +34,12 @@ export async function listBranchesAsync({ projectId }: { projectId: string }) {
|
||||
id
|
||||
updateBranches(offset: 0, limit: $limit) {
|
||||
id
|
||||
name
|
||||
updates(offset: 0, limit: 10) {
|
||||
id
|
||||
actor {
|
||||
__typename
|
||||
id
|
||||
... on User {
|
||||
username
|
||||
}
|
||||
... on Robot {
|
||||
firstName
|
||||
}
|
||||
}
|
||||
createdAt
|
||||
message
|
||||
runtimeVersion
|
||||
group
|
||||
platform
|
||||
}
|
||||
...UpdateBranchFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${print(UpdateBranchFragmentNode)}
|
||||
`,
|
||||
{
|
||||
appId: projectId,
|
||||
@@ -58,7 +52,7 @@ export async function listBranchesAsync({ projectId }: { projectId: string }) {
|
||||
return data?.app?.byId.updateBranches ?? [];
|
||||
}
|
||||
|
||||
export default class BranchList extends Command {
|
||||
export default class BranchList extends EasCommand {
|
||||
static hidden = true;
|
||||
|
||||
static description = 'List all branches on this project.';
|
||||
@@ -70,7 +64,7 @@ export default class BranchList extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = this.parse(BranchList);
|
||||
|
||||
const projectDir = await findProjectRootAsync(process.cwd());
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { ExpoConfig, getConfig, getDefaultTarget } from '@expo/config';
|
||||
import { getRuntimeVersionForSDKVersion } from '@expo/sdk-runtime-versions';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import dateFormat from 'dateformat';
|
||||
import gql from 'graphql-tag';
|
||||
import { uniqBy } from 'lodash';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
GetUpdateGroupAsyncQuery,
|
||||
@@ -30,6 +30,7 @@ import {
|
||||
} from '../../project/publish';
|
||||
import { promptAsync, selectAsync } from '../../prompts';
|
||||
import { formatUpdate } from '../../update/utils';
|
||||
import uniqBy from '../../utils/expodash/uniqBy';
|
||||
import formatFields from '../../utils/formatFields';
|
||||
import vcs from '../../vcs';
|
||||
import { createUpdateBranchOnAppAsync } from './create';
|
||||
@@ -66,7 +67,7 @@ async function getUpdateGroupAsync({
|
||||
return updatesByGroup;
|
||||
}
|
||||
|
||||
async function ensureBranchExists({
|
||||
async function ensureBranchExistsAsync({
|
||||
appId,
|
||||
name: branchName,
|
||||
}: {
|
||||
@@ -93,7 +94,7 @@ async function ensureBranchExists({
|
||||
return { id: newUpdateBranch.id, updates: [] };
|
||||
}
|
||||
|
||||
export default class BranchPublish extends Command {
|
||||
export default class BranchPublish extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Publish an update group to a branch.';
|
||||
|
||||
@@ -144,7 +145,7 @@ export default class BranchPublish extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name: branchName },
|
||||
flags: {
|
||||
@@ -201,7 +202,7 @@ export default class BranchPublish extends Command {
|
||||
assert(branchName, 'branch name must be specified.');
|
||||
}
|
||||
|
||||
const { id: branchId, updates } = await ensureBranchExists({
|
||||
const { id: branchId, updates } = await ensureBranchExistsAsync({
|
||||
appId: projectId,
|
||||
name: branchName,
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
EditUpdateBranchInput,
|
||||
@@ -49,7 +50,7 @@ async function renameUpdateBranchOnAppAsync({
|
||||
return data.updateBranch.editUpdateBranch;
|
||||
}
|
||||
|
||||
export default class BranchRename extends Command {
|
||||
export default class BranchRename extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Rename a branch.';
|
||||
|
||||
@@ -68,7 +69,7 @@ export default class BranchRename extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
flags: { json: jsonFlag, from: currentName, to: newName },
|
||||
} = this.parse(BranchRename);
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import Table from 'cli-table3';
|
||||
import gql from 'graphql-tag';
|
||||
import { groupBy } from 'lodash';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import { ViewBranchQuery, ViewBranchQueryVariables } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
|
||||
import { promptAsync } from '../../prompts';
|
||||
import { UPDATE_COLUMNS, formatUpdate, getPlatformsForGroup } from '../../update/utils';
|
||||
import groupBy from '../../utils/expodash/groupBy';
|
||||
import formatFields from '../../utils/formatFields';
|
||||
|
||||
const PAGE_LIMIT = 10_000;
|
||||
@@ -64,7 +65,7 @@ export async function viewUpdateBranchAsync({
|
||||
return data;
|
||||
}
|
||||
|
||||
export default class BranchView extends Command {
|
||||
export default class BranchView extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'View a branch.';
|
||||
|
||||
@@ -83,7 +84,7 @@ export default class BranchView extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name },
|
||||
flags: { json: jsonFlag },
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
Build,
|
||||
@@ -109,12 +109,12 @@ async function ensureBuildExistsAsync(buildId: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
export default class BuildCancel extends Command {
|
||||
export default class BuildCancel extends EasCommand {
|
||||
static description = 'Cancel a build.';
|
||||
|
||||
static args = [{ name: 'BUILD_ID' }];
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const { BUILD_ID: buildIdFromArg } = this.parse(BuildCancel).args;
|
||||
|
||||
const projectDir = (await findProjectRootAsync()) ?? process.cwd();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { configureAsync } from '../../build/configure';
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import Log, { learnMore } from '../../log';
|
||||
import { RequestedPlatform } from '../../platform';
|
||||
import { findProjectRootAsync } from '../../project/projectUtils';
|
||||
import { promptAsync } from '../../prompts';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
|
||||
export default class BuildConfigure extends Command {
|
||||
export default class BuildConfigure extends EasCommand {
|
||||
static description = 'Configure the project to support EAS Build.';
|
||||
|
||||
static flags = {
|
||||
@@ -19,7 +19,7 @@ export default class BuildConfigure extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = this.parse(BuildConfigure);
|
||||
Log.log(
|
||||
'💡 The following process will configure your iOS and/or Android project to be compatible with EAS Build. These changes only apply to your local project files and you can safely revert them at any time.'
|
||||
@@ -29,7 +29,6 @@ export default class BuildConfigure extends Command {
|
||||
const platform =
|
||||
(flags.platform as RequestedPlatform | undefined) ?? (await promptForPlatformAsync());
|
||||
|
||||
await ensureLoggedInAsync();
|
||||
await configureAsync({
|
||||
platform,
|
||||
projectDir: (await findProjectRootAsync()) ?? process.cwd(),
|
||||
@@ -40,7 +39,7 @@ export default class BuildConfigure extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
function logSuccess(platform: RequestedPlatform) {
|
||||
function logSuccess(platform: RequestedPlatform): void {
|
||||
let platformsText = 'iOS and Android projects are';
|
||||
let storesText = 'the Apple App Store or Google Play Store';
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import { BuildRequestSender, waitForBuildEndAsync } from '../../build/build';
|
||||
import { ensureProjectConfiguredAsync } from '../../build/configure';
|
||||
import { BuildContext, createBuildContextAsync } from '../../build/context';
|
||||
import { prepareIosBuildAsync } from '../../build/ios/build';
|
||||
import { ensureExpoDevClientInstalledForDevClientBuildsAsync } from '../../build/utils/devClient';
|
||||
import { printBuildResults, printLogsUrls } from '../../build/utils/printBuildInfo';
|
||||
import { ensureRepoIsCleanAsync } from '../../build/utils/repository';
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
@@ -127,7 +128,7 @@ export default class Build extends EasCommand {
|
||||
|
||||
private metroConfigValidated = false;
|
||||
|
||||
async run(): Promise<void> {
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags: rawFlags } = this.parse(Build);
|
||||
if (rawFlags.json) {
|
||||
enableJsonOutput();
|
||||
@@ -144,6 +145,12 @@ export default class Build extends EasCommand {
|
||||
await ensureProjectConfiguredAsync(projectDir, requestedPlatform);
|
||||
|
||||
const platforms = toPlatforms(requestedPlatform);
|
||||
await ensureExpoDevClientInstalledForDevClientBuildsAsync({
|
||||
platforms,
|
||||
projectDir,
|
||||
profile: flags.profile,
|
||||
nonInteractive: flags.nonInteractive,
|
||||
});
|
||||
|
||||
const startedBuilds: BuildFragment[] = [];
|
||||
for (const platform of platforms) {
|
||||
@@ -259,6 +266,7 @@ export default class Build extends EasCommand {
|
||||
}): Promise<BuildFragment | undefined> {
|
||||
const easJsonReader = new EasJsonReader(projectDir);
|
||||
const buildProfile = await easJsonReader.readBuildProfileAsync(platform, flags.profile);
|
||||
|
||||
const buildCtx = await createBuildContextAsync({
|
||||
buildProfileName: flags.profile,
|
||||
clearCache: flags.clearCache,
|
||||
@@ -315,6 +323,7 @@ export default class Build extends EasCommand {
|
||||
}): Promise<SubmissionFragment> {
|
||||
const easJsonReader = new EasJsonReader(projectDir);
|
||||
const platform = toPlatform(build.platform);
|
||||
const buildProfile = await easJsonReader.readBuildProfileAsync(platform, flags.profile);
|
||||
const submitProfile = await easJsonReader.readSubmitProfileAsync(platform, flags.submitProfile);
|
||||
const submissionCtx = createSubmissionContext({
|
||||
platform,
|
||||
@@ -323,6 +332,7 @@ export default class Build extends EasCommand {
|
||||
profile: submitProfile,
|
||||
archiveFlags: { id: build.id },
|
||||
nonInteractive: flags.nonInteractive,
|
||||
env: buildProfile.env,
|
||||
});
|
||||
|
||||
if (moreBuilds) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import ora from 'ora';
|
||||
|
||||
import { BuildDistributionType, BuildStatus } from '../../build/types';
|
||||
import { formatGraphQLBuild } from '../../build/utils/formatBuild';
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import {
|
||||
AppPlatform,
|
||||
DistributionType,
|
||||
@@ -20,7 +21,7 @@ import {
|
||||
} from '../../project/projectUtils';
|
||||
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
|
||||
|
||||
export default class BuildList extends Command {
|
||||
export default class BuildList extends EasCommand {
|
||||
static description = 'list all builds for your project';
|
||||
|
||||
static flags = {
|
||||
@@ -58,7 +59,7 @@ export default class BuildList extends Command {
|
||||
limit: flags.integer(),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = this.parse(BuildList);
|
||||
const {
|
||||
json,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import ora from 'ora';
|
||||
|
||||
import { formatGraphQLBuild } from '../../build/utils/formatBuild';
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { BuildFragment } from '../../graphql/generated';
|
||||
import { BuildQuery } from '../../graphql/queries/BuildQuery';
|
||||
import Log from '../../log';
|
||||
@@ -13,7 +14,7 @@ import {
|
||||
} from '../../project/projectUtils';
|
||||
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
|
||||
|
||||
export default class BuildView extends Command {
|
||||
export default class BuildView extends EasCommand {
|
||||
static description = 'view a build for your project';
|
||||
|
||||
static args = [{ name: 'BUILD_ID' }];
|
||||
@@ -24,7 +25,7 @@ export default class BuildView extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { BUILD_ID: buildId },
|
||||
flags,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
CreateUpdateChannelOnAppMutation,
|
||||
@@ -57,7 +58,7 @@ async function createUpdateChannelOnAppAsync({
|
||||
);
|
||||
}
|
||||
|
||||
export default class ChannelCreate extends Command {
|
||||
export default class ChannelCreate extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Create a channel on the current project.';
|
||||
|
||||
@@ -77,7 +78,7 @@ export default class ChannelCreate extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name: channelName },
|
||||
flags: { json: jsonFlag },
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
GetChannelByNameToEditQuery,
|
||||
@@ -92,7 +93,7 @@ export async function updateChannelBranchMappingAsync({
|
||||
return data.updateChannel.editUpdateChannel!;
|
||||
}
|
||||
|
||||
export default class ChannelEdit extends Command {
|
||||
export default class ChannelEdit extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Point a channel at a new branch.';
|
||||
|
||||
@@ -114,7 +115,7 @@ export default class ChannelEdit extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name: channelName },
|
||||
flags: { branch: branchName, json: jsonFlag },
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
GetAllChannelsForAppQuery,
|
||||
@@ -63,7 +64,7 @@ async function getAllUpdateChannelForAppAsync({
|
||||
);
|
||||
}
|
||||
|
||||
export default class ChannelList extends Command {
|
||||
export default class ChannelList extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'List all channels on the current project.';
|
||||
|
||||
@@ -74,7 +75,7 @@ export default class ChannelList extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
flags: { json: jsonFlag },
|
||||
} = this.parse(ChannelList);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { GetChannelByNameForAppQuery, UpdateBranch } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
import {
|
||||
@@ -305,7 +306,7 @@ async function endRolloutAsync({
|
||||
return { newChannelInfo, logMessage };
|
||||
}
|
||||
|
||||
export default class ChannelRollout extends Command {
|
||||
export default class ChannelRollout extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Rollout a new branch out to a channel incrementally.';
|
||||
|
||||
@@ -336,7 +337,7 @@ export default class ChannelRollout extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { channel: channelName },
|
||||
flags: { json: jsonFlag, end: endFlag },
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import Table from 'cli-table3';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
GetChannelByNameForAppQuery,
|
||||
@@ -189,7 +190,7 @@ export function logChannelDetails(channel: {
|
||||
Log.log(table.toString());
|
||||
}
|
||||
|
||||
export default class ChannelView extends Command {
|
||||
export default class ChannelView extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'View a channel on the current project.';
|
||||
|
||||
@@ -208,7 +209,7 @@ export default class ChannelView extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { name: channelName },
|
||||
flags: { json: jsonFlag },
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import { getProjectConfigDescription } from '@expo/config';
|
||||
import { Platform } from '@expo/eas-build-job';
|
||||
import { EasJsonReader } from '@expo/eas-json';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
|
||||
import EasCommand from '../commandUtils/EasCommand';
|
||||
import Log from '../log';
|
||||
import { getExpoConfig } from '../project/expoConfig';
|
||||
import { findProjectRootAsync } from '../project/projectUtils';
|
||||
import { selectAsync } from '../prompts';
|
||||
import { handleDeprecatedEasJsonAsync } from './build';
|
||||
|
||||
export default class Config extends Command {
|
||||
export default class Config extends EasCommand {
|
||||
static description = 'show the eas.json config';
|
||||
|
||||
static flags = {
|
||||
@@ -17,7 +18,9 @@ export default class Config extends Command {
|
||||
profile: flags.string(),
|
||||
};
|
||||
|
||||
async run() {
|
||||
protected requiresAuthentication = false;
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = this.parse(Config);
|
||||
const { platform: maybePlatform, profile: maybeProfile } = flags as {
|
||||
platform?: Platform;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { SelectPlatform } from '../credentials/manager/SelectPlatform';
|
||||
export default class Credentials extends EasCommand {
|
||||
static description = 'manage your credentials';
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const ctx = await createCredentialsContextAsync(process.cwd(), {});
|
||||
await new SelectPlatform().runAsync(ctx);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
import { Command } from '@oclif/command';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import AppStoreApi from '../../credentials/ios/appstore/AppStoreApi';
|
||||
import { createContext } from '../../devices/context';
|
||||
import { createContextAsync } from '../../devices/context';
|
||||
import DeviceManager from '../../devices/manager';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
|
||||
export default class DeviceCreate extends Command {
|
||||
export default class DeviceCreate extends EasCommand {
|
||||
static description = 'register new Apple Devices to use for internal distribution';
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const user = await ensureLoggedInAsync();
|
||||
|
||||
const ctx = await createContext({ appStore: new AppStoreApi(), user });
|
||||
const ctx = await createContextAsync({ appStore: new AppStoreApi(), user });
|
||||
const manager = new DeviceManager(ctx);
|
||||
await manager.createAsync();
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { AppleDeviceQuery } from '../../credentials/ios/api/graphql/queries/AppleDeviceQuery';
|
||||
import { AppleTeamQuery } from '../../credentials/ios/api/graphql/queries/AppleTeamQuery';
|
||||
import formatDevice from '../../devices/utils/formatDevice';
|
||||
@@ -11,14 +12,14 @@ import Log from '../../log';
|
||||
import { findProjectRootAsync, getProjectAccountNameAsync } from '../../project/projectUtils';
|
||||
import { promptAsync } from '../../prompts';
|
||||
|
||||
export default class BuildList extends Command {
|
||||
export default class BuildList extends EasCommand {
|
||||
static description = 'list all registered devices for your account';
|
||||
|
||||
static flags = {
|
||||
'apple-team-id': flags.string(),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
let appleTeamIdentifier = this.parse(BuildList).flags['apple-team-id'];
|
||||
|
||||
const projectDir = (await findProjectRootAsync()) ?? process.cwd();
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command } from '@oclif/command';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { AppleDeviceQuery } from '../../credentials/ios/api/graphql/queries/AppleDeviceQuery';
|
||||
import formatDevice from '../../devices/utils/formatDevice';
|
||||
import Log from '../../log';
|
||||
import { findProjectRootAsync, getProjectAccountNameAsync } from '../../project/projectUtils';
|
||||
|
||||
export default class DeviceView extends Command {
|
||||
export default class DeviceView extends EasCommand {
|
||||
static description = 'view a device for your project';
|
||||
|
||||
static args = [{ name: 'UDID' }];
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const { UDID } = this.parse(DeviceView).args;
|
||||
|
||||
if (!UDID) {
|
||||
@@ -36,7 +36,7 @@ If you are not sure what is the UDID of the device you are looking for, run:
|
||||
const spinner = ora().start(`Fetching device details for ${UDID}…`);
|
||||
|
||||
try {
|
||||
const device = await AppleDeviceQuery.getByDeviceIdentifier(accountName, UDID);
|
||||
const device = await AppleDeviceQuery.getByDeviceIdentifierAsync(accountName, UDID);
|
||||
|
||||
if (device) {
|
||||
spinner.succeed('Fetched device details');
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
import { Command } from '@oclif/command';
|
||||
import envinfo from 'envinfo';
|
||||
|
||||
import EasCommand from '../commandUtils/EasCommand';
|
||||
import Log from '../log';
|
||||
|
||||
const packageJSON = require('../../package.json');
|
||||
|
||||
export default class Diagnostics extends Command {
|
||||
export default class Diagnostics extends EasCommand {
|
||||
static description = 'log environment info to the console';
|
||||
|
||||
async run() {
|
||||
protected requiresAuthentication = false;
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const info = await envinfo.run(
|
||||
{
|
||||
System: ['OS', 'Shell'],
|
||||
@@ -16,14 +18,16 @@ export default class Diagnostics extends Command {
|
||||
Utilities: ['Git'],
|
||||
npmPackages: [
|
||||
'expo',
|
||||
'expo-cli',
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-native',
|
||||
'react-native-web',
|
||||
'react-navigation',
|
||||
'@expo/webpack-config',
|
||||
'expo-dev-client',
|
||||
],
|
||||
npmGlobalPackages: ['eas-cli'],
|
||||
npmGlobalPackages: ['eas-cli', 'expo-cli'],
|
||||
},
|
||||
{
|
||||
title: `EAS CLI ${packageJSON.version} environment info`,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command } from '@oclif/command';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import { AppInfoQuery, AppInfoQueryVariables } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
@@ -30,10 +30,10 @@ async function projectInfoByIdAsync(appId: string): Promise<AppInfoQuery> {
|
||||
return data;
|
||||
}
|
||||
|
||||
export default class ProjectInfo extends Command {
|
||||
export default class ProjectInfo extends EasCommand {
|
||||
static description = 'information about the current project';
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const projectDir = await findProjectRootAsync(process.cwd());
|
||||
if (!projectDir) {
|
||||
throw new Error('Please run this command inside a project directory.');
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import Log from '../../log';
|
||||
import { findProjectRootAsync, setProjectIdAsync } from '../../project/projectUtils';
|
||||
|
||||
export default class ProjectInit extends Command {
|
||||
export default class ProjectInit extends EasCommand {
|
||||
static description = 'create or link an EAS project';
|
||||
static aliases = ['init'];
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const projectDir = await findProjectRootAsync(process.cwd());
|
||||
if (!projectDir) {
|
||||
throw new Error('Please run this command inside a project directory.');
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { EnvironmentSecretMutation } from '../../graphql/mutations/EnvironmentSecretMutation';
|
||||
import {
|
||||
EnvironmentSecretScope,
|
||||
@@ -22,7 +23,7 @@ import { findAccountByName } from '../../user/Account';
|
||||
import { getActorDisplayName } from '../../user/User';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
|
||||
export default class EnvironmentSecretCreate extends Command {
|
||||
export default class EnvironmentSecretCreate extends EasCommand {
|
||||
static description = 'Create an environment secret on the current project or owner account.';
|
||||
|
||||
static flags = {
|
||||
@@ -43,7 +44,7 @@ export default class EnvironmentSecretCreate extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const actor = await ensureLoggedInAsync();
|
||||
let {
|
||||
flags: { name, value: secretValue, scope, force },
|
||||
@@ -123,7 +124,7 @@ export default class EnvironmentSecretCreate extends Command {
|
||||
const existingSecret = existingSecrets.find(secret => secret.name === name);
|
||||
|
||||
if (existingSecret) {
|
||||
await EnvironmentSecretMutation.delete(existingSecret.id);
|
||||
await EnvironmentSecretMutation.deleteAsync(existingSecret.id);
|
||||
Log.withTick(
|
||||
`Deleting existing secret ${chalk.bold(name)} on project ${chalk.bold(
|
||||
`@${accountName}/${slug}`
|
||||
@@ -132,7 +133,7 @@ export default class EnvironmentSecretCreate extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
const secret = await EnvironmentSecretMutation.createForApp(
|
||||
const secret = await EnvironmentSecretMutation.createForAppAsync(
|
||||
{ name, value: secretValue },
|
||||
projectId
|
||||
);
|
||||
@@ -149,6 +150,7 @@ export default class EnvironmentSecretCreate extends Command {
|
||||
);
|
||||
} else if (scope === EnvironmentSecretScope.ACCOUNT) {
|
||||
const ownerAccount = findAccountByName(actor.accounts, accountName);
|
||||
|
||||
if (!ownerAccount) {
|
||||
Log.warn(
|
||||
`Your account (${getActorDisplayName(actor)}) doesn't have access to the ${chalk.bold(
|
||||
@@ -159,11 +161,12 @@ export default class EnvironmentSecretCreate extends Command {
|
||||
}
|
||||
|
||||
if (force) {
|
||||
const existingSecrets = await EnvironmentSecretsQuery.byAcccountNameAsync(projectId);
|
||||
const existingSecrets = await EnvironmentSecretsQuery.byAccountNameAsync(ownerAccount.name);
|
||||
const existingSecret = existingSecrets.find(secret => secret.name === name);
|
||||
|
||||
if (existingSecret) {
|
||||
await EnvironmentSecretMutation.delete(existingSecret.id);
|
||||
await EnvironmentSecretMutation.deleteAsync(existingSecret.id);
|
||||
|
||||
Log.withTick(
|
||||
`Deleting existing secret ${chalk.bold(name)} on account ${chalk.bold(
|
||||
ownerAccount.name
|
||||
@@ -172,7 +175,7 @@ export default class EnvironmentSecretCreate extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
const secret = await EnvironmentSecretMutation.createForAccount(
|
||||
const secret = await EnvironmentSecretMutation.createForAccountAsync(
|
||||
{ name, value: secretValue },
|
||||
ownerAccount.id
|
||||
);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { EnvironmentSecretMutation } from '../../graphql/mutations/EnvironmentSecretMutation';
|
||||
import {
|
||||
EnvironmentSecretScope,
|
||||
@@ -19,9 +20,8 @@ import {
|
||||
getProjectIdAsync,
|
||||
} from '../../project/projectUtils';
|
||||
import { promptAsync, toggleConfirmAsync } from '../../prompts';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
|
||||
export default class EnvironmentSecretDelete extends Command {
|
||||
export default class EnvironmentSecretDelete extends EasCommand {
|
||||
static description = `Delete an environment secret by ID.
|
||||
Unsure where to find the secret's ID? Run ${chalk.bold('eas secrets:list')}`;
|
||||
|
||||
@@ -31,9 +31,7 @@ Unsure where to find the secret's ID? Run ${chalk.bold('eas secrets:list')}`;
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
await ensureLoggedInAsync();
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const projectDir = (await findProjectRootAsync()) ?? process.cwd();
|
||||
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
|
||||
const projectId = await getProjectIdAsync(exp);
|
||||
@@ -93,7 +91,7 @@ Unsure where to find the secret's ID? Run ${chalk.bold('eas secrets:list')}`;
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await EnvironmentSecretMutation.delete(id);
|
||||
await EnvironmentSecretMutation.deleteAsync(id);
|
||||
|
||||
Log.withTick(`️Deleted secret${secret?.name ? ` "${secret?.name}"` : ''} with id "${id}".`);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import Table from 'cli-table3';
|
||||
import dateFormat from 'dateformat';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { EnvironmentSecretsQuery } from '../../graphql/queries/EnvironmentSecretsQuery';
|
||||
import Log from '../../log';
|
||||
import {
|
||||
@@ -15,14 +15,11 @@ import {
|
||||
getProjectAccountNameAsync,
|
||||
getProjectIdAsync,
|
||||
} from '../../project/projectUtils';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
|
||||
export default class EnvironmentSecretList extends Command {
|
||||
export default class EnvironmentSecretList extends EasCommand {
|
||||
static description = 'Lists environment secrets available for your current app';
|
||||
|
||||
async run(): Promise<void> {
|
||||
await ensureLoggedInAsync();
|
||||
|
||||
async runAsync(): Promise<void> {
|
||||
const projectDir = (await findProjectRootAsync()) ?? process.cwd();
|
||||
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
|
||||
const projectId = await getProjectIdAsync(exp);
|
||||
|
||||
@@ -89,7 +89,7 @@ See how to configure submits with eas.json: ${learnMore('https://docs.expo.dev/s
|
||||
}),
|
||||
};
|
||||
|
||||
async run(): Promise<void> {
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags: rawFlags } = this.parse(Submit);
|
||||
const flags = await this.sanitizeFlagsAsync(rawFlags);
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import {
|
||||
DeleteUpdateGroupMutation,
|
||||
@@ -33,7 +34,7 @@ async function deleteUpdateGroupAsync({
|
||||
);
|
||||
}
|
||||
|
||||
export default class UpdateDelete extends Command {
|
||||
export default class UpdateDelete extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Delete all the updates in an update Group.';
|
||||
|
||||
@@ -52,7 +53,7 @@ export default class UpdateDelete extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { groupId: group },
|
||||
flags: { json: jsonFlag },
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import Table from 'cli-table3';
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
|
||||
import { UpdatesByGroupQuery, UpdatesByGroupQueryVariables } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
@@ -47,7 +48,7 @@ export async function viewUpdateAsync({
|
||||
}
|
||||
return data;
|
||||
}
|
||||
export default class UpdateView extends Command {
|
||||
export default class UpdateView extends EasCommand {
|
||||
static hidden = true;
|
||||
static description = 'Update group details.';
|
||||
|
||||
@@ -66,7 +67,7 @@ export default class UpdateView extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { groupId },
|
||||
flags: { json: jsonFlag },
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { WebhookType } from '../../graphql/generated';
|
||||
import { WebhookMutation } from '../../graphql/mutations/WebhookMutation';
|
||||
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
import { prepareInputParamsAsync } from '../../webhooks/input';
|
||||
|
||||
export default class WebhookCreate extends Command {
|
||||
export default class WebhookCreate extends EasCommand {
|
||||
static description = 'Create a webhook on the current project.';
|
||||
|
||||
static flags = {
|
||||
@@ -26,8 +26,7 @@ export default class WebhookCreate extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
await ensureLoggedInAsync();
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = this.parse(WebhookCreate);
|
||||
const webhookInputParams = await prepareInputParamsAsync(flags);
|
||||
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command } from '@oclif/command';
|
||||
import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import nullthrows from 'nullthrows';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { WebhookFragment } from '../../graphql/generated';
|
||||
import { WebhookMutation } from '../../graphql/mutations/WebhookMutation';
|
||||
import { WebhookQuery } from '../../graphql/queries/WebhookQuery';
|
||||
import Log from '../../log';
|
||||
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
|
||||
import { promptAsync, toggleConfirmAsync } from '../../prompts';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
import { formatWebhook } from '../../webhooks/formatWebhook';
|
||||
|
||||
export default class WebhookDelete extends Command {
|
||||
export default class WebhookDelete extends EasCommand {
|
||||
static description = 'Delete a webhook on the current project.';
|
||||
|
||||
static args = [
|
||||
@@ -25,8 +24,7 @@ export default class WebhookDelete extends Command {
|
||||
},
|
||||
];
|
||||
|
||||
async run() {
|
||||
await ensureLoggedInAsync();
|
||||
async runAsync(): Promise<void> {
|
||||
let {
|
||||
args: { ID: webhookId },
|
||||
} = this.parse(WebhookDelete);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { getConfig } from '@expo/config';
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import { flags } from '@oclif/command';
|
||||
import chalk from 'chalk';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { WebhookType } from '../../graphql/generated';
|
||||
import { WebhookQuery } from '../../graphql/queries/WebhookQuery';
|
||||
import Log from '../../log';
|
||||
@@ -11,10 +12,9 @@ import {
|
||||
getProjectFullNameAsync,
|
||||
getProjectIdAsync,
|
||||
} from '../../project/projectUtils';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
import { formatWebhook } from '../../webhooks/formatWebhook';
|
||||
|
||||
export default class WebhookList extends Command {
|
||||
export default class WebhookList extends EasCommand {
|
||||
static description = 'List webhooks on the current project.';
|
||||
|
||||
static flags = {
|
||||
@@ -24,8 +24,7 @@ export default class WebhookList extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
await ensureLoggedInAsync();
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
flags: { event },
|
||||
} = this.parse(WebhookList);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { Command, flags } from '@oclif/command';
|
||||
import pick from 'lodash/pick';
|
||||
import { flags } from '@oclif/command';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { WebhookType } from '../../graphql/generated';
|
||||
import { WebhookMutation } from '../../graphql/mutations/WebhookMutation';
|
||||
import { WebhookQuery } from '../../graphql/queries/WebhookQuery';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
import pick from '../../utils/expodash/pick';
|
||||
import { prepareInputParamsAsync } from '../../webhooks/input';
|
||||
|
||||
export default class WebhookUpdate extends Command {
|
||||
export default class WebhookUpdate extends EasCommand {
|
||||
static description = 'Create a webhook on the current project.';
|
||||
|
||||
static flags = {
|
||||
@@ -30,8 +30,7 @@ export default class WebhookUpdate extends Command {
|
||||
}),
|
||||
};
|
||||
|
||||
async run() {
|
||||
await ensureLoggedInAsync();
|
||||
async runAsync(): Promise<void> {
|
||||
const { flags } = this.parse(WebhookUpdate);
|
||||
|
||||
const webhookId = flags.id;
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { Command } from '@oclif/command';
|
||||
import ora from 'ora';
|
||||
|
||||
import EasCommand from '../../commandUtils/EasCommand';
|
||||
import { WebhookQuery } from '../../graphql/queries/WebhookQuery';
|
||||
import Log from '../../log';
|
||||
import { ensureLoggedInAsync } from '../../user/actions';
|
||||
import { formatWebhook } from '../../webhooks/formatWebhook';
|
||||
|
||||
export default class WebhookView extends Command {
|
||||
export default class WebhookView extends EasCommand {
|
||||
static description = 'View a webhook on the current project.';
|
||||
|
||||
static args = [
|
||||
@@ -17,8 +16,7 @@ export default class WebhookView extends Command {
|
||||
},
|
||||
];
|
||||
|
||||
async run() {
|
||||
await ensureLoggedInAsync();
|
||||
async runAsync(): Promise<void> {
|
||||
const {
|
||||
args: { ID: webhookId },
|
||||
} = this.parse(WebhookView);
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
AppFragment,
|
||||
CommonAndroidAppCredentialsFragment,
|
||||
} from '../../graphql/generated';
|
||||
import * as AndroidGraphqlClient from '../android/api/GraphqlClient';
|
||||
import { Keystore } from '../android/credentials';
|
||||
import {
|
||||
testKeystore2Base64,
|
||||
@@ -115,7 +116,7 @@ export const testAndroidAppCredentialsFragment: CommonAndroidAppCredentialsFragm
|
||||
androidAppBuildCredentialsList: [testLegacyAndroidBuildCredentialsFragment],
|
||||
};
|
||||
|
||||
export function getNewAndroidApiMock() {
|
||||
export function getNewAndroidApiMock(): { [key in keyof typeof AndroidGraphqlClient]?: any } {
|
||||
return {
|
||||
getAndroidAppCredentialsWithCommonFieldsAsync: jest.fn(),
|
||||
getAndroidAppBuildCredentialsListAsync: jest.fn(() => []),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import AppStoreApi from '../ios/appstore/AppStoreApi';
|
||||
import { AuthCtx } from '../ios/appstore/authenticate';
|
||||
|
||||
export const testAuthCtx: AuthCtx = {
|
||||
@@ -6,7 +7,7 @@ export const testAuthCtx: AuthCtx = {
|
||||
team: { id: 'test-team-id', name: 'test-team-name', inHouse: false },
|
||||
};
|
||||
|
||||
export function getAppstoreMock() {
|
||||
export function getAppstoreMock(): AppStoreApi {
|
||||
return {
|
||||
ensureAuthenticatedAsync: jest.fn(),
|
||||
ensureBundleIdExistsAsync: jest.fn(),
|
||||
@@ -21,5 +22,5 @@ export function getAppstoreMock() {
|
||||
createProvisioningProfileAsync: jest.fn(),
|
||||
revokeProvisioningProfileAsync: jest.fn(),
|
||||
createOrReuseAdhocProvisioningProfileAsync: jest.fn(),
|
||||
};
|
||||
} as any;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import merge from 'lodash/merge';
|
||||
import merge from 'ts-deepmerge';
|
||||
|
||||
import { Context } from '../context';
|
||||
import { getNewAndroidApiMock } from './fixtures-android';
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
IosAppBuildCredentialsFragment,
|
||||
IosDistributionType,
|
||||
} from '../../graphql/generated';
|
||||
import * as IosGraphqlClient from '../ios/api/GraphqlClient';
|
||||
import { DistributionCertificate, ProvisioningProfile } from '../ios/appstore/Credentials.types';
|
||||
import { Target } from '../ios/types';
|
||||
import { testProvisioningProfileBase64 } from './fixtures-base64-data';
|
||||
@@ -117,7 +118,7 @@ export const testAppleTeam = {
|
||||
id: 'test-team-id',
|
||||
};
|
||||
|
||||
export function getNewIosApiMock() {
|
||||
export function getNewIosApiMock(): { [key in keyof typeof IosGraphqlClient]?: any } {
|
||||
return {
|
||||
getIosAppCredentialsWithCommonFieldsAsync: jest.fn(),
|
||||
createOrGetIosAppCredentialsWithCommonFieldsAsync: jest.fn(),
|
||||
|
||||
@@ -34,7 +34,7 @@ export default class AndroidCredentialsProvider {
|
||||
}
|
||||
|
||||
private async getRemoteAsync(): Promise<AndroidCredentials> {
|
||||
const setupBuildCredentialsAction = await new SetupBuildCredentials({ app: this.options.app });
|
||||
const setupBuildCredentialsAction = new SetupBuildCredentials({ app: this.options.app });
|
||||
const buildCredentials = await setupBuildCredentialsAction.runAsync(this.ctx);
|
||||
return this.toAndroidCredentials(buildCredentials);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import ora from 'ora';
|
||||
|
||||
import { AndroidAppBuildCredentialsFragment } from '../../../graphql/generated';
|
||||
import { getApplicationIdAsync } from '../../../project/android/applicationId';
|
||||
import { GradleBuildContext } from '../../../project/android/gradle';
|
||||
import { getProjectAccountName, getProjectConfigDescription } from '../../../project/projectUtils';
|
||||
import { promptAsync } from '../../../prompts';
|
||||
import { findAccountByName } from '../../../user/Account';
|
||||
@@ -83,7 +84,10 @@ export async function promptUserAndCopyLegacyCredentialsAsync(
|
||||
spinner.succeed('Credentials copied to EAS.');
|
||||
}
|
||||
|
||||
export async function getAppLookupParamsFromContextAsync(ctx: Context): Promise<AppLookupParams> {
|
||||
export async function getAppLookupParamsFromContextAsync(
|
||||
ctx: Context,
|
||||
gradleContext?: GradleBuildContext
|
||||
): Promise<AppLookupParams> {
|
||||
ctx.ensureProjectContext();
|
||||
const projectName = ctx.exp.slug;
|
||||
const accountName = getProjectAccountName(ctx.exp, ctx.user);
|
||||
@@ -92,7 +96,11 @@ export async function getAppLookupParamsFromContextAsync(ctx: Context): Promise<
|
||||
throw new Error(`You do not have access to account: ${accountName}`);
|
||||
}
|
||||
|
||||
const androidApplicationIdentifier = await getApplicationIdAsync(ctx.projectDir, ctx.exp);
|
||||
const androidApplicationIdentifier = await getApplicationIdAsync(
|
||||
ctx.projectDir,
|
||||
ctx.exp,
|
||||
gradleContext
|
||||
);
|
||||
if (!androidApplicationIdentifier) {
|
||||
throw new Error(
|
||||
`android.package needs to be defined in your ${getProjectConfigDescription(
|
||||
|
||||
@@ -41,7 +41,7 @@ export class RemoveKeystore {
|
||||
Log.succeed('Keystore removed');
|
||||
}
|
||||
|
||||
displayWarning() {
|
||||
displayWarning(): void {
|
||||
Log.newLine();
|
||||
Log.warn(
|
||||
`Clearing your Android build credentials from our build servers is a ${chalk.bold(
|
||||
|
||||
@@ -184,7 +184,7 @@ export async function createOrUpdateAndroidAppBuildCredentialsByNameAsync(
|
||||
});
|
||||
}
|
||||
|
||||
export async function createOrUpdateDefaultIosAppBuildCredentialsAsync() {
|
||||
export async function createOrUpdateDefaultIosAppBuildCredentialsAsync(): Promise<void> {
|
||||
throw new Error('This requires user prompting. Look for me in BuildCredentialsUtils');
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ export async function createKeystoreAsync(
|
||||
account: Account,
|
||||
keystore: KeystoreWithType
|
||||
): Promise<AndroidKeystoreFragment> {
|
||||
return await AndroidKeystoreMutation.createAndroidKeystore(
|
||||
return await AndroidKeystoreMutation.createAndroidKeystoreAsync(
|
||||
{
|
||||
base64EncodedKeystore: keystore.keystore,
|
||||
keystorePassword: keystore.keystorePassword,
|
||||
@@ -205,7 +205,7 @@ export async function createKeystoreAsync(
|
||||
}
|
||||
|
||||
export async function deleteKeystoreAsync(keystore: AndroidKeystoreFragment): Promise<void> {
|
||||
return await AndroidKeystoreMutation.deleteAndroidKeystore(keystore.id);
|
||||
return await AndroidKeystoreMutation.deleteAndroidKeystoreAsync(keystore.id);
|
||||
}
|
||||
|
||||
export async function createFcmAsync(
|
||||
@@ -213,11 +213,14 @@ export async function createFcmAsync(
|
||||
fcmApiKey: string,
|
||||
version: AndroidFcmVersion
|
||||
): Promise<AndroidFcmFragment> {
|
||||
return await AndroidFcmMutation.createAndroidFcm({ credential: fcmApiKey, version }, account.id);
|
||||
return await AndroidFcmMutation.createAndroidFcmAsync(
|
||||
{ credential: fcmApiKey, version },
|
||||
account.id
|
||||
);
|
||||
}
|
||||
|
||||
export async function deleteFcmAsync(fcm: AndroidFcmFragment): Promise<void> {
|
||||
return await AndroidFcmMutation.deleteAndroidFcm(fcm.id);
|
||||
return await AndroidFcmMutation.deleteAndroidFcmAsync(fcm.id);
|
||||
}
|
||||
|
||||
async function getAppAsync(appLookupParams: AppLookupParams): Promise<AppFragment> {
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import {
|
||||
import { AndroidFcmFragmentNode } from '../../../../../graphql/types/credentials/AndroidFcm';
|
||||
|
||||
const AndroidFcmMutation = {
|
||||
async createAndroidFcm(
|
||||
async createAndroidFcmAsync(
|
||||
androidFcmInput: AndroidFcmInput,
|
||||
accountId: string
|
||||
): Promise<AndroidFcmFragment> {
|
||||
@@ -43,7 +43,7 @@ const AndroidFcmMutation = {
|
||||
);
|
||||
return data.androidFcm.createAndroidFcm;
|
||||
},
|
||||
async deleteAndroidFcm(androidFcmId: string): Promise<void> {
|
||||
async deleteAndroidFcmAsync(androidFcmId: string): Promise<void> {
|
||||
await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<DeleteAndroidFcmMutation>(
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ import {
|
||||
import { AndroidKeystoreFragmentNode } from '../../../../../graphql/types/credentials/AndroidKeystore';
|
||||
|
||||
const AndroidKeystoreMutation = {
|
||||
async createAndroidKeystore(
|
||||
async createAndroidKeystoreAsync(
|
||||
androidKeystoreInput: AndroidKeystoreInput,
|
||||
accountId: string
|
||||
): Promise<AndroidKeystoreFragment> {
|
||||
@@ -49,7 +49,7 @@ const AndroidKeystoreMutation = {
|
||||
);
|
||||
return data.androidKeystore.createAndroidKeystore;
|
||||
},
|
||||
async deleteAndroidKeystore(androidKeystoreId: string): Promise<void> {
|
||||
async deleteAndroidKeystoreAsync(androidKeystoreId: string): Promise<void> {
|
||||
await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<DeleteAndroidKeystoreMutation>(
|
||||
|
||||
@@ -91,7 +91,7 @@ function displayAndroidBuildCredentials(
|
||||
Log.newLine();
|
||||
}
|
||||
|
||||
export function displayAndroidKeystore(keystore: AndroidKeystoreFragment) {
|
||||
export function displayAndroidKeystore(keystore: AndroidKeystoreFragment): void {
|
||||
const {
|
||||
keyAlias,
|
||||
type,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { ExpoConfig, getConfig } from '@expo/config';
|
||||
import chalk from 'chalk';
|
||||
import pick from 'lodash/pick';
|
||||
|
||||
import Log from '../log';
|
||||
import { getExpoConfig } from '../project/expoConfig';
|
||||
@@ -8,6 +7,7 @@ import { getProjectAccountName } from '../project/projectUtils';
|
||||
import { confirmAsync } from '../prompts';
|
||||
import { Actor, getActorDisplayName } from '../user/User';
|
||||
import { ensureLoggedInAsync } from '../user/actions';
|
||||
import pick from '../utils/expodash/pick';
|
||||
import * as AndroidGraphqlClient from './android/api/GraphqlClient';
|
||||
import * as IosGraphqlClient from './ios/api/GraphqlClient';
|
||||
import AppStoreApi from './ios/appstore/AppStoreApi';
|
||||
@@ -85,7 +85,7 @@ class CredentialsContext implements Context {
|
||||
return this._exp!;
|
||||
}
|
||||
|
||||
public ensureProjectContext() {
|
||||
public ensureProjectContext(): void {
|
||||
if (this.hasProjectContext) {
|
||||
return;
|
||||
}
|
||||
@@ -93,7 +93,7 @@ class CredentialsContext implements Context {
|
||||
getConfig(this.projectDir, { skipSDKVersionRequirement: true });
|
||||
}
|
||||
|
||||
public logOwnerAndProject() {
|
||||
public logOwnerAndProject(): void {
|
||||
if (this.hasProjectContext) {
|
||||
const owner = getProjectAccountName(this.exp, this.user);
|
||||
// Figure out if User A is configuring credentials as admin for User B's project
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import fs from 'fs-extra';
|
||||
import zipObject from 'lodash/zipObject';
|
||||
import nullthrows from 'nullthrows';
|
||||
import path from 'path';
|
||||
|
||||
import { AndroidAppBuildCredentialsFragment, IosDistributionType } from '../../graphql/generated';
|
||||
import Log from '../../log';
|
||||
import { findApplicationTarget, findTargetByName } from '../../project/ios/target';
|
||||
import zipObject from '../../utils/expodash/zipObject';
|
||||
import vcs from '../../vcs';
|
||||
import GitClient from '../../vcs/git';
|
||||
import { Context } from '../context';
|
||||
@@ -300,7 +300,7 @@ async function isFileUntrackedAsync(path: string): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
function displayUntrackedFilesWarning(newFilePaths: string[]) {
|
||||
function displayUntrackedFilesWarning(newFilePaths: string[]): void {
|
||||
if (newFilePaths.length === 1) {
|
||||
Log.warn(
|
||||
`File ${newFilePaths[0]} is currently untracked, remember to add it to .gitignore, or to encrypt it (e.g. with git-crypt).`
|
||||
|
||||
@@ -2,12 +2,12 @@ import { AppleDevice, AppleDeviceFragment } from '../../../graphql/generated';
|
||||
import { APPLE_DEVICE_CLASS_LABELS } from '../../../graphql/types/credentials/AppleDevice';
|
||||
import { promptAsync } from '../.././../prompts';
|
||||
|
||||
export async function chooseDevices(
|
||||
export async function chooseDevicesAsync(
|
||||
allDevices: AppleDeviceFragment[],
|
||||
preselectedDeviceIdentifiers: string[] = []
|
||||
): Promise<AppleDevice[]> {
|
||||
const preselectedDeviceIdentifierSet = new Set(preselectedDeviceIdentifiers);
|
||||
const isSelected = (device: AppleDeviceFragment) =>
|
||||
const isSelected = (device: AppleDeviceFragment): boolean =>
|
||||
preselectedDeviceIdentifierSet.size === 0 ||
|
||||
preselectedDeviceIdentifierSet.has(device.identifier);
|
||||
const { devices } = await promptAsync({
|
||||
|
||||
@@ -8,7 +8,7 @@ import { fromNow } from '../../../utils/date';
|
||||
import { Context } from '../../context';
|
||||
import { askForUserProvidedAsync } from '../../utils/promptForCredentials';
|
||||
import { PushKey, PushKeyStoreInfo } from '../appstore/Credentials.types';
|
||||
import { filterRevokedAndUntrackedPushKeysFromEasServers } from '../appstore/CredentialsUtils';
|
||||
import { filterRevokedAndUntrackedPushKeysFromEasServersAsync } from '../appstore/CredentialsUtils';
|
||||
import { APPLE_KEYS_TOO_MANY_GENERATED_ERROR } from '../appstore/pushKey';
|
||||
import { pushKeySchema } from '../credentials';
|
||||
import { isPushKeyValidAndTrackedAsync } from '../validators/validatePushKey';
|
||||
@@ -137,7 +137,7 @@ export async function getValidAndTrackedPushKeysOnEasServersAsync(
|
||||
pushKeysForAccount: ApplePushKeyFragment[]
|
||||
): Promise<ApplePushKeyFragment[]> {
|
||||
const pushInfoFromApple = await ctx.appStore.listPushKeysAsync();
|
||||
return await filterRevokedAndUntrackedPushKeysFromEasServers(
|
||||
return await filterRevokedAndUntrackedPushKeysFromEasServersAsync(
|
||||
pushKeysForAccount,
|
||||
pushInfoFromApple
|
||||
);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import assert from 'assert';
|
||||
import chalk from 'chalk';
|
||||
import differenceBy from 'lodash/differenceBy';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import nullthrows from 'nullthrows';
|
||||
|
||||
import DeviceCreateAction, { RegistrationMethod } from '../../../devices/actions/create/action';
|
||||
@@ -15,13 +13,14 @@ import {
|
||||
} from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync, pressAnyKeyToContinueAsync } from '../../../prompts';
|
||||
import differenceBy from '../../../utils/expodash/differenceBy';
|
||||
import { Context } from '../../context';
|
||||
import { MissingCredentialsNonInteractiveError } from '../../errors';
|
||||
import { AppLookupParams } from '../api/GraphqlClient';
|
||||
import { validateProvisioningProfileAsync } from '../validators/validateProvisioningProfile';
|
||||
import { resolveAppleTeamIfAuthenticatedAsync } from './AppleTeamUtils';
|
||||
import { assignBuildCredentialsAsync, getBuildCredentialsAsync } from './BuildCredentialsUtils';
|
||||
import { chooseDevices, formatDeviceLabel } from './DeviceUtils';
|
||||
import { chooseDevicesAsync, formatDeviceLabel } from './DeviceUtils';
|
||||
import { SetupDistributionCertificate } from './SetupDistributionCertificate';
|
||||
|
||||
export class SetupAdhocProvisioningProfile {
|
||||
@@ -98,7 +97,10 @@ export class SetupAdhocProvisioningProfile {
|
||||
const provisionedDeviceIdentifiers = (
|
||||
currentBuildCredentials?.provisioningProfile?.appleDevices ?? []
|
||||
).map(i => i.identifier);
|
||||
const chosenDevices = await chooseDevices(registeredAppleDevices, provisionedDeviceIdentifiers);
|
||||
const chosenDevices = await chooseDevicesAsync(
|
||||
registeredAppleDevices,
|
||||
provisionedDeviceIdentifiers
|
||||
);
|
||||
|
||||
// 4. Reuse or create the profile on Apple Developer Portal
|
||||
const provisioningProfileStoreInfo =
|
||||
@@ -230,6 +232,17 @@ export class SetupAdhocProvisioningProfile {
|
||||
}
|
||||
}
|
||||
|
||||
function doUDIDsMatch(udidsA: string[], udidsB: string[]): boolean {
|
||||
return isEqual(new Set(udidsA), new Set(udidsB));
|
||||
export function doUDIDsMatch(udidsA: string[], udidsB: string[]): boolean {
|
||||
const setA = new Set(udidsA);
|
||||
const setB = new Set(udidsB);
|
||||
|
||||
if (setA.size !== setB.size) {
|
||||
return false;
|
||||
}
|
||||
for (const a of setA) {
|
||||
if (!setB.has(a)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
import assert from 'assert';
|
||||
import sortBy from 'lodash/sortBy';
|
||||
|
||||
import {
|
||||
AppleDistributionCertificate,
|
||||
@@ -8,6 +7,7 @@ import {
|
||||
} from '../../../graphql/generated';
|
||||
import Log from '../../../log';
|
||||
import { confirmAsync, promptAsync } from '../../../prompts';
|
||||
import sortBy from '../../../utils/expodash/sortBy';
|
||||
import { Context } from '../../context';
|
||||
import { MissingCredentialsNonInteractiveError } from '../../errors';
|
||||
import { AppLookupParams } from '../api/GraphqlClient';
|
||||
@@ -71,7 +71,7 @@ export class SetupDistributionCertificate {
|
||||
const validDistCertsOnFile = await this.getValidDistCertsAsync(ctx);
|
||||
return validDistCertsOnFile.length === 0
|
||||
? await this.createNewDistCertAsync(ctx)
|
||||
: await this.createOrReuseDistCert(ctx);
|
||||
: await this.createOrReuseDistCertAsync(ctx);
|
||||
}
|
||||
|
||||
private async isCurrentCertificateValidAsync(
|
||||
@@ -107,7 +107,9 @@ export class SetupDistributionCertificate {
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private async createOrReuseDistCert(ctx: Context): Promise<AppleDistributionCertificateFragment> {
|
||||
private async createOrReuseDistCertAsync(
|
||||
ctx: Context
|
||||
): Promise<AppleDistributionCertificateFragment> {
|
||||
const validDistCerts = await this.getValidDistCertsAsync(ctx);
|
||||
const autoselectedDistCert = validDistCerts[0];
|
||||
|
||||
|
||||
@@ -37,16 +37,16 @@ export class SetupPushKey {
|
||||
if (pushKeysForAccount.length === 0) {
|
||||
pushKey = await new CreatePushKey(this.app.account).runAsync(ctx);
|
||||
} else {
|
||||
pushKey = await this.createOrReusePushKey(ctx);
|
||||
pushKey = await this.createOrReusePushKeyAsync(ctx);
|
||||
}
|
||||
return await new AssignPushKey(this.app).runAsync(ctx, pushKey);
|
||||
}
|
||||
|
||||
private async createOrReusePushKey(ctx: Context): Promise<ApplePushKeyFragment> {
|
||||
private async createOrReusePushKeyAsync(ctx: Context): Promise<ApplePushKeyFragment> {
|
||||
const pushKeysForAccount = await ctx.ios.getPushKeysForAccountAsync(this.app.account);
|
||||
assert(
|
||||
pushKeysForAccount.length > 0,
|
||||
'createOrReusePushKey: There are no Push Keys available in your EAS account.'
|
||||
'createOrReusePushKeyAsync: There are no Push Keys available in your EAS account.'
|
||||
);
|
||||
|
||||
if (ctx.appStore.authCtx) {
|
||||
|
||||
@@ -37,14 +37,14 @@ export class SetupTargetBuildCredentials implements Action<IosAppBuildCredential
|
||||
);
|
||||
}
|
||||
try {
|
||||
return await this.setupBuildCredentials(ctx);
|
||||
return await this.setupBuildCredentialsAsync(ctx);
|
||||
} catch (error) {
|
||||
Log.error('Failed to setup credentials.');
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async setupBuildCredentials(ctx: Context): Promise<IosAppBuildCredentialsFragment> {
|
||||
async setupBuildCredentialsAsync(ctx: Context): Promise<IosAppBuildCredentialsFragment> {
|
||||
const { app, distribution, enterpriseProvisioning } = this.options;
|
||||
if (distribution === 'internal') {
|
||||
if (enterpriseProvisioning === 'adhoc') {
|
||||
|
||||
+1
-1
@@ -170,7 +170,7 @@ export class SetupTargetBuildCredentialsFromCredentialsJson {
|
||||
function displaySingleTargetProjectCredentials(
|
||||
app: AppLookupParams,
|
||||
buildCredentials: IosAppBuildCredentialsFragment
|
||||
) {
|
||||
): void {
|
||||
const targetName = app.projectName;
|
||||
displayProjectCredentials(app, { [targetName]: buildCredentials }, [
|
||||
{ targetName, bundleIdentifier: app.bundleIdentifier },
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ mockdate.set(new Date('4/20/2021'));
|
||||
describe('select credentials', () => {
|
||||
it('select an AppleDistributionCertificate fragment', async () => {
|
||||
const testDistCerts = (
|
||||
await AppleDistributionCertificateQuery.getAllForAccount('quinAccount')
|
||||
await AppleDistributionCertificateQuery.getAllForAccountAsync('quinAccount')
|
||||
).sort((a, b) => (a.serialNumber > b.serialNumber ? 1 : -1));
|
||||
const loggedSoFar = testDistCerts
|
||||
.map(cert => formatDistributionCertificate(cert))
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { doUDIDsMatch } from '../SetupAdhocProvisioningProfile';
|
||||
|
||||
describe(doUDIDsMatch, () => {
|
||||
it('return false if UDIDs do not match', () => {
|
||||
const udidsA: string[] = ['00001111-001122334455662E', '11110000-771122334455662E'];
|
||||
const udidsB: string[] = ['34330000-771122334455662E', '00001111-001122334455662E'];
|
||||
expect(doUDIDsMatch(udidsA, udidsB)).toBe(false);
|
||||
});
|
||||
it('return true if UDIDs match', () => {
|
||||
const udidsA: string[] = ['00001111-001122334455662E', '11110000-771122334455662E'];
|
||||
const udidsB: string[] = ['11110000-771122334455662E', '00001111-001122334455662E'];
|
||||
expect(doUDIDsMatch(udidsA, udidsB)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -347,7 +347,7 @@ export async function getDistributionCertificateForAppAsync(
|
||||
export async function getDistributionCertificatesForAccountAsync(
|
||||
account: Account
|
||||
): Promise<AppleDistributionCertificateFragment[]> {
|
||||
return await AppleDistributionCertificateQuery.getAllForAccount(account.name);
|
||||
return await AppleDistributionCertificateQuery.getAllForAccountAsync(account.name);
|
||||
}
|
||||
|
||||
export async function createDistributionCertificateAsync(
|
||||
@@ -358,7 +358,7 @@ export async function createDistributionCertificateAsync(
|
||||
appleTeamIdentifier: distCert.teamId,
|
||||
appleTeamName: distCert.teamName,
|
||||
});
|
||||
return await AppleDistributionCertificateMutation.createAppleDistributionCertificate(
|
||||
return await AppleDistributionCertificateMutation.createAppleDistributionCertificateAsync(
|
||||
{
|
||||
certP12: distCert.certP12,
|
||||
certPassword: distCert.certPassword,
|
||||
@@ -373,7 +373,7 @@ export async function createDistributionCertificateAsync(
|
||||
export async function deleteDistributionCertificateAsync(
|
||||
distributionCertificateId: string
|
||||
): Promise<void> {
|
||||
return await AppleDistributionCertificateMutation.deleteAppleDistributionCertificate(
|
||||
return await AppleDistributionCertificateMutation.deleteAppleDistributionCertificateAsync(
|
||||
distributionCertificateId
|
||||
);
|
||||
}
|
||||
@@ -386,7 +386,7 @@ export async function createPushKeyAsync(
|
||||
appleTeamIdentifier: pushKey.teamId,
|
||||
appleTeamName: pushKey.teamName,
|
||||
});
|
||||
return await ApplePushKeyMutation.createApplePushKey(
|
||||
return await ApplePushKeyMutation.createApplePushKeyAsync(
|
||||
{
|
||||
keyP8: pushKey.apnsKeyP8,
|
||||
keyIdentifier: pushKey.apnsKeyId,
|
||||
@@ -399,7 +399,7 @@ export async function createPushKeyAsync(
|
||||
export async function getPushKeysForAccountAsync(
|
||||
account: Account
|
||||
): Promise<ApplePushKeyFragment[]> {
|
||||
return await ApplePushKeyQuery.getAllForAccount(account.name);
|
||||
return await ApplePushKeyQuery.getAllForAccountAsync(account.name);
|
||||
}
|
||||
|
||||
export async function getPushKeyForAppAsync(
|
||||
@@ -410,7 +410,7 @@ export async function getPushKeyForAppAsync(
|
||||
}
|
||||
|
||||
export async function deletePushKeyAsync(pushKeyId: string): Promise<void> {
|
||||
return await ApplePushKeyMutation.deleteApplePushKey(pushKeyId);
|
||||
return await ApplePushKeyMutation.deleteApplePushKeyAsync(pushKeyId);
|
||||
}
|
||||
|
||||
const formatProjectFullName = ({ account, projectName }: AppLookupParams): string =>
|
||||
|
||||
+4
-2
@@ -18,7 +18,7 @@ export type AppleDistributionCertificateMutationResult = AppleDistributionCertif
|
||||
};
|
||||
|
||||
const AppleDistributionCertificateMutation = {
|
||||
async createAppleDistributionCertificate(
|
||||
async createAppleDistributionCertificateAsync(
|
||||
appleDistributionCertificateInput: AppleDistributionCertificateInput,
|
||||
accountId: string
|
||||
): Promise<AppleDistributionCertificateMutationResult> {
|
||||
@@ -60,7 +60,9 @@ const AppleDistributionCertificateMutation = {
|
||||
);
|
||||
return data.appleDistributionCertificate.createAppleDistributionCertificate;
|
||||
},
|
||||
async deleteAppleDistributionCertificate(appleDistributionCertificateId: string): Promise<void> {
|
||||
async deleteAppleDistributionCertificateAsync(
|
||||
appleDistributionCertificateId: string
|
||||
): Promise<void> {
|
||||
await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<DeleteAppleDistributionCertificateMutation>(
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
import { ApplePushKeyFragmentNode } from '../../../../../graphql/types/credentials/ApplePushKey';
|
||||
|
||||
const ApplePushKeyMutation = {
|
||||
async createApplePushKey(
|
||||
async createApplePushKeyAsync(
|
||||
applePushKeyInput: ApplePushKeyInput,
|
||||
accountId: string
|
||||
): Promise<ApplePushKeyFragment> {
|
||||
@@ -46,7 +46,7 @@ const ApplePushKeyMutation = {
|
||||
);
|
||||
return data.applePushKey.createApplePushKey;
|
||||
},
|
||||
async deleteApplePushKey(applePushKeyId: string): Promise<void> {
|
||||
async deleteApplePushKeyAsync(applePushKeyId: string): Promise<void> {
|
||||
await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.mutation<DeleteApplePushKeyMutation>(
|
||||
|
||||
@@ -119,7 +119,7 @@ const AppleDeviceQuery = {
|
||||
return data.account.byName.appleTeams[0];
|
||||
},
|
||||
|
||||
async getByDeviceIdentifier(
|
||||
async getByDeviceIdentifierAsync(
|
||||
accountName: string,
|
||||
identifier: string
|
||||
): Promise<AppleDevicesByIdentifierQueryResult | null> {
|
||||
|
||||
+3
-1
@@ -71,7 +71,9 @@ const AppleDistributionCertificateQuery = {
|
||||
?.distributionCertificate ?? null
|
||||
);
|
||||
},
|
||||
async getAllForAccount(accountName: string): Promise<AppleDistributionCertificateFragment[]> {
|
||||
async getAllForAccountAsync(
|
||||
accountName: string
|
||||
): Promise<AppleDistributionCertificateFragment[]> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.query<AppleDistributionCertificateByAccountQuery>(
|
||||
|
||||
@@ -6,7 +6,7 @@ import { ApplePushKeyByAccountQuery, ApplePushKeyFragment } from '../../../../..
|
||||
import { ApplePushKeyFragmentNode } from '../../../../../graphql/types/credentials/ApplePushKey';
|
||||
|
||||
const ApplePushKeyQuery = {
|
||||
async getAllForAccount(accountName: string): Promise<ApplePushKeyFragment[]> {
|
||||
async getAllForAccountAsync(accountName: string): Promise<ApplePushKeyFragment[]> {
|
||||
const data = await withErrorHandlingAsync(
|
||||
graphqlClient
|
||||
.query<ApplePushKeyByAccountQuery>(
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
const AppleDistributionCertificateQuery = {
|
||||
getAllForAccount: jest.fn().mockImplementation(() => {
|
||||
getAllForAccountAsync: jest.fn().mockImplementation(() => {
|
||||
return [
|
||||
{
|
||||
id: '6a7422cc-392b-451d-984c-b0b4b027680a',
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
* It is possible an uploaded key could have a valid p8 but invalid identifier, making it impossible for us to
|
||||
* track it's status on the Apple Developer Portal
|
||||
*/
|
||||
export async function filterRevokedAndUntrackedPushKeys<T extends PushKey>(
|
||||
export async function filterRevokedAndUntrackedPushKeysAsync<T extends PushKey>(
|
||||
pushKeys: T[],
|
||||
pushInfoFromApple: PushKeyStoreInfo[]
|
||||
): Promise<T[]> {
|
||||
@@ -30,7 +30,7 @@ export async function filterRevokedAndUntrackedPushKeys<T extends PushKey>(
|
||||
* It is possible an uploaded key could have a valid p8 but invalid identifier, making it impossible for us to
|
||||
* track it's status on the Apple Developer Portal
|
||||
*/
|
||||
export async function filterRevokedAndUntrackedPushKeysFromEasServers(
|
||||
export async function filterRevokedAndUntrackedPushKeysFromEasServersAsync(
|
||||
pushKeys: ApplePushKeyFragment[],
|
||||
pushInfoFromApple: PushKeyStoreInfo[]
|
||||
): Promise<ApplePushKeyFragment[]> {
|
||||
|
||||
+9
-7
@@ -1,6 +1,6 @@
|
||||
import { syncCapabilityIdentifiersForEntitlementsAsync } from '../capabilityIdentifiers';
|
||||
|
||||
function mockCapabilities(Apple: any) {
|
||||
function mockCapabilities(Apple: any): void {
|
||||
Apple.MerchantId.getAsync = jest.fn(() => [
|
||||
{
|
||||
id: 'XXX-merch-1',
|
||||
@@ -149,12 +149,14 @@ describe(syncCapabilityIdentifiersForEntitlementsAsync, () => {
|
||||
it(`throws when creating a missing capability that is reserved`, async () => {
|
||||
const Apple = require('@expo/apple-utils');
|
||||
mockCapabilities(Apple);
|
||||
Apple.MerchantId.createAsync = jest.fn((ctx: any, { identifier }: { identifier: string }) => {
|
||||
// e2e test with: merchant.expodemo
|
||||
throw new Error(
|
||||
`There is a problem with the request entity - A Merchant ID with Identifier '${identifier}' is not available. Please enter a different string.`
|
||||
);
|
||||
});
|
||||
Apple.MerchantId.createAsync = jest.fn(
|
||||
(ctx: any, { identifier }: { identifier: string }): any => {
|
||||
// e2e test with: merchant.expodemo
|
||||
throw new Error(
|
||||
`There is a problem with the request entity - A Merchant ID with Identifier '${identifier}' is not available. Please enter a different string.`
|
||||
);
|
||||
}
|
||||
);
|
||||
const bundleId = {
|
||||
context: {},
|
||||
updateBundleIdCapabilityAsync: jest.fn(),
|
||||
|
||||
@@ -127,7 +127,7 @@ async function loginWithUserCredentialsAsync({
|
||||
password?: string;
|
||||
teamId?: string;
|
||||
providerId?: number;
|
||||
}) {
|
||||
}): Promise<Session.AuthState> {
|
||||
// Start a new login flow
|
||||
const newSession = await Auth.loginWithUserCredentialsAsync({
|
||||
username,
|
||||
|
||||
@@ -106,10 +106,19 @@ export async function syncCapabilitiesForEntitlementsAsync(
|
||||
return { enabled: enabledCapabilityNames, disabled: disabledCapabilityNames };
|
||||
}
|
||||
|
||||
interface CapabilitiesRequest {
|
||||
capabilityType: CapabilityType;
|
||||
option: any;
|
||||
}
|
||||
|
||||
function getCapabilitiesToEnable(
|
||||
currentCapabilities: BundleIdCapability[],
|
||||
entitlements: JSONObject
|
||||
) {
|
||||
): {
|
||||
enabledCapabilityNames: string[];
|
||||
request: CapabilitiesRequest[];
|
||||
remainingCapabilities: BundleIdCapability[];
|
||||
} {
|
||||
const enabledCapabilityNames: string[] = [];
|
||||
const request: { capabilityType: CapabilityType; option: any }[] = [];
|
||||
const remainingCapabilities = [...currentCapabilities];
|
||||
@@ -177,8 +186,8 @@ export function assertValidOptions(classifier: CapabilityClassifier, value: any)
|
||||
function getCapabilitiesToDisable(
|
||||
bundleId: BundleId,
|
||||
currentCapabilities: BundleIdCapability[],
|
||||
request: { capabilityType: CapabilityType; option: any }[]
|
||||
) {
|
||||
request: CapabilitiesRequest[]
|
||||
): { disabledCapabilityNames: string[]; request: CapabilitiesRequest[] } {
|
||||
if (Log.isDebug) {
|
||||
Log.log(
|
||||
`Existing to disable: `,
|
||||
|
||||
@@ -17,7 +17,9 @@ async function getContractStatusAsync(
|
||||
}
|
||||
}
|
||||
|
||||
async function getContractMessagesAsync(context: RequestContext) {
|
||||
async function getContractMessagesAsync(
|
||||
context: RequestContext
|
||||
): Promise<ITCAgreements.ITCContractMessage[] | null> {
|
||||
try {
|
||||
return await ITCAgreements.getContractMessagesAsync(context);
|
||||
} catch (error: any) {
|
||||
@@ -75,7 +77,10 @@ export function formatContractMessage(message: ITCAgreements.ITCContractMessage)
|
||||
});
|
||||
}
|
||||
|
||||
export async function assertContractMessagesAsync(context: RequestContext, spinner?: Ora) {
|
||||
export async function assertContractMessagesAsync(
|
||||
context: RequestContext,
|
||||
spinner?: Ora
|
||||
): Promise<void> {
|
||||
const { messages, isFatal } = await getRequiredContractMessagesAsync(context);
|
||||
|
||||
if (Array.isArray(messages) && messages.length) {
|
||||
|
||||
@@ -24,7 +24,7 @@ export async function getCertificateBySerialNumberAsync(
|
||||
return cert;
|
||||
}
|
||||
|
||||
export async function getDistributionCertificateAync(
|
||||
export async function getDistributionCertificateAsync(
|
||||
context: RequestContext,
|
||||
serialNumber: string
|
||||
): Promise<Certificate | null> {
|
||||
|
||||
Loaded 100 of 189 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user