Compare commits

...
25 Commits
Author SHA1 Message Date
Stanisław Chmiela e63de21702 v16.7.2 2025-06-03 15:58:23 +02:00
Stanisław Chmiela e3bbdd519e [eas-cli] Add support for array flavorDimensions (#3043)
# Why

https://exponent-internal.slack.com/archives/C06EFBQK3B7/p1748956922999689

# How

Added support for `flavorDimensions` specified as array of strings.

# Test Plan

Added tests.
2025-06-03 15:56:54 +02:00
Expo CI 25cc555189 update CHANGELOG.md 2025-06-03 07:25:43 +00:00
Stanisław Chmiela be73d3a337 v16.7.1 2025-06-03 09:19:10 +02:00
Stanisław Chmiela ecb6458a28 [eas-cli] Do not require eas.json or package.json to create a workflow run (#3028)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

`eas.json` is not _required_ to run workflows. Builds will fail, but we can warn about it and also the workflow error makes sense.

# How

Check before uploading the non-required files.

# Test Plan

<img width="946" alt="Zrzut ekranu 2025-06-2 o 21 45 31" src="https://github.com/user-attachments/assets/b6b4aad1-608f-471c-b541-302850744062" />
2025-06-03 09:18:17 +02:00
Will Schurman 475d90ea23 [eas-cli] Fix update republishing not including environment or git info (#3036)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

These fields were missing in republished updates.

Closes ENG-15846.

# How

Copy these fields over as well when republishing.

# Test Plan

`neas update` with dirty working tree.
`neas update:republish`

Verify republished update has same dirty working tree status.
2025-06-02 08:28:21 -07:00
Douglas Lowder 59171230d4 [eas-cli] Fix failing unit tests (#3035) 2025-05-29 14:10:58 -07:00
Expo CI b8b16139bf update CHANGELOG.md 2025-05-29 10:30:14 +00:00
Quinlan Jung 24b725438e v16.7.0 2025-05-29 12:24:48 +02:00
Quinlan Jung 3d2454ebf2 [eas-cli] add rollout flag to update:republish (#3029)
* [eas-cli] add rollout flag to update:republish

* Temporary Commit at 5/29/2025, 12:17:09 PM
2025-05-29 12:21:56 +02:00
Will Schurman 5caef3bc05 [eas-json][eas-cli] Add support for manifest host and asset host overriding (#3021)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

CLI change corresponding to https://github.com/expo/universe/pull/20131.

This adds the ability to override the manifest and asset hosts for EAS Update such that a set of proxy hosts can be used.

Closes ENG-15804.

# How

Considered putting these in flags, but it turned out that many many commands need to detect EAS Update configuration so they need access to these as well. Therefore, I added the new fields to `eas-json`.

The fields are:
- `manifestHostOverride` - a host to replace `u.expo.dev` in the URL.
- `assetHostOverride` - a host to replace `assets.eascdn.net` in asset URLs in the generated update manifests.

Then, in every place in EAS CLI when we generate a manifest URL, instead use the overridden URL.

Then, supply the manifest URL and asset URL overrides when creating updates (or republishes).

# Test Plan

Lengthy, but here it goes:
1. Create two proxies, one for assets and one for manifests. All these proxies do is proxy the requests.
    - https://github.com/wschurman/updates-test-proxy is a proxy for the manifest request built using expo router API routes and EAS Hosting. It is hosted at https://updates-test-proxy.expo.app and just fetches the URL input but at `u.expo.dev` and returns the response.
    - https://github.com/wschurman/updates-test-asset-proxy is the same but for assets. https://updates-test-asset-proxy.expo.app
2. Create an app on staging
3. Add the following to eas.json:
    ```
    "update": {
        "assetHostOverride": "updates-test-asset-proxy.expo.app",
        "manifestHostOverride": "updates-test-proxy.expo.app"
      }
    ```
4. run `neas update:configure`, see overridden URL in app.json
5. run `neas update`, see update is published, visit overridden manifest URL, see an update!
6. Visit one of the asset URLs (supplying authorization header) and see it correctly proxies.
7. configure code signing
8. publish again, see code signing works (downloads from `manifestPermalink`)
9. republish the last update, see it works and sets the overrides correctly.
2025-05-23 10:50:58 -07:00
Expo CI cc987ab71c update CHANGELOG.md 2025-05-23 17:45:39 +00:00
Will Schurman 32d3020659 v16.6.2 2025-05-21 09:05:18 -07:00
Will Schurman 17db11fa72 [eas-cli] Further no longer require owner field for SDK >= 53 or canary (#3017) 2025-05-16 17:19:51 -07:00
Expo CI b5305a38cc update CHANGELOG.md 2025-05-14 19:54:34 +00:00
Quinlan Jung 3ec7bb7334 v16.6.1 2025-05-14 12:47:29 -07:00
Quinlan Jung ceb07d4f54 [eas-cli] onboarding: add cwd to spawned git process (#3015)
* [eas-cli] onboarding: add cwd to spawned git process

* Temporary Commit at 5/14/2025, 12:39:27 PM
2025-05-14 12:44:22 -07:00
Expo CI 92e12a57a7 update CHANGELOG.md 2025-05-14 03:56:06 +00:00
Gabriel Donadel 373a4d40fa v16.6.0 2025-05-14 00:50:57 -03:00
Gabriel Donadel Dall'Agnol 568faf7697 [eas-cli] Add support for uploading for ipa files (#3014)
* [eas-cli] Add support uploading for ipa files

* Add changelog entry

* Add appIdentifier and appName to metadata
2025-05-14 05:49:05 +02:00
Expo CI df6ff1bb7a update CHANGELOG.md 2025-05-13 09:10:26 +00:00
Stanisław Chmiela a4a7b1c57f v16.5.0 2025-05-13 11:01:39 +02:00
Stanisław Chmiela a9f8bfd1ff [eas-cli] Add --json flag to workflow:run (#3013)
# Why

Affirm asked for this.

# How

Added `--json` flag which is going to print out all useful job information.

# Test Plan

`--wait --json`:
```
{
  "id": "0196c564-5553-70ed-8835-adff6484e8cf",
  "name": "easd.yml",
  "status": "SUCCESS",
  "createdAt": "2025-05-12T16:46:49.171Z",
  "workflow": {
    "id": "48ee38cd-44d3-4359-8b35-d71297545ea5",
    "fileName": "easd.yml"
  },
  "jobs": [
    {
      "id": "0196c564-58c9-75da-a3ef-931c64b756a2",
      "key": "test",
      "name": "test",
      "type": "CUSTOM",
      "status": "SUCCESS",
      "outputs": {},
      "createdAt": "2025-05-12T16:46:50.057Z"
    }
  ],
  "url": "http://expo.test/accounts/stanley/projects/test-local/workflows/0196c564-5553-70ed-8835-adff6484e8cf"
}
```


`--json`:
```
{
  "id": "0196c563-5a25-75e1-9447-e35d82f8fef0",
  "url": "http://expo.test/accounts/stanley/projects/test-local/workflows/0196c563-5a25-75e1-9447-e35d82f8fef0"
}
```
2025-05-13 11:00:40 +02:00
Stanisław Chmiela e7f687b45d [eas-cli] Add --wait flag to workflow:run (#3012)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

https://exponent-internal.slack.com/archives/C083Q88U4M8/p1747060067200209

# How

Added `--wait`/`--no-wait` flag to `workflow:run`. It's off by default (keeping current behavior).

# Test Plan

```
Compressing project files and uploading to EAS. Learn more: https://expo.fyi/eas-build-archive
✔ Uploaded project archive to EAS 1s
✔ Uploaded eas.json to EAS 
✔ Uploaded package.json to EAS 

See logs: http://expo.test/accounts/stanley/projects/test-local/workflows/0196c530-e558-7357-85ab-139314b21171
✔ Workflow run started successfully.
```

```
See logs: http://expo.test/accounts/stanley/projects/test-local/workflows/0196c52f-0536-774a-8639-1e9de629d88e

Waiting for workflow run to complete. You can press Ctrl+C to exit.
✖ Workflow run has failed.
```

```
See logs: http://expo.test/accounts/stanley/projects/test-local/workflows/0196c52d-2065-7bb3-85d0-571d8d166d82

Waiting for workflow run to complete. You can press Ctrl+C to exit.
⚠ Workflow run has been canceled.
```

```
See logs: http://expo.test/accounts/stanley/projects/test-local/workflows/0196c53e-8150-7c52-91d4-7610b38eee11

Waiting for workflow run to complete. You can press Ctrl+C to exit.
⠏ ⚠ Failed to fetch the workflow run status. Check your network connection.
```

```
See logs: http://expo.test/accounts/stanley/projects/test-local/workflows/0196c53e-8150-7c52-91d4-7610b38eee11

Waiting for workflow run to complete. You can press Ctrl+C to exit.
✖ Failed to fetch the workflow run status 6 times in a row. Aborting wait.
```

```
USAGE
  $ eas workflow:run [FILE] [--non-interactive] [--wait]

ARGUMENTS
  FILE  Path to the workflow file to run

FLAGS
  --non-interactive  Run the command in non-interactive mode.
  --[no-]wait        Wait for workflow run to complete

DESCRIPTION
  Run an EAS workflow

FLAG DESCRIPTIONS
  --[no-]wait  Wait for workflow run to complete

    Exit codes: 0 = success, 11 = failure, 12 = canceled, 13 = wait aborted.
```
2025-05-12 23:41:34 +02:00
Gabriel Donadel 666a885ba5 update CHANGELOG.md 2025-05-10 19:52:22 -03:00
45 changed files with 2219 additions and 390 deletions

No files matched your search

+46
View File
@@ -10,6 +10,52 @@ This is the log of notable changes to EAS CLI and related packages.
### 🐛 Bug fixes
- Add support for array `flavorDimensions` (`flavorDimensions = ['version']`). ([#3043](https://github.com/expo/eas-cli/pull/3043) by [@sjchmiela](https://github.com/sjchmiela))
### 🧹 Chores
## [16.7.1](https://github.com/expo/eas-cli/releases/tag/v16.7.1) - 2025-06-03
### 🐛 Bug fixes
- Fix some unit tests by updating mocks. ([#3035](https://github.com/expo/eas-cli/pull/3035) by [@douglowder](https://github.com/douglowder))
- Fix update republishing not including environment or git info. ([#3036](https://github.com/expo/eas-cli/pull/3036) by [@wschurman](https://github.com/wschurman))
- Do not require `eas.json` or `package.json` files when creating new workflow runs. ([#3028](https://github.com/expo/eas-cli/pull/3028) by [@sjchmiela](https://github.com/sjchmiela))
## [16.7.0](https://github.com/expo/eas-cli/releases/tag/v16.7.0) - 2025-05-29
### 🎉 New features
- Add support for manifest host and asset host overriding for EAS Update. ([#3021](https://github.com/expo/eas-cli/pull/3021) by [@wschurman](https://github.com/wschurman))
- Add rollout flag to update:republish. ([#3029](https://github.com/expo/eas-cli/pull/3029) by [@quinlanj](https://github.com/quinlanj))
## [16.6.2](https://github.com/expo/eas-cli/releases/tag/v16.6.2) - 2025-05-23
### 🧹 Chores
- Further no longer require owner field for SDK >= 53 or canary. ([#3017](https://github.com/expo/eas-cli/pull/3017) by [@wschurman](https://github.com/wschurman))
## [16.6.1](https://github.com/expo/eas-cli/releases/tag/v16.6.1) - 2025-05-14
### 🐛 Bug fixes
- Onboarding: add cwd to spawned git process. ([#3015](https://github.com/expo/eas-cli/pull/3015) by [@quinlanj](https://github.com/quinlanj))
## [16.6.0](https://github.com/expo/eas-cli/releases/tag/v16.6.0) - 2025-05-14
### 🎉 New features
- Add support for uploading iOS internal distribution local builds. ([#3014](https://github.com/expo/eas-cli/pull/3014) by [@gabrieldonadel](https://github.com/gabrieldonadel))
## [16.5.0](https://github.com/expo/eas-cli/releases/tag/v16.5.0) - 2025-05-13
### 🎉 New features
- Add `--wait`/`--no-wait` flag to `eas workflow:run`. ([#3012](https://github.com/expo/eas-cli/pull/3012) by [@sjchmiela](https://github.com/sjchmiela))
- Add `--json` flag to `eas workflow:run`. ([#3013](https://github.com/expo/eas-cli/pull/3013) by [@sjchmiela](https://github.com/sjchmiela))
## [16.4.2](https://github.com/expo/eas-cli/releases/tag/v16.4.2) - 2025-05-10
### 🧹 Chores
- Update `eas-build-cache-provider` function names to use `buildCacheProvider` key. ([#3002](https://github.com/expo/eas-cli/pull/3002) by [@gabrieldonadel](https://github.com/gabrieldonadel))
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "16.4.2",
"version": "16.7.2",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+92 -81
View File
@@ -162,7 +162,7 @@ ALIASES
$ eas login
```
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/account/login.ts)_
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -179,7 +179,7 @@ ALIASES
$ eas logout
```
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -196,7 +196,7 @@ ALIASES
$ eas whoami
```
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/account/view.ts)_
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -210,7 +210,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/analytics.ts)_
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -262,7 +262,7 @@ DESCRIPTION
create a branch
```
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -283,7 +283,7 @@ DESCRIPTION
delete a branch
```
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -303,7 +303,7 @@ DESCRIPTION
list all branches
```
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -323,7 +323,7 @@ DESCRIPTION
rename a branch
```
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -346,7 +346,7 @@ DESCRIPTION
view a branch
```
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -384,7 +384,7 @@ DESCRIPTION
start a build
```
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/index.ts)_
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -403,7 +403,7 @@ DESCRIPTION
cancel a build
```
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -420,7 +420,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
@@ -439,7 +439,7 @@ DESCRIPTION
delete a build
```
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/delete.ts)_
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/delete.ts)_
## `eas build:dev`
@@ -459,7 +459,7 @@ DESCRIPTION
run dev client simulator/emulator build with matching fingerprint or create a new one
```
_See code: [packages/eas-cli/src/commands/build/dev.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/dev.ts)_
_See code: [packages/eas-cli/src/commands/build/dev.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/dev.ts)_
## `eas build:download`
@@ -480,7 +480,7 @@ DESCRIPTION
download simulator/emulator builds for a given fingerprint hash
```
_See code: [packages/eas-cli/src/commands/build/download.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/download.ts)_
_See code: [packages/eas-cli/src/commands/build/download.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/download.ts)_
## `eas build:inspect`
@@ -515,7 +515,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -567,7 +567,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/list.ts)_
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:resign`
@@ -596,7 +596,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/resign.ts)_
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/resign.ts)_
## `eas build:run`
@@ -622,7 +622,7 @@ DESCRIPTION
run simulator/emulator builds from eas-cli
```
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/run.ts)_
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/run.ts)_
## `eas build:submit`
@@ -672,7 +672,7 @@ DESCRIPTION
get the latest version from EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/version/get.ts)_
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -691,7 +691,7 @@ DESCRIPTION
update version of an app
```
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/version/set.ts)_
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -710,7 +710,7 @@ DESCRIPTION
update a version in native code with a value stored on EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/version/sync.ts)_
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -727,7 +727,7 @@ DESCRIPTION
view a build for your project
```
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/build/view.ts)_
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -748,7 +748,7 @@ DESCRIPTION
create a channel
```
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -770,7 +770,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -790,7 +790,7 @@ DESCRIPTION
list all channels
```
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:pause [NAME]`
@@ -812,7 +812,7 @@ DESCRIPTION
pause a channel to stop it from sending updates
```
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/pause.ts)_
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/pause.ts)_
## `eas channel:resume [NAME]`
@@ -834,7 +834,7 @@ DESCRIPTION
resume a channel to start sending updates
```
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/resume.ts)_
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/resume.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -867,7 +867,7 @@ DESCRIPTION
Roll a new branch out on a channel incrementally.
```
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/rollout.ts)_
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -890,7 +890,7 @@ DESCRIPTION
view a channel
```
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -911,7 +911,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/config.ts)_
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -928,7 +928,7 @@ DESCRIPTION
manage credentials
```
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/credentials/index.ts)_
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/credentials/index.ts)_
## `eas credentials:configure-build`
@@ -946,7 +946,7 @@ DESCRIPTION
Set up credentials for building your project.
```
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/credentials/configure-build.ts)_
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas deploy [options]`
@@ -974,7 +974,7 @@ ALIASES
$ eas worker:deploy
```
_See code: [packages/eas-cli/src/commands/deploy/index.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/deploy/index.ts)_
_See code: [packages/eas-cli/src/commands/deploy/index.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/deploy/index.ts)_
## `eas deploy:alias`
@@ -999,7 +999,7 @@ ALIASES
$ eas deploy:promote
```
_See code: [packages/eas-cli/src/commands/deploy/alias.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/deploy/alias.ts)_
_See code: [packages/eas-cli/src/commands/deploy/alias.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/deploy/alias.ts)_
## `eas deploy:promote`
@@ -1036,7 +1036,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/device/create.ts)_
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -1056,7 +1056,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -1077,7 +1077,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/device/list.ts)_
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:rename`
@@ -1098,7 +1098,7 @@ DESCRIPTION
rename a registered device
```
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/device/rename.ts)_
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -1112,7 +1112,7 @@ DESCRIPTION
view a device for your project
```
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/device/view.ts)_
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -1126,7 +1126,7 @@ DESCRIPTION
display environment info
```
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas env:create [ENVIRONMENT]`
@@ -1155,7 +1155,7 @@ DESCRIPTION
create an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/create.ts)_
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/create.ts)_
## `eas env:delete [ENVIRONMENT]`
@@ -1179,7 +1179,7 @@ DESCRIPTION
delete an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/delete.ts)_
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/delete.ts)_
## `eas env:exec ENVIRONMENT BASH_COMMAND`
@@ -1200,7 +1200,7 @@ DESCRIPTION
execute a command with environment variables from the selected environment
```
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/exec.ts)_
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/exec.ts)_
## `eas env:get [ENVIRONMENT]`
@@ -1225,7 +1225,7 @@ DESCRIPTION
view an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/get.ts)_
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/get.ts)_
## `eas env:list [ENVIRONMENT]`
@@ -1250,7 +1250,7 @@ DESCRIPTION
list environment variables for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/list.ts)_
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/list.ts)_
## `eas env:pull [ENVIRONMENT]`
@@ -1273,7 +1273,7 @@ DESCRIPTION
pull environment variables for the selected environment to .env file
```
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/pull.ts)_
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/pull.ts)_
## `eas env:push [ENVIRONMENT]`
@@ -1294,7 +1294,7 @@ DESCRIPTION
push environment variables from .env file to the selected environment
```
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/push.ts)_
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/push.ts)_
## `eas env:update [ENVIRONMENT]`
@@ -1325,7 +1325,7 @@ DESCRIPTION
update an environment variable on the current project or account
```
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/env/update.ts)_
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/env/update.ts)_
## `eas fingerprint:compare [HASH1] [HASH2]`
@@ -1370,7 +1370,7 @@ EXAMPLES
$ eas fingerprint:compare <FINGERPRINT-HASH> --update-id <UPDATE-ID> # Compare fingerprint from update against provided fingerprint
```
_See code: [packages/eas-cli/src/commands/fingerprint/compare.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/fingerprint/compare.ts)_
_See code: [packages/eas-cli/src/commands/fingerprint/compare.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/fingerprint/compare.ts)_
## `eas fingerprint:generate`
@@ -1401,7 +1401,7 @@ EXAMPLES
$ eas fingerprint:generate --json --non-interactive --platform android # Output fingerprint json to stdout
```
_See code: [packages/eas-cli/src/commands/fingerprint/generate.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/fingerprint/generate.ts)_
_See code: [packages/eas-cli/src/commands/fingerprint/generate.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/fingerprint/generate.ts)_
## `eas help [COMMAND]`
@@ -1509,7 +1509,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/metadata/lint.ts)_
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -1526,7 +1526,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -1543,7 +1543,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1573,7 +1573,7 @@ DESCRIPTION
open the project page in a web browser
```
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/open.ts)_
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/open.ts)_
## `eas project:info`
@@ -1587,7 +1587,7 @@ DESCRIPTION
information about the current project
```
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/project/info.ts)_
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -1610,7 +1610,7 @@ ALIASES
$ eas init
```
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/project/init.ts)_
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/project/init.ts)_
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1628,7 +1628,7 @@ ALIASES
$ eas onboarding
```
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/project/onboarding.ts)_
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/project/onboarding.ts)_
## `eas submit`
@@ -1659,7 +1659,7 @@ ALIASES
$ eas build:submit
```
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/submit.ts)_
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -1701,7 +1701,7 @@ DESCRIPTION
publish an update group
```
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/index.ts)_
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1721,7 +1721,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1742,7 +1742,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:edit [GROUPID]`
@@ -1766,7 +1766,7 @@ DESCRIPTION
edit all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/edit.ts)_
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/edit.ts)_
## `eas update:list`
@@ -1788,7 +1788,7 @@ DESCRIPTION
view the recent updates
```
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/list.ts)_
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1797,8 +1797,8 @@ roll back to an existing update
```
USAGE
$ eas update:republish [--channel <value> | --branch <value> | --group <value>] [--destination-channel <value> |
--destination-branch <value>] [-m <value>] [-p android|ios|all] [--private-key-path <value>] [--json
--non-interactive]
--destination-branch <value>] [-m <value>] [-p android|ios|all] [--private-key-path <value>] [--rollout-percentage
<value>] [--json --non-interactive]
FLAGS
-m, --message=<value> Short message describing the republished update group
@@ -1815,12 +1815,16 @@ FLAGS
expo-updates' configuration. Defaults to a file named "private-key.pem" in the
certificate's directory. Only relevant if you are using code signing:
https://docs.expo.dev/eas-update/code-signing/
--rollout-percentage=<value> Percentage of users this update should be immediately available to. Users not in the
rollout will be served the previous latest update on the branch, even if that update
is itself being rolled out. The specified number must be an integer between 1 and
100. When not specified, this defaults to 100.
DESCRIPTION
roll back to an existing update
```
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/republish.ts)_
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/republish.ts)_
## `eas update:roll-back-to-embedded`
@@ -1848,7 +1852,7 @@ DESCRIPTION
roll back to the embedded update
```
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
@@ -1868,7 +1872,7 @@ DESCRIPTION
roll back to an embedded update or an existing update
```
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/rollback.ts)_
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -1888,7 +1892,7 @@ DESCRIPTION
update group details
```
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/update/view.ts)_
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1909,7 +1913,7 @@ DESCRIPTION
create a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1929,7 +1933,7 @@ DESCRIPTION
delete a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1947,7 +1951,7 @@ DESCRIPTION
list webhooks
```
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1969,7 +1973,7 @@ DESCRIPTION
update a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1986,7 +1990,7 @@ DESCRIPTION
view a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
@@ -2070,27 +2074,34 @@ DESCRIPTION
create a new workflow configuration YAML file
```
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/workflow/create.ts)_
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/workflow/create.ts)_
## `eas workflow:run [FILE]`
Run an EAS workflow
run an EAS workflow
```
USAGE
$ eas workflow:run [FILE] [--non-interactive]
$ eas workflow:run [FILE] [--non-interactive] [--wait] [--json]
ARGUMENTS
FILE Path to the workflow file to run
FLAGS
--json Enable JSON output, non-JSON messages will be printed to stderr.
--non-interactive Run the command in non-interactive mode.
--[no-]wait Wait for workflow run to complete
DESCRIPTION
Run an EAS workflow
run an EAS workflow
FLAG DESCRIPTIONS
--[no-]wait Wait for workflow run to complete
Exit codes: 0 = success, 11 = failure, 12 = canceled, 13 = wait aborted.
```
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/workflow/run.ts)_
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/workflow/run.ts)_
## `eas workflow:validate PATH`
@@ -2110,5 +2121,5 @@ DESCRIPTION
validate a workflow configuration yaml file
```
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v16.4.1/packages/eas-cli/src/commands/workflow/validate.ts)_
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v16.7.2/packages/eas-cli/src/commands/workflow/validate.ts)_
<!-- commandsstop -->
+940 -99
View File
File diff suppressed because it is too large. Load diff
+3 -2
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "16.4.1",
"version": "16.7.2",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -13,7 +13,7 @@
"@expo/config": "10.0.6",
"@expo/config-plugins": "9.0.12",
"@expo/eas-build-job": "1.0.173",
"@expo/eas-json": "16.4.0",
"@expo/eas-json": "16.7.0",
"@expo/env": "^1.0.0",
"@expo/json-file": "8.3.3",
"@expo/logger": "1.0.117",
@@ -38,6 +38,7 @@
"ajv": "8.11.0",
"ajv-formats": "2.1.1",
"better-opn": "3.0.2",
"bplist-parser": "^0.3.0",
"chalk": "4.1.2",
"cli-progress": "3.12.0",
"dateformat": "4.6.3",
+5 -1
View File
@@ -95,7 +95,11 @@ export function getExpoWebsiteBaseUrl(): string {
}
}
export function getEASUpdateURL(projectId: string): string {
export function getEASUpdateURL(projectId: string, manifestHostOverride: string | null): string {
if (manifestHostOverride) {
return new URL(projectId, `https://${manifestHostOverride}`).href;
}
if (process.env.EXPO_STAGING) {
return new URL(projectId, `https://staging-u.expo.dev`).href;
} else if (process.env.EXPO_LOCAL) {
@@ -12,7 +12,7 @@ import slash from 'slash';
import { AndroidCredentials } from '../../credentials/android/AndroidCredentialsProvider';
import { getCustomBuildConfigPathForJob } from '../../project/customBuildConfig';
import { getUsername } from '../../project/projectUtils';
import { getUsernameForBuildMetadataAndBuildJob } from '../../project/projectUtils';
import { BuildContext } from '../context';
interface JobData {
@@ -29,7 +29,7 @@ export async function prepareJobAsync(
ctx: BuildContext<Platform.ANDROID>,
jobData: JobData
): Promise<Android.Job> {
const username = getUsername(ctx.exp, ctx.user);
const username = getUsernameForBuildMetadataAndBuildJob(ctx.user);
const buildProfile: BuildProfile<Platform.ANDROID> = ctx.buildProfile;
const projectRootDirectory =
slash(path.relative(await ctx.vcsClient.getRootPathAsync(), ctx.projectDir)) || '.';
+2 -2
View File
@@ -14,7 +14,7 @@ import slash from 'slash';
import { IosCredentials, TargetCredentials } from '../../credentials/ios/types';
import { IosJobSecretsInput } from '../../graphql/generated';
import { getCustomBuildConfigPathForJob } from '../../project/customBuildConfig';
import { getUsername } from '../../project/projectUtils';
import { getUsernameForBuildMetadataAndBuildJob } from '../../project/projectUtils';
import { BuildContext } from '../context';
interface JobData {
@@ -32,7 +32,7 @@ export async function prepareJobAsync(
ctx: BuildContext<Platform.IOS>,
jobData: JobData
): Promise<Ios.Job> {
const username = getUsername(ctx.exp, ctx.user);
const username = getUsernameForBuildMetadataAndBuildJob(ctx.user);
const buildProfile: BuildProfile<Platform.IOS> = ctx.buildProfile;
const projectRootDirectory =
slash(path.relative(await ctx.vcsClient.getRootPathAsync(), ctx.projectDir)) || '.';
+5 -2
View File
@@ -9,7 +9,10 @@ import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios
import { LocalBuildMode } from './local';
import { BuildDistributionType } from './types';
import Log from '../log';
import { getUsername, isExpoUpdatesInstalled } from '../project/projectUtils';
import {
getUsernameForBuildMetadataAndBuildJob,
isExpoUpdatesInstalled,
} from '../project/projectUtils';
import { readChannelSafelyAsync as readAndroidChannelSafelyAsync } from '../update/android/UpdatesModule';
import { readChannelSafelyAsync as readIosChannelSafelyAsync } from '../update/ios/UpdatesModule';
import { easCliVersion } from '../utils/easCli';
@@ -48,7 +51,7 @@ export async function collectMetadataAsync<T extends Platform>(
ctx.localBuildOptions.localBuildMode === LocalBuildMode.INTERNAL
? false
: await ctx.vcsClient.hasUncommittedChangesAsync(),
username: getUsername(ctx.exp, ctx.user),
username: getUsernameForBuildMetadataAndBuildJob(ctx.user),
message: ctx.message,
...(ctx.platform === Platform.IOS && {
iosEnterpriseProvisioning: resolveIosEnterpriseProvisioning(
@@ -230,6 +230,7 @@ export async function runBuildAndSubmitAsync({
getDynamicPrivateProjectConfigAsync,
customBuildConfigMetadata: customBuildConfigMetadataByPlatform[platform],
env,
easJsonAccessor,
});
if (maybeBuild) {
startedBuilds.push({ build: maybeBuild, buildProfile });
@@ -367,6 +368,7 @@ async function prepareAndStartBuildAsync({
getDynamicPrivateProjectConfigAsync,
customBuildConfigMetadata,
env,
easJsonAccessor,
}: {
projectDir: string;
flags: BuildFlags;
@@ -379,6 +381,7 @@ async function prepareAndStartBuildAsync({
vcsClient: Client;
getDynamicPrivateProjectConfigAsync: DynamicConfigContextFn;
customBuildConfigMetadata?: CustomBuildConfigMetadata;
easJsonAccessor: EasJsonAccessor;
env: Env;
}): Promise<{ build: BuildFragment | undefined; buildCtx: BuildContext<Platform> }> {
const buildCtx = await createBuildContextAsync({
@@ -426,8 +429,18 @@ async function prepareAndStartBuildAsync({
nonInteractive: flags.nonInteractive,
buildProfile,
env: buildProfile.profile.env,
easJsonAccessor,
});
if (isUsingEASUpdate(buildCtx.exp, buildCtx.projectId)) {
const easJsonUpdateConfig: EasJson['update'] =
(await EasJsonUtils.getUpdateConfigAsync(easJsonAccessor)) ?? {};
if (
isUsingEASUpdate(
buildCtx.exp,
buildCtx.projectId,
easJsonUpdateConfig.manifestHostOverride ?? null
)
) {
const doesChannelExist = await doesChannelExistAsync(graphqlClient, {
appId: buildCtx.projectId,
channelName: buildProfile.profile.channel,
@@ -606,6 +619,7 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
nonInteractive,
sdkVersion,
env,
easJsonAccessor,
}: {
exp: ExpoConfig;
projectId: string;
@@ -615,6 +629,7 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
nonInteractive: boolean;
sdkVersion?: string;
env: Env | undefined;
easJsonAccessor: EasJsonAccessor;
}): Promise<void> {
if (isExpoUpdatesInstalledOrAvailable(projectDir, sdkVersion)) {
return;
@@ -636,6 +651,9 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
message: `Would you like to install the "expo-updates" package and configure EAS Update now?`,
});
if (installExpoUpdates) {
const easJsonUpdateConfig: EasJson['update'] =
(await EasJsonUtils.getUpdateConfigAsync(easJsonAccessor)) ?? {};
await ensureEASUpdateIsConfiguredAsync({
exp,
projectId,
@@ -643,6 +661,7 @@ async function validateExpoUpdatesInstalledAsProjectDependencyAsync({
platform: RequestedPlatform.All,
vcsClient,
env,
manifestHostOverride: easJsonUpdateConfig.manifestHostOverride ?? null,
});
Log.withTick('Installed expo-updates and configured EAS Update.');
throw new Error('Command must be re-run to pick up new updates configuration.');
@@ -18,6 +18,7 @@ export const testUpdateBranch1: UpdateBranchObject = {
isRollBackToEmbedded: false,
manifestPermalink: 'https://u.expo.dev/update/bbe3e63a-f620-4603-8c4d-258f3e51590d',
gitCommitHash: 'e91c5bb733eff675dd8a3722ed5d4f885a4b10ce',
isGitWorkingTreeDirty: false,
actor: {
__typename: 'User',
id: '026ace2b-c1f8-4a02-818d-6b52c100bdf2',
@@ -43,6 +44,7 @@ export const testUpdateBranch1: UpdateBranchObject = {
isRollBackToEmbedded: false,
manifestPermalink: 'https://u.expo.dev/update/db22401b-d321-4629-a068-21d6d1f19c02',
gitCommitHash: 'e91c5bb733eff675dd8a3722ed5d4f885a4b10ce',
isGitWorkingTreeDirty: false,
actor: {
__typename: 'User',
id: '026ace2b-c1f8-4a02-818d-6b52c100bdf2',
@@ -78,6 +80,7 @@ export const testUpdateBranch2: UpdateBranchObject = {
isRollBackToEmbedded: false,
manifestPermalink: 'https://u.expo.dev/update/f04aafc1-0bf5-4548-8c35-726b467e7c40',
gitCommitHash: 'e91c5bb733eff675dd8a3722ed5d4f885a4b10ce',
isGitWorkingTreeDirty: false,
actor: {
__typename: 'User',
id: '026ace2b-c1f8-4a02-818d-6b52c100bdf2',
@@ -103,6 +106,7 @@ export const testUpdateBranch2: UpdateBranchObject = {
isRollBackToEmbedded: false,
manifestPermalink: 'https://u.expo.dev/update/d8d15786-2727-407f-bf3e-f4bda7e397d9',
gitCommitHash: 'e91c5bb733eff675dd8a3722ed5d4f885a4b10ce',
isGitWorkingTreeDirty: false,
actor: {
__typename: 'User',
id: '026ace2b-c1f8-4a02-818d-6b52c100bdf2',
@@ -180,7 +180,7 @@ export async function validateOrSetProjectIdAsync({
Log.warn('EAS project not configured.');
const getAccountNameForEASProjectSync = (exp: ExpoConfig, user: Actor): string => {
const getDefaultAccountNameForEASProject = (exp: ExpoConfig, user: Actor): string => {
if (exp.owner) {
return exp.owner;
}
@@ -191,7 +191,7 @@ export async function validateOrSetProjectIdAsync({
return user.username;
case 'Robot':
throw new Error(
'The "owner" manifest property is required when using robot users. See: https://docs.expo.dev/versions/latest/config/app/#owner'
'Must configure EAS project by running "eas init" before using a robot user to manage the project.'
);
}
};
@@ -199,7 +199,7 @@ export async function validateOrSetProjectIdAsync({
const projectId = await fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync(
graphqlClient,
{
accountName: getAccountNameForEASProjectSync(exp, actor),
accountName: getDefaultAccountNameForEASProject(exp, actor),
projectName: exp.slug,
},
{
@@ -1,4 +1,5 @@
import { Platform, Workflow } from '@expo/eas-build-job';
import { EasJson, EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
@@ -66,8 +67,13 @@ export default class BuildConfigure extends EasCommand {
nonInteractive: false,
vcsClient,
});
if (didCreateEasJson && isUsingEASUpdate(exp, projectId)) {
await ensureEASUpdateIsConfiguredInEasJsonAsync(projectDir);
if (didCreateEasJson) {
const easJsonAccessor = EasJsonAccessor.fromProjectPath(projectDir);
const easJsonUpdateConfig: EasJson['update'] =
(await EasJsonUtils.getUpdateConfigAsync(easJsonAccessor)) ?? {};
if (isUsingEASUpdate(exp, projectId, easJsonUpdateConfig.manifestHostOverride ?? null)) {
await ensureEASUpdateIsConfiguredInEasJsonAsync(projectDir);
}
}
// configure expo-updates
@@ -401,7 +401,7 @@ async function configureProjectFromBareDefaultExpoTemplateAsync({
const bundleIdentifier = `com.${userPrefix}${stripInvalidCharactersForBundleIdentifier(
app.ownerAccount.name
)}.${slugPrefix}${stripInvalidCharactersForBundleIdentifier(app.slug)}`;
const updateUrl = getEASUpdateURL(app.id);
const updateUrl = getEASUpdateURL(app.id, /* manifestHostOverride */ null);
const easBuildGitHubConfig = {
android: {
@@ -35,6 +35,7 @@ const updateStub: UpdateFragment = {
runtimeVersion: 'exposdk:47.0.0',
platform: 'ios',
gitCommitHash: 'commit',
isGitWorkingTreeDirty: false,
manifestFragment: JSON.stringify({ fake: 'manifest' }),
isRollBackToEmbedded: false,
manifestPermalink: 'https://expo.dev/fake/manifest/link',
@@ -32,6 +32,7 @@ const updateStub: UpdateFragment = {
runtimeVersion: 'exposdk:47.0.0',
platform: 'ios',
gitCommitHash: 'commit',
isGitWorkingTreeDirty: false,
manifestFragment: JSON.stringify({ fake: 'manifest' }),
isRollBackToEmbedded: false,
manifestPermalink: 'https://expo.dev/fake/manifest/link',
@@ -32,6 +32,7 @@ const updateStub: UpdateFragment = {
runtimeVersion: 'exposdk:47.0.0',
platform: 'ios',
gitCommitHash: 'commit',
isGitWorkingTreeDirty: false,
manifestFragment: JSON.stringify({ fake: 'manifest' }),
isRollBackToEmbedded: false,
manifestPermalink: 'https://expo.dev/fake/manifest/link',
@@ -1,3 +1,4 @@
import { EasJson, EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
@@ -47,6 +48,10 @@ export default class UpdateConfigure extends EasCommand {
await vcsClient.ensureRepoExistsAsync();
const easJsonAccessor = EasJsonAccessor.fromProjectPath(projectDir);
const easJsonUpdateConfig: EasJson['update'] =
(await EasJsonUtils.getUpdateConfigAsync(easJsonAccessor)) ?? {};
await ensureEASUpdateIsConfiguredAsync({
exp,
projectId,
@@ -55,6 +60,7 @@ export default class UpdateConfigure extends EasCommand {
vcsClient,
env: undefined,
forceNativeConfigSync: true,
manifestHostOverride: easJsonUpdateConfig.manifestHostOverride ?? null,
});
await ensureEASUpdateIsConfiguredInEasJsonAsync(projectDir);
@@ -1,4 +1,5 @@
import { Workflow } from '@expo/eas-build-job';
import { EasJson, EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import { Errors, Flags } from '@oclif/core';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
@@ -211,6 +212,10 @@ export default class UpdatePublish extends EasCommand {
await maybeWarnAboutEasOutagesAsync(graphqlClient, [StatuspageServiceName.EasUpdate]);
const easJsonAccessor = EasJsonAccessor.fromProjectPath(projectDir);
const easJsonUpdateConfig: EasJson['update'] =
(await EasJsonUtils.getUpdateConfigAsync(easJsonAccessor)) ?? {};
await ensureEASUpdateIsConfiguredAsync({
exp: expPossiblyWithoutEasUpdateConfigured,
platform: requestedPlatform,
@@ -218,6 +223,7 @@ export default class UpdatePublish extends EasCommand {
projectId,
vcsClient,
env: undefined,
manifestHostOverride: easJsonUpdateConfig.manifestHostOverride ?? null,
});
const { exp } = await getDynamicPublicProjectConfigAsync();
@@ -507,6 +513,8 @@ export default class UpdatePublish extends EasCommand {
isGitWorkingTreeDirty,
awaitingCodeSigningInfo: !!codeSigningInfo,
environment: environment ?? null,
manifestHostOverride: easJsonUpdateConfig.manifestHostOverride ?? null,
assetHostOverride: easJsonUpdateConfig.assetHostOverride ?? null,
};
}
);
@@ -31,6 +31,7 @@ type UpdateRepublishRawFlags = {
'private-key-path'?: string;
'non-interactive': boolean;
json?: boolean;
'rollout-percentage'?: number;
};
type UpdateRepublishFlags = {
@@ -44,6 +45,7 @@ type UpdateRepublishFlags = {
privateKeyPath?: string;
nonInteractive: boolean;
json: boolean;
rolloutPercentage?: number;
};
export default class UpdateRepublish extends EasCommand {
@@ -86,6 +88,12 @@ export default class UpdateRepublish extends EasCommand {
description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory. Only relevant if you are using code signing: https://docs.expo.dev/eas-update/code-signing/`,
required: false,
}),
'rollout-percentage': Flags.integer({
description: `Percentage of users this update should be immediately available to. Users not in the rollout will be served the previous latest update on the branch, even if that update is itself being rolled out. The specified number must be an integer between 1 and 100. When not specified, this defaults to 100.`,
required: false,
min: 0,
max: 100,
}),
...EasNonInteractiveAndJsonFlags,
};
@@ -163,6 +171,7 @@ export default class UpdateRepublish extends EasCommand {
updateMessage,
codeSigningInfo,
json: flags.json,
rolloutPercentage: flags.rolloutPercentage,
});
}
@@ -191,6 +200,7 @@ export default class UpdateRepublish extends EasCommand {
platform,
updateMessage: rawFlags.message,
privateKeyPath,
rolloutPercentage: rawFlags['rollout-percentage'],
json: rawFlags.json ?? false,
nonInteractive,
};
@@ -1,4 +1,5 @@
import { Platform as PublishPlatform } from '@expo/config';
import { EasJson, EasJsonAccessor, EasJsonUtils } from '@expo/eas-json';
import { Errors, Flags } from '@oclif/core';
import nullthrows from 'nullthrows';
@@ -148,6 +149,10 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
await maybeWarnAboutEasOutagesAsync(graphqlClient, [StatuspageServiceName.EasUpdate]);
const easJsonAccessor = EasJsonAccessor.fromProjectPath(projectDir);
const easJsonUpdateConfig: EasJson['update'] =
(await EasJsonUtils.getUpdateConfigAsync(easJsonAccessor)) ?? {};
await ensureEASUpdateIsConfiguredAsync({
exp: expPossiblyWithoutEasUpdateConfigured,
platform: platformFlag,
@@ -155,6 +160,7 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
projectId,
vcsClient,
env: undefined,
manifestHostOverride: easJsonUpdateConfig.manifestHostOverride ?? null,
});
// check that the expo-updates package version supports roll back to embedded
+86 -7
View File
@@ -13,6 +13,7 @@ import EasCommand from '../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { EasNonInteractiveAndJsonFlags } from '../commandUtils/flags';
import {
BuildMetadataInput,
DistributionType,
LocalBuildArchiveSourceType,
UploadSessionType,
@@ -27,6 +28,7 @@ import { uploadFileAtPathToGCSAsync } from '../uploads';
import { fromNow } from '../utils/date';
import { enableJsonOutput, printJsonOnlyOutput } from '../utils/json';
import { getTmpDirectory } from '../utils/paths';
import { parseBinaryPlistBuffer } from '../utils/plist';
import { createProgressTracker } from '../utils/progress';
export default class BuildUpload extends EasCommand {
@@ -82,6 +84,7 @@ export default class BuildUpload extends EasCommand {
fingerprintHash: buildFingerprintHash,
developmentClient,
simulator,
...otherMetadata
} = await extractAppMetadataAsync(localBuildPath, platform);
let fingerprint = manualFingerprintHash ?? buildFingerprintHash;
@@ -120,7 +123,12 @@ export default class BuildUpload extends EasCommand {
projectId,
{ platform: toAppPlatform(platform), simulator },
{ type: LocalBuildArchiveSourceType.Gcs, bucketKey },
{ distribution: DistributionType.Internal, fingerprintHash: fingerprint, developmentClient }
{
distribution: DistributionType.Internal,
fingerprintHash: fingerprint,
developmentClient,
...otherMetadata,
}
);
if (jsonFlag) {
@@ -303,19 +311,33 @@ async function uploadAppArchiveAsync(
return bucketKey;
}
type AppMetadata = {
fingerprintHash?: string;
developmentClient: boolean;
function getInfoPlistMetadata(infoPlist: any): {
appName?: string;
appIdentifier?: string;
simulator: boolean;
};
} {
const appName = infoPlist?.CFBundleDisplayName ?? infoPlist?.CFBundleName;
const appIdentifier = infoPlist?.CFBundleIdentifier;
const simulator = infoPlist?.DTPlatformName?.includes('simulator');
return {
appName,
appIdentifier,
simulator,
};
}
async function extractAppMetadataAsync(
buildPath: string,
platform: Platform
): Promise<AppMetadata> {
): Promise<{ developmentClient: boolean; simulator: boolean } & BuildMetadataInput> {
let developmentClient = false;
let fingerprintHash: string | undefined;
const simulator = platform === Platform.IOS;
// By default, we assume the iOS apps are for simulators
let simulator = platform === Platform.IOS;
let appName: string | undefined;
let appIdentifier: string | undefined;
const basePath = platform === Platform.ANDROID ? 'assets/' : buildPath;
const fingerprintFilePath =
@@ -340,14 +362,51 @@ async function extractAppMetadataAsync(
}
} else if (buildExtension === '.app') {
developmentClient = await fs.exists(path.join(basePath, devMenuBundlePath));
if (await fs.exists(path.join(basePath, 'Info.plist'))) {
const infoPlistBuffer = await fs.readFile(path.join(basePath, 'Info.plist'));
const infoPlist = parseBinaryPlistBuffer(infoPlistBuffer);
({ simulator, appIdentifier, appName } = getInfoPlistMetadata(infoPlist));
}
if (await fs.exists(path.join(basePath, fingerprintFilePath))) {
fingerprintHash = await fs.readFile(path.join(basePath, fingerprintFilePath), 'utf8');
}
} else if (buildExtension === '.ipa') {
const zip = new StreamZip.async({ file: buildPath });
try {
const entries = await zip.entries();
const entriesKeys = Object.keys(entries);
await Promise.all(
entriesKeys.map(async path => {
const infoPlistRegex = /^Payload\/[^/]+\.app\/Info\.plist$/;
if (infoPlistRegex.test(path)) {
const infoPlistBuffer = await zip.entryData(entries[path]);
const infoPlist = parseBinaryPlistBuffer(infoPlistBuffer);
({ simulator, appIdentifier, appName } = getInfoPlistMetadata(infoPlist));
return;
}
if (path.includes('/EXDevMenu.bundle')) {
developmentClient = true;
return;
}
if (path.includes('EXUpdates.bundle/fingerprint')) {
fingerprintHash = (await zip.entryData(entries[path])).toString('utf-8');
}
})
);
} catch (err) {
Log.error(`Error reading ${buildExtension}: ${err}`);
} finally {
await zip.close();
}
} else {
// Use tar to list files in the archive
try {
let fingerprintHashPromise: Promise<string> | undefined;
let infoPlistPromise: Promise<Buffer> | undefined;
await tar.list({
file: buildPath,
// eslint-disable-next-line async-protect/async-suffix
@@ -368,11 +427,29 @@ async function extractAppMetadataAsync(
}
});
}
if (entry.path.endsWith('Info.plist')) {
infoPlistPromise = new Promise<Buffer>(async (resolve, reject) => {
try {
const chunks: Buffer[] = [];
for await (const chunk of entry) {
chunks.push(chunk);
}
const content = Buffer.concat(chunks);
resolve(content);
} catch (error) {
reject(error);
}
});
}
},
});
if (fingerprintHashPromise !== undefined) {
fingerprintHash = await fingerprintHashPromise;
}
if (infoPlistPromise !== undefined) {
const infoPlist = parseBinaryPlistBuffer(await infoPlistPromise);
({ simulator, appIdentifier, appName } = getInfoPlistMetadata(infoPlist));
}
} catch (err) {
Log.error(`Error reading ${buildExtension}: ${err}`);
}
@@ -382,5 +459,7 @@ async function extractAppMetadataAsync(
developmentClient,
fingerprintHash,
simulator,
appName,
appIdentifier,
};
}
+184 -39
View File
@@ -1,25 +1,50 @@
import { Flags } from '@oclif/core';
import { CombinedError } from '@urql/core';
import chalk from 'chalk';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { getWorkflowRunUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import { WorkflowProjectSourceType } from '../../graphql/generated';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { EASNonInteractiveFlag, EasJsonOnlyFlag } from '../../commandUtils/flags';
import {
WorkflowProjectSourceType,
WorkflowRunByIdQuery,
WorkflowRunStatus,
} from '../../graphql/generated';
import { WorkflowRevisionMutation } from '../../graphql/mutations/WorkflowRevisionMutation';
import { WorkflowRunMutation } from '../../graphql/mutations/WorkflowRunMutation';
import { WorkflowRunQuery } from '../../graphql/queries/WorkflowRunQuery';
import Log, { link } from '../../log';
import { ora } from '../../ora';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import { uploadAccountScopedFileAsync } from '../../project/uploadAccountScopedFileAsync';
import { uploadAccountScopedProjectSourceAsync } from '../../project/uploadAccountScopedProjectSourceAsync';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
import { sleepAsync } from '../../utils/promise';
import { WorkflowFile } from '../../utils/workflowFile';
const EXIT_CODES = {
WORKFLOW_FAILED: 11,
WORKFLOW_CANCELED: 12,
WAIT_ABORTED: 13,
};
export default class WorkflowRun extends EasCommand {
static override description = 'Run an EAS workflow';
static override description = 'run an EAS workflow';
static override args = [{ name: 'file', description: 'Path to the workflow file to run' }];
static override flags = {
...EASNonInteractiveFlag,
wait: Flags.boolean({
default: false,
allowNo: true,
description: 'Exit codes: 0 = success, 11 = failure, 12 = canceled, 13 = wait aborted.',
summary: 'Wait for workflow run to complete',
}),
...EasJsonOnlyFlag,
};
static override contextDefinition = {
@@ -32,6 +57,10 @@ export default class WorkflowRun extends EasCommand {
async runAsync(): Promise<void> {
const { flags, args } = await this.parse(WorkflowRun);
if (flags.json) {
enableJsonOutput();
}
const {
getDynamicPrivateProjectConfigAsync,
loggedIn: { graphqlClient },
@@ -80,8 +109,11 @@ export default class WorkflowRun extends EasCommand {
}
let projectArchiveBucketKey: string;
let easJsonBucketKey: string;
let packageJsonBucketKey: string;
let easJsonBucketKey: string | null = null;
let packageJsonBucketKey: string | null = null;
const easJsonPath = path.join(projectDir, 'eas.json');
const packageJsonPath = path.join(projectDir, 'package.json');
try {
({ projectArchiveBucketKey } = await uploadAccountScopedProjectSourceAsync({
@@ -89,54 +121,167 @@ export default class WorkflowRun extends EasCommand {
vcsClient,
accountId: account.id,
}));
({ fileBucketKey: easJsonBucketKey } = await uploadAccountScopedFileAsync({
graphqlClient,
accountId: account.id,
filePath: path.join(projectDir, 'eas.json'),
maxSizeBytes: 1024 * 1024,
}));
({ fileBucketKey: packageJsonBucketKey } = await uploadAccountScopedFileAsync({
graphqlClient,
accountId: account.id,
filePath: path.join(projectDir, 'package.json'),
maxSizeBytes: 1024 * 1024,
}));
if (await fileExistsAsync(easJsonPath)) {
({ fileBucketKey: easJsonBucketKey } = await uploadAccountScopedFileAsync({
graphqlClient,
accountId: account.id,
filePath: easJsonPath,
maxSizeBytes: 1024 * 1024,
}));
} else {
Log.warn(
`⚠ No ${chalk.bold('eas.json')} found in the project directory. Running ${chalk.bold(
'type: build'
)} jobs will not work. Run ${chalk.bold(
'eas build:configure'
)} to configure your project for builds.`
);
}
if (await fileExistsAsync(packageJsonPath)) {
({ fileBucketKey: packageJsonBucketKey } = await uploadAccountScopedFileAsync({
graphqlClient,
accountId: account.id,
filePath: packageJsonPath,
maxSizeBytes: 1024 * 1024,
}));
} else {
Log.warn(
`⚠ No ${chalk.bold(
'package.json'
)} found in the project directory. It is used to automatically infer best job configuration for your project. You may want to define ${chalk.bold(
'image'
)} property in your workflow to specify the image to use.`
);
}
} catch (err) {
Log.error('Failed to upload project sources.');
throw err;
}
let workflowRunId: string;
try {
const { id: workflowRunId } = await WorkflowRunMutation.createWorkflowRunAsync(
graphqlClient,
{
appId: projectId,
workflowRevisionInput: {
fileName: path.basename(args.file),
yamlConfig,
({ id: workflowRunId } = await WorkflowRunMutation.createWorkflowRunAsync(graphqlClient, {
appId: projectId,
workflowRevisionInput: {
fileName: path.basename(args.file),
yamlConfig,
},
workflowRunInput: {
projectSource: {
type: WorkflowProjectSourceType.Gcs,
projectArchiveBucketKey,
easJsonBucketKey,
packageJsonBucketKey,
},
workflowRunInput: {
projectSource: {
type: WorkflowProjectSourceType.Gcs,
projectArchiveBucketKey,
easJsonBucketKey,
packageJsonBucketKey,
},
},
}
);
},
}));
Log.newLine();
Log.succeed(
`Workflow run started successfully. See logs: ${link(
getWorkflowRunUrl(account.name, projectName, workflowRunId)
)}`
);
Log.log(`See logs: ${link(getWorkflowRunUrl(account.name, projectName, workflowRunId))}`);
} catch (err) {
Log.error('Failed to start the workflow with the API.');
throw err;
}
if (!flags.wait) {
Log.succeed('Workflow run started successfully.');
if (flags.json) {
printJsonOnlyOutput({
id: workflowRunId,
url: getWorkflowRunUrl(account.name, projectName, workflowRunId),
});
}
process.exit(0);
}
Log.newLine();
const { status } = await waitForWorkflowRunToEndAsync(graphqlClient, {
workflowRunId,
});
if (flags.json) {
const workflowRun = await WorkflowRunQuery.withJobsByIdAsync(graphqlClient, workflowRunId, {
useCache: false,
});
printJsonOnlyOutput({
...workflowRun,
url: getWorkflowRunUrl(account.name, projectName, workflowRunId),
});
}
if (status === WorkflowRunStatus.Failure) {
process.exit(EXIT_CODES.WORKFLOW_FAILED);
} else if (status === WorkflowRunStatus.Canceled) {
process.exit(EXIT_CODES.WORKFLOW_CANCELED);
}
}
}
async function waitForWorkflowRunToEndAsync(
graphqlClient: ExpoGraphqlClient,
{ workflowRunId }: { workflowRunId: string }
): Promise<WorkflowRunByIdQuery['workflowRuns']['byId']> {
Log.log('Waiting for workflow run to complete. You can press Ctrl+C to exit.');
const spinner = ora('Currently waiting for workflow run to start.').start();
let failedFetchesCount = 0;
while (true) {
try {
const workflowRun = await WorkflowRunQuery.byIdAsync(graphqlClient, workflowRunId, {
useCache: false,
});
failedFetchesCount = 0;
switch (workflowRun.status) {
case WorkflowRunStatus.InProgress:
spinner.start('Workflow run is in progress.');
break;
case WorkflowRunStatus.ActionRequired:
spinner.warn('Workflow run is waiting for action.');
break;
case WorkflowRunStatus.PendingCancel:
case WorkflowRunStatus.Canceled:
spinner.warn('Workflow run has been canceled.');
return workflowRun;
case WorkflowRunStatus.Failure:
spinner.fail('Workflow run has failed.');
return workflowRun;
case WorkflowRunStatus.Success:
spinner.succeed('Workflow run completed successfully.');
return workflowRun;
}
} catch {
spinner.text = '⚠ Failed to fetch the workflow run status. Check your network connection.';
failedFetchesCount += 1;
if (failedFetchesCount > 6) {
spinner.fail('Failed to fetch the workflow run status 6 times in a row. Aborting wait.');
process.exit(EXIT_CODES.WAIT_ABORTED);
}
}
await sleepAsync(10 /* seconds */ * 1000 /* milliseconds */);
}
}
async function fileExistsAsync(filePath: string): Promise<boolean> {
return await fs.promises
.access(filePath, fs.constants.F_OK)
.then(() => true)
.catch(() => false);
}
@@ -14,9 +14,14 @@ import { displayAndroidAppCredentials } from '../printCredentials';
jest.mock('../../../../log');
jest.mock('chalk', () => ({
red: jest.fn(text => `red(${text})`),
blue: jest.fn(text => `blue(${text})`),
yellow: jest.fn(text => `yellow(${text})`),
green: jest.fn(text => `green(${text})`),
gray: jest.fn(text => `gray(${text})`),
bold: jest.fn(log => log),
cyan: { bold: jest.fn(log => log) },
dim: jest.fn(log => log),
cyan: { bold: jest.fn(log => log) },
}));
jest.mock('../../../../graphql/queries/AppQuery');
@@ -5,12 +5,29 @@ import { ExpoGraphqlClient } from '../../../../commandUtils/context/contextUtils
import { AppleDistributionCertificateQuery } from '../../api/graphql/queries/AppleDistributionCertificateQuery';
import { formatDistributionCertificate } from '../DistributionCertificateUtils';
jest.mock('../../api/graphql/queries/AppleDistributionCertificateQuery');
/*
jest.mock('chalk', () => {
return {
__esModule: true, // this property makes it work
default: { gray: jest.fn(log => log), underline: jest.fn(log => log) },
default: {
blue: jest.fn(log => log),
gray: jest.fn(log => log),
underline: jest.fn(log => log),
},
};
});
*/
jest.mock('chalk', () => ({
red: jest.fn(text => `red(${text})`),
blue: jest.fn(text => `blue(${text})`),
yellow: jest.fn(text => `yellow(${text})`),
green: jest.fn(text => `green(${text})`),
gray: jest.fn(log => log),
bold: jest.fn(log => log),
dim: jest.fn(log => log),
cyan: { bold: jest.fn(log => log) },
underline: jest.fn(log => log),
}));
mockdate.set(new Date('4/20/2021'));
describe('select credentials', () => {
@@ -9,7 +9,15 @@ import { App, Target } from '../../types';
import { displayIosCredentials } from '../printCredentials';
jest.mock('../../../../log');
jest.mock('chalk', () => ({ bold: jest.fn(log => log), cyan: { bold: jest.fn(log => log) } }));
jest.mock('chalk', () => ({
red: jest.fn(text => `red(${text})`),
blue: jest.fn(text => `blue(${text})`),
yellow: jest.fn(text => `yellow(${text})`),
green: jest.fn(text => `green(${text})`),
gray: jest.fn(text => `gray(${text})`),
bold: jest.fn(log => log),
cyan: { bold: jest.fn(log => log) },
}));
jest.mock('../../api/graphql/queries/IosAppCredentialsQuery');
mockdate.set(new Date('4/20/2021'));
+151 -33
View File
@@ -118,6 +118,8 @@ export type Account = {
billingPeriod: BillingPeriod;
/** (EAS Build) Builds associated with this account */
builds: Array<Build>;
/** Whether this account can enable SSO. */
canEnableSSO: Scalars['Boolean']['output'];
createdAt: Scalars['DateTime']['output'];
/** Environment secrets for an account */
environmentSecrets: Array<EnvironmentSecret>;
@@ -144,7 +146,10 @@ export type Account = {
name: Scalars['String']['output'];
/** Offers set on this account */
offers?: Maybe<Array<Offer>>;
/** Owning User of this account if personal account */
/**
* Owning User of this account if personal account
* @deprecated Deprecated in favor of ownerUserActor
*/
owner?: Maybe<User>;
/** Owning UserActor of this account if personal account */
ownerUserActor?: Maybe<UserActor>;
@@ -557,6 +562,8 @@ export type AccountMutation = {
changePlan: Account;
/** Add specified account Permissions for Actor. Actor must already have at least one permission on the account. */
grantActorPermissions: Account;
/** Remove profile image for the account. Do nothing if there's no profile image associated. */
removeProfileImage: Account;
/** Rename this account and the primary user's username if this account is a personal account */
rename: Account;
/** Requests a refund for the specified charge by requesting a manual refund from support */
@@ -598,6 +605,11 @@ export type AccountMutationGrantActorPermissionsArgs = {
};
export type AccountMutationRemoveProfileImageArgs = {
accountID: Scalars['ID']['input'];
};
export type AccountMutationRenameArgs = {
accountID: Scalars['ID']['input'];
newName: Scalars['String']['input'];
@@ -1213,6 +1225,7 @@ export type AndroidSubmissionConfig = {
export type AndroidSubmissionConfigInput = {
applicationIdentifier?: InputMaybe<Scalars['String']['input']>;
archiveUrl?: InputMaybe<Scalars['String']['input']>;
changelog?: InputMaybe<Scalars['String']['input']>;
changesNotSentForReview?: InputMaybe<Scalars['Boolean']['input']>;
googleServiceAccountKeyId?: InputMaybe<Scalars['String']['input']>;
googleServiceAccountKeyJson?: InputMaybe<Scalars['String']['input']>;
@@ -1395,6 +1408,7 @@ export type App = Project & {
workerDeploymentsCrashes?: Maybe<WorkerDeploymentCrashes>;
workerDeploymentsRequest: WorkerDeploymentRequestEdge;
workerDeploymentsRequests?: Maybe<WorkerDeploymentRequests>;
workflowRunGitBranchesPaginated: AppWorkflowRunGitBranchesConnection;
workflowRunsPaginated: AppWorkflowRunsConnection;
workflows: Array<Workflow>;
};
@@ -1681,10 +1695,21 @@ export type AppWorkerDeploymentsRequestsArgs = {
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppWorkflowRunGitBranchesPaginatedArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<WorkflowRunGitBranchFilterInput>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppWorkflowRunsPaginatedArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
filter?: InputMaybe<WorkflowRunFilterInput>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
@@ -1821,10 +1846,10 @@ export type AppMutation = {
__typename?: 'AppMutation';
/** Create an app */
createApp: App;
/** Create an app and GitHub repository if user desire to */
createAppAndGithubRepository: CreateAppAndGithubRepositoryResponse;
/** @deprecated No longer supported */
grantAccess?: Maybe<App>;
/** Remove profile image (icon) for the app. Do nothing if there's no profile image associated. */
removeProfileImage: App;
/** Delete an App. Returns the ID of the background job receipt. Use BackgroundJobReceiptQuery to get the status of the job. */
scheduleAppDeletion: BackgroundJobReceipt;
/** Set display info for app */
@@ -1841,17 +1866,17 @@ export type AppMutationCreateAppArgs = {
};
export type AppMutationCreateAppAndGithubRepositoryArgs = {
appInput: AppWithGithubRepositoryInput;
};
export type AppMutationGrantAccessArgs = {
accessLevel?: InputMaybe<Scalars['String']['input']>;
toUser: Scalars['ID']['input'];
};
export type AppMutationRemoveProfileImageArgs = {
appId: Scalars['ID']['input'];
};
export type AppMutationScheduleAppDeletionArgs = {
appId: Scalars['ID']['input'];
};
@@ -2188,6 +2213,24 @@ export type AppWorkflowRunEdge = {
node: WorkflowRun;
};
export type AppWorkflowRunGitBranchEdge = {
__typename?: 'AppWorkflowRunGitBranchEdge';
cursor: Scalars['String']['output'];
node: AppWorkflowRunGitBranchNode;
};
export type AppWorkflowRunGitBranchNode = {
__typename?: 'AppWorkflowRunGitBranchNode';
lastRunAt: Scalars['DateTime']['output'];
name: Scalars['String']['output'];
};
export type AppWorkflowRunGitBranchesConnection = {
__typename?: 'AppWorkflowRunGitBranchesConnection';
edges: Array<AppWorkflowRunGitBranchEdge>;
pageInfo: PageInfo;
};
export type AppWorkflowRunsConnection = {
__typename?: 'AppWorkflowRunsConnection';
edges: Array<AppWorkflowRunEdge>;
@@ -2550,6 +2593,16 @@ export type AscApiKeyInput = {
keyP8: Scalars['String']['input'];
};
export type Asset = {
__typename?: 'Asset';
contentType: Scalars['String']['output'];
fileSHA256: Scalars['String']['output'];
fileSize: Scalars['Int']['output'];
finalFileSize?: Maybe<Scalars['Int']['output']>;
id: Scalars['ID']['output'];
storageKey: Scalars['String']['output'];
};
export type AssetMapGroup = {
android?: InputMaybe<AssetMapSourceInput>;
ios?: InputMaybe<AssetMapSourceInput>;
@@ -2593,7 +2646,15 @@ export type AssetMutationGetSignedAssetUploadSpecificationsArgs = {
/** Check to see if assets with given storageKeys exist */
export type AssetQuery = {
__typename?: 'AssetQuery';
byStorageKeys: Array<Asset>;
metadata: Array<AssetMetadataResult>;
signedUrls: Array<AssetSignedUrlResult>;
};
/** Check to see if assets with given storageKeys exist */
export type AssetQueryByStorageKeysArgs = {
storageKeys: Array<Scalars['String']['input']>;
};
@@ -2602,6 +2663,20 @@ export type AssetQueryMetadataArgs = {
storageKeys: Array<Scalars['String']['input']>;
};
/** Check to see if assets with given storageKeys exist */
export type AssetQuerySignedUrlsArgs = {
storageKeys: Array<Scalars['String']['input']>;
updateId: Scalars['ID']['input'];
};
export type AssetSignedUrlResult = {
__typename?: 'AssetSignedUrlResult';
headers?: Maybe<Scalars['JSON']['output']>;
storageKey: Scalars['String']['output'];
url: Scalars['String']['output'];
};
export type AuditLog = {
__typename?: 'AuditLog';
account?: Maybe<Account>;
@@ -2683,9 +2758,11 @@ export enum AuthProviderIdentifier {
StubIdp = 'STUB_IDP'
}
export type AverageMetrics = {
__typename?: 'AverageMetrics';
averageDownloadSize: Scalars['Int']['output'];
export type AverageAssetMetrics = {
__typename?: 'AverageAssetMetrics';
averageDownloadSizeBytes: Scalars['Int']['output'];
count: Scalars['Int']['output'];
storageKey: Scalars['String']['output'];
};
export type BackgroundJobReceipt = {
@@ -3437,12 +3514,6 @@ export type CreateAndroidSubmissionInput = {
submittedBuildId?: InputMaybe<Scalars['ID']['input']>;
};
export type CreateAppAndGithubRepositoryResponse = {
__typename?: 'CreateAppAndGithubRepositoryResponse';
app: App;
cloneUrl?: Maybe<Scalars['String']['output']>;
};
export type CreateBuildResult = {
__typename?: 'CreateBuildResult';
build: Build;
@@ -3544,6 +3615,12 @@ export type CreateSubmissionResult = {
submission: Submission;
};
export type CumulativeAverageMetrics = {
__typename?: 'CumulativeAverageMetrics';
averageUpdatePayloadBytes: Scalars['Int']['output'];
launchAssetCount: Scalars['Int']['output'];
};
export type CumulativeMetrics = {
__typename?: 'CumulativeMetrics';
data: UpdatesMetricsData;
@@ -4007,6 +4084,7 @@ export enum EasServiceMetric {
AssetsRequests = 'ASSETS_REQUESTS',
BandwidthUsage = 'BANDWIDTH_USAGE',
Builds = 'BUILDS',
LocalBuilds = 'LOCAL_BUILDS',
ManifestRequests = 'MANIFEST_REQUESTS',
RunTime = 'RUN_TIME',
UniqueUpdaters = 'UNIQUE_UPDATERS',
@@ -5237,6 +5315,7 @@ export type IosSubmissionConfigInput = {
ascApiKey?: InputMaybe<AscApiKeyInput>;
ascApiKeyId?: InputMaybe<Scalars['String']['input']>;
ascAppIdentifier: Scalars['String']['input'];
changelog?: InputMaybe<Scalars['String']['input']>;
groups?: InputMaybe<Array<Scalars['String']['input']>>;
isVerboseFastlaneEnabled?: InputMaybe<Scalars['Boolean']['input']>;
};
@@ -5868,6 +5947,7 @@ export type PublicArtifacts = {
};
export type PublishUpdateGroupInput = {
assetHostOverride?: InputMaybe<Scalars['String']['input']>;
assetMapGroup?: InputMaybe<AssetMapGroup>;
awaitingCodeSigningInfo?: InputMaybe<Scalars['Boolean']['input']>;
branchId: Scalars['String']['input'];
@@ -5876,6 +5956,7 @@ export type PublishUpdateGroupInput = {
fingerprintInfoGroup?: InputMaybe<FingerprintInfoGroup>;
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
isGitWorkingTreeDirty?: InputMaybe<Scalars['Boolean']['input']>;
manifestHostOverride?: InputMaybe<Scalars['String']['input']>;
message?: InputMaybe<Scalars['String']['input']>;
rollBackToEmbeddedInfoGroup?: InputMaybe<UpdateRollBackToEmbeddedGroup>;
rolloutInfoGroup?: InputMaybe<UpdateRolloutInfoGroup>;
@@ -5897,6 +5978,7 @@ export enum RequestMethod {
export type RequestsFilters = {
cacheStatus?: InputMaybe<Array<ResponseCacheStatus>>;
continent?: InputMaybe<Array<ContinentCode>>;
country?: InputMaybe<Array<Scalars['String']['input']>>;
hasCustomDomainOrigin?: InputMaybe<Scalars['Boolean']['input']>;
isAsset?: InputMaybe<Scalars['Boolean']['input']>;
isCrash?: InputMaybe<Scalars['Boolean']['input']>;
@@ -6303,6 +6385,7 @@ export type RootQueryAppByAppIdArgs = {
export type RootQueryUpdatesByGroupArgs = {
group: Scalars['ID']['input'];
platform?: InputMaybe<Scalars['String']['input']>;
};
@@ -6985,6 +7068,7 @@ export type Update = ActivityTimelineProjectActivity & {
activityTimestamp: Scalars['DateTime']['output'];
actor?: Maybe<Actor>;
app: App;
assetHostOverride?: Maybe<Scalars['String']['output']>;
assetMapUrl?: Maybe<Scalars['String']['output']>;
awaitingCodeSigningInfo: Scalars['Boolean']['output'];
branch: UpdateBranch;
@@ -7004,6 +7088,7 @@ export type Update = ActivityTimelineProjectActivity & {
isRollBackToEmbedded: Scalars['Boolean']['output'];
jobRun?: Maybe<JobRun>;
manifestFragment: Scalars['String']['output'];
manifestHostOverride?: Maybe<Scalars['String']['output']>;
manifestPermalink: Scalars['String']['output'];
message?: Maybe<Scalars['String']['output']>;
platform: Scalars['String']['output'];
@@ -7227,7 +7312,8 @@ export type UpdateInfoGroup = {
export type UpdateInsights = {
__typename?: 'UpdateInsights';
averageMetrics: AverageMetrics;
averageAssetMetrics: Array<AverageAssetMetrics>;
cumulativeAverageMetrics: CumulativeAverageMetrics;
cumulativeMetrics: CumulativeMetrics;
id: Scalars['ID']['output'];
totalUniqueUsers: Scalars['Int']['output'];
@@ -7814,7 +7900,12 @@ export enum UserEntityTypeName {
export type UserInvitation = {
__typename?: 'UserInvitation';
accountName: Scalars['String']['output'];
/** If the invite is for a personal team, the profile photo of account owner */
/** The profile image URL of the account owner */
accountProfileImageUrl: Scalars['String']['output'];
/**
* If the invite is for a personal team, the profile photo of account owner
* @deprecated Use accountProfileImageUrl
*/
accountProfilePhoto?: Maybe<Scalars['String']['output']>;
created: Scalars['DateTime']['output'];
/** Email to which this invitation was sent */
@@ -7891,6 +7982,7 @@ export type UserInvitationMutationResendUserInvitationArgs = {
export type UserInvitationPublicData = {
__typename?: 'UserInvitationPublicData';
accountName: Scalars['String']['output'];
accountProfileImageUrl: Scalars['String']['output'];
accountProfilePhoto?: Maybe<Scalars['String']['output']>;
created: Scalars['DateTime']['output'];
email: Scalars['String']['output'];
@@ -8126,6 +8218,8 @@ export type WorkerDeployment = ActivityTimelineProjectActivity & {
initiatingActor?: Maybe<Actor>;
logs?: Maybe<WorkerDeploymentLogs>;
requests?: Maybe<WorkerDeploymentRequests>;
signedAssetsURL: Scalars['String']['output'];
signedDeploymentURL: Scalars['String']['output'];
subdomain: Scalars['String']['output'];
url: Scalars['String']['output'];
};
@@ -8318,6 +8412,7 @@ export type WorkerDeploymentRequestNode = {
requestId: Scalars['WorkerDeploymentRequestID']['output'];
requestTimestamp: Scalars['DateTime']['output'];
responseType: ResponseType;
routerPath?: Maybe<Scalars['String']['output']>;
scriptName: Scalars['String']['output'];
search?: Maybe<Scalars['String']['output']>;
status: Scalars['Int']['output'];
@@ -8641,6 +8736,7 @@ export enum WorkflowJobType {
Deploy = 'DEPLOY',
Fingerprint = 'FINGERPRINT',
GetBuild = 'GET_BUILD',
MaestroCloud = 'MAESTRO_CLOUD',
MaestroTest = 'MAESTRO_TEST',
RequireApproval = 'REQUIRE_APPROVAL',
Slack = 'SLACK',
@@ -8649,7 +8745,7 @@ export enum WorkflowJobType {
}
export type WorkflowProjectSourceInput = {
easJsonBucketKey: Scalars['String']['input'];
easJsonBucketKey?: InputMaybe<Scalars['String']['input']>;
packageJsonBucketKey?: InputMaybe<Scalars['String']['input']>;
projectArchiveBucketKey: Scalars['String']['input'];
type: WorkflowProjectSourceType;
@@ -8724,12 +8820,12 @@ export type WorkflowRun = ActivityTimelineProjectActivity & {
activityTimestamp: Scalars['DateTime']['output'];
actor?: Maybe<Actor>;
createdAt: Scalars['DateTime']['output'];
durationSeconds?: Maybe<Scalars['Int']['output']>;
errors: Array<WorkflowRunError>;
gitCommitHash?: Maybe<Scalars['String']['output']>;
gitCommitMessage?: Maybe<Scalars['String']['output']>;
githubRepository?: Maybe<GitHubRepository>;
id: Scalars['ID']['output'];
initiatingUser?: Maybe<User>;
jobs: Array<WorkflowJob>;
name: Scalars['String']['output'];
pullRequestNumber?: Maybe<Scalars['Int']['output']>;
@@ -8758,6 +8854,14 @@ export type WorkflowRunError = {
title?: Maybe<Scalars['String']['output']>;
};
export type WorkflowRunFilterInput = {
requestedGitRef?: InputMaybe<Scalars['String']['input']>;
};
export type WorkflowRunGitBranchFilterInput = {
searchTerm?: InputMaybe<Scalars['String']['input']>;
};
export type WorkflowRunInput = {
projectSource: WorkflowProjectSourceInput;
};
@@ -9514,7 +9618,7 @@ export type UpdatePublishMutationVariables = Exact<{
}>;
export type UpdatePublishMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', publishUpdateGroups: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> } };
export type UpdatePublishMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', publishUpdateGroups: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> } };
export type SetCodeSigningInfoMutationVariables = Exact<{
updateId: Scalars['ID']['input'];
@@ -9530,7 +9634,7 @@ export type SetRolloutPercentageMutationVariables = Exact<{
}>;
export type SetRolloutPercentageMutation = { __typename?: 'RootMutation', update: { __typename?: 'UpdateMutation', setRolloutPercentage: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type SetRolloutPercentageMutation = { __typename?: 'RootMutation', update: { __typename?: 'UpdateMutation', setRolloutPercentage: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type CreateAndroidSubmissionMutationVariables = Exact<{
appId: Scalars['ID']['input'];
@@ -9677,7 +9781,7 @@ export type BranchesByAppQueryVariables = Exact<{
}>;
export type BranchesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> }> } } };
export type BranchesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> }> } } };
export type BranchesBasicPaginatedOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -9698,7 +9802,7 @@ export type ViewBranchesOnUpdateChannelQueryVariables = Exact<{
}>;
export type ViewBranchesOnUpdateChannelQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type ViewBranchesOnUpdateChannelQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type BuildsByIdQueryVariables = Exact<{
buildId: Scalars['ID']['input'];
@@ -9746,7 +9850,7 @@ export type ViewUpdateChannelOnAppQueryVariables = Exact<{
}>;
export type ViewUpdateChannelOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type ViewUpdateChannelOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> } | null } } };
export type ViewUpdateChannelsOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -9755,7 +9859,7 @@ export type ViewUpdateChannelsOnAppQueryVariables = Exact<{
}>;
export type ViewUpdateChannelsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannels: Array<{ __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> }> } } };
export type ViewUpdateChannelsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannels: Array<{ __typename?: 'UpdateChannel', id: string, isPaused: boolean, name: string, updatedAt: any, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> }> }> } } };
export type ViewUpdateChannelsPaginatedOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -9891,7 +9995,7 @@ export type ViewUpdatesByGroupQueryVariables = Exact<{
}>;
export type ViewUpdatesByGroupQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type ViewUpdatesByGroupQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type ViewUpdateGroupsOnBranchQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -9902,7 +10006,7 @@ export type ViewUpdateGroupsOnBranchQueryVariables = Exact<{
}>;
export type ViewUpdateGroupsOnBranchQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } | null } } };
export type ViewUpdateGroupsOnBranchQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } | null } } };
export type ViewUpdateGroupsOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -9912,14 +10016,14 @@ export type ViewUpdateGroupsOnAppQueryVariables = Exact<{
}>;
export type ViewUpdateGroupsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } } };
export type ViewUpdateGroupsOnAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateGroups: Array<Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }>> } } };
export type UpdateByIdQueryVariables = Exact<{
updateId: Scalars['ID']['input'];
}>;
export type UpdateByIdQuery = { __typename?: 'RootQuery', updates: { __typename?: 'UpdateQuery', byId: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type UpdateByIdQuery = { __typename?: 'RootQuery', updates: { __typename?: 'UpdateQuery', byId: { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null } } };
export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
@@ -9941,6 +10045,20 @@ export type WebhookByIdQueryVariables = Exact<{
export type WebhookByIdQuery = { __typename?: 'RootQuery', webhook: { __typename?: 'WebhookQuery', byId: { __typename?: 'Webhook', id: string, event: WebhookType, url: string, createdAt: any, updatedAt: any } } };
export type WorkflowRunByIdQueryVariables = Exact<{
workflowRunId: Scalars['ID']['input'];
}>;
export type WorkflowRunByIdQuery = { __typename?: 'RootQuery', workflowRuns: { __typename?: 'WorkflowRunQuery', byId: { __typename?: 'WorkflowRun', id: string, status: WorkflowRunStatus } } };
export type WorkflowRunByIdWithJobsQueryVariables = Exact<{
workflowRunId: Scalars['ID']['input'];
}>;
export type WorkflowRunByIdWithJobsQuery = { __typename?: 'RootQuery', workflowRuns: { __typename?: 'WorkflowRunQuery', byId: { __typename?: 'WorkflowRun', id: string, name: string, status: WorkflowRunStatus, createdAt: any, workflow: { __typename?: 'Workflow', id: string, name?: string | null, fileName: string }, jobs: Array<{ __typename?: 'WorkflowJob', id: string, key: string, name: string, type: WorkflowJobType, status: WorkflowJobStatus, outputs: any, createdAt: any }> } } };
export type AccountFragment = { __typename?: 'Account', id: string, name: string, ownerUserActor?: { __typename?: 'SSOUser', id: string, username: string } | { __typename?: 'User', id: string, username: string } | null, users: Array<{ __typename?: 'UserPermission', role: Role, actor: { __typename?: 'Robot', id: string } | { __typename?: 'SSOUser', id: string } | { __typename?: 'User', id: string } }> };
export type AppFragment = { __typename?: 'App', id: string, name: string, fullName: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string, ownerUserActor?: { __typename?: 'SSOUser', id: string, username: string } | { __typename?: 'User', id: string, username: string } | null, users: Array<{ __typename?: 'UserPermission', role: Role, actor: { __typename?: 'Robot', id: string } | { __typename?: 'SSOUser', id: string } | { __typename?: 'User', id: string } }> }, githubRepository?: { __typename?: 'GitHubRepository', id: string, metadata: { __typename?: 'GitHubRepositoryMetadata', githubRepoOwnerName: string, githubRepoName: string } } | null };
@@ -9967,9 +10085,9 @@ export type StatuspageServiceFragment = { __typename?: 'StatuspageService', id:
export type SubmissionFragment = { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null };
export type UpdateFragment = { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null };
export type UpdateFragment = { __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, rolloutPercentage?: number | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, isRollBackToEmbedded: boolean, manifestPermalink: string, gitCommitHash?: string | null, isGitWorkingTreeDirty: boolean, environment?: EnvironmentVariableEnvironment | null, rolloutPercentage?: number | null, manifestHostOverride?: string | null, assetHostOverride?: string | null, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'SSOUser', username: string, id: string } | { __typename: 'User', username: string, id: string } | null, branch: { __typename?: 'UpdateBranch', id: string, name: string }, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, sig: string, alg: string } | null, rolloutControlUpdate?: { __typename?: 'Update', id: string } | null, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null, source?: { __typename?: 'FingerprintSource', type: FingerprintSourceType, bucketKey: string, isDebugFingerprint?: boolean | null } | null } | null }> };
export type UpdateBranchBasicInfoFragment = { __typename?: 'UpdateBranch', id: string, name: string };
@@ -0,0 +1,87 @@
import gql from 'graphql-tag';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import {
WorkflowRunByIdQuery,
WorkflowRunByIdQueryVariables,
WorkflowRunByIdWithJobsQuery,
WorkflowRunByIdWithJobsQueryVariables,
} from '../generated';
export const WorkflowRunQuery = {
async byIdAsync(
graphqlClient: ExpoGraphqlClient,
workflowRunId: string,
{ useCache = true }: { useCache?: boolean } = {}
): Promise<WorkflowRunByIdQuery['workflowRuns']['byId']> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<WorkflowRunByIdQuery, WorkflowRunByIdQueryVariables>(
gql`
query WorkflowRunById($workflowRunId: ID!) {
workflowRuns {
byId(workflowRunId: $workflowRunId) {
id
status
}
}
}
`,
{ workflowRunId },
{
requestPolicy: useCache ? 'cache-first' : 'network-only',
additionalTypenames: ['WorkflowRun'],
}
)
.toPromise()
);
return data.workflowRuns.byId;
},
async withJobsByIdAsync(
graphqlClient: ExpoGraphqlClient,
workflowRunId: string,
{ useCache = true }: { useCache?: boolean } = {}
): Promise<WorkflowRunByIdWithJobsQuery['workflowRuns']['byId']> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<WorkflowRunByIdWithJobsQuery, WorkflowRunByIdWithJobsQueryVariables>(
gql`
query WorkflowRunByIdWithJobs($workflowRunId: ID!) {
workflowRuns {
byId(workflowRunId: $workflowRunId) {
id
name
status
createdAt
workflow {
id
name
fileName
}
jobs {
id
key
name
type
status
outputs
createdAt
}
}
}
}
`,
{ workflowRunId },
{
requestPolicy: useCache ? 'cache-first' : 'network-only',
additionalTypenames: ['WorkflowRun'],
}
)
.toPromise()
);
return data.workflowRuns.byId;
},
};
@@ -12,6 +12,8 @@ export const UpdateFragmentNode = gql`
isRollBackToEmbedded
manifestPermalink
gitCommitHash
isGitWorkingTreeDirty
environment
actor {
__typename
id
@@ -45,5 +47,7 @@ export const UpdateFragmentNode = gql`
isDebugFingerprint
}
}
manifestHostOverride
assetHostOverride
}
`;
@@ -0,0 +1,232 @@
apply plugin: "com.android.application"
import com.android.build.OutputFile
/**
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
* and bundleReleaseJsAndAssets).
* These basically call `react-native bundle` with the correct arguments during the Android build
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
* bundle directly from the development server. Below you can see all the possible configurations
* and their defaults. If you decide to add a configuration block, make sure to add it before the
* `apply from: "../../node_modules/react-native/react.gradle"` line.
*
* project.ext.react = [
* // the name of the generated asset file containing your JS bundle
* bundleAssetName: "index.android.bundle",
*
* // the entry file for bundle generation. If none specified and
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
* // default. Can be overridden with ENTRY_FILE environment variable.
* entryFile: "index.android.js",
*
* // https://reactnative.dev/docs/performance#enable-the-ram-format
* bundleCommand: "ram-bundle",
*
* // whether to bundle JS and assets in debug mode
* bundleInDebug: false,
*
* // whether to bundle JS and assets in release mode
* bundleInRelease: true,
*
* // whether to bundle JS and assets in another build variant (if configured).
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
* // The configuration property can be in the following formats
* // 'bundleIn${productFlavor}${buildType}'
* // 'bundleIn${buildType}'
* // bundleInFreeDebug: true,
* // bundleInPaidRelease: true,
* // bundleInBeta: true,
*
* // whether to disable dev mode in custom build variants (by default only disabled in release)
* // for example: to disable dev mode in the staging build type (if configured)
* devDisabledInStaging: true,
* // The configuration property can be in the following formats
* // 'devDisabledIn${productFlavor}${buildType}'
* // 'devDisabledIn${buildType}'
*
* // the root of your project, i.e. where "package.json" lives
* root: "../../",
*
* // where to put the JS bundle asset in debug mode
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
*
* // where to put the JS bundle asset in release mode
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in debug mode
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
*
* // where to put drawable resources / React Native assets, e.g. the ones you use via
* // require('./image.png')), in release mode
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
*
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
* // for example, you might want to remove it from here.
* inputExcludes: ["android/**", "ios/**"],
*
* // override which node gets called and with what additional arguments
* nodeExecutableAndArgs: ["node"],
*
* // supply additional arguments to the packager
* extraPackagerArgs: []
* ]
*/
project.ext.react = [
enableHermes: false
]
apply from: '../../node_modules/react-native-unimodules/gradle.groovy'
apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/expo-updates/scripts/create-manifest-android.gradle"
/**
* Set this to true to create two separate APKs instead of one:
* - An APK that only works on ARM devices
* - An APK that only works on x86 devices
* The advantage is the size of the APK is reduced by about 4MB.
* Upload all the APKs to the Play Store and people will download
* the correct one based on the CPU architecture of their device.
*/
def enableSeparateBuildPerCPUArchitecture = false
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = false
/**
* The preferred build flavor of JavaScriptCore.
*
* For example, to use the international variant, you can use:
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
*
* The international variant includes ICU i18n library and necessary data
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
* give correct results when using with locales other than en-US. Note that
* this variant is about 6MiB larger per architecture than default.
*/
def jscFlavor = 'org.webkit:android-jsc:+'
/**
* Whether to enable the Hermes VM.
*
* This should be set on project.ext.react and mirrored here. If it is not set
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
* and the benefits of using Hermes will therefore be sharply reduced.
*/
def enableHermes = project.ext.react.get("enableHermes", false);
android {
compileSdkVersion rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
applicationId "com.testapp"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
}
splits {
abi {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk false // If true, also generate a universal APK
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
}
}
signingConfigs {
debug {
storeFile rootProject.file('keystores/debug.keystore')
storePassword 'android'
keyAlias 'androiddebugkey'
keyPassword 'android'
}
}
flavorDimensions = ["version"]
productFlavors {
development {
dimension "version"
applicationId "com.amanhimself.multiflavor"
}
production {
dimension "version"
applicationId "com.amanhimself.multiflavor.dark"
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
}
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
signingConfig signingConfigs.debug
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
}
}
// applicationVariants are e.g. debug, release
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
// https://developer.android.com/studio/build/configure-apk-splits.html
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
def abi = output.getFilter(OutputFile.ABI)
if (abi != null) { // null for the universal-debug, universal-release variants
output.versionCodeOverride =
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
}
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
}
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
exclude group:'com.squareup.okhttp3', module:'okhttp'
}
debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
exclude group:'com.facebook.flipper'
}
addUnimodulesDependencies()
if (enableHermes) {
def hermesPath = "../../node_modules/hermes-engine/android/";
debugImplementation files(hermesPath + "hermes-debug.aar")
releaseImplementation files(hermesPath + "hermes-release.aar")
} else {
implementation jscFlavor
}
}
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
from configurations.compile
into 'libs'
}
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
apply from: "./eas-build.gradle"
@@ -131,6 +131,41 @@ describe(getAppBuildGradleAsync, () => {
},
});
});
test('parsing build.gradle with flavor dimensions as array', async () => {
vol.fromJSON(
{
'android/app/build.gradle': await fsReal.promises.readFile(
path.join(__dirname, 'fixtures/multiflavor-with-dimensions-array-build.gradle'),
'utf-8'
),
},
'/test'
);
const buildGradle = await getAppBuildGradleAsync('/test');
expect(
pick(buildGradle?.android ?? {}, ['defaultConfig', 'flavorDimensions', 'productFlavors'])
).toEqual({
defaultConfig: {
applicationId: 'com.testapp',
minSdkVersion: 'rootProject.ext.minSdkVersion',
targetSdkVersion: 'rootProject.ext.targetSdkVersion',
versionCode: '1',
versionName: '1.0',
},
flavorDimensions: ['version'],
productFlavors: {
development: {
applicationId: 'com.amanhimself.multiflavor',
dimension: 'version',
},
production: {
applicationId: 'com.amanhimself.multiflavor.dark',
dimension: 'version',
},
},
});
});
});
describe(parseGradleCommand, () => {
@@ -172,6 +207,12 @@ describe(parseGradleCommand, () => {
const result = parseGradleCommand('bundleRelease --console verbose', {});
expect(result).toEqual({ buildType: 'release' });
});
test('parsing with array flavor dimensions', async () => {
const result = parseGradleCommand(':app:buildExampleRelease', {
android: { flavorDimensions: ['version'], productFlavors: { example: {} } },
});
expect(result).toEqual({ moduleName: 'app', flavor: 'example', buildType: 'release' });
});
});
describe(resolveConfigValue, () => {
@@ -20,7 +20,14 @@ interface Config {
interface AppBuildGradle {
android?: {
defaultConfig?: Config;
flavorDimensions?: string; // e.g. '"dimension1", "dimension2"'
/**
* If defined as `flavorDimensions = ['dimension1', 'dimension2']`,
* this will be an array of strings (`['dimension1', 'dimension2']`).
*
* If defined as `flavorDimensions "dimension1", "dimension2"`,
* this will be a string (`"dimension1", "dimension2"`).
*/
flavorDimensions?: string | string[];
productFlavors?: Record<string, Config>;
};
}
@@ -65,7 +72,11 @@ export function resolveConfigValue(
* the flavor name
**/
export function parseGradleCommand(cmd: string, buildGradle: AppBuildGradle): GradleCommand {
const hasFlavorDimensions = (buildGradle.android?.flavorDimensions ?? '').split(',').length > 1;
const flavorDimensions =
typeof buildGradle.android?.flavorDimensions === 'string'
? buildGradle.android.flavorDimensions.split(',')
: buildGradle.android?.flavorDimensions;
const hasFlavorDimensions = flavorDimensions && flavorDimensions.length > 1;
if (hasFlavorDimensions) {
throw new Error('flavorDimensions in build.gradle are not supported yet');
}
+7 -9
View File
@@ -13,19 +13,13 @@ import Log, { learnMore } from '../log';
import { Actor } from '../user/User';
import { expoCommandAsync } from '../utils/expoCli';
export function getUsername(exp: ExpoConfig, user: Actor): string | undefined {
export function getUsernameForBuildMetadataAndBuildJob(user: Actor): string | undefined {
switch (user.__typename) {
case 'User':
return user.username;
case 'SSOUser':
return user.username;
case 'Robot':
// owner field is necessary to run `expo prebuild`
if (!exp.owner) {
throw new Error(
'The "owner" manifest property is required when using robot users. See: https://docs.expo.dev/versions/latest/config/app/#owner'
);
}
// robot users don't have usernames
return undefined;
}
@@ -84,8 +78,12 @@ export function isExpoUpdatesInstalledOrAvailable(
return isExpoUpdatesInstalled(projectDir);
}
export function isUsingEASUpdate(exp: ExpoConfig, projectId: string): boolean {
return exp.updates?.url === getEASUpdateURL(projectId);
export function isUsingEASUpdate(
exp: ExpoConfig,
projectId: string,
manifestHostOverride: string | null
): boolean {
return exp.updates?.url === getEASUpdateURL(projectId, manifestHostOverride);
}
export async function getExpoUpdatesPackageVersionIfInstalledAsync(
+47 -22
View File
@@ -1073,27 +1073,52 @@ export async function getRuntimeToUpdateRolloutInfoGroupMappingAsync(
runtimeToPlatformsAndFingerprintInfoMapping.map(r => [r.runtimeVersion, r.platforms])
);
return await mapMapAsync(runtimeToPlatformsMap, async (platforms, runtimeVersion) => {
return Object.fromEntries(
await Promise.all(
platforms.map<Promise<[string, UpdateRolloutInfo]>>(async platform => {
const updateIdForPlatform = await BranchQuery.getLatestUpdateIdOnBranchAsync(
graphqlClient,
{
appId,
branchName,
runtimeVersion,
platform: updatePublishPlatformToAppPlatform[platform],
}
);
if (!updateIdForPlatform) {
throw new Error(
`No updates on branch ${branchName} for platform ${platform} and runtimeVersion ${runtimeVersion} to roll out from.`
);
}
return [platform, { rolloutPercentage, rolloutControlUpdateId: updateIdForPlatform }];
})
)
);
return await getUpdateRolloutInfoGroupAsync(graphqlClient, {
appId,
branchName,
rolloutPercentage,
runtimeVersion,
platforms,
});
});
}
export async function getUpdateRolloutInfoGroupAsync(
graphqlClient: ExpoGraphqlClient,
{
appId,
branchName,
rolloutPercentage,
runtimeVersion,
platforms,
}: {
appId: string;
branchName: string;
rolloutPercentage: number;
runtimeVersion: string;
platforms: UpdatePublishPlatform[];
}
): Promise<UpdateRolloutInfoGroup> {
return Object.fromEntries(
await Promise.all(
platforms.map<Promise<[string, UpdateRolloutInfo]>>(async platform => {
const updateIdForPlatform = await BranchQuery.getLatestUpdateIdOnBranchAsync(
graphqlClient,
{
appId,
branchName,
runtimeVersion,
platform: updatePublishPlatformToAppPlatform[platform],
}
);
if (!updateIdForPlatform) {
throw new Error(
`No updates on branch ${branchName} for platform ${platform} and runtimeVersion ${runtimeVersion} to roll out from.`
);
}
return [platform, { rolloutPercentage, rolloutControlUpdateId: updateIdForPlatform }];
})
)
);
}
+7 -2
View File
@@ -98,17 +98,19 @@ async function ensureEASUpdatesIsConfiguredInExpoConfigAsync({
projectDir,
platform,
workflows,
manifestHostOverride,
}: {
exp: ExpoConfig;
projectId: string;
projectDir: string;
platform: RequestedPlatform;
workflows: Record<Platform, Workflow>;
manifestHostOverride: string | null;
}): Promise<{ projectChanged: boolean; exp: ExpoConfig }> {
const modifyConfig: Partial<ExpoConfig> = {};
if (exp.updates?.url !== getEASUpdateURL(projectId)) {
modifyConfig.updates = { url: getEASUpdateURL(projectId) };
if (exp.updates?.url !== getEASUpdateURL(projectId, manifestHostOverride)) {
modifyConfig.updates = { url: getEASUpdateURL(projectId, manifestHostOverride) };
}
let androidRuntimeVersion = exp.android?.runtimeVersion ?? exp.runtimeVersion;
@@ -372,6 +374,7 @@ export async function ensureEASUpdateIsConfiguredAsync({
platform,
env,
forceNativeConfigSync,
manifestHostOverride,
}: {
exp: ExpoConfig;
projectId: string;
@@ -380,6 +383,7 @@ export async function ensureEASUpdateIsConfiguredAsync({
platform: RequestedPlatform | null;
env: Env | undefined;
forceNativeConfigSync?: boolean;
manifestHostOverride: string | null;
}): Promise<void> {
const hasExpoUpdates = isExpoUpdatesInstalledOrAvailable(
projectDir,
@@ -409,6 +413,7 @@ export async function ensureEASUpdateIsConfiguredAsync({
projectId,
platform,
workflows,
manifestHostOverride,
});
if (forceNativeConfigSync || projectChanged || !hasExpoUpdates) {
+35 -1
View File
@@ -10,6 +10,7 @@ import { PublishMutation } from '../graphql/mutations/PublishMutation';
import Log, { link } from '../log';
import { ora } from '../ora';
import { getOwnerAccountForProjectIdAsync } from '../project/projectUtils';
import { UpdatePublishPlatform, getUpdateRolloutInfoGroupAsync } from '../project/publish';
import {
CodeSigningInfo,
checkDirectiveBodyAgainstUpdateInfoGroup,
@@ -39,6 +40,7 @@ export async function republishAsync({
updateMessage,
codeSigningInfo,
json,
rolloutPercentage,
}: {
graphqlClient: ExpoGraphqlClient;
app: { exp: ExpoConfig; projectId: string };
@@ -47,6 +49,7 @@ export async function republishAsync({
updateMessage: string;
codeSigningInfo?: CodeSigningInfo;
json?: boolean;
rolloutPercentage?: number;
}): Promise<void> {
const { branchName: targetBranchName, branchId: targetBranchId } = targetBranch;
@@ -57,7 +60,9 @@ export async function republishAsync({
update.groupId === arbitraryUpdate.groupId &&
update.branchId === arbitraryUpdate.branchId &&
update.branchName === arbitraryUpdate.branchName &&
update.runtimeVersion === arbitraryUpdate.runtimeVersion;
update.runtimeVersion === arbitraryUpdate.runtimeVersion &&
update.manifestHostOverride === arbitraryUpdate.manifestHostOverride &&
update.assetHostOverride === arbitraryUpdate.assetHostOverride;
assert(
updatesToPublish.every(isSameGroup),
'All updates being republished must belong to the same update group'
@@ -139,6 +144,15 @@ export async function republishAsync({
];
})
),
rolloutInfoGroup: rolloutPercentage
? await getUpdateRolloutInfoGroupAsync(graphqlClient, {
appId: app.projectId,
branchName: targetBranchName,
runtimeVersion,
rolloutPercentage,
platforms: updatesToPublish.map(update => update.platform as UpdatePublishPlatform),
})
: null,
};
updatesRepublished = await PublishMutation.publishUpdateGroupAsync(graphqlClient, [
@@ -148,7 +162,11 @@ export async function republishAsync({
message: updateMessage,
...objectToMergeIn,
gitCommitHash: updatesToPublish[0].gitCommitHash,
isGitWorkingTreeDirty: updatesToPublish[0].isGitWorkingTreeDirty,
environment: updatesToPublish[0].environment,
awaitingCodeSigningInfo: !!codeSigningInfo,
manifestHostOverride: updatesToPublish[0].manifestHostOverride,
assetHostOverride: updatesToPublish[0].assetHostOverride,
},
]);
@@ -226,6 +244,22 @@ export async function republishAsync({
...(updatesRepublishedByPlatform.ios
? [{ label: 'iOS update ID', value: updatesRepublishedByPlatform.ios.id }]
: []),
...(updatesRepublishedByPlatform.android?.rolloutControlUpdate
? [
{
label: 'Android Rollout',
value: `${updatesRepublishedByPlatform.android?.rolloutPercentage}% (Base update ID: ${updatesRepublishedByPlatform.android?.rolloutControlUpdate.id})`,
},
]
: []),
...(updatesRepublishedByPlatform.ios?.rolloutControlUpdate
? [
{
label: 'iOS Rollout',
value: `${updatesRepublishedByPlatform.ios?.rolloutPercentage}% (Base update ID: ${updatesRepublishedByPlatform.ios?.rolloutControlUpdate.id})`,
},
]
: []),
{ label: 'Message', value: updateMessage },
{ label: 'EAS Dashboard', value: link(updateGroupUrl, { dim: false }) },
])
-11
View File
@@ -3,7 +3,6 @@ import { format } from '@expo/timeago.js';
import chalk from 'chalk';
import dateFormat from 'dateformat';
import { getEASUpdateURL } from '../api';
import {
Robot,
SsoUser,
@@ -270,13 +269,3 @@ export function getBranchDescription(branch: UpdateBranchFragment): FormattedBra
},
};
}
export async function checkEASUpdateURLIsSetAsync(
exp: ExpoConfig,
projectId: string
): Promise<boolean> {
const configuredURL = exp.updates?.url;
const expectedURL = getEASUpdateURL(projectId);
return configuredURL === expectedURL;
}
@@ -3,6 +3,8 @@ import Log from '../../log';
jest.mock('chalk', () => ({
red: jest.fn(text => `red(${text})`),
blue: jest.fn(text => `blue(${text})`),
yellow: jest.fn(text => `yellow(${text})`),
green: jest.fn(text => `green(${text})`),
gray: jest.fn(text => `gray(${text})`),
cyan: jest.fn(text => `cyan(${text})`),
+22
View File
@@ -1,5 +1,6 @@
import { IOSConfig } from '@expo/config-plugins';
import plist from '@expo/plist';
import binaryPlist from 'bplist-parser';
import fs from 'fs-extra';
import path from 'path';
@@ -25,3 +26,24 @@ export async function writePlistAsync(
await fs.mkdirp(path.dirname(plistPath));
await fs.writeFile(plistPath, contents);
}
const CHAR_CHEVRON_OPEN = 60;
const CHAR_B_LOWER = 98;
export function parseBinaryPlistBuffer(contents: Buffer): any {
if (contents[0] === CHAR_CHEVRON_OPEN) {
const info = plist.parse(contents.toString());
if (Array.isArray(info)) {
return info[0];
}
return info;
} else if (contents[0] === CHAR_B_LOWER) {
const info = binaryPlist.parseBuffer(contents);
if (Array.isArray(info)) {
return info[0];
}
return info;
} else {
throw new Error(`Cannot parse plist of type byte (0x${contents[0].toString(16)})`);
}
}
+73 -63
View File
@@ -104,7 +104,7 @@ export default class GitClient extends Client {
commitAllFiles?: boolean;
nonInteractive: boolean;
}): Promise<void> {
await ensureGitConfiguredAsync({ nonInteractive });
await this.ensureGitConfiguredAsync({ nonInteractive });
try {
if (commitAllFiles) {
@@ -391,74 +391,84 @@ export default class GitClient extends Client {
public override canGetLastCommitMessage(): boolean {
return true;
}
}
async function ensureGitConfiguredAsync({
nonInteractive,
}: {
nonInteractive: boolean;
}): Promise<void> {
let usernameConfigured = true;
let emailConfigured = true;
try {
await spawnAsync('git', ['config', '--get', 'user.name']);
} catch (err: any) {
Log.debug(err);
usernameConfigured = false;
}
try {
await spawnAsync('git', ['config', '--get', 'user.email']);
} catch (err: any) {
Log.debug(err);
emailConfigured = false;
}
if (usernameConfigured && emailConfigured) {
return;
}
Log.warn(
`You need to configure Git with your ${[
!usernameConfigured && 'username (user.name)',
!emailConfigured && 'email address (user.email)',
]
.filter(i => i)
.join(' and ')}`
);
if (nonInteractive) {
throw new Error('Git cannot be configured automatically in non-interactive mode');
}
if (!usernameConfigured) {
const { username } = await promptAsync({
type: 'text',
name: 'username',
message: 'Username:',
validate: (input: string) => input !== '',
});
const spinner = ora(
`Running ${chalk.bold(`git config --local user.name ${username}`)}`
).start();
private async ensureGitConfiguredAsync({
nonInteractive,
}: {
nonInteractive: boolean;
}): Promise<void> {
let usernameConfigured = true;
let emailConfigured = true;
try {
await spawnAsync('git', ['config', '--local', 'user.name', username]);
spinner.succeed();
await spawnAsync('git', ['config', '--get', 'user.name'], {
cwd: this.maybeCwdOverride,
});
} catch (err: any) {
spinner.fail();
throw err;
Log.debug(err);
usernameConfigured = false;
}
}
if (!emailConfigured) {
const { email } = await promptAsync({
type: 'text',
name: 'email',
message: 'Email address:',
validate: (input: string) => input !== '',
});
const spinner = ora(`Running ${chalk.bold(`git config --local user.email ${email}`)}`).start();
try {
await spawnAsync('git', ['config', '--local', 'user.email', email]);
spinner.succeed();
await spawnAsync('git', ['config', '--get', 'user.email'], {
cwd: this.maybeCwdOverride,
});
} catch (err: any) {
spinner.fail();
throw err;
Log.debug(err);
emailConfigured = false;
}
if (usernameConfigured && emailConfigured) {
return;
}
Log.warn(
`You need to configure Git with your ${[
!usernameConfigured && 'username (user.name)',
!emailConfigured && 'email address (user.email)',
]
.filter(i => i)
.join(' and ')}`
);
if (nonInteractive) {
throw new Error('Git cannot be configured automatically in non-interactive mode');
}
if (!usernameConfigured) {
const { username } = await promptAsync({
type: 'text',
name: 'username',
message: 'Username:',
validate: (input: string) => input !== '',
});
const spinner = ora(
`Running ${chalk.bold(`git config --local user.name ${username}`)}`
).start();
try {
await spawnAsync('git', ['config', '--local', 'user.name', username], {
cwd: this.maybeCwdOverride,
});
spinner.succeed();
} catch (err: any) {
spinner.fail();
throw err;
}
}
if (!emailConfigured) {
const { email } = await promptAsync({
type: 'text',
name: 'email',
message: 'Email address:',
validate: (input: string) => input !== '',
});
const spinner = ora(
`Running ${chalk.bold(`git config --local user.email ${email}`)}`
).start();
try {
await spawnAsync('git', ['config', '--local', 'user.email', email], {
cwd: this.maybeCwdOverride,
});
spinner.succeed();
} catch (err: any) {
spinner.fail();
throw err;
}
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "16.4.0",
"version": "16.7.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
+4
View File
@@ -14,4 +14,8 @@ export const EasJsonSchema = Joi.object({
}),
build: Joi.object().pattern(Joi.string(), BuildProfileSchema),
submit: Joi.object().pattern(Joi.string(), UnresolvedSubmitProfileSchema),
update: Joi.object({
assetHostOverride: Joi.string(),
manifestHostOverride: Joi.string(),
}),
});
+4
View File
@@ -25,4 +25,8 @@ export interface EasJson {
};
build?: { [profileName: string]: EasJsonBuildProfile };
submit?: { [profileName: string]: EasJsonSubmitProfile };
update?: {
assetHostOverride?: string;
manifestHostOverride?: string;
};
}
+14
View File
@@ -102,6 +102,20 @@ export class EasJsonUtils {
}
}
public static async getUpdateConfigAsync(
accessor: EasJsonAccessor
): Promise<EasJson['update'] | null> {
try {
const easJson = await accessor.readAsync();
return easJson.update ?? null;
} catch (err: any) {
if (err instanceof MissingEasJsonError) {
return null;
}
throw err;
}
}
public static async getSubmitProfileNamesAsync(accessor: EasJsonAccessor): Promise<string[]> {
const easJson = await accessor.readAsync();
return Object.keys(easJson?.submit ?? {});
Generated
+7
View File
@@ -4970,6 +4970,13 @@ [email protected]:
dependencies:
big-integer "1.6.x"
bplist-parser@^0.3.0:
version "0.3.2"
resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.3.2.tgz#3ac79d67ec52c4c107893e0237eb787cbacbced7"
integrity sha512-apC2+fspHGI3mMKj+dGevkGo/tCqVB8jMb6i+OX+E29p0Iposz07fABkRIfVUPNd5A5VbuOz1bZbnmkKLYF+wQ==
dependencies:
big-integer "1.6.x"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"