Compare commits

...
16 Commits
Author SHA1 Message Date
Dominik Sokal 34deafe440 v1.0.0 2022-08-22 09:55:27 +02:00
Dominik Sokal 55d8b650d3 remove timeout when waiting for build / submit (#1289)
* remove timeout when waiting for build / submit

* update CHANGELOG.md
2022-08-22 09:43:57 +02:00
Will Schurman 3ef6802d55 [eas-cli] Limit the number of SignedAssetUploadSpecifications fetched at a time (#1287) 2022-08-19 10:11:26 -07:00
Dominik Sokal e9484ffa5a update CODEOWNERS 2022-08-19 13:51:38 +02:00
Will Schurman c2b50a3a08 [eas-cli] Remove git merge artifact from CHANGELOG (#1285) 2022-08-17 11:31:02 -07:00
Will Schurman 06bb202bdf [eas-cli] Improve reliability of update asset presigned upload requests (#1278) 2022-08-17 10:59:18 -07:00
Will Schurman 64b67e9ea7 [eas-cli] Configure EAS project ID in app config in all cases (#1282) 2022-08-17 10:12:14 -07:00
faf1e90bed [eas-cli] Add js metadata config file support (#1270)
* [eas-cli] Add js metadata config file support

* [eas-cli] Add js metadata config file download support

* update CHANGELOG.md

* [eas-cli] Only save static files when pulling metadata

* [eas-cli] Support config functions and async functions in metadata

* [eas-cli] Tweak the metadata logs

* [eas-cli] Improve the dynamic config return validation

* [eas-cli] Apply improved language suggestions from the pros

Co-authored-by: Dominik Sokal <[email protected]>

* [eas-cli] Apply code changes from review

Co-authored-by: Dominik Sokal <[email protected]>
Co-authored-by: Wojciech Kozyra <[email protected]>

* [eas-cli] Split out load config logging and move validation to single method

* [eas-cli] Fix missed renamed function

Co-authored-by: Dominik Sokal <[email protected]>
Co-authored-by: Wojciech Kozyra <[email protected]>
2022-08-17 16:16:52 +02:00
c8935e199b [workspace] improve DX while working on Windows (#1272)
Co-authored-by: Dominik Sokal <[email protected]>
Co-authored-by: Wojciech Kozyra <[email protected]>
2022-08-16 15:10:55 +02:00
Wojciech Kozyra af76a9ce48 [eas-cli] remove shell check (#1281) 2022-08-16 13:54:22 +02:00
Wojciech Kozyra 3986e2fbb7 [eas-cli] remove install script (#1280)
* [eas-cli] remove installer

* update CHANGELOG.md
2022-08-16 13:27:13 +02:00
Dominik Sokal 1f97e8cc1c [eas-cli] init git repo in monorepo root (#1279)
* [eas-cli] init git repo in monorepo root

* update CHANGELOG.md
2022-08-16 11:02:05 +02:00
dependabot[bot] be1e2d7189 Bump simple-plist from 1.1.1 to 1.3.1 (#1139)
Bumps [simple-plist](https://github.com/wollardj/simple-plist) from 1.1.1 to 1.3.1.
- [Release notes](https://github.com/wollardj/simple-plist/releases)
- [Commits](https://github.com/wollardj/simple-plist/compare/v1.1.1...v1.3.1)

---
updated-dependencies:
- dependency-name: simple-plist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-16 10:13:25 +02:00
Evan Bacon 8c4d7a6d0e fix: log binding was incorrect after ora instance (#1113)
* fix: log binding was incorrect after ora instance

* update CHANGELOG.md
2022-08-15 12:50:17 +02:00
Bartosz Kaszubowski 0849bf80b0 [workspace] bump Node used by oclif (#1273) 2022-08-12 15:20:40 +02:00
Expo CI 57ea4cd8c2 update CHANGELOG.md 2022-08-12 11:43:54 +00:00
45 changed files with 957 additions and 364 deletions

No files matched your search

+1
View File
@@ -1 +1,2 @@
* text eol=lf
**/yarn.lock linguist-generated
-20
View File
@@ -1,20 +0,0 @@
name: Installer tests
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize]
jobs:
test:
name: Run the installer
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- run: bash bin/install.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: eas --version
-1
View File
@@ -32,7 +32,6 @@ jobs:
# Remove this whenever we solved those OOM errors.
NODE_OPTIONS: --max-old-space-size=4096
- run: yarn lint --max-warnings=0
- run: shellcheck bin/*.sh
- uses: codecov/codecov-action@v1
if: ${{ matrix.coverage }}
with:
+2 -1
View File
@@ -4,5 +4,6 @@
"singleQuote": true,
"bracketSameLine": true,
"trailingComma": "es5",
"arrowParens": "avoid"
"arrowParens": "avoid",
"endOfLine": "auto"
}
+19 -2
View File
@@ -6,12 +6,29 @@ This is the log of notable changes to EAS CLI and related packages.
### 🛠 Breaking changes
- Remove timeout when waiting for build / submission. ([#1289](https://github.com/expo/eas-cli/pull/1289) by [@dsokal](https://github.com/dsokal))
### 🎉 New features
- Add metadata support for dynamic store.config.js files. ([#1270](https://github.com/expo/eas-cli/pull/1270) by [@byCedric](https://github.com/byCedric))
- Improve reliability of update asset presigned upload requests. ([#1278](https://github.com/expo/eas-cli/pull/1278) by [@wschurman](https://github.com/wschurman))
### 🐛 Bug fixes
- Rebind `console.info` correctly after `ora` instance stops. ([#1113](https://github.com/expo/eas-cli/pull/1113) by [@EvanBacon](https://github.com/EvanBacon))
- Fix initializing git repository in monorepo. ([#1279](https://github.com/expo/eas-cli/pull/1279) by [@dsokal](https://github.com/dsokal))
- Limit the number of SignedAssetUploadSpecifications fetched at a time. ([#1287](https://github.com/expo/eas-cli/pull/1287) by [@wschurman](https://github.com/wschurman))
### 🧹 Chores
- Remove unused install script. ([#1280](https://github.com/expo/eas-cli/pull/1280), [#1281](https://github.com/expo/eas-cli/pull/1281) by [@wkozyra95](https://github.com/wkozyra95))
## [0.60.0](https://github.com/expo/eas-cli/releases/tag/v0.60.0) - 2022-08-12
### 🎉 New features
- Add `appVersion` runtime policy. ([#1267](https://github.com/expo/eas-cli/pull/1267) by [@wkozyra95](https://github.com/wkozyra95))
### 🐛 Bug fixes
### 🧹 Chores
- Add JSON Schema `metadataPath` to iOS submission profile. ([#1269](https://github.com/expo/eas-cli/pull/1269) by [@byCedric](https://github.com/byCedric))
+2 -2
View File
@@ -3,8 +3,8 @@
packages/eas-cli/src/build @dsokal @wkozyra95
packages/eas-cli/src/commands/build @dsokal @wkozyra95
packages/eas-cli/src/submit @barthap @dsokal
packages/eas-cli/src/commands/submit.ts @barthap @dsokal
packages/eas-cli/src/submit @dsokal
packages/eas-cli/src/commands/submit.ts @dsokal
packages/eas-cli/src/update @kgc00 @wschurman
packages/eas-cli/src/commands/update @kgc00 @wschurman
-130
View File
@@ -1,130 +0,0 @@
#!/bin/bash
# This script downloads the latest release version of EAS CLI from GitHub and
# installs it in /usr/local/bin
{
# All code is inside a block to ensure the script executes only when
# downloaded completely.
set -euo pipefail
prefix="${EAS_PREFIX:-/usr/local}"
temp_dir="$(mktemp -d)"
if [ -t 1 ] && [ -z "${NO_COLOR:-}" ]
then
# Use colors when stdout is a terminal and NO_COLOR isn't set.
text_bold=$'\033[1m'
text_normal=$'\033[22m'
text_red=$'\033[31m'
text_default_color=$'\033[39m'
else
# Disable colors
text_bold=""
text_normal=""
text_red=""
text_default_color=""
fi
abort() {
echo -e "$text_bold$text_red$1$text_normal$text_default_color"
exit 1
}
install() {
needs_sudo=""
# Make sure path exists and can be written to by the current user.
if ! mkdir -p "$prefix/lib" || [[ ! -w "$prefix/lib" ]]
then
needs_sudo=true
fi
if ! mkdir -p "$prefix/bin" || [[ ! -w "$prefix/bin" ]]
then
needs_sudo=true
fi
if ! rm -rf "$prefix/lib/eas"
then
needs_sudo=true
fi
# Run commands with sudo if necessary.
if [ -n "$needs_sudo" ]
then
if [ "$EUID" -ne 0 ]
then
echo "Installing requires superuser access."
echo "The sudo command will prompt for your password."
fi
sudo rm -rf "$prefix/lib/eas"
sudo mv "$temp_dir/eas" "$prefix/lib/eas"
sudo ln -fs "$prefix/lib/eas/bin/eas" "$prefix/bin/eas"
else
mv "$temp_dir/eas" "$prefix/lib/eas"
ln -fs "$prefix/lib/eas/bin/eas" "$prefix/bin/eas"
fi
}
if [[ ! ":$PATH:" == *":$prefix/bin:"* ]]; then
abort "Your path is missing $prefix/bin, you need to add this to \$PATH use this installer."
fi
hardware="$(uname -m)"
case "$hardware" in
x86_64)
arch="x64"
;;
arm*)
arch="arm"
;;
*)
abort "Unsupported CPU architecture $hardware."
;;
esac
case "$(uname -s)" in
Darwin*)
platform="darwin"
if [[ "$arch" != "x64" ]]; then
abort "Unsupported CPU architecture $hardware on macOS."
fi
;;
Linux*)
platform="linux"
;;
*)
abort "This installer is supported only on macOS, Linux, and Windows Subsystem for Linux."
;;
esac
url=$(hub release -L 1 | xargs hub release show --show-downloads | grep "${platform}-${arch}.tar.gz")
echo "Installing EAS CLI from $url"
mkdir -p "$temp_dir"
cd "$temp_dir"
echo
echo "Downloading..."
if [ "$(command -v curl)" ]
then
curl --location --progress-bar "$url" | tar xz
else
wget -O- "$url" | tar xz
fi
# Move the installation over and link the executable (may require sudo)
install
# Test the bundled node binary and if it doesn't work remove it (fall back to
# node installed in path).
"$prefix/lib/eas/bin/node" -v > /dev/null || {
rm "$prefix/lib/eas/bin/node"
}
# Test the CLI
executable=$(command -v eas) || abort "Could not run eas after installation."
echo
echo -e "EAS CLI is installed to ${executable}"
eas --version
echo
echo -e "Type ${text_bold}eas --help${text_normal} to get started."
}
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.60.0"
"version": "1.0.0"
}
+46 -46
View File
@@ -102,7 +102,7 @@ ALIASES
$ eas login
```
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/account/login.ts)_
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -119,7 +119,7 @@ ALIASES
$ eas logout
```
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -136,7 +136,7 @@ ALIASES
$ eas whoami
```
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/account/view.ts)_
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -150,7 +150,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/analytics.ts)_
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -199,7 +199,7 @@ DESCRIPTION
create a branch
```
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -219,7 +219,7 @@ DESCRIPTION
delete a branch
```
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -240,7 +240,7 @@ DESCRIPTION
list all branches
```
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -259,7 +259,7 @@ DESCRIPTION
rename a branch
```
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -283,7 +283,7 @@ DESCRIPTION
view a branch
```
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -313,7 +313,7 @@ DESCRIPTION
start a build
```
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/index.ts)_
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -327,7 +327,7 @@ DESCRIPTION
cancel a build
```
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -344,7 +344,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:inspect`
@@ -379,7 +379,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -412,7 +412,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/list.ts)_
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:submit`
@@ -459,7 +459,7 @@ DESCRIPTION
Update version of an app.
```
_See code: [src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/version/set.ts)_
_See code: [src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -478,7 +478,7 @@ DESCRIPTION
Update a version in native code with a value stored on EAS servers
```
_See code: [src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/version/sync.ts)_
_See code: [src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -495,7 +495,7 @@ DESCRIPTION
view a build for your project
```
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/build/view.ts)_
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -515,7 +515,7 @@ DESCRIPTION
create a channel
```
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -536,7 +536,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -553,7 +553,7 @@ DESCRIPTION
list all channels
```
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:view [NAME]`
@@ -573,7 +573,7 @@ DESCRIPTION
view a channel
```
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -591,7 +591,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -605,7 +605,7 @@ DESCRIPTION
manage credentials
```
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/credentials.ts)_
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/credentials.ts)_
## `eas device:create`
@@ -619,7 +619,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/device/create.ts)_
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -637,7 +637,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -654,7 +654,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/device/list.ts)_
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:view [UDID]`
@@ -668,7 +668,7 @@ DESCRIPTION
view a device for your project
```
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/device/view.ts)_
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -682,7 +682,7 @@ DESCRIPTION
display environment info
```
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -764,7 +764,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -781,7 +781,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas project:info`
@@ -795,7 +795,7 @@ DESCRIPTION
information about the current project
```
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/project/info.ts)_
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -812,7 +812,7 @@ ALIASES
$ eas init
```
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/project/init.ts)_
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas secret:create`
@@ -832,7 +832,7 @@ DESCRIPTION
create an environment secret on the current project or owner account
```
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/secret/create.ts)_
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/secret/create.ts)_
## `eas secret:delete`
@@ -849,7 +849,7 @@ DESCRIPTION
delete an environment secret by ID
```
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/secret/delete.ts)_
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/secret/delete.ts)_
## `eas secret:list`
@@ -863,7 +863,7 @@ DESCRIPTION
list environment secrets available for your current app
```
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/secret/list.ts)_
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/secret/list.ts)_
## `eas submit`
@@ -893,7 +893,7 @@ ALIASES
$ eas build:submit
```
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/submit.ts)_
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -923,7 +923,7 @@ DESCRIPTION
publish an update group
```
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/update/index.ts)_
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -940,7 +940,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -960,7 +960,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:list`
@@ -979,7 +979,7 @@ DESCRIPTION
view the recent updates for a branch
```
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/update/list.ts)_
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:view GROUPID`
@@ -999,7 +999,7 @@ DESCRIPTION
update group details
```
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/update/view.ts)_
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1019,7 +1019,7 @@ DESCRIPTION
create a webhook
```
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1036,7 +1036,7 @@ DESCRIPTION
delete a webhook
```
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1053,7 +1053,7 @@ DESCRIPTION
list webhooks
```
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1074,7 +1074,7 @@ DESCRIPTION
update a webhook
```
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1091,7 +1091,7 @@ DESCRIPTION
view a webhook
```
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.60.0/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v1.0.0/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
+1 -1
View File
@@ -14,7 +14,7 @@ generates:
dedupeOperationSuffix: true
hooks:
afterOneFileWrite:
- ./annotate-graphql-codegen.sh
- 'node ./scripts/annotate-graphql-codegen.js'
./graphql.schema.json:
plugins:
- 'introspection'
+290
View File
@@ -1008,6 +1008,30 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "githubAppInstallations",
"description": "GitHub App installations for an account",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "GitHubAppInstallation",
"ofType": null
}
}
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "googleServiceAccountKeys",
"description": "Android credentials for account",
@@ -15013,6 +15037,49 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "CreateGitHubAppInstallationInput",
"description": "",
"fields": null,
"inputFields": [
{
"name": "accountId",
"description": "",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "installationIdentifier",
"description": "",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"interfaces": null,
"enumValues": null,
"possibleTypes": null
},
{
"kind": "INPUT_OBJECT",
"name": "CreateIosSubmissionInput",
@@ -16503,6 +16570,197 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "GitHubAppInstallation",
"description": "",
"fields": [
{
"name": "account",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Account",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "actor",
"description": "",
"args": [],
"type": {
"kind": "INTERFACE",
"name": "Actor",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "id",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "installationIdentifier",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "GitHubAppInstallationMutation",
"description": "",
"fields": [
{
"name": "createGitHubAppInstallationForAccount",
"description": "Create a GitHub App installation for an Account",
"args": [
{
"name": "githubAppInstallationData",
"description": "",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "INPUT_OBJECT",
"name": "CreateGitHubAppInstallationInput",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "GitHubAppInstallation",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "deleteGitHubAppInstallation",
"description": "Delete a GitHub App installation by ID",
"args": [
{
"name": "githubAppInstallationId",
"description": "",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "GitHubAppInstallation",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "GitHubAppQuery",
"description": "",
"fields": [
{
"name": "appIdentifier",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "clientIdentifier",
"description": "",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "GoogleServiceAccountKey",
@@ -21659,6 +21917,22 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "githubAppInstallation",
"description": "Mutations for GitHub App installations",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "GitHubAppInstallationMutation",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "googleServiceAccountKey",
"description": "Mutations that modify a Google Service Account Key",
@@ -21894,6 +22168,22 @@
"name": "RootQuery",
"description": "",
"fields": [
{
"name": "GitHubApp",
"description": "Top-level query object for querying GitHub App information and resources it has access to.",
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "GitHubAppQuery",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "_doNotUse",
"description": "This is a placeholder field",
+10 -6
View File
@@ -1,7 +1,7 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "0.60.0",
"version": "1.0.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
@@ -14,9 +14,10 @@
"@expo/config-plugins": "5.0.1",
"@expo/config-types": "46.0.2",
"@expo/eas-build-job": "0.2.85",
"@expo/eas-json": "0.60.0",
"@expo/eas-json": "1.0.0",
"@expo/json-file": "8.2.36",
"@expo/multipart-body-parser": "1.1.0",
"@expo/package-manager": "0.0.56",
"@expo/pkcs12": "0.0.8",
"@expo/plist": "0.0.18",
"@expo/plugin-autocomplete": "1.4.0",
@@ -62,6 +63,7 @@
"ora": "5.1.0",
"pkg-dir": "4.2.0",
"promise-limit": "2.7.0",
"promise-retry": "2.0.1",
"prompts": "2.4.2",
"qrcode-terminal": "0.12.0",
"resolve-from": "5.0.0",
@@ -89,6 +91,7 @@
"@types/mime": "2.0.3",
"@types/node-fetch": "2.6.2",
"@types/node-forge": "1.0.4",
"@types/promise-retry": "1.1.3",
"@types/prompts": "2.0.14",
"@types/semver": "7.3.10",
"@types/tar": "6.1.2",
@@ -101,6 +104,7 @@
"memfs": "3.4.7",
"mockdate": "3.0.5",
"nock": "13.2.9",
"rimraf": "3.0.2",
"tempy": "0.7.0",
"ts-deepmerge": "2.0.5",
"ts-mockito": "2.6.1",
@@ -172,7 +176,7 @@
},
"update": {
"node": {
"version": "12.13.0"
"version": "18.6.0"
},
"s3": {
"templates": {
@@ -192,8 +196,8 @@
},
"repository": "expo/eas-cli",
"scripts": {
"postpack": "rm -f oclif.manifest.json",
"prepack": "./scripts/prepack.sh",
"postpack": "rimraf oclif.manifest.json",
"prepack": "rimraf build && yarn build && node ./scripts/prepack.js",
"pretarball-ci": "./scripts/pretarball-ci.sh",
"build": "tsc --project tsconfig.build.json",
"watch": "yarn build --watch --preserveWatchOutput",
@@ -201,7 +205,7 @@
"test": "jest",
"version": "yarn oclif readme && node scripts/patch-readme && git add README.md",
"generate-graphql-code": "graphql-codegen --config graphql-codegen.yml",
"clean": "rm -rf dist build tmp node_modules yarn-error.log"
"clean": "rimraf dist build tmp node_modules yarn-error.log"
},
"volta": {
"node": "18.6.0",
@@ -1,13 +1,15 @@
#!/usr/bin/env sh
const fs = require('fs/promises');
OUTFILE="src/graphql/generated.ts"
const path = './src/graphql/generated.ts';
content="/**
(async () => {
const generatedCode = await fs.readFile(path, 'utf8');
const comment = `/**
* This file was generated using GraphQL Codegen
* Command: yarn generate-graphql-code
* Run this during development for automatic type generation when editing GraphQL documents
* For more info and docs, visit https://graphql-code-generator.com/
*/
"
*/\n\n`;
printf '%s\n%s\n' "$content" "$(cat $OUTFILE)" > $OUTFILE
await fs.writeFile(path, comment + generatedCode);
})();
+1 -1
View File
@@ -1,4 +1,4 @@
const { promises: fs } = require('fs');
const fs = require('fs/promises');
(async () => {
// Patch `oclif readme` path and link generation
+7
View File
@@ -0,0 +1,7 @@
const spawn = require('@expo/spawn-async');
(async () => {
if (!process.env.CLI_SIZE_CHECK) {
await spawn('yarn', ['oclif', 'manifest'], { stdio: 'inherit' });
}
})();
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env bash
set -eo pipefail
rm -rf build
yarn build
if [ -z "$CLI_SIZE_CHECK" ]; then
yarn oclif manifest
fi
+2 -11
View File
@@ -243,11 +243,7 @@ type MaybeBuildFragment = BuildFragment | null;
export async function waitForBuildEndAsync(
{ buildIds, accountName }: { buildIds: string[]; accountName: string },
{
// 2 hours (max build time limit) + 10 minutes (possible queue time)
timeoutSec = 2 * 60 * 60 + 10 * 60,
intervalSec = 10,
} = {}
{ intervalSec = 10 } = {}
): Promise<MaybeBuildFragment[]> {
let spinner;
let originalSpinnerText;
@@ -259,8 +255,7 @@ export async function waitForBuildEndAsync(
originalSpinnerText = 'Waiting for builds to complete. You can press Ctrl+C to exit.';
spinner = ora('Waiting for builds to complete. You can press Ctrl+C to exit.').start();
}
const endTime = new Date().getTime() + timeoutSec * 1000;
while (new Date().getTime() <= endTime) {
while (true) {
const builds = await getBuildsSafelyAsync(buildIds);
const { refetch } =
builds.length === 1
@@ -271,10 +266,6 @@ export async function waitForBuildEndAsync(
}
await sleepAsync(intervalSec * 1000);
}
spinner.fail('Timed out');
throw new Error(
'Timeout reached! It is taking longer than expected to finish the build, aborting...'
);
}
async function getBuildsSafelyAsync(buildIds: string[]): Promise<MaybeBuildFragment[]> {
@@ -51,11 +51,11 @@ export default class MetadataPull extends EasCommand {
const relativePath = path.relative(process.cwd(), filePath);
Log.addNewLineIfNone();
Log.log(`🎉 Your store configuration is ready.
Log.log(`🎉 Your store config is ready.
- Update the ${chalk.bold(relativePath)} file to prepare the app information.
- Run ${chalk.bold('eas submit')} or manually upload a new app version to the app stores.
- Once the app is uploaded, run ${chalk.bold('eas metadata:push')} to sync the store configuration.
- Once the app is uploaded, run ${chalk.bold('eas metadata:push')} to sync the store config.
- ${learnMore('https://docs.expo.dev/eas-metadata/introduction/')}`);
} catch (error: any) {
handleMetadataError(error);
@@ -18,6 +18,7 @@ export const jester2: Actor = {
export const testUsername = jester.username;
export const testSlug = 'testApp';
export const testProjectId = '7ef93448-3bc7-4b57-be32-99326dcf24f0';
export const testBundleIdentifier = 'test.com.app';
export const testPackageName = 'test.com.app';
export const testExperienceName = `@${testUsername}/${testSlug}`;
@@ -35,6 +36,11 @@ export const testAppJson = {
sdkVersion: '38.0.0',
ios: { bundleIdentifier: testBundleIdentifier },
android: { package: testPackageName },
extra: {
eas: {
projectId: testProjectId,
},
},
};
export const testAppJsonWithDifferentOwner = {
+43
View File
@@ -105,6 +105,8 @@ export type Account = {
createdAt: Scalars['DateTime'];
/** Environment secrets for an account */
environmentSecrets: Array<EnvironmentSecret>;
/** GitHub App installations for an account */
githubAppInstallations: Array<GitHubAppInstallation>;
/** Android credentials for account */
googleServiceAccountKeys: Array<GoogleServiceAccountKey>;
id: Scalars['ID'];
@@ -2164,6 +2166,11 @@ export type CreateEnvironmentSecretInput = {
value: Scalars['String'];
};
export type CreateGitHubAppInstallationInput = {
accountId: Scalars['ID'];
installationIdentifier: Scalars['Int'];
};
export type CreateIosSubmissionInput = {
appId: Scalars['ID'];
archiveUrl?: InputMaybe<Scalars['String']>;
@@ -2402,6 +2409,38 @@ export type GetSignedAssetUploadSpecificationsResult = {
specifications: Array<Scalars['String']>;
};
export type GitHubAppInstallation = {
__typename?: 'GitHubAppInstallation';
account: Account;
actor?: Maybe<Actor>;
id: Scalars['ID'];
installationIdentifier: Scalars['Int'];
};
export type GitHubAppInstallationMutation = {
__typename?: 'GitHubAppInstallationMutation';
/** Create a GitHub App installation for an Account */
createGitHubAppInstallationForAccount: GitHubAppInstallation;
/** Delete a GitHub App installation by ID */
deleteGitHubAppInstallation: GitHubAppInstallation;
};
export type GitHubAppInstallationMutationCreateGitHubAppInstallationForAccountArgs = {
githubAppInstallationData: CreateGitHubAppInstallationInput;
};
export type GitHubAppInstallationMutationDeleteGitHubAppInstallationArgs = {
githubAppInstallationId: Scalars['ID'];
};
export type GitHubAppQuery = {
__typename?: 'GitHubAppQuery';
appIdentifier: Scalars['String'];
clientIdentifier: Scalars['String'];
};
export type GoogleServiceAccountKey = {
__typename?: 'GoogleServiceAccountKey';
account: Account;
@@ -3128,6 +3167,8 @@ export type RootMutation = {
emailSubscription: EmailSubscriptionMutation;
/** Mutations that create and delete EnvironmentSecrets */
environmentSecret: EnvironmentSecretMutation;
/** Mutations for GitHub App installations */
githubAppInstallation: GitHubAppInstallationMutation;
/** Mutations that modify a Google Service Account Key */
googleServiceAccountKey: GoogleServiceAccountKeyMutation;
/** Mutations that modify the build credentials for an iOS app */
@@ -3174,6 +3215,8 @@ export type RootMutationBuildJobArgs = {
export type RootQuery = {
__typename?: 'RootQuery';
/** Top-level query object for querying GitHub App information and resources it has access to. */
GitHubApp: GitHubAppQuery;
/**
* This is a placeholder field
* @deprecated Not used.
@@ -0,0 +1,128 @@
import path from 'path';
import { getStaticConfigFilePath, loadConfigAsync } from '../config';
import { MetadataValidationError } from '../errors';
describe(getStaticConfigFilePath, () => {
const projectDir = '/app';
it(`returns same file for store.config.json`, () => {
const metadataPath = 'store.config.json';
const expectedFile = path.join(projectDir, metadataPath);
expect(getStaticConfigFilePath({ projectDir, metadataPath })).toBe(expectedFile);
});
it(`returns store.config.json for store.config.js`, () => {
const metadataPath = 'store.config.js';
const expectedFile = path.join(projectDir, 'store.config.json');
expect(getStaticConfigFilePath({ projectDir, metadataPath })).toBe(expectedFile);
});
it(`returns store.staging.json file for store.staging.js`, () => {
const metadataPath = 'store.staging.js';
const expectedFile = path.join(projectDir, 'store.staging.json');
expect(getStaticConfigFilePath({ projectDir, metadataPath })).toBe(expectedFile);
});
// This shouldn't be used IRL, but it tests if this function is working properly
it(`returns custom-name.json file for custom-name.js`, () => {
const metadataPath = 'custom-name.js';
const expectedFile = path.join(projectDir, 'custom-name.json');
expect(getStaticConfigFilePath({ projectDir, metadataPath })).toBe(expectedFile);
});
});
describe(loadConfigAsync, () => {
const projectDir = path.resolve(__dirname, 'fixtures');
it(`throws when file doesn't exist`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'doesnt-exist.json' })
).rejects.toThrow('file not found');
});
it(`throws when validation errors are found without skipping validation`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid.config.json' })
).rejects.toThrow('errors found');
});
it(`returns config from "store.config.json"`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'store.config.json' })
).resolves.toHaveProperty('apple.copyright', 'ACME');
});
it(`returns config from "store.config.js"`, async () => {
const year = new Date().getFullYear();
await expect(
loadConfigAsync({ projectDir, metadataPath: 'store.config.js' })
).resolves.toHaveProperty('apple.copyright', `${year} ACME`);
});
it(`returns config from "store.function.js"`, async () => {
const year = new Date().getFullYear();
await expect(
loadConfigAsync({ projectDir, metadataPath: 'store.function.js' })
).resolves.toHaveProperty('apple.copyright', `${year} ACME`);
});
it(`returns config from "store.async.js"`, async () => {
const year = new Date().getFullYear();
await expect(
loadConfigAsync({ projectDir, metadataPath: 'store.async.js' })
).resolves.toHaveProperty('apple.copyright', `${year} ACME`);
});
it(`returns invalid config from "invalid.config.json`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid.config.json', skipValidation: true })
).resolves.toMatchObject({ configVersion: -1 });
});
it(`returns invalid config from "invalid.config.js`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid.config.js', skipValidation: true })
).resolves.toMatchObject({ configVersion: -1 });
});
it(`returns invalid config from "invalid.function.js`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid.function.js', skipValidation: true })
).resolves.toMatchObject({ configVersion: -1 });
});
it(`returns invalid config from "invalid.async.js`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid.async.js', skipValidation: true })
).resolves.toMatchObject({ configVersion: -1 });
});
it(`throws invalid config type from "invalid-type.config.json"`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid-type.config.json' })
).rejects.toThrow(MetadataValidationError);
});
it(`throws invalid config type from "invalid-type.config.js"`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid-type.config.js' })
).rejects.toThrow(MetadataValidationError);
});
it(`throws invalid config type from "invalid-type.function.js"`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid-type.function.js' })
).rejects.toThrow(MetadataValidationError);
});
it(`throws invalid config type from "invalid-type.async.js"`, async () => {
await expect(
loadConfigAsync({ projectDir, metadataPath: 'invalid-type.async.js' })
).rejects.toThrow(MetadataValidationError);
});
});
@@ -0,0 +1,3 @@
module.exports = async function () {
return await Promise.resolve(null);
};
@@ -0,0 +1 @@
module.exports = 1337;
@@ -0,0 +1,5 @@
[
{
"configVersion": -1
}
]
@@ -0,0 +1,3 @@
module.exports = function () {
return true;
};
@@ -0,0 +1,3 @@
module.exports = async function () {
return await Promise.resolve({ configVersion: -1 });
};
@@ -0,0 +1,3 @@
module.exports = {
configVersion: -1,
};
@@ -0,0 +1,3 @@
{
"configVersion": -1
}
@@ -0,0 +1,3 @@
module.exports = function () {
return { configVersion: -1 };
};
@@ -0,0 +1,5 @@
module.exports = async function () {
const config = require('./store.config.json');
config.apple.copyright = `${new Date().getFullYear()} ACME`;
return await Promise.resolve(config);
};
@@ -0,0 +1,5 @@
const config = require('./store.config.json');
config.apple.copyright = `${new Date().getFullYear()} ACME`;
module.exports = config;
@@ -0,0 +1,22 @@
{
"configVersion": 0,
"apple": {
"copyright": "ACME",
"info": {
"en-US": {
"title": "App title",
"subtitle": "Subtitle for your app",
"description": "A longer description of what your app does",
"keywords": [
"keyword"
],
"releaseNotes": "Bug fixes and improved stability",
"promoText": "Short tagline for your app",
"marketingUrl": "https://example.com/en/marketing",
"supportUrl": "https://example.com/en/support",
"privacyPolicyUrl": "https://example.com/en/privacy",
"privacyChoicesUrl": "https://example.com/en/choices"
}
}
}
}
@@ -0,0 +1,5 @@
module.exports = function () {
const config = require('./store.config.json');
config.apple.copyright = `${new Date().getFullYear()} ACME`;
return config;
};
+65
View File
@@ -1,9 +1,12 @@
import Ajv from 'ajv';
import assert from 'assert';
import fs from 'fs-extra';
import path from 'path';
import { AppleConfigReader } from './apple/config/reader';
import { AppleConfigWriter } from './apple/config/writer';
import { AppleMetadata } from './apple/types';
import { MetadataValidationError } from './errors';
export interface MetadataConfig {
/** The store configuration version */
@@ -12,6 +15,68 @@ export interface MetadataConfig {
apple?: AppleMetadata;
}
/**
* Resolve the dynamic config from the user.
* It supports methods, async methods, or objects (json).
*/
async function resolveDynamicConfigAsync(configFile: string): Promise<unknown> {
const userConfigOrFunction = await import(configFile).then(file => file.default ?? file);
return typeof userConfigOrFunction === 'function'
? await userConfigOrFunction()
: userConfigOrFunction;
}
/**
* Get the static configuration file path, based on the metadata context.
* This uses any custom name provided, but swaps out the extension for `.json`.
*/
export function getStaticConfigFilePath({
projectDir,
metadataPath,
}: {
projectDir: string;
metadataPath: string;
}): string {
const configFile = path.join(projectDir, metadataPath);
const configExtension = path.extname(configFile);
return path.join(projectDir, `${path.basename(configFile, configExtension)}.json`);
}
/**
* Load the store configuration from a metadata context.
* This can load `.json` and `.js` config files, using `require`.
* It throws MetadataValidationErrors when the file doesn't exist, or contains errors.
* The user is prompted to try anyway when errors are found.
*/
export async function loadConfigAsync({
projectDir,
metadataPath,
skipValidation = false,
}: {
projectDir: string;
metadataPath: string;
skipValidation?: boolean;
}): Promise<MetadataConfig> {
const configFile = path.join(projectDir, metadataPath);
if (!(await fs.pathExists(configFile))) {
throw new MetadataValidationError(`Metadata store config file not found: "${configFile}"`);
}
const configData = await resolveDynamicConfigAsync(configFile);
if (!skipValidation) {
const { valid, errors: validationErrors } = validateConfig(configData);
if (!valid) {
throw new MetadataValidationError(`Metadata store config errors found`, validationErrors);
}
}
return configData as MetadataConfig;
}
/**
* Run the JSON Schema validation to normalize defaults and flag early config errors.
* This includes validating the known store limitations for every configurable property.
+7 -6
View File
@@ -6,7 +6,7 @@ import Log from '../log';
import { confirmAsync } from '../prompts';
import { AppleData } from './apple/data';
import { createAppleTasks } from './apple/tasks';
import { createAppleWriter } from './config';
import { createAppleWriter, getStaticConfigFilePath } from './config';
import { MetadataContext, ensureMetadataAppStoreAuthenticatedAsync } from './context';
import { MetadataDownloadError, MetadataValidationError } from './errors';
import { subscribeTelemetry } from './utils/telemetry';
@@ -16,15 +16,16 @@ import { subscribeTelemetry } from './utils/telemetry';
* Note, only App Store is supported at this time.
*/
export async function downloadMetadataAsync(metadataCtx: MetadataContext): Promise<string> {
const filePath = path.resolve(metadataCtx.projectDir, metadataCtx.metadataPath);
const filePath = getStaticConfigFilePath(metadataCtx);
const fileExists = await fs.pathExists(filePath);
if (fileExists) {
const filePathRelative = path.relative(metadataCtx.projectDir, filePath);
const overwrite = await confirmAsync({
message: `Do you want to overwrite the existing store configuration "${metadataCtx.metadataPath}"?`,
message: `Do you want to overwrite the existing "${filePathRelative}"?`,
});
if (!overwrite) {
throw new MetadataValidationError(`Store configuration already exists at "${filePath}"`);
throw new MetadataValidationError(`Store config already exists at "${filePath}"`);
}
}
@@ -35,7 +36,7 @@ export async function downloadMetadataAsync(metadataCtx: MetadataContext): Promi
);
Log.addNewLineIfNone();
Log.log('Downloading App Store configuration...');
Log.log('Downloading App Store config...');
const errors: Error[] = [];
const config = createAppleWriter();
@@ -59,7 +60,7 @@ export async function downloadMetadataAsync(metadataCtx: MetadataContext): Promi
}
try {
await fs.writeJson(filePath, config.toSchema(), { spaces: 2 });
await fs.writeJSON(filePath, config.toSchema(), { spaces: 2 });
} finally {
unsubscribeTelemetry();
}
+25 -27
View File
@@ -1,12 +1,9 @@
import fs from 'fs-extra';
import path from 'path';
import { MetadataEvent } from '../analytics/events';
import Log from '../log';
import { confirmAsync } from '../prompts';
import { AppleData } from './apple/data';
import { createAppleTasks } from './apple/tasks';
import { createAppleReader, validateConfig } from './config';
import { MetadataConfig, createAppleReader, loadConfigAsync } from './config';
import { MetadataContext, ensureMetadataAppStoreAuthenticatedAsync } from './context';
import { MetadataUploadError, MetadataValidationError, logMetadataValidationError } from './errors';
import { subscribeTelemetry } from './utils/telemetry';
@@ -18,28 +15,7 @@ import { subscribeTelemetry } from './utils/telemetry';
export async function uploadMetadataAsync(
metadataCtx: MetadataContext
): Promise<{ appleLink: string }> {
const filePath = path.resolve(metadataCtx.projectDir, metadataCtx.metadataPath);
if (!(await fs.pathExists(filePath))) {
throw new MetadataValidationError(`Store configuration file not found "${filePath}"`);
}
const fileData = await fs.readJson(filePath);
const { valid, errors: validationErrors } = validateConfig(fileData);
if (!valid) {
const error = new MetadataValidationError(`Store configuration errors found`, validationErrors);
logMetadataValidationError(error);
Log.newLine();
Log.warn(
'Without further updates, the current store configuration may fail to be synchronized with the App Store or pass App Store review.'
);
const attempt = await confirmAsync({
message: 'Do you still want to push the store configuration?',
});
if (!attempt) {
throw error;
}
}
const storeConfig = await loadConfigWithValidationPromptAsync(metadataCtx);
const { app, auth } = await ensureMetadataAppStoreAuthenticatedAsync(metadataCtx);
const { unsubscribeTelemetry, executionId } = subscribeTelemetry(
MetadataEvent.APPLE_METADATA_UPLOAD,
@@ -50,7 +26,7 @@ export async function uploadMetadataAsync(
Log.log('Uploading App Store configuration...');
const errors: Error[] = [];
const config = createAppleReader(fileData);
const config = createAppleReader(storeConfig);
const tasks = createAppleTasks(metadataCtx, {
// We need to resolve a different version as soon as possible.
// This version is the parent model of all changes we are going to push.
@@ -83,3 +59,25 @@ export async function uploadMetadataAsync(
return { appleLink: `https://appstoreconnect.apple.com/apps/${app.id}/appstore` };
}
async function loadConfigWithValidationPromptAsync(
metadataCtx: MetadataContext
): Promise<MetadataConfig> {
try {
return await loadConfigAsync(metadataCtx);
} catch (error) {
if (error instanceof MetadataValidationError) {
logMetadataValidationError(error);
Log.newLine();
Log.warn(
'Without further updates, the current store configuration can fail to be synchronized with the App Store or pass App Store review.'
);
if (await confirmAsync({ message: 'Do you still want to push the store configuration?' })) {
return await loadConfigAsync({ ...metadataCtx, skipValidation: true });
}
}
throw error;
}
}
+1 -1
View File
@@ -56,7 +56,7 @@ export function ora(options?: Options | string): Ora {
// eslint-disable-next-line no-console
console.log = logReal;
// eslint-disable-next-line no-console
console.info = logReal;
console.info = infoReal;
// eslint-disable-next-line no-console
console.warn = warnReal;
// eslint-disable-next-line no-console
@@ -1,3 +1,4 @@
import { getConfig, modifyConfigAsync } from '@expo/config';
import { vol } from 'memfs';
import { confirmAsync } from '../../prompts';
@@ -10,6 +11,7 @@ import {
findProjectRootAsync,
getProjectAccountName,
getProjectAccountNameAsync,
getProjectIdAsync,
promptToCreateProjectIfNotExistsAsync,
} from '../projectUtils';
@@ -248,3 +250,28 @@ describe(promptToCreateProjectIfNotExistsAsync, () => {
expect(projectId).toBe(null);
});
});
describe(getProjectIdAsync, () => {
it('gets the project ID from app config if exists', async () => {
await expect(
getProjectIdAsync({ name: 'test', slug: 'test', extra: { eas: { projectId: '1234' } } })
).resolves.toEqual('1234');
});
it('fetches the project ID when not in app config, and sets it in the config', async () => {
jest.mocked(getConfig).mockReturnValue({ exp: { name: 'test', slug: 'test' } } as any);
jest.mocked(modifyConfigAsync).mockResolvedValue({
type: 'success',
config: { expo: { name: 'test', slug: 'test', extra: { eas: { projectId: '2345' } } } },
});
jest.mocked(ensureProjectExistsAsync).mockImplementation(async () => '2345');
const projectId = await getProjectIdAsync({ name: 'test', slug: 'test' }, {}, { cwd: '/app' });
expect(projectId).toBe('2345');
expect(modifyConfigAsync).toHaveBeenCalledTimes(1);
expect(modifyConfigAsync).toHaveBeenCalledWith('/app', {
extra: { eas: { projectId: '2345' } },
});
});
});
+6 -11
View File
@@ -129,24 +129,19 @@ export async function setProjectIdAsync(
export async function getProjectIdAsync(
exp: ExpoConfig,
options: { env?: Env } = {}
options: { env?: Env } = {},
findProjectRootOptions: {
cwd?: string;
defaultToProcessCwd?: boolean;
} = {}
): Promise<string> {
if (!process.env.EAS_ENABLE_PROJECT_ID) {
const privacy = toAppPrivacy(exp.privacy);
return await ensureProjectExistsAsync({
accountName: getProjectAccountName(exp, await ensureLoggedInAsync()),
projectName: exp.slug,
privacy,
});
}
const localProjectId = exp.extra?.eas?.projectId;
if (localProjectId) {
return localProjectId;
}
// Set the project ID if it is missing.
const projectDir = await findProjectRootAsync();
const projectDir = await findProjectRootAsync(findProjectRootOptions);
if (!projectDir) {
throw new Error('Please run this command inside a project directory.');
}
+13 -6
View File
@@ -11,8 +11,9 @@ import { AssetMetadataStatus, PartialManifestAsset } from '../graphql/generated'
import { PublishMutation } from '../graphql/mutations/PublishMutation';
import { PresignedPost } from '../graphql/mutations/UploadSessionMutation';
import { PublishQuery } from '../graphql/queries/PublishQuery';
import { uploadWithPresignedPostAsync } from '../uploads';
import { uploadWithPresignedPostWithRetryAsync } from '../uploads';
import { expoCommandAsync } from '../utils/expoCli';
import chunk from '../utils/expodash/chunk';
import uniqBy from '../utils/expodash/uniqBy';
export type PublishPlatform = Extract<'android' | 'ios', Platform>;
@@ -285,12 +286,18 @@ export async function uploadAssetsAsync(
const totalAssets = uniqueAssets.length;
updateSpinnerText?.(totalAssets, totalAssets);
let missingAssets = await filterOutAssetsThatAlreadyExistAsync(uniqueAssets);
const uniqueUploadedAssetCount = missingAssets.length;
const { specifications } = await PublishMutation.getUploadURLsAsync(
missingAssets.map(ma => ma.contentType)
);
const missingAssetChunks = chunk(missingAssets, 100);
const specifications: string[] = [];
for (const missingAssets of missingAssetChunks) {
const { specifications: chunkSpecifications } = await PublishMutation.getUploadURLsAsync(
missingAssets.map(ma => ma.contentType)
);
specifications.push(...chunkSpecifications);
}
updateSpinnerText?.(totalAssets, missingAssets.length);
const assetUploadPromiseLimit = promiseLimit(15);
@@ -300,7 +307,7 @@ export async function uploadAssetsAsync(
missingAssets.map((missingAsset, i) => {
assetUploadPromiseLimit(async () => {
const presignedPost: PresignedPost = JSON.parse(specifications[i]);
await uploadWithPresignedPostAsync(missingAsset.path, presignedPost);
await uploadWithPresignedPostWithRetryAsync(missingAsset.path, presignedPost);
});
}),
]);
+1 -7
View File
@@ -11,7 +11,6 @@ const APP_STORE_NAMES: Record<AppPlatform, string> = {
[AppPlatform.Ios]: 'Apple App Store Connect',
};
const CHECK_TIMEOUT_MS = 3600_000;
const CHECK_INTERVAL_MS = 5_000;
export async function waitForSubmissionsEndAsync(
@@ -25,9 +24,7 @@ export async function waitForSubmissionsEndAsync(
const spinner = ora(`Submitting`).start();
let time = new Date().getTime();
const timeoutTime = time + CHECK_TIMEOUT_MS;
while (time <= timeoutTime) {
while (true) {
const submissions = await Promise.all(
initialSubmissions.map(({ id }) => {
try {
@@ -76,11 +73,8 @@ export async function waitForSubmissionsEndAsync(
}
}
time = new Date().getTime();
await sleepAsync(CHECK_INTERVAL_MS);
}
spinner.warn('Timed out');
throw new Error('Timeout reached! It is taking longer than expected to complete, aborting...');
}
function getSingleSpinnerText(submission: SubmissionFragment): string {
+86 -24
View File
@@ -3,6 +3,7 @@ import FormData from 'form-data';
import fs from 'fs-extra';
import { Response } from 'node-fetch';
import nullthrows from 'nullthrows';
import promiseRetry from 'promise-retry';
import { URL } from 'url';
import fetch from './fetch';
@@ -18,7 +19,11 @@ export async function uploadFileAtPathToS3Async(
const presignedPost = await UploadSessionMutation.createUploadSessionAsync(type);
assert(presignedPost.fields.key, 'key is not specified in in presigned post');
const response = await uploadWithPresignedPostAsync(path, presignedPost, handleProgressEvent);
const response = await uploadWithPresignedPostWithProgressAsync(
path,
presignedPost,
handleProgressEvent
);
const location = nullthrows(
response.headers.get('location'),
`location does not exist in response headers (make sure you're uploading to AWS S3)`
@@ -27,11 +32,48 @@ export async function uploadFileAtPathToS3Async(
return { url, bucketKey: presignedPost.fields.key };
}
export async function uploadWithPresignedPostAsync(
export async function uploadWithPresignedPostWithRetryAsync(
file: string,
presignedPost: PresignedPost,
handleProgressEvent?: ProgressHandler
presignedPost: PresignedPost
): Promise<Response> {
return await promiseRetry(
async retry => {
// retry fetch errors (usually connection or DNS errors)
let response: Response;
try {
response = await uploadWithPresignedPostAsync(file, presignedPost);
} catch (e: any) {
return retry(e);
}
// retry 408, 429, 5xx as suggested by google
if (
response.status === 408 ||
response.status === 429 ||
(response.status >= 500 && response.status <= 599)
) {
return retry(new Error(`Presigned upload responded with a ${response.status} status`));
}
// don't retry other errors
if (!response.ok) {
throw new Error(`Presigned upload responded with a ${response.status} status`);
}
return response;
},
// retry parameters match google suggested defaults: https://cloud.google.com/storage/docs/retry-strategy#node.js
{
retries: 3,
factor: 2,
}
);
}
async function createPresignedPostFormDataAsync(
file: string,
presignedPost: PresignedPost
): Promise<{ form: FormData; fileSize: number }> {
const fileStat = await fs.stat(file);
const fileSize = fileStat.size;
const form = new FormData();
@@ -39,6 +81,30 @@ export async function uploadWithPresignedPostAsync(
form.append(fieldKey, fieldValue);
}
form.append('file', fs.createReadStream(file), { knownLength: fileSize });
return { form, fileSize };
}
async function uploadWithPresignedPostAsync(
file: string,
presignedPost: PresignedPost
): Promise<Response> {
const { form } = await createPresignedPostFormDataAsync(file, presignedPost);
const formHeaders = form.getHeaders();
return await fetch(presignedPost.url, {
method: 'POST',
body: form,
headers: {
...formHeaders,
},
});
}
async function uploadWithPresignedPostWithProgressAsync(
file: string,
presignedPost: PresignedPost,
handleProgressEvent: ProgressHandler
): Promise<Response> {
const { form, fileSize } = await createPresignedPostFormDataAsync(file, presignedPost);
const formHeaders = form.getHeaders();
const uploadPromise = fetch(presignedPost.url, {
method: 'POST',
@@ -49,27 +115,23 @@ export async function uploadWithPresignedPostAsync(
});
let currentSize = 0;
if (handleProgressEvent) {
form.addListener('data', (chunk: Buffer) => {
currentSize += Buffer.byteLength(chunk);
handleProgressEvent({
progress: {
total: fileSize,
percent: currentSize / fileSize,
transferred: currentSize,
},
});
form.addListener('data', (chunk: Buffer) => {
currentSize += Buffer.byteLength(chunk);
handleProgressEvent({
progress: {
total: fileSize,
percent: currentSize / fileSize,
transferred: currentSize,
},
});
try {
const response = await uploadPromise;
handleProgressEvent({ isComplete: true });
return response;
} catch (error: any) {
handleProgressEvent({ isComplete: true, error });
throw error;
}
} else {
return await uploadPromise;
});
try {
const response = await uploadPromise;
handleProgressEvent({ isComplete: true });
return response;
} catch (error: any) {
handleProgressEvent({ isComplete: true, error });
throw error;
}
}
+5 -2
View File
@@ -1,3 +1,4 @@
import * as PackageManagerUtils from '@expo/package-manager';
import spawnAsync from '@expo/spawn-async';
import { Errors } from '@oclif/core';
import chalk from 'chalk';
@@ -33,15 +34,17 @@ export default class GitClient extends Client {
Log.warn("It looks like you haven't initialized the git repository yet.");
Log.warn('EAS Build requires you to use a git repository for your project.');
const cwd = process.cwd();
const repoRoot = PackageManagerUtils.findWorkspaceRoot(cwd) ?? cwd;
const confirmInit = await confirmAsync({
message: `Would you like us to run 'git init' in the current directory for you?`,
message: `Would you like us to run 'git init' in ${repoRoot} for you?`,
});
if (!confirmInit) {
throw new Error(
'A git repository is required for building your project. Initialize it and run this command again.'
);
}
await spawnAsync('git', ['init']);
await spawnAsync('git', ['init'], { cwd: repoRoot });
Log.log("We're going to make an initial commit for your repository.");
+4 -3
View File
@@ -1,7 +1,7 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "0.60.0",
"version": "1.0.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
@@ -18,6 +18,7 @@
"devDependencies": {
"@types/fs-extra": "9.0.13",
"memfs": "3.4.7",
"rimraf": "3.0.2",
"typescript": "4.7.4"
},
"engines": {
@@ -32,9 +33,9 @@
"build": "tsc --project tsconfig.build.json",
"watch": "yarn build --watch --preserveWatchOutput",
"typecheck": "tsc",
"prepack": "rm -rf build && yarn build",
"prepack": "rimraf build && yarn build",
"test": "jest",
"clean": "rm -rf build node_modules yarn-error.log"
"clean": "rimraf build node_modules yarn-error.log"
},
"files": [
"/build"
Generated
+87 -37
View File
@@ -1386,6 +1386,22 @@
nullthrows "^1.1.1"
structured-headers "^0.4.1"
"@expo/[email protected]":
version "0.0.56"
resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-0.0.56.tgz#214a8db48752cde968827c20c5b54a88187b5422"
integrity sha512-PGk34uz4XDyhoNIlPh2D+BDsiXYuW2jXavTiax8d32uvHlRO6FN0cAsqlWD6fx3H2hRn8cU/leTuc4M7pYovCQ==
dependencies:
"@expo/json-file" "8.2.36"
"@expo/spawn-async" "^1.5.0"
ansi-regex "^5.0.0"
chalk "^4.0.0"
find-up "^5.0.0"
find-yarn-workspace-root "~2.0.0"
npm-package-arg "^7.0.0"
rimraf "^3.0.2"
split "^1.0.1"
sudo-prompt "9.1.1"
"@expo/[email protected]":
version "0.0.8"
resolved "https://registry.yarnpkg.com/@expo/pkcs12/-/pkcs12-0.0.8.tgz#40ddde3007d90d4fd58779670f1aabfa82ce2950"
@@ -1479,7 +1495,7 @@
dependencies:
cross-spawn "^6.0.5"
"@expo/[email protected]":
"@expo/[email protected]", "@expo/spawn-async@^1.5.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.7.0.tgz#3ab6082b24318cccc4e73b13464da91325555500"
integrity sha512-sqPAjOEFTrjaTybrh9SnPFLInDXcoMC06psEFmH68jLTmoipSQCq8GCEfIoHhxRDALWB+DsiwXJSbXlE/iVIIQ==
@@ -3881,6 +3897,13 @@
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3"
integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==
"@types/[email protected]":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@types/promise-retry/-/promise-retry-1.1.3.tgz#baab427419da9088a1d2f21bf56249c21b3dd43c"
integrity sha512-LxIlEpEX6frE3co3vCO2EUJfHIta1IOmhDlcAsR4GMMv9hev1iTI9VwberVGkePJAuLZs5rMucrV8CziCfuJMw==
dependencies:
"@types/retry" "*"
"@types/[email protected]":
version "2.0.14"
resolved "https://registry.yarnpkg.com/@types/prompts/-/prompts-2.0.14.tgz#10cb8899844bb0771cabe57c1becaaaca9a3b521"
@@ -3888,6 +3911,11 @@
dependencies:
"@types/node" "*"
"@types/retry@*":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a"
integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==
"@types/[email protected]":
version "7.3.10"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.10.tgz#5f19ee40cbeff87d916eedc8c2bfe2305d957f73"
@@ -4614,10 +4642,10 @@ before-after-hook@^2.2.0:
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e"
integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==
big-integer@^1.6.44:
version "1.6.48"
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e"
integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==
[email protected].x:
version "1.6.51"
resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686"
integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==
bin-links@^3.0.0:
version "3.0.0"
@@ -4650,19 +4678,19 @@ bl@^4.0.3, bl@^4.1.0:
inherits "^2.0.4"
readable-stream "^3.4.0"
bplist-creator@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.8.tgz#56b2a6e79e9aec3fc33bf831d09347d73794e79c"
integrity sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==
bplist-creator@0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.1.0.tgz#018a2d1b587f769e379ef5519103730f8963ba1e"
integrity sha512-sXaHZicyEEmY86WyueLTQesbeoH/mquvarJaQNbjuOQO+7gbFcDEWqKmcWA4cOTLzFlfgvkiVxolk1k5bBIpmg==
dependencies:
stream-buffers "~2.2.0"
stream-buffers "2.2.x"
bplist-parser@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e"
integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==
bplist-parser@0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.3.1.tgz#e1c90b2ca2a9f9474cc72f6862bbf3fee8341fd1"
integrity sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==
dependencies:
big-integer "^1.6.44"
big-integer "1.6.x"
brace-expansion@^1.1.7:
version "1.1.11"
@@ -6672,7 +6700,7 @@ [email protected]:
micromatch "^4.0.2"
pkg-dir "^4.2.0"
find-yarn-workspace-root@^2.0.0:
find-yarn-workspace-root@^2.0.0, find-yarn-workspace-root@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
@@ -7388,6 +7416,13 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hosted-git-info@^3.0.2:
version "3.0.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d"
integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==
dependencies:
lru-cache "^6.0.0"
hosted-git-info@^4.0.0, hosted-git-info@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961"
@@ -9820,6 +9855,16 @@ npm-normalize-package-bin@^1.0.0, npm-normalize-package-bin@^1.0.1:
resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2"
integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==
npm-package-arg@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-7.0.0.tgz#52cdf08b491c0c59df687c4c925a89102ef794a5"
integrity sha512-xXxr8y5U0kl8dVkz2oK7yZjPBvqM2fwaO5l3Yg13p03v8+E3qQcD0JNhHzjL1vyGgxcKkD0cco+NLR72iuPk3g==
dependencies:
hosted-git-info "^3.0.2"
osenv "^0.1.5"
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5:
version "8.1.5"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44"
@@ -10126,7 +10171,7 @@ os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
osenv@^0.1.4:
osenv@^0.1.4, osenv@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
@@ -10543,10 +10588,10 @@ [email protected], pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"
plist@^3.0.1:
version "3.0.4"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.4.tgz#a62df837e3aed2bb3b735899d510c4f186019cbe"
integrity sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==
plist@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.5.tgz#2cbeb52d10e3cdccccf0c11a63a85d830970a987"
integrity sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==
dependencies:
base64-js "^1.5.1"
xmlbuilder "^9.0.7"
@@ -10638,7 +10683,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/promise-limit/-/promise-limit-2.7.0.tgz#eb5737c33342a030eaeaecea9b3d3a93cb592b26"
integrity sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==
promise-retry@^2.0.1:
[email protected], promise-retry@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22"
integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==
@@ -11118,6 +11163,13 @@ rfdc@^1.3.0:
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
[email protected], rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
@@ -11125,13 +11177,6 @@ rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
dependencies:
glob "^7.1.3"
rimraf@~2.4.0:
version "2.4.5"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
@@ -11337,13 +11382,13 @@ signedsource@^1.0.0:
integrity sha1-HdrOSYF5j5O9gzlzgD2A1S6TrWo=
simple-plist@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.1.1.tgz#54367ca28bc5996a982c325c1c4a4c1a05f4047c"
integrity sha512-pKMCVKvZbZTsqYR6RKgLfBHkh2cV89GXcA/0CVPje3sOiNOnXA8+rp/ciAMZ7JRaUdLzlEM6JFfUn+fS6Nt3hg==
version "1.3.1"
resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.3.1.tgz#16e1d8f62c6c9b691b8383127663d834112fb017"
integrity sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==
dependencies:
bplist-creator "0.0.8"
bplist-parser "0.2.0"
plist "^3.0.1"
bplist-creator "0.1.0"
bplist-parser "0.3.1"
plist "^3.0.5"
sisteransi@^1.0.4, sisteransi@^1.0.5:
version "1.0.5"
@@ -11512,7 +11557,7 @@ split2@^3.0.0:
dependencies:
readable-stream "^3.0.0"
split@^1.0.0:
split@^1.0.0, split@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
@@ -11560,7 +11605,7 @@ stack-utils@^2.0.3:
dependencies:
escape-string-regexp "^2.0.0"
stream-buffers@~2.2.0:
[email protected].x:
version "2.2.0"
resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4"
integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=
@@ -11830,6 +11875,11 @@ sucrase@^3.20.0:
pirates "^4.0.1"
ts-interface-checker "^0.1.9"
[email protected]:
version "9.1.1"
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0"
integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA==
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"